Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

334 lines
9.3 KiB

  1. /*--------------------------------------------------------------------------
  2. | admin.c - Ethernet common admin-packet handling. Includes common
  3. admin. packet handling code.
  4. 6-17-97 - start using index field assigned to box to id rx-messages.
  5. Copyright 1996,97 Comtrol Corporation. All rights reserved. Proprietary
  6. information not permitted for development or use with non-Comtrol products.
  7. |--------------------------------------------------------------------------*/
  8. #include "precomp.h"
  9. static int eth_command_reset(BYTE *rx, BYTE *pkt_in, int size);
  10. static int eth_loop_back(BYTE *pkt_in, int size);
  11. static int eth_id_reply(BYTE *rx, BYTE *pkt_in);
  12. static int eth_id_req(BYTE *mac_addr);
  13. #define TraceStr(s) GTrace(D_Nic, sz_modid, s)
  14. #define TraceErr(s) GTrace(D_Error, sz_modid_err, s)
  15. static char *sz_modid = {"Admin"};
  16. static char *sz_modid_err = {"Error,Admin"};
  17. #define MAX_SEND_DATA_SIZE 220
  18. #define DEV_OK 0
  19. #define DEV_PORT_TIMEOUT 1
  20. #define DEV_NO_REPLY 2
  21. #define DEV_SHORT_REPLY 3
  22. #define DEV_BAD_RHEADSHORT 4
  23. #define DEV_BAD_RHEAD 5
  24. #define DEV_BAD_CHKSUM 6
  25. #define DEV_OVERRUN 7
  26. #define DEV_RESPOND_ERROR 100
  27. /*----------------------------------------------------------------------------
  28. | admin_send_query_id -
  29. |----------------------------------------------------------------------------*/
  30. int admin_send_query_id(Nic *nic, BYTE *dest_addr, int set_us_as_master,
  31. BYTE assigned_index)
  32. {
  33. BYTE pkt[60];
  34. int stat;
  35. TraceStr("SndQuery");
  36. memset(pkt, 0, 60);
  37. if (set_us_as_master)
  38. pkt[26] = 2; // take over device(makes it save our mac-addr)
  39. // 2H = Observe Owner LockOut
  40. else pkt[26] = 1; // set 1 bit so device does not save off mac-addr
  41. // 1H = Passive Query
  42. pkt[15] = assigned_index; // assign the box a index value which we
  43. // use to "id" the box messages.
  44. // server query for box-id
  45. if (dest_addr == NULL)
  46. stat = admin_send(nic, pkt, 26, ADMIN_ID_QUERY, broadcast_addr);
  47. else stat = admin_send(nic, pkt, 26, ADMIN_ID_QUERY, dest_addr);
  48. if (stat != 0)
  49. TraceErr("txer5A!");
  50. return stat;
  51. }
  52. /*----------------------------------------------------------------------------
  53. | admin_send_reset -
  54. |----------------------------------------------------------------------------*/
  55. int admin_send_reset(Nic *nic, BYTE *dest_addr)
  56. {
  57. BYTE pkt[60];
  58. int stat;
  59. TraceStr("SndReset");
  60. memset(pkt, 0, 60);
  61. *((WORD *)&pkt[20]) = 0x5555;
  62. if (dest_addr == NULL)
  63. stat = admin_send(nic, pkt, 26, ADMIN_ID_RESET, broadcast_addr);
  64. else stat = admin_send(nic, pkt, 26, ADMIN_ID_RESET, dest_addr);
  65. if (stat != 0)
  66. TraceErr("txer4A!");
  67. return stat;
  68. }
  69. /*----------------------------------------------------------------------------
  70. | admin_send - Used to send common admin packets, takes care of
  71. filling in the header.
  72. |----------------------------------------------------------------------------*/
  73. int admin_send(Nic *nic, BYTE *buf, int len, int admin_type, BYTE *mac_dest)
  74. {
  75. int stat;
  76. TraceStr("SndPkt");
  77. memcpy(&buf[0], mac_dest, 6);
  78. memcpy(&buf[6], nic->address, 6); // our addr
  79. // BYTE 12-13: Comtrol PCI ID (11H, FEH), Ethernet Len field
  80. *((WORD *)&buf[12]) = 0xfe11;
  81. buf[14] = ASYNC_PRODUCT_HEADER_ID; // comtrol packet type = driver management, any product.
  82. buf[15] = 0; // conc. index field
  83. buf[16] = 1; // admin
  84. *((WORD *)&buf[17]) = len;
  85. buf[19] = admin_type; // ADMIN packet type, 1=boot-loader, 3=id-reply
  86. if (admin_type == ADMIN_ID_QUERY)
  87. memcpy(&buf[20], nic->address, 6); // our addr
  88. if (len < 60)
  89. len = 60;
  90. stat = nic_send_pkt(nic, buf, len);
  91. if (stat)
  92. {
  93. TraceErr("txer3!");
  94. }
  95. return stat;
  96. }
  97. /*---------------------------------------------------------------------------
  98. | ioctl_device - send admin, boot loader packets to the box to
  99. upload code, do misc ioctl commands, etc.
  100. |---------------------------------------------------------------------------*/
  101. int ioctl_device(int cmd,
  102. BYTE *buf,
  103. BYTE *pkt,
  104. ULONG offset, // or ioctl-subfunction if cmd=ioctl
  105. int size)
  106. {
  107. int stat;
  108. int pkt_size;
  109. TraceStr("Ioctl");
  110. stat = 1; // err
  111. switch(cmd)
  112. {
  113. case IOCTL_COMMAND:
  114. stat = eth_device_data(cmd, offset, size, buf, pkt, &pkt_size);
  115. break;
  116. case DOWNLOAD_COMMAND:
  117. stat = eth_device_data(cmd, offset, size, buf, pkt, &pkt_size);
  118. break;
  119. case UPLOAD_COMMAND:
  120. stat = eth_device_data(cmd, offset, size, buf, pkt, &pkt_size);
  121. break;
  122. }
  123. return stat;
  124. }
  125. /*---------------------------------------------------------------------------
  126. | eth_device_data - talks with the device, either sets device data or gets
  127. | device data. Returns 0 if communications ok.
  128. |---------------------------------------------------------------------------*/
  129. int eth_device_data(int message_type,
  130. unsigned long offset,
  131. int num_bytes,
  132. unsigned char *data,
  133. unsigned char *pkt,
  134. int *pkt_size)
  135. {
  136. int i;
  137. unsigned char chksum, command, dat_in;
  138. WORD packet_length;
  139. int pkt_i;
  140. unsigned char *bf;
  141. int in_size = num_bytes;
  142. command = message_type;
  143. switch (message_type)
  144. {
  145. case IOCTL_COMMAND :
  146. packet_length = in_size + 6; // num bytes after len, no chksum included
  147. break;
  148. case UPLOAD_COMMAND :
  149. // send: 0=header, 1=addr, 2=len, 3,4=cmd, 5,6,7,8=offset, data, chksum
  150. // reply: 0=header, 1=addr, 2=len, 3,4=cmd, 5=chksum
  151. packet_length = in_size + 6;
  152. break;
  153. case DOWNLOAD_COMMAND :
  154. // 0=header, 1=addr, 2=len, 3,4=cmd, 5,6,7,8=offset, 9=len_ret
  155. // reply: 0=header, 1=addr, 2=len, 3,4=cmd, data, chksum
  156. packet_length = 8;
  157. break;
  158. }
  159. //-------- flush any ethernet packets in rx buffer
  160. //eth_flush();
  161. pkt_i=0; // start data area in eth. packet
  162. pkt[pkt_i++] = '~';
  163. pkt[pkt_i] = (unsigned char) packet_length;
  164. chksum = pkt[pkt_i++];
  165. pkt[pkt_i] = (unsigned char) (packet_length >> 8);
  166. chksum += pkt[pkt_i++];
  167. chksum += command;
  168. pkt[pkt_i++] = command;
  169. pkt[pkt_i++] = 0; /* hi-byte, command */
  170. switch (message_type)
  171. {
  172. case IOCTL_COMMAND :
  173. bf = (BYTE *) &offset;
  174. chksum += bf[0]; pkt[pkt_i++] = bf[0];
  175. chksum += bf[1]; pkt[pkt_i++] = bf[1];
  176. chksum += bf[2]; pkt[pkt_i++] = bf[2];
  177. chksum += bf[3]; pkt[pkt_i++] = bf[3];
  178. //printf("ioctl-id:%d, size\n", bf[3], in_size);
  179. for (i=0; i<in_size; i++)
  180. {
  181. dat_in = data[i];
  182. chksum += dat_in;
  183. pkt[pkt_i++] = dat_in;
  184. }
  185. break;
  186. case UPLOAD_COMMAND :
  187. bf = (BYTE *) &offset;
  188. chksum += bf[0]; pkt[pkt_i++] = bf[0];
  189. chksum += bf[1]; pkt[pkt_i++] = bf[1];
  190. chksum += bf[2]; pkt[pkt_i++] = bf[2];
  191. chksum += bf[3]; pkt[pkt_i++] = bf[3];
  192. for (i=0; i<in_size; i++)
  193. {
  194. dat_in = data[i];
  195. chksum += dat_in;
  196. pkt[pkt_i++] = dat_in;
  197. }
  198. break;
  199. case DOWNLOAD_COMMAND :
  200. bf = (BYTE *) &offset;
  201. chksum += bf[0]; pkt[pkt_i++] = bf[0];
  202. chksum += bf[1]; pkt[pkt_i++] = bf[1];
  203. chksum += bf[2]; pkt[pkt_i++] = bf[2];
  204. chksum += bf[3]; pkt[pkt_i++] = bf[3];
  205. chksum += (unsigned char) in_size;
  206. pkt[pkt_i++] = (unsigned char) in_size;
  207. chksum += (unsigned char) (in_size >> 8);
  208. pkt[pkt_i++] = (unsigned char) (in_size >> 8);
  209. break;
  210. default:
  211. break;
  212. }
  213. pkt[pkt_i++] = ~chksum;
  214. *pkt_size = pkt_i;
  215. return 0;
  216. }
  217. /*---------------------------------------------------------------------------
  218. | eth_device_reply - Validate the ACK reply pkt due to a sent
  219. boot packet. Ack reply may include data if an IOCTL or
  220. DOWNLOAD type. We use UPLOAD command for code uploads.
  221. | Returns 0 if communications ok.
  222. |---------------------------------------------------------------------------*/
  223. int eth_device_reply(int message_type,
  224. unsigned long offset,
  225. int *num_bytes,
  226. unsigned char *data,
  227. unsigned char *pkt)
  228. {
  229. int i;
  230. unsigned char chksum;
  231. unsigned char *bf;
  232. unsigned char uc;
  233. WORD ret_size;
  234. BYTE *bptr;
  235. bptr = pkt;
  236. if (bptr[0] != '|') // good reply header
  237. {
  238. TraceErr("Err3");
  239. return DEV_BAD_RHEAD;
  240. }
  241. chksum = bptr[1];
  242. ret_size = bptr[1]; // get len
  243. chksum += bptr[2];
  244. ret_size += ((WORD)(bptr[2]) << 8); // get len
  245. if (ret_size > 1600) // limit
  246. ret_size = 0;
  247. uc = bptr[3]; // get command return word
  248. chksum += uc;
  249. uc = bptr[4];
  250. chksum += uc;
  251. i = 0;
  252. if ((message_type == IOCTL_COMMAND) || (message_type == DOWNLOAD_COMMAND))
  253. {
  254. // o_printf("ret size:%d\n", ret_size-2);
  255. if (data == NULL)
  256. return 20; // err out
  257. bf = data;
  258. for (i=0; i<ret_size-2; i++)
  259. {
  260. bf[i] = bptr[5+i];
  261. chksum += bf[i];
  262. }
  263. i = ret_size-2;
  264. }
  265. chksum += bptr[5+i];
  266. if (chksum != 0xff)
  267. {
  268. return DEV_BAD_CHKSUM; /* bad chksum */
  269. }
  270. if ((message_type == IOCTL_COMMAND) || (message_type == DOWNLOAD_COMMAND))
  271. *num_bytes = ret_size-2;
  272. else
  273. *num_bytes = 0;
  274. return 0; // ok
  275. }