sunvnet.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164
  1. /* sunvnet.c: Sun LDOM Virtual Network Driver.
  2. *
  3. * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
  4. */
  5. #include <linux/module.h>
  6. #include <linux/kernel.h>
  7. #include <linux/types.h>
  8. #include <linux/slab.h>
  9. #include <linux/delay.h>
  10. #include <linux/init.h>
  11. #include <linux/netdevice.h>
  12. #include <linux/ethtool.h>
  13. #include <linux/etherdevice.h>
  14. #include <asm/vio.h>
  15. #include <asm/ldc.h>
  16. #include "sunvnet.h"
  17. #define DRV_MODULE_NAME "sunvnet"
  18. #define PFX DRV_MODULE_NAME ": "
  19. #define DRV_MODULE_VERSION "1.0"
  20. #define DRV_MODULE_RELDATE "June 25, 2007"
  21. static char version[] __devinitdata =
  22. DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
  23. MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
  24. MODULE_DESCRIPTION("Sun LDOM virtual network driver");
  25. MODULE_LICENSE("GPL");
  26. MODULE_VERSION(DRV_MODULE_VERSION);
  27. /* Ordered from largest major to lowest */
  28. static struct vio_version vnet_versions[] = {
  29. { .major = 1, .minor = 0 },
  30. };
  31. static inline u32 vnet_tx_dring_avail(struct vio_dring_state *dr)
  32. {
  33. return vio_dring_avail(dr, VNET_TX_RING_SIZE);
  34. }
  35. static int vnet_handle_unknown(struct vnet_port *port, void *arg)
  36. {
  37. struct vio_msg_tag *pkt = arg;
  38. printk(KERN_ERR PFX "Received unknown msg [%02x:%02x:%04x:%08x]\n",
  39. pkt->type, pkt->stype, pkt->stype_env, pkt->sid);
  40. printk(KERN_ERR PFX "Resetting connection.\n");
  41. ldc_disconnect(port->vio.lp);
  42. return -ECONNRESET;
  43. }
  44. static int vnet_send_attr(struct vio_driver_state *vio)
  45. {
  46. struct vnet_port *port = to_vnet_port(vio);
  47. struct net_device *dev = port->vp->dev;
  48. struct vio_net_attr_info pkt;
  49. int i;
  50. memset(&pkt, 0, sizeof(pkt));
  51. pkt.tag.type = VIO_TYPE_CTRL;
  52. pkt.tag.stype = VIO_SUBTYPE_INFO;
  53. pkt.tag.stype_env = VIO_ATTR_INFO;
  54. pkt.tag.sid = vio_send_sid(vio);
  55. pkt.xfer_mode = VIO_DRING_MODE;
  56. pkt.addr_type = VNET_ADDR_ETHERMAC;
  57. pkt.ack_freq = 0;
  58. for (i = 0; i < 6; i++)
  59. pkt.addr |= (u64)dev->dev_addr[i] << ((5 - i) * 8);
  60. pkt.mtu = ETH_FRAME_LEN;
  61. viodbg(HS, "SEND NET ATTR xmode[0x%x] atype[0x%x] addr[%llx] "
  62. "ackfreq[%u] mtu[%llu]\n",
  63. pkt.xfer_mode, pkt.addr_type,
  64. (unsigned long long) pkt.addr,
  65. pkt.ack_freq,
  66. (unsigned long long) pkt.mtu);
  67. return vio_ldc_send(vio, &pkt, sizeof(pkt));
  68. }
  69. static int handle_attr_info(struct vio_driver_state *vio,
  70. struct vio_net_attr_info *pkt)
  71. {
  72. viodbg(HS, "GOT NET ATTR INFO xmode[0x%x] atype[0x%x] addr[%llx] "
  73. "ackfreq[%u] mtu[%llu]\n",
  74. pkt->xfer_mode, pkt->addr_type,
  75. (unsigned long long) pkt->addr,
  76. pkt->ack_freq,
  77. (unsigned long long) pkt->mtu);
  78. pkt->tag.sid = vio_send_sid(vio);
  79. if (pkt->xfer_mode != VIO_DRING_MODE ||
  80. pkt->addr_type != VNET_ADDR_ETHERMAC ||
  81. pkt->mtu != ETH_FRAME_LEN) {
  82. viodbg(HS, "SEND NET ATTR NACK\n");
  83. pkt->tag.stype = VIO_SUBTYPE_NACK;
  84. (void) vio_ldc_send(vio, pkt, sizeof(*pkt));
  85. return -ECONNRESET;
  86. } else {
  87. viodbg(HS, "SEND NET ATTR ACK\n");
  88. pkt->tag.stype = VIO_SUBTYPE_ACK;
  89. return vio_ldc_send(vio, pkt, sizeof(*pkt));
  90. }
  91. }
  92. static int handle_attr_ack(struct vio_driver_state *vio,
  93. struct vio_net_attr_info *pkt)
  94. {
  95. viodbg(HS, "GOT NET ATTR ACK\n");
  96. return 0;
  97. }
  98. static int handle_attr_nack(struct vio_driver_state *vio,
  99. struct vio_net_attr_info *pkt)
  100. {
  101. viodbg(HS, "GOT NET ATTR NACK\n");
  102. return -ECONNRESET;
  103. }
  104. static int vnet_handle_attr(struct vio_driver_state *vio, void *arg)
  105. {
  106. struct vio_net_attr_info *pkt = arg;
  107. switch (pkt->tag.stype) {
  108. case VIO_SUBTYPE_INFO:
  109. return handle_attr_info(vio, pkt);
  110. case VIO_SUBTYPE_ACK:
  111. return handle_attr_ack(vio, pkt);
  112. case VIO_SUBTYPE_NACK:
  113. return handle_attr_nack(vio, pkt);
  114. default:
  115. return -ECONNRESET;
  116. }
  117. }
  118. static void vnet_handshake_complete(struct vio_driver_state *vio)
  119. {
  120. struct vio_dring_state *dr;
  121. dr = &vio->drings[VIO_DRIVER_RX_RING];
  122. dr->snd_nxt = dr->rcv_nxt = 1;
  123. dr = &vio->drings[VIO_DRIVER_TX_RING];
  124. dr->snd_nxt = dr->rcv_nxt = 1;
  125. }
  126. /* The hypervisor interface that implements copying to/from imported
  127. * memory from another domain requires that copies are done to 8-byte
  128. * aligned buffers, and that the lengths of such copies are also 8-byte
  129. * multiples.
  130. *
  131. * So we align skb->data to an 8-byte multiple and pad-out the data
  132. * area so we can round the copy length up to the next multiple of
  133. * 8 for the copy.
  134. *
  135. * The transmitter puts the actual start of the packet 6 bytes into
  136. * the buffer it sends over, so that the IP headers after the ethernet
  137. * header are aligned properly. These 6 bytes are not in the descriptor
  138. * length, they are simply implied. This offset is represented using
  139. * the VNET_PACKET_SKIP macro.
  140. */
  141. static struct sk_buff *alloc_and_align_skb(struct net_device *dev,
  142. unsigned int len)
  143. {
  144. struct sk_buff *skb = netdev_alloc_skb(dev, len+VNET_PACKET_SKIP+8+8);
  145. unsigned long addr, off;
  146. if (unlikely(!skb))
  147. return NULL;
  148. addr = (unsigned long) skb->data;
  149. off = ((addr + 7UL) & ~7UL) - addr;
  150. if (off)
  151. skb_reserve(skb, off);
  152. return skb;
  153. }
  154. static int vnet_rx_one(struct vnet_port *port, unsigned int len,
  155. struct ldc_trans_cookie *cookies, int ncookies)
  156. {
  157. struct net_device *dev = port->vp->dev;
  158. unsigned int copy_len;
  159. struct sk_buff *skb;
  160. int err;
  161. err = -EMSGSIZE;
  162. if (unlikely(len < ETH_ZLEN || len > ETH_FRAME_LEN)) {
  163. dev->stats.rx_length_errors++;
  164. goto out_dropped;
  165. }
  166. skb = alloc_and_align_skb(dev, len);
  167. err = -ENOMEM;
  168. if (unlikely(!skb)) {
  169. dev->stats.rx_missed_errors++;
  170. goto out_dropped;
  171. }
  172. copy_len = (len + VNET_PACKET_SKIP + 7U) & ~7U;
  173. skb_put(skb, copy_len);
  174. err = ldc_copy(port->vio.lp, LDC_COPY_IN,
  175. skb->data, copy_len, 0,
  176. cookies, ncookies);
  177. if (unlikely(err < 0)) {
  178. dev->stats.rx_frame_errors++;
  179. goto out_free_skb;
  180. }
  181. skb_pull(skb, VNET_PACKET_SKIP);
  182. skb_trim(skb, len);
  183. skb->protocol = eth_type_trans(skb, dev);
  184. dev->stats.rx_packets++;
  185. dev->stats.rx_bytes += len;
  186. netif_rx(skb);
  187. return 0;
  188. out_free_skb:
  189. kfree_skb(skb);
  190. out_dropped:
  191. dev->stats.rx_dropped++;
  192. return err;
  193. }
  194. static int vnet_send_ack(struct vnet_port *port, struct vio_dring_state *dr,
  195. u32 start, u32 end, u8 vio_dring_state)
  196. {
  197. struct vio_dring_data hdr = {
  198. .tag = {
  199. .type = VIO_TYPE_DATA,
  200. .stype = VIO_SUBTYPE_ACK,
  201. .stype_env = VIO_DRING_DATA,
  202. .sid = vio_send_sid(&port->vio),
  203. },
  204. .dring_ident = dr->ident,
  205. .start_idx = start,
  206. .end_idx = end,
  207. .state = vio_dring_state,
  208. };
  209. int err, delay;
  210. hdr.seq = dr->snd_nxt;
  211. delay = 1;
  212. do {
  213. err = vio_ldc_send(&port->vio, &hdr, sizeof(hdr));
  214. if (err > 0) {
  215. dr->snd_nxt++;
  216. break;
  217. }
  218. udelay(delay);
  219. if ((delay <<= 1) > 128)
  220. delay = 128;
  221. } while (err == -EAGAIN);
  222. return err;
  223. }
  224. static u32 next_idx(u32 idx, struct vio_dring_state *dr)
  225. {
  226. if (++idx == dr->num_entries)
  227. idx = 0;
  228. return idx;
  229. }
  230. static u32 prev_idx(u32 idx, struct vio_dring_state *dr)
  231. {
  232. if (idx == 0)
  233. idx = dr->num_entries - 1;
  234. else
  235. idx--;
  236. return idx;
  237. }
  238. static struct vio_net_desc *get_rx_desc(struct vnet_port *port,
  239. struct vio_dring_state *dr,
  240. u32 index)
  241. {
  242. struct vio_net_desc *desc = port->vio.desc_buf;
  243. int err;
  244. err = ldc_get_dring_entry(port->vio.lp, desc, dr->entry_size,
  245. (index * dr->entry_size),
  246. dr->cookies, dr->ncookies);
  247. if (err < 0)
  248. return ERR_PTR(err);
  249. return desc;
  250. }
  251. static int put_rx_desc(struct vnet_port *port,
  252. struct vio_dring_state *dr,
  253. struct vio_net_desc *desc,
  254. u32 index)
  255. {
  256. int err;
  257. err = ldc_put_dring_entry(port->vio.lp, desc, dr->entry_size,
  258. (index * dr->entry_size),
  259. dr->cookies, dr->ncookies);
  260. if (err < 0)
  261. return err;
  262. return 0;
  263. }
  264. static int vnet_walk_rx_one(struct vnet_port *port,
  265. struct vio_dring_state *dr,
  266. u32 index, int *needs_ack)
  267. {
  268. struct vio_net_desc *desc = get_rx_desc(port, dr, index);
  269. struct vio_driver_state *vio = &port->vio;
  270. int err;
  271. if (IS_ERR(desc))
  272. return PTR_ERR(desc);
  273. viodbg(DATA, "vio_walk_rx_one desc[%02x:%02x:%08x:%08x:%lx:%lx]\n",
  274. desc->hdr.state, desc->hdr.ack,
  275. desc->size, desc->ncookies,
  276. desc->cookies[0].cookie_addr,
  277. desc->cookies[0].cookie_size);
  278. if (desc->hdr.state != VIO_DESC_READY)
  279. return 1;
  280. err = vnet_rx_one(port, desc->size, desc->cookies, desc->ncookies);
  281. if (err == -ECONNRESET)
  282. return err;
  283. desc->hdr.state = VIO_DESC_DONE;
  284. err = put_rx_desc(port, dr, desc, index);
  285. if (err < 0)
  286. return err;
  287. *needs_ack = desc->hdr.ack;
  288. return 0;
  289. }
  290. static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr,
  291. u32 start, u32 end)
  292. {
  293. struct vio_driver_state *vio = &port->vio;
  294. int ack_start = -1, ack_end = -1;
  295. end = (end == (u32) -1) ? prev_idx(start, dr) : next_idx(end, dr);
  296. viodbg(DATA, "vnet_walk_rx start[%08x] end[%08x]\n", start, end);
  297. while (start != end) {
  298. int ack = 0, err = vnet_walk_rx_one(port, dr, start, &ack);
  299. if (err == -ECONNRESET)
  300. return err;
  301. if (err != 0)
  302. break;
  303. if (ack_start == -1)
  304. ack_start = start;
  305. ack_end = start;
  306. start = next_idx(start, dr);
  307. if (ack && start != end) {
  308. err = vnet_send_ack(port, dr, ack_start, ack_end,
  309. VIO_DRING_ACTIVE);
  310. if (err == -ECONNRESET)
  311. return err;
  312. ack_start = -1;
  313. }
  314. }
  315. if (unlikely(ack_start == -1))
  316. ack_start = ack_end = prev_idx(start, dr);
  317. return vnet_send_ack(port, dr, ack_start, ack_end, VIO_DRING_STOPPED);
  318. }
  319. static int vnet_rx(struct vnet_port *port, void *msgbuf)
  320. {
  321. struct vio_dring_data *pkt = msgbuf;
  322. struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_RX_RING];
  323. struct vio_driver_state *vio = &port->vio;
  324. viodbg(DATA, "vnet_rx stype_env[%04x] seq[%016lx] rcv_nxt[%016lx]\n",
  325. pkt->tag.stype_env, pkt->seq, dr->rcv_nxt);
  326. if (unlikely(pkt->tag.stype_env != VIO_DRING_DATA))
  327. return 0;
  328. if (unlikely(pkt->seq != dr->rcv_nxt)) {
  329. printk(KERN_ERR PFX "RX out of sequence seq[0x%lx] "
  330. "rcv_nxt[0x%lx]\n", pkt->seq, dr->rcv_nxt);
  331. return 0;
  332. }
  333. dr->rcv_nxt++;
  334. /* XXX Validate pkt->start_idx and pkt->end_idx XXX */
  335. return vnet_walk_rx(port, dr, pkt->start_idx, pkt->end_idx);
  336. }
  337. static int idx_is_pending(struct vio_dring_state *dr, u32 end)
  338. {
  339. u32 idx = dr->cons;
  340. int found = 0;
  341. while (idx != dr->prod) {
  342. if (idx == end) {
  343. found = 1;
  344. break;
  345. }
  346. idx = next_idx(idx, dr);
  347. }
  348. return found;
  349. }
  350. static int vnet_ack(struct vnet_port *port, void *msgbuf)
  351. {
  352. struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING];
  353. struct vio_dring_data *pkt = msgbuf;
  354. struct net_device *dev;
  355. struct vnet *vp;
  356. u32 end;
  357. if (unlikely(pkt->tag.stype_env != VIO_DRING_DATA))
  358. return 0;
  359. end = pkt->end_idx;
  360. if (unlikely(!idx_is_pending(dr, end)))
  361. return 0;
  362. dr->cons = next_idx(end, dr);
  363. vp = port->vp;
  364. dev = vp->dev;
  365. if (unlikely(netif_queue_stopped(dev) &&
  366. vnet_tx_dring_avail(dr) >= VNET_TX_WAKEUP_THRESH(dr)))
  367. return 1;
  368. return 0;
  369. }
  370. static int vnet_nack(struct vnet_port *port, void *msgbuf)
  371. {
  372. /* XXX just reset or similar XXX */
  373. return 0;
  374. }
  375. static void maybe_tx_wakeup(struct vnet *vp)
  376. {
  377. struct net_device *dev = vp->dev;
  378. netif_tx_lock(dev);
  379. if (likely(netif_queue_stopped(dev))) {
  380. struct vnet_port *port;
  381. int wake = 1;
  382. list_for_each_entry(port, &vp->port_list, list) {
  383. struct vio_dring_state *dr;
  384. dr = &port->vio.drings[VIO_DRIVER_TX_RING];
  385. if (vnet_tx_dring_avail(dr) <
  386. VNET_TX_WAKEUP_THRESH(dr)) {
  387. wake = 0;
  388. break;
  389. }
  390. }
  391. if (wake)
  392. netif_wake_queue(dev);
  393. }
  394. netif_tx_unlock(dev);
  395. }
  396. static void vnet_event(void *arg, int event)
  397. {
  398. struct vnet_port *port = arg;
  399. struct vio_driver_state *vio = &port->vio;
  400. unsigned long flags;
  401. int tx_wakeup, err;
  402. spin_lock_irqsave(&vio->lock, flags);
  403. if (unlikely(event == LDC_EVENT_RESET ||
  404. event == LDC_EVENT_UP)) {
  405. vio_link_state_change(vio, event);
  406. spin_unlock_irqrestore(&vio->lock, flags);
  407. return;
  408. }
  409. if (unlikely(event != LDC_EVENT_DATA_READY)) {
  410. printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event);
  411. spin_unlock_irqrestore(&vio->lock, flags);
  412. return;
  413. }
  414. tx_wakeup = err = 0;
  415. while (1) {
  416. union {
  417. struct vio_msg_tag tag;
  418. u64 raw[8];
  419. } msgbuf;
  420. err = ldc_read(vio->lp, &msgbuf, sizeof(msgbuf));
  421. if (unlikely(err < 0)) {
  422. if (err == -ECONNRESET)
  423. vio_conn_reset(vio);
  424. break;
  425. }
  426. if (err == 0)
  427. break;
  428. viodbg(DATA, "TAG [%02x:%02x:%04x:%08x]\n",
  429. msgbuf.tag.type,
  430. msgbuf.tag.stype,
  431. msgbuf.tag.stype_env,
  432. msgbuf.tag.sid);
  433. err = vio_validate_sid(vio, &msgbuf.tag);
  434. if (err < 0)
  435. break;
  436. if (likely(msgbuf.tag.type == VIO_TYPE_DATA)) {
  437. if (msgbuf.tag.stype == VIO_SUBTYPE_INFO) {
  438. err = vnet_rx(port, &msgbuf);
  439. } else if (msgbuf.tag.stype == VIO_SUBTYPE_ACK) {
  440. err = vnet_ack(port, &msgbuf);
  441. if (err > 0)
  442. tx_wakeup |= err;
  443. } else if (msgbuf.tag.stype == VIO_SUBTYPE_NACK) {
  444. err = vnet_nack(port, &msgbuf);
  445. }
  446. } else if (msgbuf.tag.type == VIO_TYPE_CTRL) {
  447. err = vio_control_pkt_engine(vio, &msgbuf);
  448. if (err)
  449. break;
  450. } else {
  451. err = vnet_handle_unknown(port, &msgbuf);
  452. }
  453. if (err == -ECONNRESET)
  454. break;
  455. }
  456. spin_unlock(&vio->lock);
  457. if (unlikely(tx_wakeup && err != -ECONNRESET))
  458. maybe_tx_wakeup(port->vp);
  459. local_irq_restore(flags);
  460. }
  461. static int __vnet_tx_trigger(struct vnet_port *port)
  462. {
  463. struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING];
  464. struct vio_dring_data hdr = {
  465. .tag = {
  466. .type = VIO_TYPE_DATA,
  467. .stype = VIO_SUBTYPE_INFO,
  468. .stype_env = VIO_DRING_DATA,
  469. .sid = vio_send_sid(&port->vio),
  470. },
  471. .dring_ident = dr->ident,
  472. .start_idx = dr->prod,
  473. .end_idx = (u32) -1,
  474. };
  475. int err, delay;
  476. hdr.seq = dr->snd_nxt;
  477. delay = 1;
  478. do {
  479. err = vio_ldc_send(&port->vio, &hdr, sizeof(hdr));
  480. if (err > 0) {
  481. dr->snd_nxt++;
  482. break;
  483. }
  484. udelay(delay);
  485. if ((delay <<= 1) > 128)
  486. delay = 128;
  487. } while (err == -EAGAIN);
  488. return err;
  489. }
  490. struct vnet_port *__tx_port_find(struct vnet *vp, struct sk_buff *skb)
  491. {
  492. unsigned int hash = vnet_hashfn(skb->data);
  493. struct hlist_head *hp = &vp->port_hash[hash];
  494. struct hlist_node *n;
  495. struct vnet_port *port;
  496. hlist_for_each_entry(port, n, hp, hash) {
  497. if (!compare_ether_addr(port->raddr, skb->data))
  498. return port;
  499. }
  500. port = NULL;
  501. if (!list_empty(&vp->port_list))
  502. port = list_entry(vp->port_list.next, struct vnet_port, list);
  503. return port;
  504. }
  505. struct vnet_port *tx_port_find(struct vnet *vp, struct sk_buff *skb)
  506. {
  507. struct vnet_port *ret;
  508. unsigned long flags;
  509. spin_lock_irqsave(&vp->lock, flags);
  510. ret = __tx_port_find(vp, skb);
  511. spin_unlock_irqrestore(&vp->lock, flags);
  512. return ret;
  513. }
  514. static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
  515. {
  516. struct vnet *vp = netdev_priv(dev);
  517. struct vnet_port *port = tx_port_find(vp, skb);
  518. struct vio_dring_state *dr;
  519. struct vio_net_desc *d;
  520. unsigned long flags;
  521. unsigned int len;
  522. void *tx_buf;
  523. int i, err;
  524. if (unlikely(!port))
  525. goto out_dropped;
  526. spin_lock_irqsave(&port->vio.lock, flags);
  527. dr = &port->vio.drings[VIO_DRIVER_TX_RING];
  528. if (unlikely(vnet_tx_dring_avail(dr) < 2)) {
  529. if (!netif_queue_stopped(dev)) {
  530. netif_stop_queue(dev);
  531. /* This is a hard error, log it. */
  532. printk(KERN_ERR PFX "%s: BUG! Tx Ring full when "
  533. "queue awake!\n", dev->name);
  534. dev->stats.tx_errors++;
  535. }
  536. spin_unlock_irqrestore(&port->vio.lock, flags);
  537. return NETDEV_TX_BUSY;
  538. }
  539. d = vio_dring_cur(dr);
  540. tx_buf = port->tx_bufs[dr->prod].buf;
  541. skb_copy_from_linear_data(skb, tx_buf + VNET_PACKET_SKIP, skb->len);
  542. len = skb->len;
  543. if (len < ETH_ZLEN) {
  544. len = ETH_ZLEN;
  545. memset(tx_buf+VNET_PACKET_SKIP+skb->len, 0, len - skb->len);
  546. }
  547. d->hdr.ack = VIO_ACK_ENABLE;
  548. d->size = len;
  549. d->ncookies = port->tx_bufs[dr->prod].ncookies;
  550. for (i = 0; i < d->ncookies; i++)
  551. d->cookies[i] = port->tx_bufs[dr->prod].cookies[i];
  552. /* This has to be a non-SMP write barrier because we are writing
  553. * to memory which is shared with the peer LDOM.
  554. */
  555. wmb();
  556. d->hdr.state = VIO_DESC_READY;
  557. err = __vnet_tx_trigger(port);
  558. if (unlikely(err < 0)) {
  559. printk(KERN_INFO PFX "%s: TX trigger error %d\n",
  560. dev->name, err);
  561. d->hdr.state = VIO_DESC_FREE;
  562. dev->stats.tx_carrier_errors++;
  563. goto out_dropped_unlock;
  564. }
  565. dev->stats.tx_packets++;
  566. dev->stats.tx_bytes += skb->len;
  567. dr->prod = (dr->prod + 1) & (VNET_TX_RING_SIZE - 1);
  568. if (unlikely(vnet_tx_dring_avail(dr) < 2)) {
  569. netif_stop_queue(dev);
  570. if (vnet_tx_dring_avail(dr) > VNET_TX_WAKEUP_THRESH(dr))
  571. netif_wake_queue(dev);
  572. }
  573. spin_unlock_irqrestore(&port->vio.lock, flags);
  574. dev_kfree_skb(skb);
  575. dev->trans_start = jiffies;
  576. return NETDEV_TX_OK;
  577. out_dropped_unlock:
  578. spin_unlock_irqrestore(&port->vio.lock, flags);
  579. out_dropped:
  580. dev_kfree_skb(skb);
  581. dev->stats.tx_dropped++;
  582. return NETDEV_TX_OK;
  583. }
  584. static void vnet_tx_timeout(struct net_device *dev)
  585. {
  586. /* XXX Implement me XXX */
  587. }
  588. static int vnet_open(struct net_device *dev)
  589. {
  590. netif_carrier_on(dev);
  591. netif_start_queue(dev);
  592. return 0;
  593. }
  594. static int vnet_close(struct net_device *dev)
  595. {
  596. netif_stop_queue(dev);
  597. netif_carrier_off(dev);
  598. return 0;
  599. }
  600. static void vnet_set_rx_mode(struct net_device *dev)
  601. {
  602. /* XXX Implement multicast support XXX */
  603. }
  604. static int vnet_change_mtu(struct net_device *dev, int new_mtu)
  605. {
  606. if (new_mtu != ETH_DATA_LEN)
  607. return -EINVAL;
  608. dev->mtu = new_mtu;
  609. return 0;
  610. }
  611. static int vnet_set_mac_addr(struct net_device *dev, void *p)
  612. {
  613. return -EINVAL;
  614. }
  615. static void vnet_get_drvinfo(struct net_device *dev,
  616. struct ethtool_drvinfo *info)
  617. {
  618. strcpy(info->driver, DRV_MODULE_NAME);
  619. strcpy(info->version, DRV_MODULE_VERSION);
  620. }
  621. static u32 vnet_get_msglevel(struct net_device *dev)
  622. {
  623. struct vnet *vp = netdev_priv(dev);
  624. return vp->msg_enable;
  625. }
  626. static void vnet_set_msglevel(struct net_device *dev, u32 value)
  627. {
  628. struct vnet *vp = netdev_priv(dev);
  629. vp->msg_enable = value;
  630. }
  631. static const struct ethtool_ops vnet_ethtool_ops = {
  632. .get_drvinfo = vnet_get_drvinfo,
  633. .get_msglevel = vnet_get_msglevel,
  634. .set_msglevel = vnet_set_msglevel,
  635. .get_link = ethtool_op_get_link,
  636. .get_perm_addr = ethtool_op_get_perm_addr,
  637. };
  638. static void vnet_port_free_tx_bufs(struct vnet_port *port)
  639. {
  640. struct vio_dring_state *dr;
  641. int i;
  642. dr = &port->vio.drings[VIO_DRIVER_TX_RING];
  643. if (dr->base) {
  644. ldc_free_exp_dring(port->vio.lp, dr->base,
  645. (dr->entry_size * dr->num_entries),
  646. dr->cookies, dr->ncookies);
  647. dr->base = NULL;
  648. dr->entry_size = 0;
  649. dr->num_entries = 0;
  650. dr->pending = 0;
  651. dr->ncookies = 0;
  652. }
  653. for (i = 0; i < VNET_TX_RING_SIZE; i++) {
  654. void *buf = port->tx_bufs[i].buf;
  655. if (!buf)
  656. continue;
  657. ldc_unmap(port->vio.lp,
  658. port->tx_bufs[i].cookies,
  659. port->tx_bufs[i].ncookies);
  660. kfree(buf);
  661. port->tx_bufs[i].buf = NULL;
  662. }
  663. }
  664. static int __devinit vnet_port_alloc_tx_bufs(struct vnet_port *port)
  665. {
  666. struct vio_dring_state *dr;
  667. unsigned long len;
  668. int i, err, ncookies;
  669. void *dring;
  670. for (i = 0; i < VNET_TX_RING_SIZE; i++) {
  671. void *buf = kzalloc(ETH_FRAME_LEN + 8, GFP_KERNEL);
  672. int map_len = (ETH_FRAME_LEN + 7) & ~7;
  673. err = -ENOMEM;
  674. if (!buf) {
  675. printk(KERN_ERR "TX buffer allocation failure\n");
  676. goto err_out;
  677. }
  678. err = -EFAULT;
  679. if ((unsigned long)buf & (8UL - 1)) {
  680. printk(KERN_ERR "TX buffer misaligned\n");
  681. kfree(buf);
  682. goto err_out;
  683. }
  684. err = ldc_map_single(port->vio.lp, buf, map_len,
  685. port->tx_bufs[i].cookies, 2,
  686. (LDC_MAP_SHADOW |
  687. LDC_MAP_DIRECT |
  688. LDC_MAP_RW));
  689. if (err < 0) {
  690. kfree(buf);
  691. goto err_out;
  692. }
  693. port->tx_bufs[i].buf = buf;
  694. port->tx_bufs[i].ncookies = err;
  695. }
  696. dr = &port->vio.drings[VIO_DRIVER_TX_RING];
  697. len = (VNET_TX_RING_SIZE *
  698. (sizeof(struct vio_net_desc) +
  699. (sizeof(struct ldc_trans_cookie) * 2)));
  700. ncookies = VIO_MAX_RING_COOKIES;
  701. dring = ldc_alloc_exp_dring(port->vio.lp, len,
  702. dr->cookies, &ncookies,
  703. (LDC_MAP_SHADOW |
  704. LDC_MAP_DIRECT |
  705. LDC_MAP_RW));
  706. if (IS_ERR(dring)) {
  707. err = PTR_ERR(dring);
  708. goto err_out;
  709. }
  710. dr->base = dring;
  711. dr->entry_size = (sizeof(struct vio_net_desc) +
  712. (sizeof(struct ldc_trans_cookie) * 2));
  713. dr->num_entries = VNET_TX_RING_SIZE;
  714. dr->prod = dr->cons = 0;
  715. dr->pending = VNET_TX_RING_SIZE;
  716. dr->ncookies = ncookies;
  717. return 0;
  718. err_out:
  719. vnet_port_free_tx_bufs(port);
  720. return err;
  721. }
  722. static struct ldc_channel_config vnet_ldc_cfg = {
  723. .event = vnet_event,
  724. .mtu = 64,
  725. .mode = LDC_MODE_UNRELIABLE,
  726. };
  727. static struct vio_driver_ops vnet_vio_ops = {
  728. .send_attr = vnet_send_attr,
  729. .handle_attr = vnet_handle_attr,
  730. .handshake_complete = vnet_handshake_complete,
  731. };
  732. const char *remote_macaddr_prop = "remote-mac-address";
  733. static int __devinit vnet_port_probe(struct vio_dev *vdev,
  734. const struct vio_device_id *id)
  735. {
  736. struct mdesc_handle *hp;
  737. struct vnet_port *port;
  738. unsigned long flags;
  739. struct vnet *vp;
  740. const u64 *rmac;
  741. int len, i, err, switch_port;
  742. vp = dev_get_drvdata(vdev->dev.parent);
  743. if (!vp) {
  744. printk(KERN_ERR PFX "Cannot find port parent vnet.\n");
  745. return -ENODEV;
  746. }
  747. hp = mdesc_grab();
  748. rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len);
  749. err = -ENODEV;
  750. if (!rmac) {
  751. printk(KERN_ERR PFX "Port lacks %s property.\n",
  752. remote_macaddr_prop);
  753. goto err_out_put_mdesc;
  754. }
  755. port = kzalloc(sizeof(*port), GFP_KERNEL);
  756. err = -ENOMEM;
  757. if (!port) {
  758. printk(KERN_ERR PFX "Cannot allocate vnet_port.\n");
  759. goto err_out_put_mdesc;
  760. }
  761. for (i = 0; i < ETH_ALEN; i++)
  762. port->raddr[i] = (*rmac >> (5 - i) * 8) & 0xff;
  763. port->vp = vp;
  764. err = vio_driver_init(&port->vio, vdev, VDEV_NETWORK,
  765. vnet_versions, ARRAY_SIZE(vnet_versions),
  766. &vnet_vio_ops, vp->dev->name);
  767. if (err)
  768. goto err_out_free_port;
  769. err = vio_ldc_alloc(&port->vio, &vnet_ldc_cfg, port);
  770. if (err)
  771. goto err_out_free_port;
  772. err = vnet_port_alloc_tx_bufs(port);
  773. if (err)
  774. goto err_out_free_ldc;
  775. INIT_HLIST_NODE(&port->hash);
  776. INIT_LIST_HEAD(&port->list);
  777. switch_port = 0;
  778. if (mdesc_get_property(hp, vdev->mp, "switch-port", NULL) != NULL)
  779. switch_port = 1;
  780. spin_lock_irqsave(&vp->lock, flags);
  781. if (switch_port)
  782. list_add(&port->list, &vp->port_list);
  783. else
  784. list_add_tail(&port->list, &vp->port_list);
  785. hlist_add_head(&port->hash, &vp->port_hash[vnet_hashfn(port->raddr)]);
  786. spin_unlock_irqrestore(&vp->lock, flags);
  787. dev_set_drvdata(&vdev->dev, port);
  788. printk(KERN_INFO "%s: PORT ( remote-mac ", vp->dev->name);
  789. for (i = 0; i < 6; i++)
  790. printk("%2.2x%c", port->raddr[i], i == 5 ? ' ' : ':');
  791. if (switch_port)
  792. printk("switch-port ");
  793. printk(")\n");
  794. vio_port_up(&port->vio);
  795. mdesc_release(hp);
  796. return 0;
  797. err_out_free_ldc:
  798. vio_ldc_free(&port->vio);
  799. err_out_free_port:
  800. kfree(port);
  801. err_out_put_mdesc:
  802. mdesc_release(hp);
  803. return err;
  804. }
  805. static int vnet_port_remove(struct vio_dev *vdev)
  806. {
  807. struct vnet_port *port = dev_get_drvdata(&vdev->dev);
  808. if (port) {
  809. struct vnet *vp = port->vp;
  810. unsigned long flags;
  811. del_timer_sync(&port->vio.timer);
  812. spin_lock_irqsave(&vp->lock, flags);
  813. list_del(&port->list);
  814. hlist_del(&port->hash);
  815. spin_unlock_irqrestore(&vp->lock, flags);
  816. vnet_port_free_tx_bufs(port);
  817. vio_ldc_free(&port->vio);
  818. dev_set_drvdata(&vdev->dev, NULL);
  819. kfree(port);
  820. }
  821. return 0;
  822. }
  823. static struct vio_device_id vnet_port_match[] = {
  824. {
  825. .type = "vnet-port",
  826. },
  827. {},
  828. };
  829. MODULE_DEVICE_TABLE(vio, vnet_match);
  830. static struct vio_driver vnet_port_driver = {
  831. .id_table = vnet_port_match,
  832. .probe = vnet_port_probe,
  833. .remove = vnet_port_remove,
  834. .driver = {
  835. .name = "vnet_port",
  836. .owner = THIS_MODULE,
  837. }
  838. };
  839. const char *local_mac_prop = "local-mac-address";
  840. static int __devinit vnet_probe(struct vio_dev *vdev,
  841. const struct vio_device_id *id)
  842. {
  843. static int vnet_version_printed;
  844. struct mdesc_handle *hp;
  845. struct net_device *dev;
  846. struct vnet *vp;
  847. const u64 *mac;
  848. int err, i, len;
  849. if (vnet_version_printed++ == 0)
  850. printk(KERN_INFO "%s", version);
  851. hp = mdesc_grab();
  852. mac = mdesc_get_property(hp, vdev->mp, local_mac_prop, &len);
  853. if (!mac) {
  854. printk(KERN_ERR PFX "vnet lacks %s property.\n",
  855. local_mac_prop);
  856. err = -ENODEV;
  857. goto err_out;
  858. }
  859. dev = alloc_etherdev(sizeof(*vp));
  860. if (!dev) {
  861. printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
  862. err = -ENOMEM;
  863. goto err_out;
  864. }
  865. for (i = 0; i < ETH_ALEN; i++)
  866. dev->dev_addr[i] = (*mac >> (5 - i) * 8) & 0xff;
  867. memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
  868. SET_NETDEV_DEV(dev, &vdev->dev);
  869. vp = netdev_priv(dev);
  870. spin_lock_init(&vp->lock);
  871. vp->dev = dev;
  872. vp->vdev = vdev;
  873. INIT_LIST_HEAD(&vp->port_list);
  874. for (i = 0; i < VNET_PORT_HASH_SIZE; i++)
  875. INIT_HLIST_HEAD(&vp->port_hash[i]);
  876. dev->open = vnet_open;
  877. dev->stop = vnet_close;
  878. dev->set_multicast_list = vnet_set_rx_mode;
  879. dev->set_mac_address = vnet_set_mac_addr;
  880. dev->tx_timeout = vnet_tx_timeout;
  881. dev->ethtool_ops = &vnet_ethtool_ops;
  882. dev->watchdog_timeo = VNET_TX_TIMEOUT;
  883. dev->change_mtu = vnet_change_mtu;
  884. dev->hard_start_xmit = vnet_start_xmit;
  885. err = register_netdev(dev);
  886. if (err) {
  887. printk(KERN_ERR PFX "Cannot register net device, "
  888. "aborting.\n");
  889. goto err_out_free_dev;
  890. }
  891. printk(KERN_INFO "%s: Sun LDOM vnet ", dev->name);
  892. for (i = 0; i < 6; i++)
  893. printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
  894. dev_set_drvdata(&vdev->dev, vp);
  895. mdesc_release(hp);
  896. return 0;
  897. err_out_free_dev:
  898. free_netdev(dev);
  899. err_out:
  900. mdesc_release(hp);
  901. return err;
  902. }
  903. static int vnet_remove(struct vio_dev *vdev)
  904. {
  905. struct vnet *vp = dev_get_drvdata(&vdev->dev);
  906. if (vp) {
  907. /* XXX unregister port, or at least check XXX */
  908. unregister_netdevice(vp->dev);
  909. dev_set_drvdata(&vdev->dev, NULL);
  910. }
  911. return 0;
  912. }
  913. static struct vio_device_id vnet_match[] = {
  914. {
  915. .type = "network",
  916. },
  917. {},
  918. };
  919. MODULE_DEVICE_TABLE(vio, vnet_match);
  920. static struct vio_driver vnet_driver = {
  921. .id_table = vnet_match,
  922. .probe = vnet_probe,
  923. .remove = vnet_remove,
  924. .driver = {
  925. .name = "vnet",
  926. .owner = THIS_MODULE,
  927. }
  928. };
  929. static int __init vnet_init(void)
  930. {
  931. int err = vio_register_driver(&vnet_driver);
  932. if (!err) {
  933. err = vio_register_driver(&vnet_port_driver);
  934. if (err)
  935. vio_unregister_driver(&vnet_driver);
  936. }
  937. return err;
  938. }
  939. static void __exit vnet_exit(void)
  940. {
  941. vio_unregister_driver(&vnet_port_driver);
  942. vio_unregister_driver(&vnet_driver);
  943. }
  944. module_init(vnet_init);
  945. module_exit(vnet_exit);