axusbnet.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203
  1. /*
  2. * Change Logs
  3. * Date Author Notes
  4. * 2022-04-17 aozima the first version for CherryUSB.
  5. */
  6. #include <string.h>
  7. #include "usbh_core.h"
  8. #include "axusbnet.h"
  9. static const char *DEV_FORMAT = "/dev/u%d";
  10. #define USE_RTTHREAD (1)
  11. // #define RX_DUMP
  12. // #define TX_DUMP
  13. // #define DUMP_RAW
  14. #if USE_RTTHREAD
  15. #include <rtthread.h>
  16. #include <netif/ethernetif.h>
  17. #include <netdev.h>
  18. #endif /* USE_RTTHREAD */
  19. #define MAX_ADDR_LEN 6
  20. #define ETH_ALEN MAX_ADDR_LEN
  21. #define mdelay rt_thread_delay
  22. #define msleep rt_thread_delay
  23. #define deverr(dev, fmt, ...) USB_LOG_ERR(fmt, ##__VA_ARGS__)
  24. #define cpu_to_le16(a) (a)
  25. #define le32_to_cpus(a) (a)
  26. /* Generic MII registers. */
  27. #define MII_BMCR 0x00 /* Basic mode control register */
  28. #define MII_BMSR 0x01 /* Basic mode status register */
  29. #define MII_PHYSID1 0x02 /* PHYS ID 1 */
  30. #define MII_PHYSID2 0x03 /* PHYS ID 2 */
  31. #define MII_ADVERTISE 0x04 /* Advertisement control reg */
  32. #define MII_LPA 0x05 /* Link partner ability reg */
  33. #define MII_EXPANSION 0x06 /* Expansion register */
  34. #define MII_CTRL1000 0x09 /* 1000BASE-T control */
  35. #define MII_STAT1000 0x0a /* 1000BASE-T status */
  36. #define MII_MMD_CTRL 0x0d /* MMD Access Control Register */
  37. #define MII_MMD_DATA 0x0e /* MMD Access Data Register */
  38. #define MII_ESTATUS 0x0f /* Extended Status */
  39. #define MII_DCOUNTER 0x12 /* Disconnect counter */
  40. #define MII_FCSCOUNTER 0x13 /* False carrier counter */
  41. #define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
  42. #define MII_RERRCOUNTER 0x15 /* Receive error counter */
  43. #define MII_SREVISION 0x16 /* Silicon revision */
  44. #define MII_RESV1 0x17 /* Reserved... */
  45. #define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
  46. #define MII_PHYADDR 0x19 /* PHY address */
  47. #define MII_RESV2 0x1a /* Reserved... */
  48. #define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
  49. #define MII_NCONFIG 0x1c /* Network interface config */
  50. /* Basic mode control register. */
  51. #define BMCR_RESV 0x003f /* Unused... */
  52. #define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
  53. #define BMCR_CTST 0x0080 /* Collision test */
  54. #define BMCR_FULLDPLX 0x0100 /* Full duplex */
  55. #define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
  56. #define BMCR_ISOLATE 0x0400 /* Isolate data paths from MII */
  57. #define BMCR_PDOWN 0x0800 /* Enable low power state */
  58. #define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
  59. #define BMCR_SPEED100 0x2000 /* Select 100Mbps */
  60. #define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
  61. #define BMCR_RESET 0x8000 /* Reset to default state */
  62. #define BMCR_SPEED10 0x0000 /* Select 10Mbps */
  63. /* Advertisement control register. */
  64. #define ADVERTISE_SLCT 0x001f /* Selector bits */
  65. #define ADVERTISE_CSMA 0x0001 /* Only selector supported */
  66. #define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
  67. #define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
  68. #define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
  69. #define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
  70. #define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
  71. #define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
  72. #define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
  73. #define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
  74. #define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
  75. #define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
  76. #define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */
  77. #define ADVERTISE_RESV 0x1000 /* Unused... */
  78. #define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
  79. #define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
  80. #define ADVERTISE_NPAGE 0x8000 /* Next page bit */
  81. #define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
  82. ADVERTISE_CSMA)
  83. #define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
  84. ADVERTISE_100HALF | ADVERTISE_100FULL)
  85. struct mii_if_info {
  86. int phy_id;
  87. };
  88. struct usbnet
  89. {
  90. #if USE_RTTHREAD
  91. /* inherit from ethernet device */
  92. struct eth_device parent;
  93. #endif /* USE_RTTHREAD */
  94. struct usbh_axusbnet *class;
  95. uint8_t dev_addr[MAX_ADDR_LEN];
  96. uint8_t internalphy:1;
  97. uint8_t PhySelect:1;
  98. uint8_t OperationMode:1;
  99. struct mii_if_info mii;
  100. };
  101. typedef struct usbnet * usbnet_t;
  102. static struct usbnet usbh_axusbnet_eth_device;
  103. #define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
  104. static void dump_hex(const void *ptr, uint32_t buflen)
  105. {
  106. unsigned char *buf = (unsigned char*)ptr;
  107. int i, j;
  108. for (i=0; i<buflen; i+=16)
  109. {
  110. printf("%08X:", i);
  111. for (j=0; j<16; j++)
  112. if (i+j < buflen)
  113. {
  114. if ((j % 8) == 0) {
  115. printf(" ");
  116. }
  117. printf("%02X ", buf[i+j]);
  118. }
  119. else
  120. printf(" ");
  121. printf(" ");
  122. for (j=0; j<16; j++)
  123. if (i+j < buflen)
  124. printf("%c", __is_print(buf[i+j]) ? buf[i+j] : '.');
  125. printf("\n");
  126. }
  127. }
  128. #if defined(RX_DUMP) || defined(TX_DUMP)
  129. static void packet_dump(const char * msg, const struct pbuf* p)
  130. {
  131. rt_uint8_t header[6 + 6 + 2];
  132. rt_uint16_t type;
  133. pbuf_copy_partial(p, header, sizeof(header), 0);
  134. type = (header[12] << 8) | header[13];
  135. rt_kprintf("%02X:%02X:%02X:%02X:%02X:%02X <== %02X:%02X:%02X:%02X:%02X:%02X ",
  136. header[0], header[1], header[2], header[3], header[4], header[5],
  137. header[6], header[7], header[8], header[9], header[10], header[11]);
  138. switch (type)
  139. {
  140. case 0x0800:
  141. rt_kprintf("IPv4. ");
  142. break;
  143. case 0x0806:
  144. rt_kprintf("ARP. ");
  145. break;
  146. case 0x86DD:
  147. rt_kprintf("IPv6. ");
  148. break;
  149. default:
  150. rt_kprintf("%04X. ", type);
  151. break;
  152. }
  153. rt_kprintf("%s %d byte. \n", msg, p->tot_len);
  154. #ifdef DUMP_RAW
  155. const struct pbuf* q;
  156. rt_uint32_t i,j;
  157. rt_uint8_t *ptr;
  158. // rt_kprintf("%s %d byte\n", msg, p->tot_len);
  159. i=0;
  160. for(q=p; q != RT_NULL; q= q->next)
  161. {
  162. ptr = q->payload;
  163. for(j=0; j<q->len; j++)
  164. {
  165. if( (i%8) == 0 )
  166. {
  167. rt_kprintf(" ");
  168. }
  169. if( (i%16) == 0 )
  170. {
  171. rt_kprintf("\r\n");
  172. }
  173. rt_kprintf("%02X ", *ptr);
  174. i++;
  175. ptr++;
  176. }
  177. }
  178. rt_kprintf("\n\n");
  179. #endif /* DUMP_RAW */
  180. }
  181. #else
  182. #define packet_dump(...)
  183. #endif /* dump */
  184. static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
  185. u16 size, void *data)
  186. {
  187. int ret = 0;
  188. struct usbh_hubport *hport = dev->class->hport;
  189. struct usb_setup_packet *setup = hport->setup;
  190. setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
  191. setup->bRequest = cmd;
  192. setup->wValue = value;
  193. setup->wIndex = index;
  194. setup->wLength = size;
  195. ret = usbh_control_transfer(hport->ep0, setup, (uint8_t *)data);
  196. if (ret != 0) {
  197. USB_LOG_ERR("%s cmd=%d ret: %d\r\n", __FUNCTION__, cmd, ret);
  198. return ret;
  199. }
  200. _exit:
  201. return ret;
  202. }
  203. static int ax8817x_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
  204. u16 size, void *data)
  205. {
  206. int ret = 0;
  207. struct usbh_hubport *hport = dev->class->hport;
  208. struct usb_setup_packet *setup = hport->setup;
  209. setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
  210. setup->bRequest = cmd;
  211. setup->wValue = value;
  212. setup->wIndex = index;
  213. setup->wLength = size;
  214. ret = usbh_control_transfer(hport->ep0, setup, (uint8_t *)data);
  215. if (ret != 0) {
  216. USB_LOG_ERR("%s cmd=%d ret: %d\r\n", __FUNCTION__, cmd, ret);
  217. return ret;
  218. }
  219. _exit:
  220. return ret;
  221. }
  222. static int ax8817x_mdio_read(struct usbnet *dev, int phy_id, int loc)
  223. {
  224. // struct usbnet *dev = netdev_priv(netdev);
  225. u16 res, ret;
  226. u8 smsr;
  227. int i = 0;
  228. // res = kmalloc(2, GFP_ATOMIC);
  229. // if (!res)
  230. // return 0;
  231. do {
  232. ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, NULL);
  233. msleep(1);
  234. // smsr = (u8 *)&ret;
  235. ax8817x_read_cmd(dev, AX_CMD_READ_STATMNGSTS_REG, 0, 0, 1, &smsr);
  236. } while (!(smsr & AX_HOST_EN) && (i++ < 30));
  237. ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (uint16_t)loc, 2, &res);
  238. ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, NULL);
  239. // ret = *res & 0xffff;
  240. // kfree(res);
  241. return res;
  242. }
  243. /* same as above, but converts resulting value to cpu byte order */
  244. static int ax8817x_mdio_read_le(struct usbnet *netdev, int phy_id, int loc)
  245. {
  246. return (ax8817x_mdio_read(netdev, phy_id, loc));
  247. }
  248. static void
  249. ax8817x_mdio_write(struct usbnet *dev, int phy_id, int loc, int val)
  250. {
  251. // struct usbnet *dev = netdev_priv(netdev);
  252. u16 res;
  253. u8 smsr;
  254. int i = 0;
  255. // res = kmalloc(2, GFP_ATOMIC);
  256. // if (!res)
  257. // return;
  258. // smsr = (u8 *) res;
  259. do {
  260. ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, NULL);
  261. msleep(1);
  262. ax8817x_read_cmd(dev, AX_CMD_READ_STATMNGSTS_REG, 0, 0, 1, &smsr);
  263. } while (!(smsr & AX_HOST_EN) && (i++ < 30));
  264. // *res = val;
  265. res = val;
  266. ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (uint16_t)loc, 2, &res);
  267. ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, NULL);
  268. // kfree(res);
  269. }
  270. static void
  271. ax88772b_mdio_write(struct usbnet *dev, int phy_id, int loc, int val)
  272. {
  273. // struct usbnet *dev = netdev_priv(netdev);
  274. u16 res = val;
  275. // res = kmalloc(2, GFP_ATOMIC);
  276. // if (!res)
  277. // return;
  278. // *res = val;
  279. ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, NULL);
  280. ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (uint16_t)loc, 2, &res);
  281. if (loc == MII_ADVERTISE) {
  282. res = cpu_to_le16(BMCR_ANENABLE | BMCR_ANRESTART);
  283. ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (uint16_t)MII_BMCR, 2, &res);
  284. }
  285. ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, NULL);
  286. // kfree(res);
  287. }
  288. /* same as above, but converts new value to le16 byte order before writing */
  289. static void
  290. ax8817x_mdio_write_le(struct usbnet *netdev, int phy_id, int loc, int val)
  291. {
  292. ax8817x_mdio_write(netdev, phy_id, loc, cpu_to_le16(val));
  293. }
  294. static int access_eeprom_mac(struct usbnet *dev, u8 *buf, u8 offset, bool wflag)
  295. {
  296. int ret = 0, i;
  297. u16 *tmp = (u16 *)buf;
  298. if (wflag) {
  299. ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_EEPROM_EN,
  300. 0, 0, 0, NULL);
  301. if (ret < 0)
  302. return ret;
  303. mdelay(15);
  304. }
  305. for (i = 0; i < (ETH_ALEN >> 1); i++) {
  306. if (wflag) {
  307. // u16 wd = cpu_to_le16(*(tmp + i));
  308. u16 wd = (*(tmp + i));
  309. ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_EEPROM, offset + i,
  310. wd, 0, NULL);
  311. if (ret < 0)
  312. break;
  313. mdelay(15);
  314. } else {
  315. ret = ax8817x_read_cmd(dev, AX_CMD_READ_EEPROM,
  316. offset + i, 0, 2, tmp + i);
  317. if (ret < 0)
  318. break;
  319. }
  320. }
  321. if (!wflag) {
  322. if (ret < 0) {
  323. // #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
  324. // netdev_dbg(dev->net, "Failed to read MAC address from EEPROM: %d\n", ret);
  325. // #else
  326. // devdbg(dev, "Failed to read MAC address from EEPROM: %d\n", ret);
  327. // #endif
  328. USB_LOG_ERR("Failed to read MAC address from EEPROM: %d\n", ret);
  329. return ret;
  330. }
  331. // memcpy(dev->net->dev_addr, buf, ETH_ALEN);
  332. } else {
  333. ax8817x_write_cmd(dev, AX_CMD_WRITE_EEPROM_DIS,
  334. 0, 0, 0, NULL);
  335. if (ret < 0)
  336. return ret;
  337. /* reload eeprom data */
  338. ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
  339. AXGPIOS_RSE, 0, 0, NULL);
  340. if (ret < 0)
  341. return ret;
  342. }
  343. return 0;
  344. }
  345. static int ax88772a_phy_powerup(struct usbnet *dev)
  346. {
  347. int ret;
  348. /* set the embedded Ethernet PHY in power-down state */
  349. ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET,
  350. AX_SWRESET_IPPD | AX_SWRESET_IPRL, 0, 0, NULL);
  351. if (ret < 0) {
  352. deverr(dev, "Failed to power down PHY: %d", ret);
  353. return ret;
  354. }
  355. msleep(10);
  356. /* set the embedded Ethernet PHY in power-up state */
  357. ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPRL,
  358. 0, 0, NULL);
  359. if (ret < 0) {
  360. deverr(dev, "Failed to reset PHY: %d", ret);
  361. return ret;
  362. }
  363. msleep(600);
  364. /* set the embedded Ethernet PHY in reset state */
  365. ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_CLEAR,
  366. 0, 0, NULL);
  367. if (ret < 0) {
  368. deverr(dev, "Failed to power up PHY: %d", ret);
  369. return ret;
  370. }
  371. /* set the embedded Ethernet PHY in power-up state */
  372. ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPRL,
  373. 0, 0, NULL);
  374. if (ret < 0) {
  375. deverr(dev, "Failed to reset PHY: %d", ret);
  376. return ret;
  377. }
  378. return 0;
  379. }
  380. static int ax88772b_reset(struct usbnet *dev)
  381. {
  382. int ret;
  383. ret = ax88772a_phy_powerup(dev);
  384. if (ret < 0)
  385. return ret;
  386. /* Set the MAC address */
  387. ret = ax8817x_write_cmd(dev, AX88772_CMD_WRITE_NODE_ID,
  388. 0, 0, ETH_ALEN, dev->dev_addr);
  389. if (ret < 0) {
  390. deverr(dev, "set MAC address failed: %d", ret);
  391. }
  392. /* stop MAC operation */
  393. ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, AX_RX_CTL_STOP,
  394. 0, 0, NULL);
  395. if (ret < 0){
  396. deverr(dev, "Reset RX_CTL failed: %d", ret);
  397. }
  398. ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE,
  399. AX88772_MEDIUM_DEFAULT, 0, 0,
  400. NULL);
  401. if (ret < 0){
  402. deverr(dev, "Write medium mode register: %d", ret);
  403. }
  404. return ret;
  405. }
  406. static int ax8817x_get_mac(struct usbnet *dev, u8 *buf)
  407. {
  408. int ret, i;
  409. ret = access_eeprom_mac(dev, buf, 0x04, 0);
  410. if (ret < 0)
  411. goto out;
  412. // if (ax8817x_check_ether_addr(dev)) {
  413. // ret = access_eeprom_mac(dev, dev->net->dev_addr, 0x04, 1);
  414. // if (ret < 0) {
  415. // deverr(dev, "Failed to write MAC to EEPROM: %d", ret);
  416. // goto out;
  417. // }
  418. // msleep(5);
  419. // ret = ax8817x_read_cmd(dev, AX88772_CMD_READ_NODE_ID,
  420. // 0, 0, ETH_ALEN, buf);
  421. // if (ret < 0) {
  422. // deverr(dev, "Failed to read MAC address: %d", ret);
  423. // goto out;
  424. // }
  425. // for (i = 0; i < ETH_ALEN; i++)
  426. // if (*(dev->net->dev_addr + i) != *((u8 *)buf + i)) {
  427. // devwarn(dev, "Found invalid EEPROM part or non-EEPROM");
  428. // break;
  429. // }
  430. // }
  431. // memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN);
  432. // /* Set the MAC address */
  433. // ax8817x_write_cmd(dev, AX88772_CMD_WRITE_NODE_ID, 0, 0,
  434. // ETH_ALEN, dev->net->dev_addr);
  435. // if (ret < 0) {
  436. // deverr(dev, "Failed to write MAC address: %d", ret);
  437. // goto out;
  438. // }
  439. return 0;
  440. out:
  441. return ret;
  442. }
  443. #if USE_RTTHREAD
  444. static rt_err_t rt_rndis_eth_init(rt_device_t dev)
  445. {
  446. return RT_EOK;
  447. }
  448. static rt_err_t rt_rndis_eth_open(rt_device_t dev, rt_uint16_t oflag)
  449. {
  450. return RT_EOK;
  451. }
  452. static rt_err_t rt_rndis_eth_close(rt_device_t dev)
  453. {
  454. return RT_EOK;
  455. }
  456. static rt_size_t rt_rndis_eth_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  457. {
  458. rt_set_errno(-RT_ENOSYS);
  459. return 0;
  460. }
  461. static rt_size_t rt_rndis_eth_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  462. {
  463. rt_set_errno(-RT_ENOSYS);
  464. return 0;
  465. }
  466. static rt_err_t rt_rndis_eth_control(rt_device_t dev, int cmd, void *args)
  467. {
  468. usbnet_t rndis_eth_dev = (usbnet_t)dev;
  469. USB_LOG_INFO("%s L%d\r\n", __FUNCTION__, __LINE__);
  470. switch(cmd)
  471. {
  472. case NIOCTL_GADDR:
  473. /* get mac address */
  474. if(args)
  475. {
  476. USB_LOG_INFO("%s L%d NIOCTL_GADDR\r\n", __FUNCTION__, __LINE__);
  477. rt_memcpy(args, rndis_eth_dev->dev_addr, MAX_ADDR_LEN);
  478. }
  479. else
  480. {
  481. return -RT_ERROR;
  482. }
  483. break;
  484. default :
  485. break;
  486. }
  487. return RT_EOK;
  488. }
  489. /* reception packet. */
  490. static struct pbuf *rt_rndis_eth_rx(rt_device_t dev)
  491. {
  492. struct pbuf* p = RT_NULL;
  493. // USB_LOG_INFO("%s L%d\r\n", __FUNCTION__, __LINE__);
  494. return p;
  495. }
  496. /* transmit packet. */
  497. static rt_err_t rt_rndis_eth_tx(rt_device_t dev, struct pbuf* p)
  498. {
  499. int ret = 0;
  500. rt_err_t result = RT_EOK;
  501. uint8_t *tmp_buf = RT_NULL;
  502. usbnet_t rndis_eth = (usbnet_t)dev;
  503. struct usbh_axusbnet *class = rndis_eth->class;
  504. rt_tick_t tick_start, tick_end;
  505. uint8_t int_notify_buf[8];
  506. #ifdef TX_DUMP
  507. packet_dump("TX", p);
  508. #endif /* TX_DUMP */
  509. tmp_buf = (uint8_t *)rt_malloc(16 + p->tot_len );
  510. if (!tmp_buf) {
  511. USB_LOG_INFO("[%s L%d], no memory for pbuf, len=%d.", __FUNCTION__, __LINE__, p->tot_len);
  512. goto _exit;
  513. }
  514. uint32_t slen = p->tot_len;
  515. uint32_t head = slen;
  516. head = ((head ^ 0x0000ffff) << 16) + (head);
  517. tmp_buf[0] = head & 0xFF;
  518. tmp_buf[1] = (head >> 8) & 0xFF;
  519. tmp_buf[2] = (head >> 16) & 0xFF;
  520. tmp_buf[3] = (head >> 24) & 0xFF;
  521. slen += 4;
  522. int padlen = ((p->tot_len + 4) % 512) ? 0 : 4;
  523. if (padlen) {
  524. tmp_buf[4 + slen + 0] = 0x00;
  525. tmp_buf[4 + slen + 1] = 0x00;
  526. tmp_buf[4 + slen + 2] = 0xFF;
  527. tmp_buf[4 + slen + 3] = 0xFF;
  528. slen += 4;
  529. }
  530. pbuf_copy_partial(p, tmp_buf + 4, p->tot_len, 0);
  531. tick_start = rt_tick_get();
  532. ret = usbh_ep_bulk_transfer(class->bulkout, tmp_buf, slen, 500);
  533. if (ret < 0) {
  534. result = -RT_EIO;
  535. USB_LOG_ERR("%s L%d send over ret:%d\r\n", __FUNCTION__, __LINE__, ret);
  536. goto _exit;
  537. }
  538. tick_end = rt_tick_get();
  539. _exit:
  540. if(tmp_buf)
  541. {
  542. rt_free(tmp_buf);
  543. }
  544. return result;
  545. }
  546. #ifdef RT_USING_DEVICE_OPS
  547. const static struct rt_device_ops rndis_device_ops =
  548. {
  549. rt_rndis_eth_init,
  550. rt_rndis_eth_open,
  551. rt_rndis_eth_close,
  552. rt_rndis_eth_read,
  553. rt_rndis_eth_write,
  554. rt_rndis_eth_control
  555. }
  556. #endif /* RT_USING_DEVICE_OPS */
  557. #endif /* USE_RTTHREAD */
  558. static void rt_thread_axusbnet_entry(void *parameter)
  559. {
  560. int ret;
  561. struct usbh_hubport *hport;
  562. uint8_t intf;
  563. uint8_t buf[2+8];
  564. USB_LOG_INFO("%s L%d\r\n", __FUNCTION__, __LINE__);
  565. rt_thread_delay(200);
  566. USB_LOG_INFO("%s L%d\r\n\r\n\r\n\r\n", __FUNCTION__, __LINE__);
  567. const char *dname = "/dev/u0";
  568. struct usbh_axusbnet *class = (struct usbh_axusbnet *)usbh_find_class_instance(dname);
  569. if (class == NULL) {
  570. USB_LOG_ERR("do not find %s\r\n", dname);
  571. return;
  572. }
  573. USB_LOG_INFO("axusbnet=%p\r\n", dname);
  574. usbh_axusbnet_eth_device.class = class;
  575. struct usbnet *dev = &usbh_axusbnet_eth_device;
  576. ret = ax8817x_read_cmd(dev, AX_CMD_SW_PHY_STATUS,
  577. 0, 0, 1, buf);
  578. if (ret < 0) {
  579. USB_LOG_ERR("AX_CMD_SW_PHY_STATUS ret=%d\r\n", ret);
  580. return;
  581. }
  582. u8 tempphyselect = buf[0];
  583. if (tempphyselect == AX_PHYSEL_SSRMII) {
  584. USB_LOG_ERR("%s L%d AX_PHYSEL_SSRMII\r\n", __FUNCTION__, __LINE__);
  585. dev->internalphy = false;
  586. return;
  587. // dev->OperationMode = OPERATION_MAC_MODE;
  588. // dev->PhySelect = 0x00;
  589. } else if (tempphyselect == AX_PHYSEL_SSRRMII) {
  590. USB_LOG_ERR("%s L%d AX_PHYSEL_SSRRMII\r\n", __FUNCTION__, __LINE__);
  591. dev->internalphy = true;
  592. return;
  593. // dev->OperationMode = OPERATION_PHY_MODE;
  594. // dev->PhySelect = 0x00;
  595. } else if (tempphyselect == AX_PHYSEL_SSMII) {
  596. USB_LOG_INFO("%s L%d internalphy AX_PHYSEL_SSMII & OPERATION_MAC_MODE\r\n", __FUNCTION__, __LINE__);
  597. dev->internalphy = true;
  598. dev->OperationMode = OPERATION_MAC_MODE;
  599. dev->PhySelect = 0x01;
  600. } else {
  601. // deverr(dev, "Unknown MII type\n");
  602. USB_LOG_INFO("%s L%d Unknown MII type\r\n", __FUNCTION__, __LINE__);
  603. return;
  604. }
  605. /* reload eeprom data */
  606. ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, AXGPIOS_RSE, 0, 0, NULL);
  607. if (ret < 0) {
  608. USB_LOG_ERR("reload eeprom data ret=%d\r\n", ret);
  609. return;
  610. }
  611. /* Get the EEPROM data: power saving configuration*/
  612. ret = ax8817x_read_cmd(dev, AX_CMD_READ_EEPROM, 0x18, 0, 2, buf);
  613. if (ret < 0) {
  614. USB_LOG_ERR("read SROM address 18h failed: %d\r\n", ret);
  615. goto err_out;
  616. }
  617. USB_LOG_INFO("reading AX88772C psc: %02x %02x\r\n", buf[0], buf[1]);
  618. // le16_to_cpus(tmp16);
  619. // ax772b_data->psc = *tmp16 & 0xFF00;
  620. /* End of get EEPROM data */
  621. ret = ax8817x_get_mac(dev, buf);
  622. if (ret < 0) {
  623. USB_LOG_ERR("Get HW address failed: %d\r\n", ret);
  624. return;
  625. }
  626. dump_hex(buf, ETH_ALEN);
  627. memcpy(dev->dev_addr, buf, ETH_ALEN);
  628. uint16_t chipcode = 0xFFFF;
  629. {
  630. uint16_t smsr;
  631. // asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &chipcode, 0);
  632. ax8817x_read_cmd(dev, AX_CMD_READ_STATMNGSTS_REG, 0, 0, 1, &chipcode);
  633. USB_LOG_ERR("AX_CMD_READ_STATMNGSTS_REG ret: %d %04X\r\n", ret, chipcode);
  634. // #define AX_CHIPCODE_MASK 0x70
  635. // #define AX_AX88772_CHIPCODE 0x00
  636. // #define AX_AX88772A_CHIPCODE 0x10
  637. // #define AX_AX88772B_CHIPCODE 0x20
  638. // #define AX_HOST_EN 0x01
  639. chipcode &= 0x70;//AX_CHIPCODE_MASK; AX_AX88772_CHIPCODE
  640. if(chipcode == 0x00)
  641. {
  642. USB_LOG_ERR("AX_CMD_READ_STATMNGSTS_REG AX_AX88772_CHIPCODE\r\n");
  643. }
  644. else if(chipcode == 0x10)
  645. {
  646. USB_LOG_ERR("AX_CMD_READ_STATMNGSTS_REG AX_AX88772A_CHIPCODE\r\n");
  647. }
  648. else if(chipcode == 0x20)
  649. {
  650. USB_LOG_ERR("AX_CMD_READ_STATMNGSTS_REG AX_AX88772B_CHIPCODE\r\n");
  651. }
  652. }
  653. /* Get the PHY id: E0 10 */
  654. ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf);
  655. if (ret < 0) {
  656. USB_LOG_ERR("Error reading PHY ID: %02x\r\n", ret);
  657. return;
  658. }
  659. if (dev->internalphy) {
  660. dev->mii.phy_id = *((u8 *)buf + 1);
  661. } else {
  662. dev->mii.phy_id = *((u8 *)buf);
  663. }
  664. USB_LOG_INFO("reading %s PHY ID: %02x\r\n", dev->internalphy?"internal":"external", dev->mii.phy_id);
  665. ret = ax8817x_write_cmd(dev, AX_CMD_SW_PHY_SELECT, dev->PhySelect, 0, 0, NULL);
  666. if (ret < 0) {
  667. USB_LOG_ERR("Select PHY #1 failed: %d", ret);
  668. return;
  669. }
  670. ret = ax88772a_phy_powerup(dev);
  671. if (ret < 0) {
  672. USB_LOG_ERR("ax88772a_phy_powerup failed: %d", ret);
  673. return;
  674. }
  675. /* stop MAC operation */
  676. ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL,
  677. AX_RX_CTL_STOP, 0, 0, NULL);
  678. if (ret < 0) {
  679. USB_LOG_ERR("Reset RX_CTL failed: %d", ret);
  680. goto err_out;
  681. }
  682. /* make sure the driver can enable sw mii operation */
  683. ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, NULL);
  684. if (ret < 0) {
  685. USB_LOG_ERR("Enabling software MII failed: %d\r\n", ret);
  686. goto err_out;
  687. }
  688. if ((dev->OperationMode == OPERATION_MAC_MODE) &&
  689. (dev->PhySelect == 0x00)) {
  690. USB_LOG_ERR("not support the external phy\r\n");
  691. goto err_out;
  692. }
  693. if (dev->OperationMode == OPERATION_PHY_MODE) {
  694. ax8817x_mdio_write_le(dev, dev->mii.phy_id, MII_BMCR, 0x3900);
  695. }
  696. if (dev->mii.phy_id != 0x10)
  697. {
  698. USB_LOG_ERR("not support phy_id != 0x10\r\n");
  699. // ax8817x_mdio_write_le(dev->net, 0x10, MII_BMCR, 0x3900);
  700. }
  701. if (dev->mii.phy_id == 0x10 && dev->OperationMode != OPERATION_PHY_MODE) {
  702. u16 tmp16 = ax8817x_mdio_read_le(dev, dev->mii.phy_id, 0x12);
  703. ax8817x_mdio_write_le(dev, dev->mii.phy_id, 0x12, ((tmp16 & 0xFF9F) | 0x0040));
  704. }
  705. ax8817x_mdio_write_le(dev, dev->mii.phy_id, MII_ADVERTISE,
  706. ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
  707. // mii_nway_restart(&dev->mii);
  708. {
  709. /* if autoneg is off, it's an error */
  710. uint16_t bmcr = ax8817x_mdio_read_le(dev, dev->mii.phy_id, MII_BMCR);
  711. if (bmcr & BMCR_ANENABLE) {
  712. bmcr |= BMCR_ANRESTART;
  713. USB_LOG_ERR("BMCR_ANENABLE ==> BMCR_ANRESTART\r\n");
  714. ax8817x_mdio_write_le(dev, dev->mii.phy_id, MII_BMCR, bmcr);
  715. } else
  716. {
  717. USB_LOG_ERR("not BMCR_ANENABLE BMCR=%04X\r\n", bmcr);
  718. }
  719. }
  720. ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, 0, 0, 0, NULL);
  721. if (ret < 0) {
  722. USB_LOG_ERR("Failed to write medium mode: %d", ret);
  723. goto err_out;
  724. }
  725. ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0,
  726. AX88772A_IPG0_DEFAULT | AX88772A_IPG1_DEFAULT << 8,
  727. AX88772A_IPG2_DEFAULT, 0, NULL);
  728. if (ret < 0) {
  729. USB_LOG_ERR("Failed to write interframe gap: %d", ret);
  730. goto err_out;
  731. }
  732. memset(buf, 0, 4);
  733. ret = ax8817x_read_cmd(dev, AX_CMD_READ_IPG012, 0, 0, 3, buf);
  734. *((u8 *)buf + 3) = 0x00;
  735. if (ret < 0) {
  736. USB_LOG_ERR("Failed to read IPG,IPG1,IPG2 failed: %d", ret);
  737. goto err_out;
  738. } else {
  739. uint32_t tmp32 = *((u32*)buf);
  740. le32_to_cpus(&tmp32);
  741. if (tmp32 != (AX88772A_IPG2_DEFAULT << 16 |
  742. AX88772A_IPG1_DEFAULT << 8 | AX88772A_IPG0_DEFAULT)) {
  743. USB_LOG_ERR("Non-authentic ASIX product\nASIX does not support it\n");
  744. // ret = -ENODEV;
  745. goto err_out;
  746. }
  747. }
  748. // TODO: optimized for high speed.
  749. ret = ax8817x_write_cmd(dev, 0x2A, 0x8000, 0x8001, 0, NULL);
  750. if (ret < 0) {
  751. USB_LOG_ERR("Reset RX_CTL failed: %d", ret);
  752. goto err_out;
  753. }
  754. ret = ax88772b_reset(dev);
  755. if (ret < 0) {
  756. USB_LOG_ERR("ax88772b_reset failed: %d", ret);
  757. goto err_out;
  758. }
  759. // OUT 29 0 0 0 AX_CMD_WRITE_MONITOR_MODE
  760. ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, 0, 0, 0, NULL);
  761. if (ret < 0) {
  762. deverr(dev, "AX_CMD_WRITE_MONITOR_MODE failed: %d", ret);
  763. }
  764. /* Set the MAC address */
  765. ret = ax8817x_write_cmd(dev, AX88772_CMD_WRITE_NODE_ID,
  766. 0, 0, ETH_ALEN, dev->dev_addr);
  767. if (ret < 0) {
  768. deverr(dev, "set MAC address failed: %d", ret);
  769. }
  770. // update Multicast AX_CMD_WRITE_MULTI_FILTER.
  771. const uint8_t multi_filter[] = {0x00, 0x00, 0x20, 0x80, 0x00, 0x00, 0x00, 0x40};
  772. ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, AX_MCAST_FILTER_SIZE, (void *)multi_filter);
  773. if (ret < 0) {
  774. USB_LOG_ERR("Reset RX_CTL failed: %d", ret);
  775. goto err_out;
  776. }
  777. /* Configure RX header type */
  778. // u16 rx_reg = (AX_RX_CTL_PRO | AX_RX_CTL_AMALL | AX_RX_CTL_START | AX_RX_CTL_AB | AX_RX_HEADER_DEFAULT);
  779. u16 rx_reg = (AX_RX_CTL_AB | AX_RX_CTL_AM | AX_RX_CTL_START);
  780. ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, rx_reg, 0, 0, NULL);
  781. if (ret < 0) {
  782. USB_LOG_ERR("Reset RX_CTL failed: %d", ret);
  783. goto err_out;
  784. }
  785. /* set the embedded Ethernet PHY in power-up state */
  786. // ax772b_data->psc = *tmp16 & 0xFF00;
  787. // psc: 15 5a AX88772C psc: %02x %02x\r\n", buf[0], buf[1]);
  788. ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPRL | (0x5a00 & 0x7FFF),
  789. 0, 0, NULL);
  790. if (ret < 0) {
  791. deverr(dev, "Failed to reset PHY: %d", ret);
  792. // return ret;
  793. }
  794. rt_thread_delay(1000);
  795. u16 mode = AX88772_MEDIUM_DEFAULT;
  796. ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
  797. if (ret < 0) {
  798. USB_LOG_ERR("AX_CMD_WRITE_MEDIUM_MODE failed: %d", ret);
  799. goto err_out;
  800. }
  801. #if USE_RTTHREAD
  802. #ifdef RT_USING_DEVICE_OPS
  803. usbh_axusbnet_eth_device.parent.parent.ops = &rndis_device_ops;
  804. #else
  805. usbh_axusbnet_eth_device.parent.parent.init = rt_rndis_eth_init;
  806. usbh_axusbnet_eth_device.parent.parent.open = rt_rndis_eth_open;
  807. usbh_axusbnet_eth_device.parent.parent.close = rt_rndis_eth_close;
  808. usbh_axusbnet_eth_device.parent.parent.read = rt_rndis_eth_read;
  809. usbh_axusbnet_eth_device.parent.parent.write = rt_rndis_eth_write;
  810. usbh_axusbnet_eth_device.parent.parent.control = rt_rndis_eth_control;
  811. #endif
  812. usbh_axusbnet_eth_device.parent.parent.user_data = RT_NULL;
  813. usbh_axusbnet_eth_device.parent.eth_rx = rt_rndis_eth_rx;
  814. usbh_axusbnet_eth_device.parent.eth_tx = rt_rndis_eth_tx;
  815. usbh_axusbnet_eth_device.class = class;
  816. eth_device_init(&usbh_axusbnet_eth_device.parent, "u0");
  817. eth_device_linkchange(&usbh_axusbnet_eth_device.parent, RT_FALSE);
  818. #endif /* USE_RTTHREAD */
  819. // check link status.
  820. {
  821. u16 bmcr = ax8817x_mdio_read_le(dev, dev->mii.phy_id, MII_BMCR);
  822. u16 mode = AX88772_MEDIUM_DEFAULT;
  823. USB_LOG_ERR("%s L%d MII_BMCR=%04X\r\n", __FUNCTION__, __LINE__, bmcr);
  824. if (!(bmcr & BMCR_FULLDPLX))
  825. {
  826. mode &= ~AX88772_MEDIUM_FULL_DUPLEX;
  827. USB_LOG_ERR("%s L%d not AX88772_MEDIUM_FULL_DUPLEX\r\n", __FUNCTION__, __LINE__);
  828. }
  829. if (!(bmcr & BMCR_SPEED100))
  830. {
  831. mode &= ~AX88772_MEDIUM_100MB;
  832. USB_LOG_ERR("%s L%d not AX88772_MEDIUM_100MB\r\n", __FUNCTION__, __LINE__);
  833. }
  834. ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
  835. }
  836. while (1)
  837. {
  838. // USB_LOG_INFO("%s L%d\r\n", __FUNCTION__, __LINE__);
  839. ret = usbh_ep_bulk_transfer(class->bulkin, class->bulkin_buf, sizeof(class->bulkin_buf), 1000);
  840. if (ret < 0) {
  841. if (ret != -2) {
  842. USB_LOG_ERR("%s L%d bulk in error ret=%d\r\n", __FUNCTION__, __LINE__, ret);
  843. }
  844. continue;
  845. }
  846. {
  847. const uint8_t *data = class->bulkin_buf;
  848. uint16_t len1, len2;
  849. len1 = data[0] | ((uint16_t)(data[1])<<8);
  850. len2 = data[2] | ((uint16_t)(data[3])<<8);
  851. // USB_LOG_INFO("transfer bulkin len1:%04X, len2:%04X, len2':%04X.\r\n", len1, len2, ~len2);
  852. len1 &= 0x07ff;
  853. if (data[0] != ((uint8_t)(~data[2]))) {
  854. USB_LOG_ERR("transfer bulkin len1:%04X, len2:%04X, len2':%04X.\r\n", len1, len2, ~len2);
  855. dump_hex(data, 32);
  856. continue;
  857. }
  858. #if !USE_RTTHREAD
  859. {
  860. static uint32_t count = 0;
  861. USB_LOG_INFO("recv: #%d, len=%d\r\n", count, ret);
  862. dump_hex(data+4, 32);
  863. if ((count % 10) == 0) {
  864. // 192.168.89.14 ==> 255.255.255.255:7 echo hello world!
  865. const uint8_t packet_bytes[] = {
  866. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
  867. 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
  868. 0x00, 0x36, 0xb0, 0xfd, 0x00, 0x00, 0x80, 0x11,
  869. 0x00, 0x00, 0xc0, 0xa8, 0x59, 0x0e, 0xff, 0xff,
  870. 0xff, 0xff, 0x00, 0x07, 0x00, 0x07, 0x00, 0x22,
  871. 0x53, 0x06, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20,
  872. 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x66, 0x72,
  873. 0x6f, 0x6d, 0x20, 0x41, 0x58, 0x38, 0x38, 0x37,
  874. 0x37, 0x32, 0x43, 0x2e
  875. };
  876. uint8_t *send_buf = (uint8_t *)class->bulkin_buf;
  877. send_buf[0] = sizeof(packet_bytes);
  878. send_buf[1] = sizeof(packet_bytes) >> 8;
  879. send_buf[2] = ~send_buf[0];
  880. send_buf[3] = ~send_buf[1];
  881. memcpy(send_buf+4, packet_bytes, sizeof(packet_bytes));
  882. memcpy(send_buf+4+6, dev->dev_addr, 6);// update src mac.
  883. ret = usbh_ep_bulk_transfer(class->bulkout, send_buf, 4 + sizeof(packet_bytes), 500);
  884. USB_LOG_INFO("bulkout, ret=%d\r\n", ret);
  885. dump_hex(send_buf, 64);
  886. }
  887. count++;
  888. }
  889. #endif /* RT-Thread */
  890. #if USE_RTTHREAD
  891. {
  892. static uint32_t count = 0;
  893. if (count == 0) {
  894. eth_device_linkchange(&usbh_axusbnet_eth_device.parent, RT_TRUE);
  895. }
  896. count++;
  897. }
  898. /* allocate buffer */
  899. struct pbuf *p = RT_NULL;
  900. p = pbuf_alloc(PBUF_LINK, len1, PBUF_RAM);
  901. if (p != NULL) {
  902. pbuf_take(p, data + 4, len1);
  903. #ifdef RX_DUMP
  904. packet_dump("RX", p);
  905. #endif /* RX_DUMP */
  906. struct eth_device *eth_dev = &usbh_axusbnet_eth_device.parent;
  907. if ((eth_dev->netif->input(p, eth_dev->netif)) != ERR_OK) {
  908. USB_LOG_INFO("F:%s L:%d IP input error\r\n", __FUNCTION__, __LINE__);
  909. pbuf_free(p);
  910. p = RT_NULL;
  911. }
  912. // USB_LOG_INFO("%s L%d input OK\r\n", __FUNCTION__, __LINE__);
  913. } else {
  914. USB_LOG_ERR("%s L%d pbuf_alloc NULL\r\n", __FUNCTION__, __LINE__);
  915. }
  916. #endif /* RT-Thread */
  917. }
  918. } // while (1)
  919. err_out:
  920. out2:
  921. return;
  922. }
  923. static int axusbnet_startup(void)
  924. {
  925. const char *tname = "axusbnet";
  926. usb_osal_thread_t usb_thread;
  927. usb_thread = usb_osal_thread_create(tname, 1024 * 6, CONFIG_USBHOST_PSC_PRIO, rt_thread_axusbnet_entry, NULL);
  928. if (usb_thread == NULL) {
  929. return -1;
  930. }
  931. return 0;
  932. }
  933. static int usbh_axusbnet_connect(struct usbh_hubport *hport, uint8_t intf)
  934. {
  935. int ret = 0;
  936. struct usbh_endpoint_cfg ep_cfg = { 0 };
  937. struct usb_endpoint_descriptor *ep_desc;
  938. USB_LOG_INFO("%s %d\r\n", __FUNCTION__, __LINE__);
  939. struct usbh_axusbnet *class = usb_malloc(sizeof(struct usbh_axusbnet));
  940. if (class == NULL)
  941. {
  942. USB_LOG_ERR("Fail to alloc class\r\n");
  943. return -ENOMEM;
  944. }
  945. memset(class, 0, sizeof(struct usbh_axusbnet));
  946. class->hport = hport;
  947. class->intf = intf;
  948. snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, intf);
  949. USB_LOG_INFO("Register axusbnet Class:%s\r\n", hport->config.intf[intf].devname);
  950. hport->config.intf[intf].priv = class;
  951. #if 1
  952. USB_LOG_INFO("hport=%p, intf=%d, intf_desc.bNumEndpoints:%d\r\n", hport, intf, hport->config.intf[intf].intf_desc.bNumEndpoints);
  953. for (uint8_t i = 0; i < hport->config.intf[intf].intf_desc.bNumEndpoints; i++)
  954. {
  955. ep_desc = &hport->config.intf[intf].ep[i].ep_desc;
  956. USB_LOG_INFO("ep[%d] bLength=%d, type=%d\r\n", i, ep_desc->bLength, ep_desc->bDescriptorType);
  957. USB_LOG_INFO("ep_addr=%02X, attr=%02X\r\n", ep_desc->bEndpointAddress, ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK);
  958. USB_LOG_INFO("wMaxPacketSize=%d, bInterval=%d\r\n\r\n", ep_desc->wMaxPacketSize, ep_desc->bInterval);
  959. }
  960. #endif
  961. for (uint8_t i = 0; i < hport->config.intf[intf].intf_desc.bNumEndpoints; i++)
  962. {
  963. ep_desc = &hport->config.intf[intf].ep[i].ep_desc;
  964. ep_cfg.ep_addr = ep_desc->bEndpointAddress;
  965. ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
  966. ep_cfg.ep_mps = ep_desc->wMaxPacketSize;
  967. ep_cfg.ep_interval = ep_desc->bInterval;
  968. ep_cfg.hport = hport;
  969. if(ep_cfg.ep_type == USB_ENDPOINT_TYPE_BULK)
  970. {
  971. if (ep_desc->bEndpointAddress & 0x80) {
  972. usbh_ep_alloc(&class->bulkin, &ep_cfg);
  973. } else {
  974. usbh_ep_alloc(&class->bulkout, &ep_cfg);
  975. }
  976. }
  977. else
  978. {
  979. usbh_ep_alloc(&class->int_notify, &ep_cfg);
  980. }
  981. }
  982. axusbnet_startup();
  983. return ret;
  984. }
  985. static int usbh_axusbnet_disconnect(struct usbh_hubport *hport, uint8_t intf)
  986. {
  987. int ret = 0;
  988. USB_LOG_ERR("TBD: %s %d\r\n", __FUNCTION__, __LINE__);
  989. return ret;
  990. }
  991. // Class:0xff,Subclass:0xff,Protocl:0x00
  992. static const struct usbh_class_driver axusbnet_class_driver = {
  993. .driver_name = "axusbnet",
  994. .connect = usbh_axusbnet_connect,
  995. .disconnect = usbh_axusbnet_disconnect
  996. };
  997. CLASS_INFO_DEFINE const struct usbh_class_info axusbnet_class_info = {
  998. .match_flags = USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
  999. .class = USB_DEVICE_CLASS_VEND_SPECIFIC,
  1000. .subclass = 0xff,
  1001. .protocol = 0x00,
  1002. .vid = 0x0b95,
  1003. .pid = 0x772b,
  1004. .class_driver = &axusbnet_class_driver
  1005. };