ether82557.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311
  1. /*
  2. * Intel 82557 Fast Ethernet PCI Bus LAN Controller
  3. * as found on the Intel EtherExpress PRO/100B. This chip is full
  4. * of smarts, unfortunately they're not all in the right place.
  5. * To do:
  6. * the PCI scanning code could be made common to other adapters;
  7. * auto-negotiation, full-duplex;
  8. * optionally use memory-mapped registers;
  9. * detach for PCI reset problems (also towards loadable drivers).
  10. */
  11. #include "u.h"
  12. #include "../port/lib.h"
  13. #include "mem.h"
  14. #include "dat.h"
  15. #include "fns.h"
  16. #include "io.h"
  17. #include "../port/error.h"
  18. #include "../port/netif.h"
  19. #include "etherif.h"
  20. enum {
  21. Nrfd = 64, /* receive frame area */
  22. Ncb = 64, /* maximum control blocks queued */
  23. NullPointer = 0xFFFFFFFF, /* 82557 NULL pointer */
  24. };
  25. enum { /* CSR */
  26. Status = 0x00, /* byte or word (word includes Ack) */
  27. Ack = 0x01, /* byte */
  28. CommandR = 0x02, /* byte or word (word includes Interrupt) */
  29. Interrupt = 0x03, /* byte */
  30. General = 0x04, /* dword */
  31. Port = 0x08, /* dword */
  32. Fcr = 0x0C, /* Flash control register */
  33. Ecr = 0x0E, /* EEPROM control register */
  34. Mcr = 0x10, /* MDI control register */
  35. };
  36. enum { /* Status */
  37. RUidle = 0x0000,
  38. RUsuspended = 0x0004,
  39. RUnoresources = 0x0008,
  40. RUready = 0x0010,
  41. RUrbd = 0x0020, /* bit */
  42. RUstatus = 0x003F, /* mask */
  43. CUidle = 0x0000,
  44. CUsuspended = 0x0040,
  45. CUactive = 0x0080,
  46. CUstatus = 0x00C0, /* mask */
  47. StatSWI = 0x0400, /* SoftWare generated Interrupt */
  48. StatMDI = 0x0800, /* MDI r/w done */
  49. StatRNR = 0x1000, /* Receive unit Not Ready */
  50. StatCNA = 0x2000, /* Command unit Not Active (Active->Idle) */
  51. StatFR = 0x4000, /* Finished Receiving */
  52. StatCX = 0x8000, /* Command eXecuted */
  53. StatTNO = 0x8000, /* Transmit NOT OK */
  54. };
  55. enum { /* Command (byte) */
  56. CUnop = 0x00,
  57. CUstart = 0x10,
  58. CUresume = 0x20,
  59. LoadDCA = 0x40, /* Load Dump Counters Address */
  60. DumpSC = 0x50, /* Dump Statistical Counters */
  61. LoadCUB = 0x60, /* Load CU Base */
  62. ResetSA = 0x70, /* Dump and Reset Statistical Counters */
  63. RUstart = 0x01,
  64. RUresume = 0x02,
  65. RUabort = 0x04,
  66. LoadHDS = 0x05, /* Load Header Data Size */
  67. LoadRUB = 0x06, /* Load RU Base */
  68. RBDresume = 0x07, /* Resume frame reception */
  69. };
  70. enum { /* Interrupt (byte) */
  71. InterruptM = 0x01, /* interrupt Mask */
  72. InterruptSI = 0x02, /* Software generated Interrupt */
  73. };
  74. enum { /* Ecr */
  75. EEsk = 0x01, /* serial clock */
  76. EEcs = 0x02, /* chip select */
  77. EEdi = 0x04, /* serial data in */
  78. EEdo = 0x08, /* serial data out */
  79. EEstart = 0x04, /* start bit */
  80. EEread = 0x02, /* read opcode */
  81. };
  82. enum { /* Mcr */
  83. MDIread = 0x08000000, /* read opcode */
  84. MDIwrite = 0x04000000, /* write opcode */
  85. MDIready = 0x10000000, /* ready bit */
  86. MDIie = 0x20000000, /* interrupt enable */
  87. };
  88. typedef struct Rfd {
  89. int field;
  90. ulong link;
  91. ulong rbd;
  92. ushort count;
  93. ushort size;
  94. uchar data[1700];
  95. } Rfd;
  96. enum { /* field */
  97. RfdCollision = 0x00000001,
  98. RfdIA = 0x00000002, /* IA match */
  99. RfdRxerr = 0x00000010, /* PHY character error */
  100. RfdType = 0x00000020, /* Type frame */
  101. RfdRunt = 0x00000080,
  102. RfdOverrun = 0x00000100,
  103. RfdBuffer = 0x00000200,
  104. RfdAlignment = 0x00000400,
  105. RfdCRC = 0x00000800,
  106. RfdOK = 0x00002000, /* frame received OK */
  107. RfdC = 0x00008000, /* reception Complete */
  108. RfdSF = 0x00080000, /* Simplified or Flexible (1) Rfd */
  109. RfdH = 0x00100000, /* Header RFD */
  110. RfdI = 0x20000000, /* Interrupt after completion */
  111. RfdS = 0x40000000, /* Suspend after completion */
  112. RfdEL = 0x80000000, /* End of List */
  113. };
  114. enum { /* count */
  115. RfdF = 0x4000,
  116. RfdEOF = 0x8000,
  117. };
  118. typedef struct Cb Cb;
  119. typedef struct Cb {
  120. ushort status;
  121. ushort command;
  122. ulong link;
  123. union {
  124. uchar data[24]; /* CbIAS + CbConfigure */
  125. struct {
  126. ulong tbd;
  127. ushort count;
  128. uchar threshold;
  129. uchar number;
  130. ulong tba;
  131. ushort tbasz;
  132. ushort pad;
  133. };
  134. };
  135. Block* bp;
  136. Cb* next;
  137. } Cb;
  138. enum { /* action command */
  139. CbU = 0x1000, /* transmit underrun */
  140. CbOK = 0x2000, /* DMA completed OK */
  141. CbC = 0x8000, /* execution Complete */
  142. CbNOP = 0x0000,
  143. CbIAS = 0x0001, /* Individual Address Setup */
  144. CbConfigure = 0x0002,
  145. CbMAS = 0x0003, /* Multicast Address Setup */
  146. CbTransmit = 0x0004,
  147. CbDump = 0x0006,
  148. CbDiagnose = 0x0007,
  149. CbCommand = 0x0007, /* mask */
  150. CbSF = 0x0008, /* Flexible-mode CbTransmit */
  151. CbI = 0x2000, /* Interrupt after completion */
  152. CbS = 0x4000, /* Suspend after completion */
  153. CbEL = 0x8000, /* End of List */
  154. };
  155. enum { /* CbTransmit count */
  156. CbEOF = 0x8000,
  157. };
  158. typedef struct Ctlr Ctlr;
  159. typedef struct Ctlr {
  160. Lock slock; /* attach */
  161. int state;
  162. int port;
  163. Pcidev* pcidev;
  164. Ctlr* next;
  165. int active;
  166. int eepromsz; /* address size in bits */
  167. ushort* eeprom;
  168. Lock miilock;
  169. Rendez timer; /* watchdog timer for receive lockup errata */
  170. int tick;
  171. Lock rlock; /* registers */
  172. int command; /* last command issued */
  173. Block* rfdhead; /* receive side */
  174. Block* rfdtail;
  175. int nrfd;
  176. Lock cblock; /* transmit side */
  177. int action;
  178. int nop;
  179. uchar configdata[24];
  180. int threshold;
  181. int ncb;
  182. Cb* cbr;
  183. Cb* cbhead;
  184. Cb* cbtail;
  185. int cbq;
  186. int cbqmax;
  187. int cbqmaxhw;
  188. Lock dlock; /* dump statistical counters */
  189. ulong dump[17];
  190. } Ctlr;
  191. static Ctlr* ctlrhead;
  192. static Ctlr* ctlrtail;
  193. static uchar configdata[24] = {
  194. 0x16, /* byte count */
  195. 0x08, /* Rx/Tx FIFO limit */
  196. 0x00, /* adaptive IFS */
  197. 0x00,
  198. 0x00, /* Rx DMA maximum byte count */
  199. // 0x80, /* Tx DMA maximum byte count */
  200. 0x00, /* Tx DMA maximum byte count */
  201. 0x32, /* !late SCB, CNA interrupts */
  202. 0x03, /* discard short Rx frames */
  203. 0x00, /* 503/MII */
  204. 0x00,
  205. 0x2E, /* normal operation, NSAI */
  206. 0x00, /* linear priority */
  207. 0x60, /* inter-frame spacing */
  208. 0x00,
  209. 0xF2,
  210. 0xC8, /* 503, promiscuous mode off */
  211. 0x00,
  212. 0x40,
  213. 0xF3, /* transmit padding enable */
  214. 0x80, /* full duplex pin enable */
  215. 0x3F, /* no Multi IA */
  216. 0x05, /* no Multi Cast ALL */
  217. };
  218. #define csr8r(c, r) (inb((c)->port+(r)))
  219. #define csr16r(c, r) (ins((c)->port+(r)))
  220. #define csr32r(c, r) (inl((c)->port+(r)))
  221. #define csr8w(c, r, b) (outb((c)->port+(r), (int)(b)))
  222. #define csr16w(c, r, w) (outs((c)->port+(r), (ushort)(w)))
  223. #define csr32w(c, r, l) (outl((c)->port+(r), (ulong)(l)))
  224. static void
  225. command(Ctlr* ctlr, int c, int v)
  226. {
  227. int timeo;
  228. ilock(&ctlr->rlock);
  229. /*
  230. * Only back-to-back CUresume can be done
  231. * without waiting for any previous command to complete.
  232. * This should be the common case.
  233. * Unfortunately there's a chip errata where back-to-back
  234. * CUresumes can be lost, the fix is to always wait.
  235. if(c == CUresume && ctlr->command == CUresume){
  236. csr8w(ctlr, CommandR, c);
  237. iunlock(&ctlr->rlock);
  238. return;
  239. }
  240. */
  241. for(timeo = 0; timeo < 100; timeo++){
  242. if(!csr8r(ctlr, CommandR))
  243. break;
  244. microdelay(1);
  245. }
  246. if(timeo >= 100){
  247. ctlr->command = -1;
  248. iunlock(&ctlr->rlock);
  249. iprint("i82557: command 0x%uX %uX timeout\n", c, v);
  250. return;
  251. }
  252. switch(c){
  253. case CUstart:
  254. case LoadDCA:
  255. case LoadCUB:
  256. case RUstart:
  257. case LoadHDS:
  258. case LoadRUB:
  259. csr32w(ctlr, General, v);
  260. break;
  261. /*
  262. case CUnop:
  263. case CUresume:
  264. case DumpSC:
  265. case ResetSA:
  266. case RUresume:
  267. case RUabort:
  268. */
  269. default:
  270. break;
  271. }
  272. csr8w(ctlr, CommandR, c);
  273. ctlr->command = c;
  274. iunlock(&ctlr->rlock);
  275. }
  276. static Block*
  277. rfdalloc(ulong link)
  278. {
  279. Block *bp;
  280. Rfd *rfd;
  281. if(bp = iallocb(sizeof(Rfd))){
  282. rfd = (Rfd*)bp->rp;
  283. rfd->field = 0;
  284. rfd->link = link;
  285. rfd->rbd = NullPointer;
  286. rfd->count = 0;
  287. rfd->size = sizeof(Etherpkt);
  288. }
  289. return bp;
  290. }
  291. static void
  292. watchdog(void* arg)
  293. {
  294. Ether *ether;
  295. Ctlr *ctlr;
  296. static void txstart(Ether*);
  297. ether = arg;
  298. for(;;){
  299. ctlr = ether->ctlr;
  300. tsleep(&ctlr->timer, return0, 0, 4000);
  301. /*
  302. * Hmmm. This doesn't seem right. Currently
  303. * the device can't be disabled but it may be in
  304. * the future.
  305. */
  306. ctlr = ether->ctlr;
  307. if(ctlr == nil || ctlr->state == 0){
  308. print("%s: exiting\n", up->text);
  309. pexit("disabled", 0);
  310. }
  311. ilock(&ctlr->cblock);
  312. if(ctlr->tick++){
  313. ctlr->action = CbMAS;
  314. txstart(ether);
  315. }
  316. iunlock(&ctlr->cblock);
  317. }
  318. }
  319. static void
  320. attach(Ether* ether)
  321. {
  322. Ctlr *ctlr;
  323. char name[KNAMELEN];
  324. ctlr = ether->ctlr;
  325. lock(&ctlr->slock);
  326. if(ctlr->state == 0){
  327. ilock(&ctlr->rlock);
  328. csr8w(ctlr, Interrupt, 0);
  329. iunlock(&ctlr->rlock);
  330. command(ctlr, RUstart, PADDR(ctlr->rfdhead->rp));
  331. ctlr->state = 1;
  332. /*
  333. * Start the watchdog timer for the receive lockup errata
  334. * unless the EEPROM compatibility word indicates it may be
  335. * omitted.
  336. */
  337. if((ctlr->eeprom[0x03] & 0x0003) != 0x0003){
  338. snprint(name, KNAMELEN, "#l%dwatchdog", ether->ctlrno);
  339. kproc(name, watchdog, ether);
  340. }
  341. }
  342. unlock(&ctlr->slock);
  343. }
  344. static long
  345. ifstat(Ether* ether, void* a, long n, ulong offset)
  346. {
  347. char *p;
  348. int i, len, phyaddr;
  349. Ctlr *ctlr;
  350. ulong dump[17];
  351. ctlr = ether->ctlr;
  352. lock(&ctlr->dlock);
  353. /*
  354. * Start the command then
  355. * wait for completion status,
  356. * should be 0xA005.
  357. */
  358. ctlr->dump[16] = 0;
  359. command(ctlr, DumpSC, 0);
  360. while(ctlr->dump[16] == 0)
  361. ;
  362. ether->oerrs = ctlr->dump[1]+ctlr->dump[2]+ctlr->dump[3];
  363. ether->crcs = ctlr->dump[10];
  364. ether->frames = ctlr->dump[11];
  365. ether->buffs = ctlr->dump[12]+ctlr->dump[15];
  366. ether->overflows = ctlr->dump[13];
  367. if(n == 0){
  368. unlock(&ctlr->dlock);
  369. return 0;
  370. }
  371. memmove(dump, ctlr->dump, sizeof(dump));
  372. unlock(&ctlr->dlock);
  373. p = malloc(READSTR);
  374. len = snprint(p, READSTR, "transmit good frames: %lud\n", dump[0]);
  375. len += snprint(p+len, READSTR-len, "transmit maximum collisions errors: %lud\n", dump[1]);
  376. len += snprint(p+len, READSTR-len, "transmit late collisions errors: %lud\n", dump[2]);
  377. len += snprint(p+len, READSTR-len, "transmit underrun errors: %lud\n", dump[3]);
  378. len += snprint(p+len, READSTR-len, "transmit lost carrier sense: %lud\n", dump[4]);
  379. len += snprint(p+len, READSTR-len, "transmit deferred: %lud\n", dump[5]);
  380. len += snprint(p+len, READSTR-len, "transmit single collisions: %lud\n", dump[6]);
  381. len += snprint(p+len, READSTR-len, "transmit multiple collisions: %lud\n", dump[7]);
  382. len += snprint(p+len, READSTR-len, "transmit total collisions: %lud\n", dump[8]);
  383. len += snprint(p+len, READSTR-len, "receive good frames: %lud\n", dump[9]);
  384. len += snprint(p+len, READSTR-len, "receive CRC errors: %lud\n", dump[10]);
  385. len += snprint(p+len, READSTR-len, "receive alignment errors: %lud\n", dump[11]);
  386. len += snprint(p+len, READSTR-len, "receive resource errors: %lud\n", dump[12]);
  387. len += snprint(p+len, READSTR-len, "receive overrun errors: %lud\n", dump[13]);
  388. len += snprint(p+len, READSTR-len, "receive collision detect errors: %lud\n", dump[14]);
  389. len += snprint(p+len, READSTR-len, "receive short frame errors: %lud\n", dump[15]);
  390. len += snprint(p+len, READSTR-len, "nop: %d\n", ctlr->nop);
  391. if(ctlr->cbqmax > ctlr->cbqmaxhw)
  392. ctlr->cbqmaxhw = ctlr->cbqmax;
  393. len += snprint(p+len, READSTR-len, "cbqmax: %d\n", ctlr->cbqmax);
  394. ctlr->cbqmax = 0;
  395. len += snprint(p+len, READSTR-len, "threshold: %d\n", ctlr->threshold);
  396. len += snprint(p+len, READSTR-len, "eeprom:");
  397. for(i = 0; i < (1<<ctlr->eepromsz); i++){
  398. if(i && ((i & 0x07) == 0))
  399. len += snprint(p+len, READSTR-len, "\n ");
  400. len += snprint(p+len, READSTR-len, " %4.4uX", ctlr->eeprom[i]);
  401. }
  402. if((ctlr->eeprom[6] & 0x1F00) && !(ctlr->eeprom[6] & 0x8000)){
  403. phyaddr = ctlr->eeprom[6] & 0x00FF;
  404. len += snprint(p+len, READSTR-len, "\nphy %2d:", phyaddr);
  405. for(i = 0; i < 6; i++){
  406. static int miir(Ctlr*, int, int);
  407. len += snprint(p+len, READSTR-len, " %4.4uX",
  408. miir(ctlr, phyaddr, i));
  409. }
  410. }
  411. snprint(p+len, READSTR-len, "\n");
  412. n = readstr(offset, a, n, p);
  413. free(p);
  414. return n;
  415. }
  416. static void
  417. txstart(Ether* ether)
  418. {
  419. Ctlr *ctlr;
  420. Block *bp;
  421. Cb *cb;
  422. ctlr = ether->ctlr;
  423. while(ctlr->cbq < (ctlr->ncb-1)){
  424. cb = ctlr->cbhead->next;
  425. if(ctlr->action == 0){
  426. bp = qget(ether->oq);
  427. if(bp == nil)
  428. break;
  429. cb->command = CbS|CbSF|CbTransmit;
  430. cb->tbd = PADDR(&cb->tba);
  431. cb->count = 0;
  432. cb->threshold = ctlr->threshold;
  433. cb->number = 1;
  434. cb->tba = PADDR(bp->rp);
  435. cb->bp = bp;
  436. cb->tbasz = BLEN(bp);
  437. }
  438. else if(ctlr->action == CbConfigure){
  439. cb->command = CbS|CbConfigure;
  440. memmove(cb->data, ctlr->configdata, sizeof(ctlr->configdata));
  441. ctlr->action = 0;
  442. }
  443. else if(ctlr->action == CbIAS){
  444. cb->command = CbS|CbIAS;
  445. memmove(cb->data, ether->ea, Eaddrlen);
  446. ctlr->action = 0;
  447. }
  448. else if(ctlr->action == CbMAS){
  449. cb->command = CbS|CbMAS;
  450. memset(cb->data, 0, sizeof(cb->data));
  451. ctlr->action = 0;
  452. }
  453. else{
  454. print("#l%d: action 0x%uX\n", ether->ctlrno, ctlr->action);
  455. ctlr->action = 0;
  456. break;
  457. }
  458. cb->status = 0;
  459. coherence();
  460. ctlr->cbhead->command &= ~CbS;
  461. ctlr->cbhead = cb;
  462. ctlr->cbq++;
  463. }
  464. /*
  465. * Workaround for some broken HUB chips
  466. * when connected at 10Mb/s half-duplex.
  467. */
  468. if(ctlr->nop){
  469. command(ctlr, CUnop, 0);
  470. microdelay(1);
  471. }
  472. command(ctlr, CUresume, 0);
  473. if(ctlr->cbq > ctlr->cbqmax)
  474. ctlr->cbqmax = ctlr->cbq;
  475. }
  476. static void
  477. configure(Ether* ether, int promiscuous)
  478. {
  479. Ctlr *ctlr;
  480. ctlr = ether->ctlr;
  481. ilock(&ctlr->cblock);
  482. if(promiscuous){
  483. ctlr->configdata[6] |= 0x80; /* Save Bad Frames */
  484. //ctlr->configdata[6] &= ~0x40; /* !Discard Overrun Rx Frames */
  485. ctlr->configdata[7] &= ~0x01; /* !Discard Short Rx Frames */
  486. ctlr->configdata[15] |= 0x01; /* Promiscuous mode */
  487. ctlr->configdata[18] &= ~0x01; /* (!Padding enable?), !stripping enable */
  488. ctlr->configdata[21] |= 0x08; /* Multi Cast ALL */
  489. }
  490. else{
  491. ctlr->configdata[6] &= ~0x80;
  492. //ctlr->configdata[6] |= 0x40;
  493. ctlr->configdata[7] |= 0x01;
  494. ctlr->configdata[15] &= ~0x01;
  495. ctlr->configdata[18] |= 0x01; /* 0x03? */
  496. ctlr->configdata[21] &= ~0x08;
  497. }
  498. ctlr->action = CbConfigure;
  499. txstart(ether);
  500. iunlock(&ctlr->cblock);
  501. }
  502. static void
  503. promiscuous(void* arg, int on)
  504. {
  505. configure(arg, on);
  506. }
  507. static void
  508. multicast(void* arg, uchar *addr, int on)
  509. {
  510. USED(addr, on);
  511. configure(arg, 1);
  512. }
  513. static void
  514. transmit(Ether* ether)
  515. {
  516. Ctlr *ctlr;
  517. ctlr = ether->ctlr;
  518. ilock(&ctlr->cblock);
  519. txstart(ether);
  520. iunlock(&ctlr->cblock);
  521. }
  522. static void
  523. receive(Ether* ether)
  524. {
  525. Rfd *rfd;
  526. Ctlr *ctlr;
  527. int count;
  528. Block *bp, *pbp, *xbp;
  529. ctlr = ether->ctlr;
  530. bp = ctlr->rfdhead;
  531. for(rfd = (Rfd*)bp->rp; rfd->field & RfdC; rfd = (Rfd*)bp->rp){
  532. /*
  533. * If it's an OK receive frame
  534. * 1) save the count
  535. * 2) if it's small, try to allocate a block and copy
  536. * the data, then adjust the necessary fields for reuse;
  537. * 3) if it's big, try to allocate a new Rfd and if
  538. * successful
  539. * adjust the received buffer pointers for the
  540. * actual data received;
  541. * initialise the replacement buffer to point to
  542. * the next in the ring;
  543. * initialise bp to point to the replacement;
  544. * 4) if there's a good packet, pass it on for disposal.
  545. */
  546. if(rfd->field & RfdOK){
  547. pbp = nil;
  548. count = rfd->count & 0x3FFF;
  549. if((count < ETHERMAXTU/4) && (pbp = iallocb(count))){
  550. memmove(pbp->rp, bp->rp+sizeof(Rfd)-sizeof(rfd->data), count);
  551. pbp->wp = pbp->rp + count;
  552. rfd->count = 0;
  553. rfd->field = 0;
  554. }
  555. else if(xbp = rfdalloc(rfd->link)){
  556. bp->rp += sizeof(Rfd)-sizeof(rfd->data);
  557. bp->wp = bp->rp + count;
  558. xbp->next = bp->next;
  559. bp->next = 0;
  560. pbp = bp;
  561. bp = xbp;
  562. }
  563. if(pbp != nil)
  564. etheriq(ether, pbp, 1);
  565. }
  566. else{
  567. rfd->count = 0;
  568. rfd->field = 0;
  569. }
  570. /*
  571. * The ring tail pointer follows the head with with one
  572. * unused buffer in between to defeat hardware prefetch;
  573. * once the tail pointer has been bumped on to the next
  574. * and the new tail has the Suspend bit set, it can be
  575. * removed from the old tail buffer.
  576. * As a replacement for the current head buffer may have
  577. * been allocated above, ensure that the new tail points
  578. * to it (next and link).
  579. */
  580. rfd = (Rfd*)ctlr->rfdtail->rp;
  581. ctlr->rfdtail = ctlr->rfdtail->next;
  582. ctlr->rfdtail->next = bp;
  583. ((Rfd*)ctlr->rfdtail->rp)->link = PADDR(bp->rp);
  584. ((Rfd*)ctlr->rfdtail->rp)->field |= RfdS;
  585. coherence();
  586. rfd->field &= ~RfdS;
  587. /*
  588. * Finally done with the current (possibly replaced)
  589. * head, move on to the next and maintain the sentinel
  590. * between tail and head.
  591. */
  592. ctlr->rfdhead = bp->next;
  593. bp = ctlr->rfdhead;
  594. }
  595. }
  596. static void
  597. interrupt(Ureg*, void* arg)
  598. {
  599. Cb* cb;
  600. Ctlr *ctlr;
  601. Ether *ether;
  602. int status;
  603. ether = arg;
  604. ctlr = ether->ctlr;
  605. for(;;){
  606. ilock(&ctlr->rlock);
  607. status = csr16r(ctlr, Status);
  608. csr8w(ctlr, Ack, (status>>8) & 0xFF);
  609. iunlock(&ctlr->rlock);
  610. if(!(status & (StatCX|StatFR|StatCNA|StatRNR|StatMDI|StatSWI)))
  611. break;
  612. /*
  613. * If the watchdog timer for the receiver lockup errata is running,
  614. * let it know the receiver is active.
  615. */
  616. if(status & (StatFR|StatRNR)){
  617. ilock(&ctlr->cblock);
  618. ctlr->tick = 0;
  619. iunlock(&ctlr->cblock);
  620. }
  621. if(status & StatFR){
  622. receive(ether);
  623. status &= ~StatFR;
  624. }
  625. if(status & StatRNR){
  626. command(ctlr, RUresume, 0);
  627. status &= ~StatRNR;
  628. }
  629. if(status & StatCNA){
  630. ilock(&ctlr->cblock);
  631. cb = ctlr->cbtail;
  632. while(ctlr->cbq){
  633. if(!(cb->status & CbC))
  634. break;
  635. if(cb->bp){
  636. freeb(cb->bp);
  637. cb->bp = nil;
  638. }
  639. if((cb->status & CbU) && ctlr->threshold < 0xE0)
  640. ctlr->threshold++;
  641. ctlr->cbq--;
  642. cb = cb->next;
  643. }
  644. ctlr->cbtail = cb;
  645. txstart(ether);
  646. iunlock(&ctlr->cblock);
  647. status &= ~StatCNA;
  648. }
  649. if(status & (StatCX|StatFR|StatCNA|StatRNR|StatMDI|StatSWI))
  650. panic("#l%d: status %uX\n", ether->ctlrno, status);
  651. }
  652. }
  653. static void
  654. ctlrinit(Ctlr* ctlr)
  655. {
  656. int i;
  657. Block *bp;
  658. Rfd *rfd;
  659. ulong link;
  660. /*
  661. * Create the Receive Frame Area (RFA) as a ring of allocated
  662. * buffers.
  663. * A sentinel buffer is maintained between the last buffer in
  664. * the ring (marked with RfdS) and the head buffer to defeat the
  665. * hardware prefetch of the next RFD and allow dynamic buffer
  666. * allocation.
  667. */
  668. link = NullPointer;
  669. for(i = 0; i < Nrfd; i++){
  670. bp = rfdalloc(link);
  671. if(ctlr->rfdhead == nil)
  672. ctlr->rfdtail = bp;
  673. bp->next = ctlr->rfdhead;
  674. ctlr->rfdhead = bp;
  675. link = PADDR(bp->rp);
  676. }
  677. ctlr->rfdtail->next = ctlr->rfdhead;
  678. rfd = (Rfd*)ctlr->rfdtail->rp;
  679. rfd->link = PADDR(ctlr->rfdhead->rp);
  680. rfd->field |= RfdS;
  681. ctlr->rfdhead = ctlr->rfdhead->next;
  682. /*
  683. * Create a ring of control blocks for the
  684. * transmit side.
  685. */
  686. ilock(&ctlr->cblock);
  687. ctlr->cbr = malloc(ctlr->ncb*sizeof(Cb));
  688. for(i = 0; i < ctlr->ncb; i++){
  689. ctlr->cbr[i].status = CbC|CbOK;
  690. ctlr->cbr[i].command = CbS|CbNOP;
  691. ctlr->cbr[i].link = PADDR(&ctlr->cbr[NEXT(i, ctlr->ncb)].status);
  692. ctlr->cbr[i].next = &ctlr->cbr[NEXT(i, ctlr->ncb)];
  693. }
  694. ctlr->cbhead = ctlr->cbr;
  695. ctlr->cbtail = ctlr->cbr;
  696. ctlr->cbq = 0;
  697. memmove(ctlr->configdata, configdata, sizeof(configdata));
  698. ctlr->threshold = 80;
  699. ctlr->tick = 0;
  700. iunlock(&ctlr->cblock);
  701. }
  702. static int
  703. miir(Ctlr* ctlr, int phyadd, int regadd)
  704. {
  705. int mcr, timo;
  706. lock(&ctlr->miilock);
  707. csr32w(ctlr, Mcr, MDIread|(phyadd<<21)|(regadd<<16));
  708. mcr = 0;
  709. for(timo = 64; timo; timo--){
  710. mcr = csr32r(ctlr, Mcr);
  711. if(mcr & MDIready)
  712. break;
  713. microdelay(1);
  714. }
  715. unlock(&ctlr->miilock);
  716. if(mcr & MDIready)
  717. return mcr & 0xFFFF;
  718. return -1;
  719. }
  720. static int
  721. miiw(Ctlr* ctlr, int phyadd, int regadd, int data)
  722. {
  723. int mcr, timo;
  724. lock(&ctlr->miilock);
  725. csr32w(ctlr, Mcr, MDIwrite|(phyadd<<21)|(regadd<<16)|(data & 0xFFFF));
  726. mcr = 0;
  727. for(timo = 64; timo; timo--){
  728. mcr = csr32r(ctlr, Mcr);
  729. if(mcr & MDIready)
  730. break;
  731. microdelay(1);
  732. }
  733. unlock(&ctlr->miilock);
  734. if(mcr & MDIready)
  735. return 0;
  736. return -1;
  737. }
  738. static int
  739. hy93c46r(Ctlr* ctlr, int r)
  740. {
  741. int data, i, op, size;
  742. /*
  743. * Hyundai HY93C46 or equivalent serial EEPROM.
  744. * This sequence for reading a 16-bit register 'r'
  745. * in the EEPROM is taken straight from Section
  746. * 3.3.4.2 of the Intel 82557 User's Guide.
  747. */
  748. reread:
  749. csr16w(ctlr, Ecr, EEcs);
  750. op = EEstart|EEread;
  751. for(i = 2; i >= 0; i--){
  752. data = (((op>>i) & 0x01)<<2)|EEcs;
  753. csr16w(ctlr, Ecr, data);
  754. csr16w(ctlr, Ecr, data|EEsk);
  755. microdelay(1);
  756. csr16w(ctlr, Ecr, data);
  757. microdelay(1);
  758. }
  759. /*
  760. * First time through must work out the EEPROM size.
  761. */
  762. if((size = ctlr->eepromsz) == 0)
  763. size = 8;
  764. for(size = size-1; size >= 0; size--){
  765. data = (((r>>size) & 0x01)<<2)|EEcs;
  766. csr16w(ctlr, Ecr, data);
  767. csr16w(ctlr, Ecr, data|EEsk);
  768. delay(1);
  769. csr16w(ctlr, Ecr, data);
  770. microdelay(1);
  771. if(!(csr16r(ctlr, Ecr) & EEdo))
  772. break;
  773. }
  774. data = 0;
  775. for(i = 15; i >= 0; i--){
  776. csr16w(ctlr, Ecr, EEcs|EEsk);
  777. microdelay(1);
  778. if(csr16r(ctlr, Ecr) & EEdo)
  779. data |= (1<<i);
  780. csr16w(ctlr, Ecr, EEcs);
  781. microdelay(1);
  782. }
  783. csr16w(ctlr, Ecr, 0);
  784. if(ctlr->eepromsz == 0){
  785. ctlr->eepromsz = 8-size;
  786. ctlr->eeprom = malloc((1<<ctlr->eepromsz)*sizeof(ushort));
  787. goto reread;
  788. }
  789. return data;
  790. }
  791. static void
  792. i82557pci(void)
  793. {
  794. Pcidev *p;
  795. Ctlr *ctlr;
  796. int nop, port;
  797. p = nil;
  798. nop = 0;
  799. while(p = pcimatch(p, 0x8086, 0)){
  800. switch(p->did){
  801. default:
  802. continue;
  803. case 0x1031: /* Intel 82562EM */
  804. case 0x2449: /* Intel 82562ET */
  805. nop = 1;
  806. /*FALLTHROUGH*/
  807. case 0x1209: /* Intel 82559ER */
  808. case 0x1229: /* Intel 8255[789] */
  809. break;
  810. }
  811. /*
  812. * bar[0] is the memory-mapped register address (4KB),
  813. * bar[1] is the I/O port register address (32 bytes) and
  814. * bar[2] is for the flash ROM (1MB).
  815. */
  816. port = p->mem[1].bar & ~0x01;
  817. if(ioalloc(port, p->mem[1].size, 0, "i82557") < 0){
  818. print("i82557: port 0x%uX in use\n", port);
  819. continue;
  820. }
  821. ctlr = malloc(sizeof(Ctlr));
  822. ctlr->port = port;
  823. ctlr->pcidev = p;
  824. ctlr->nop = nop;
  825. if(ctlrhead != nil)
  826. ctlrtail->next = ctlr;
  827. else
  828. ctlrhead = ctlr;
  829. ctlrtail = ctlr;
  830. pcisetbme(p);
  831. }
  832. }
  833. static char* mediatable[9] = {
  834. "10BASE-T", /* TP */
  835. "10BASE-2", /* BNC */
  836. "10BASE-5", /* AUI */
  837. "100BASE-TX",
  838. "10BASE-TFD",
  839. "100BASE-TXFD",
  840. "100BASE-T4",
  841. "100BASE-FX",
  842. "100BASE-FXFD",
  843. };
  844. static int
  845. scanphy(Ctlr* ctlr)
  846. {
  847. int i, oui, x;
  848. for(i = 0; i < 32; i++){
  849. if((oui = miir(ctlr, i, 2)) == -1 || oui == 0 || oui == 0xFFFF)
  850. continue;
  851. oui <<= 6;
  852. x = miir(ctlr, i, 3);
  853. oui |= x>>10;
  854. //print("phy%d: oui %uX reg1 %uX\n", i, oui, miir(ctlr, i, 1));
  855. ctlr->eeprom[6] = i;
  856. if(oui == 0xAA00)
  857. ctlr->eeprom[6] |= 0x07<<8;
  858. else if(oui == 0x80017){
  859. if(x & 0x01)
  860. ctlr->eeprom[6] |= 0x0A<<8;
  861. else
  862. ctlr->eeprom[6] |= 0x04<<8;
  863. }
  864. return i;
  865. }
  866. return -1;
  867. }
  868. static void
  869. shutdown(Ether* ether)
  870. {
  871. Ctlr *ctlr = ether->ctlr;
  872. print("ether82557 shutting down\n");
  873. csr32w(ctlr, Port, 0);
  874. delay(1);
  875. csr8w(ctlr, Interrupt, InterruptM);
  876. }
  877. static int
  878. reset(Ether* ether)
  879. {
  880. int anar, anlpar, bmcr, bmsr, i, k, medium, phyaddr, x;
  881. unsigned short sum;
  882. uchar ea[Eaddrlen];
  883. Ctlr *ctlr;
  884. if(ctlrhead == nil)
  885. i82557pci();
  886. /*
  887. * Any adapter matches if no ether->port is supplied,
  888. * otherwise the ports must match.
  889. */
  890. for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
  891. if(ctlr->active)
  892. continue;
  893. if(ether->port == 0 || ether->port == ctlr->port){
  894. ctlr->active = 1;
  895. break;
  896. }
  897. }
  898. if(ctlr == nil)
  899. return -1;
  900. /*
  901. * Initialise the Ctlr structure.
  902. * Perform a software reset after which should ensure busmastering
  903. * is still enabled. The EtherExpress PRO/100B appears to leave
  904. * the PCI configuration alone (see the 'To do' list above) so punt
  905. * for now.
  906. * Load the RUB and CUB registers for linear addressing (0).
  907. */
  908. ether->ctlr = ctlr;
  909. ether->port = ctlr->port;
  910. ether->irq = ctlr->pcidev->intl;
  911. ether->tbdf = ctlr->pcidev->tbdf;
  912. ilock(&ctlr->rlock);
  913. csr32w(ctlr, Port, 0);
  914. delay(1);
  915. csr8w(ctlr, Interrupt, InterruptM);
  916. iunlock(&ctlr->rlock);
  917. command(ctlr, LoadRUB, 0);
  918. command(ctlr, LoadCUB, 0);
  919. command(ctlr, LoadDCA, PADDR(ctlr->dump));
  920. /*
  921. * Initialise the receive frame, transmit ring and configuration areas.
  922. */
  923. ctlr->ncb = Ncb;
  924. ctlrinit(ctlr);
  925. /*
  926. * Read the EEPROM.
  927. * Do a dummy read first to get the size
  928. * and allocate ctlr->eeprom.
  929. */
  930. hy93c46r(ctlr, 0);
  931. sum = 0;
  932. for(i = 0; i < (1<<ctlr->eepromsz); i++){
  933. x = hy93c46r(ctlr, i);
  934. ctlr->eeprom[i] = x;
  935. sum += x;
  936. }
  937. if(sum != 0xBABA)
  938. print("#l%d: EEPROM checksum - 0x%4.4uX\n", ether->ctlrno, sum);
  939. /*
  940. * Eeprom[6] indicates whether there is a PHY and whether
  941. * it's not 10Mb-only, in which case use the given PHY address
  942. * to set any PHY specific options and determine the speed.
  943. * Unfortunately, sometimes the EEPROM is blank except for
  944. * the ether address and checksum; in this case look at the
  945. * controller type and if it's am 82558 or 82559 it has an
  946. * embedded PHY so scan for that.
  947. * If no PHY, assume 82503 (serial) operation.
  948. */
  949. if((ctlr->eeprom[6] & 0x1F00) && !(ctlr->eeprom[6] & 0x8000))
  950. phyaddr = ctlr->eeprom[6] & 0x00FF;
  951. else
  952. switch(ctlr->pcidev->rid){
  953. case 0x01: /* 82557 A-step */
  954. case 0x02: /* 82557 B-step */
  955. case 0x03: /* 82557 C-step */
  956. default:
  957. phyaddr = -1;
  958. break;
  959. case 0x04: /* 82558 A-step */
  960. case 0x05: /* 82558 B-step */
  961. case 0x06: /* 82559 A-step */
  962. case 0x07: /* 82559 B-step */
  963. case 0x08: /* 82559 C-step */
  964. case 0x09: /* 82559ER A-step */
  965. phyaddr = scanphy(ctlr);
  966. break;
  967. }
  968. if(phyaddr >= 0){
  969. /*
  970. * Resolve the highest common ability of the two
  971. * link partners. In descending order:
  972. * 0x0100 100BASE-TX Full Duplex
  973. * 0x0200 100BASE-T4
  974. * 0x0080 100BASE-TX
  975. * 0x0040 10BASE-T Full Duplex
  976. * 0x0020 10BASE-T
  977. */
  978. anar = miir(ctlr, phyaddr, 0x04);
  979. anlpar = miir(ctlr, phyaddr, 0x05) & 0x03E0;
  980. anar &= anlpar;
  981. bmcr = 0;
  982. if(anar & 0x380)
  983. bmcr = 0x2000;
  984. if(anar & 0x0140)
  985. bmcr |= 0x0100;
  986. switch((ctlr->eeprom[6]>>8) & 0x001F){
  987. case 0x04: /* DP83840 */
  988. case 0x0A: /* DP83840A */
  989. /*
  990. * The DP83840[A] requires some tweaking for
  991. * reliable operation.
  992. * The manual says bit 10 should be unconditionally
  993. * set although it supposedly only affects full-duplex
  994. * operation (an & 0x0140).
  995. */
  996. x = miir(ctlr, phyaddr, 0x17) & ~0x0520;
  997. x |= 0x0420;
  998. for(i = 0; i < ether->nopt; i++){
  999. if(cistrcmp(ether->opt[i], "congestioncontrol"))
  1000. continue;
  1001. x |= 0x0100;
  1002. break;
  1003. }
  1004. miiw(ctlr, phyaddr, 0x17, x);
  1005. /*
  1006. * If the link partner can't autonegotiate, determine
  1007. * the speed from elsewhere.
  1008. */
  1009. if(anlpar == 0){
  1010. miir(ctlr, phyaddr, 0x01);
  1011. bmsr = miir(ctlr, phyaddr, 0x01);
  1012. x = miir(ctlr, phyaddr, 0x19);
  1013. if((bmsr & 0x0004) && !(x & 0x0040))
  1014. bmcr = 0x2000;
  1015. }
  1016. break;
  1017. case 0x07: /* Intel 82555 */
  1018. /*
  1019. * Auto-negotiation may fail if the other end is
  1020. * a DP83840A and the cable is short.
  1021. */
  1022. miir(ctlr, phyaddr, 0x01);
  1023. bmsr = miir(ctlr, phyaddr, 0x01);
  1024. if((miir(ctlr, phyaddr, 0) & 0x1000) && !(bmsr & 0x0020)){
  1025. miiw(ctlr, phyaddr, 0x1A, 0x2010);
  1026. x = miir(ctlr, phyaddr, 0);
  1027. miiw(ctlr, phyaddr, 0, 0x0200|x);
  1028. for(i = 0; i < 3000; i++){
  1029. delay(1);
  1030. if(miir(ctlr, phyaddr, 0x01) & 0x0020)
  1031. break;
  1032. }
  1033. miiw(ctlr, phyaddr, 0x1A, 0x2000);
  1034. anar = miir(ctlr, phyaddr, 0x04);
  1035. anlpar = miir(ctlr, phyaddr, 0x05) & 0x03E0;
  1036. anar &= anlpar;
  1037. bmcr = 0;
  1038. if(anar & 0x380)
  1039. bmcr = 0x2000;
  1040. if(anar & 0x0140)
  1041. bmcr |= 0x0100;
  1042. }
  1043. break;
  1044. }
  1045. /*
  1046. * Force speed and duplex if no auto-negotiation.
  1047. */
  1048. if(anlpar == 0){
  1049. medium = -1;
  1050. for(i = 0; i < ether->nopt; i++){
  1051. for(k = 0; k < nelem(mediatable); k++){
  1052. if(cistrcmp(mediatable[k], ether->opt[i]))
  1053. continue;
  1054. medium = k;
  1055. break;
  1056. }
  1057. switch(medium){
  1058. default:
  1059. break;
  1060. case 0x00: /* 10BASE-T */
  1061. case 0x01: /* 10BASE-2 */
  1062. case 0x02: /* 10BASE-5 */
  1063. bmcr &= ~(0x2000|0x0100);
  1064. ctlr->configdata[19] &= ~0x40;
  1065. break;
  1066. case 0x03: /* 100BASE-TX */
  1067. case 0x06: /* 100BASE-T4 */
  1068. case 0x07: /* 100BASE-FX */
  1069. ctlr->configdata[19] &= ~0x40;
  1070. bmcr |= 0x2000;
  1071. break;
  1072. case 0x04: /* 10BASE-TFD */
  1073. bmcr = (bmcr & ~0x2000)|0x0100;
  1074. ctlr->configdata[19] |= 0x40;
  1075. break;
  1076. case 0x05: /* 100BASE-TXFD */
  1077. case 0x08: /* 100BASE-FXFD */
  1078. bmcr |= 0x2000|0x0100;
  1079. ctlr->configdata[19] |= 0x40;
  1080. break;
  1081. }
  1082. }
  1083. if(medium != -1)
  1084. miiw(ctlr, phyaddr, 0x00, bmcr);
  1085. }
  1086. if(bmcr & 0x2000)
  1087. ether->mbps = 100;
  1088. ctlr->configdata[8] = 1;
  1089. ctlr->configdata[15] &= ~0x80;
  1090. }
  1091. else{
  1092. ctlr->configdata[8] = 0;
  1093. ctlr->configdata[15] |= 0x80;
  1094. }
  1095. /*
  1096. * Workaround for some broken HUB chips when connected at 10Mb/s
  1097. * half-duplex.
  1098. * This is a band-aid, but as there's no dynamic auto-negotiation
  1099. * code at the moment, only deactivate the workaround code in txstart
  1100. * if the link is 100Mb/s.
  1101. */
  1102. if(ether->mbps != 10)
  1103. ctlr->nop = 0;
  1104. /*
  1105. * Load the chip configuration and start it off.
  1106. */
  1107. if(ether->oq == 0)
  1108. ether->oq = qopen(256*1024, Qmsg, 0, 0);
  1109. configure(ether, 0);
  1110. command(ctlr, CUstart, PADDR(&ctlr->cbr->status));
  1111. /*
  1112. * Check if the adapter's station address is to be overridden.
  1113. * If not, read it from the EEPROM and set in ether->ea prior to loading
  1114. * the station address with the Individual Address Setup command.
  1115. */
  1116. memset(ea, 0, Eaddrlen);
  1117. if(memcmp(ea, ether->ea, Eaddrlen) == 0){
  1118. for(i = 0; i < Eaddrlen/2; i++){
  1119. x = ctlr->eeprom[i];
  1120. ether->ea[2*i] = x;
  1121. ether->ea[2*i+1] = x>>8;
  1122. }
  1123. }
  1124. ilock(&ctlr->cblock);
  1125. ctlr->action = CbIAS;
  1126. txstart(ether);
  1127. iunlock(&ctlr->cblock);
  1128. /*
  1129. * Linkage to the generic ethernet driver.
  1130. */
  1131. ether->attach = attach;
  1132. ether->transmit = transmit;
  1133. ether->interrupt = interrupt;
  1134. ether->ifstat = ifstat;
  1135. ether->shutdown = shutdown;
  1136. ether->promiscuous = promiscuous;
  1137. ether->multicast = multicast;
  1138. ether->arg = ether;
  1139. return 0;
  1140. }
  1141. void
  1142. ether82557link(void)
  1143. {
  1144. addethercard("i82557", reset);
  1145. }