etherif.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. #include "all.h"
  2. #include "io.h"
  3. #include "mem.h"
  4. #include "../ip/ip.h"
  5. #include "etherif.h"
  6. extern int etherga620reset(Ether*);
  7. extern int ether21140reset(Ether*);
  8. extern int etherelnk3reset(Ether*);
  9. extern int etheri82557reset(Ether*);
  10. extern int igbepnp(Ether *);
  11. extern int dp83815reset(Ether*);
  12. extern int dp83820pnp(Ether*);
  13. extern int rtl8139pnp(Ether*);
  14. static struct
  15. {
  16. char* type;
  17. int (*reset)(Ether*);
  18. } etherctlr[] =
  19. {
  20. { "21140", ether21140reset, },
  21. { "2114x", ether21140reset, },
  22. { "3C509", etherelnk3reset, },
  23. { "83815", dp83815reset, },
  24. { "dp83820", dp83820pnp, },
  25. { "elnk3", etherelnk3reset, },
  26. { "ga620", etherga620reset, },
  27. { "i82557", etheri82557reset, },
  28. { "igbe", igbepnp, },
  29. { "rtl8139", rtl8139pnp, },
  30. { 0, },
  31. };
  32. static Ether etherif[MaxEther];
  33. void
  34. etheriq(Ether* ether, Msgbuf* mb)
  35. {
  36. ilock(&ether->rqlock);
  37. if(ether->rqhead)
  38. ether->rqtail->next = mb;
  39. else
  40. ether->rqhead = mb;
  41. ether->rqtail = mb;
  42. mb->next = 0;
  43. iunlock(&ether->rqlock);
  44. wakeup(&ether->rqr);
  45. }
  46. static int
  47. isinput(void* arg)
  48. {
  49. return ((Ether*)arg)->rqhead != 0;
  50. }
  51. #include "compat.h"
  52. static void
  53. etheri(void)
  54. {
  55. Ether *ether;
  56. Ifc *ifc;
  57. Msgbuf *mb;
  58. Enpkt *p;
  59. ether = getarg();
  60. ifc = &ether->ifc;
  61. print("ether%di: %E %I\n", ether->ctlrno, ether->ifc.ea, ether->ifc.ipa);
  62. (*ether->attach)(ether);
  63. for(;;) {
  64. while(!isinput(ether))
  65. sleep(&ether->rqr, isinput, ether);
  66. ilock(&ether->rqlock);
  67. if(ether->rqhead == 0) {
  68. iunlock(&ether->rqlock);
  69. continue;
  70. }
  71. mb = ether->rqhead;
  72. ether->rqhead = mb->next;
  73. iunlock(&ether->rqlock);
  74. p = (Enpkt*)mb->data;
  75. switch(nhgets(p->type)){
  76. case Arptype:
  77. arpreceive(p, mb->count, ifc);
  78. break;
  79. case Iptype:
  80. ipreceive(p, mb->count, ifc);
  81. ifc->rxpkt++;
  82. ifc->work[0].count++;
  83. ifc->work[1].count++;
  84. ifc->work[2].count++;
  85. ifc->rate[0].count += mb->count;
  86. ifc->rate[1].count += mb->count;
  87. ifc->rate[2].count += mb->count;
  88. break;
  89. }
  90. mbfree(mb);
  91. }
  92. }
  93. static void
  94. ethero(void)
  95. {
  96. Ether *ether;
  97. Ifc *ifc;
  98. Msgbuf *mb;
  99. int len;
  100. ether = getarg();
  101. ifc = &ether->ifc;
  102. print("ether%do: %E %I\n", ether->ctlrno, ifc->ea, ifc->ipa);
  103. for(;;) {
  104. for(;;) {
  105. mb = recv(ifc->reply, 0);
  106. if(mb != nil)
  107. break;
  108. }
  109. if(mb->data == 0) {
  110. print("ether%do: pkt nil cat=%d free=%d\n",
  111. ether->ctlrno, mb->category, mb->flags&FREE);
  112. if(!(mb->flags & FREE))
  113. mbfree(mb);
  114. continue;
  115. }
  116. len = mb->count;
  117. if(len > ETHERMAXTU) {
  118. print("ether%do: pkt too big - %d\n", ether->ctlrno, len);
  119. mbfree(mb);
  120. continue;
  121. }
  122. if(len < ETHERMINTU) {
  123. memset(mb->data+len, 0, ETHERMINTU-len);
  124. mb->count = len = ETHERMINTU;
  125. }
  126. memmove(((Enpkt*)(mb->data))->s, ifc->ea, sizeof(ifc->ea));
  127. ilock(&ether->tqlock);
  128. if(ether->tqhead)
  129. ether->tqtail->next = mb;
  130. else
  131. ether->tqhead = mb;
  132. ether->tqtail = mb;
  133. mb->next = 0;
  134. iunlock(&ether->tqlock);
  135. (*ether->transmit)(ether);
  136. ifc->work[0].count++;
  137. ifc->work[1].count++;
  138. ifc->work[2].count++;
  139. ifc->rate[0].count += len;
  140. ifc->rate[1].count += len;
  141. ifc->rate[2].count += len;
  142. ifc->txpkt++;
  143. }
  144. }
  145. Msgbuf*
  146. etheroq(Ether* ether)
  147. {
  148. Msgbuf *mb;
  149. mb = nil;
  150. ilock(&ether->tqlock);
  151. if(ether->tqhead){
  152. mb = ether->tqhead;
  153. ether->tqhead = mb->next;
  154. }
  155. iunlock(&ether->tqlock);
  156. return mb;
  157. }
  158. static void
  159. cmd_state(int, char*[])
  160. {
  161. Ether *ether;
  162. Ifc *ifc;
  163. for(ether = &etherif[0]; ether < &etherif[MaxEther]; ether++){
  164. if(ether->mbps == 0)
  165. continue;
  166. ifc = &ether->ifc;
  167. if(!isvalidip(ifc->ipa))
  168. continue;
  169. print("ether stats %d\n", ether->ctlrno);
  170. print(" work =%7W%7W%7W pkts\n", ifc->work+0, ifc->work+1, ifc->work+2);
  171. print(" rate =%7W%7W%7W tBps\n", ifc->rate+0, ifc->rate+1, ifc->rate+2);
  172. print(" err = %3ld rc %3ld sum\n", ifc->rcverr, ifc->sumerr);
  173. }
  174. }
  175. void
  176. etherstart(void)
  177. {
  178. Ether *ether;
  179. Ifc *ifc;
  180. int anystarted;
  181. char buf[100], *p;
  182. anystarted = 0;
  183. for(ether = &etherif[0]; ether < &etherif[MaxEther]; ether++){
  184. if(ether->mbps == 0)
  185. continue;
  186. ifc = &ether->ifc;
  187. lock(ifc);
  188. getipa(ifc, ether->ctlrno);
  189. if(!isvalidip(ifc->ipa)){
  190. unlock(ifc);
  191. ether->mbps = 0;
  192. continue;
  193. }
  194. if(ifc->reply == 0){
  195. dofilter(ifc->work+0, C0a, C0b, 1);
  196. dofilter(ifc->work+1, C1a, C1b, 1);
  197. dofilter(ifc->work+2, C2a, C2b, 1);
  198. dofilter(ifc->rate+0, C0a, C0b, 1000);
  199. dofilter(ifc->rate+1, C1a, C1b, 1000);
  200. dofilter(ifc->rate+2, C2a, C2b, 1000);
  201. ifc->reply = newqueue(Nqueue);
  202. }
  203. unlock(ifc);
  204. sprint(ether->oname, "ether%do", ether->ctlrno);
  205. userinit(ethero, ether, ether->oname);
  206. sprint(ether->iname, "ether%di", ether->ctlrno);
  207. userinit(etheri, ether, ether->iname);
  208. ifc->next = enets;
  209. enets = ifc;
  210. anystarted++;
  211. }
  212. if(anystarted){
  213. cmd_install("state", "-- ether stats", cmd_state);
  214. arpstart();
  215. if((p = getconf("route")) && strlen(p) < sizeof(buf)-7){
  216. sprint(buf, "route %s", p);
  217. cmd_exec(buf);
  218. }
  219. }
  220. }
  221. static int
  222. parseether(uchar *to, char *from)
  223. {
  224. char nip[4];
  225. char *p;
  226. int i;
  227. p = from;
  228. while(*p == ' ')
  229. ++p;
  230. for(i = 0; i < 6; i++){
  231. if(*p == 0)
  232. return -1;
  233. nip[0] = *p++;
  234. if(*p == 0)
  235. return -1;
  236. nip[1] = *p++;
  237. nip[2] = 0;
  238. to[i] = strtoul(nip, 0, 16);
  239. if(*p == ':')
  240. p++;
  241. }
  242. return 0;
  243. }
  244. void
  245. etherinit(void)
  246. {
  247. Ether *ether;
  248. int i, n, ctlrno;
  249. for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
  250. ether = &etherif[ctlrno];
  251. memset(ether, 0, sizeof(Ether));
  252. if(!isaconfig("ether", ctlrno, ether))
  253. continue;
  254. for(n = 0; etherctlr[n].type; n++){
  255. if(cistrcmp(etherctlr[n].type, ether->type))
  256. continue;
  257. ether->ctlrno = ctlrno;
  258. ether->tbdf = BUSUNKNOWN;
  259. for(i = 0; i < ether->nopt; i++){
  260. if(strncmp(ether->opt[i], "ea=", 3))
  261. continue;
  262. if(parseether(ether->ea, &ether->opt[i][3]) == -1)
  263. memset(ether->ea, 0, Easize);
  264. }
  265. if((*etherctlr[n].reset)(ether))
  266. break;
  267. if(ether->irq == 2)
  268. ether->irq = 9;
  269. setvec(Int0vec + ether->irq, ether->interrupt, ether);
  270. memmove(ether->ifc.ea, ether->ea, sizeof(ether->ea));
  271. print("ether%d: %s: %dMbps port 0x%lux irq %ld",
  272. ctlrno, ether->type, ether->mbps, ether->port, ether->irq);
  273. if(ether->mem)
  274. print(" addr 0x%lux", ether->mem & ~KZERO);
  275. if(ether->size)
  276. print(" size 0x%lux", ether->size);
  277. print(": ");
  278. for(i = 0; i < sizeof(ether->ea); i++)
  279. print("%2.2ux", ether->ea[i]);
  280. print("\n");
  281. break;
  282. }
  283. }
  284. }