skgepnmi.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:201k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. case OID_SKGE_SENSOR_TYPE:
  2. case OID_SKGE_SENSOR_STATUS:
  3. if (*pLen < Limit - Index) {
  4. *pLen = Limit - Index;
  5. return (SK_PNMI_ERR_TOO_SHORT);
  6. }
  7. break;
  8. case OID_SKGE_SENSOR_WAR_CTS:
  9. case OID_SKGE_SENSOR_WAR_TIME:
  10. case OID_SKGE_SENSOR_ERR_CTS:
  11. case OID_SKGE_SENSOR_ERR_TIME:
  12. if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
  13. *pLen = (Limit - Index) * sizeof(SK_U64);
  14. return (SK_PNMI_ERR_TOO_SHORT);
  15. }
  16. break;
  17. default:
  18. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
  19. SK_PNMI_ERR012MSG);
  20. *pLen = 0;
  21. return (SK_PNMI_ERR_GENERAL);
  22. }
  23. /*
  24.  * Get value
  25.  */
  26. for (Offset = 0; Index < Limit; Index ++) {
  27. switch (Id) {
  28. case OID_SKGE_SENSOR_INDEX:
  29. *(pBuf + Offset) = (char)Index;
  30. Offset += sizeof(char);
  31. break;
  32. case OID_SKGE_SENSOR_DESCR:
  33. Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
  34. SK_MEMCPY(pBuf + Offset + 1,
  35. pAC->I2c.SenTable[Index].SenDesc, Len);
  36. *(pBuf + Offset) = (char)Len;
  37. Offset += Len + 1;
  38. break;
  39. case OID_SKGE_SENSOR_TYPE:
  40. *(pBuf + Offset) =
  41. (char)pAC->I2c.SenTable[Index].SenType;
  42. Offset += sizeof(char);
  43. break;
  44. case OID_SKGE_SENSOR_VALUE:
  45. Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
  46. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  47. Offset += sizeof(SK_U32);
  48. break;
  49. case OID_SKGE_SENSOR_WAR_THRES_LOW:
  50. Val32 = (SK_U32)pAC->I2c.SenTable[Index].
  51. SenThreWarnLow;
  52. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  53. Offset += sizeof(SK_U32);
  54. break;
  55. case OID_SKGE_SENSOR_WAR_THRES_UPP:
  56. Val32 = (SK_U32)pAC->I2c.SenTable[Index].
  57. SenThreWarnHigh;
  58. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  59. Offset += sizeof(SK_U32);
  60. break;
  61. case OID_SKGE_SENSOR_ERR_THRES_LOW:
  62. Val32 = (SK_U32)pAC->I2c.SenTable[Index].
  63. SenThreErrLow;
  64. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  65. Offset += sizeof(SK_U32);
  66. break;
  67. case OID_SKGE_SENSOR_ERR_THRES_UPP:
  68. Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
  69. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  70. Offset += sizeof(SK_U32);
  71. break;
  72. case OID_SKGE_SENSOR_STATUS:
  73. *(pBuf + Offset) =
  74. (char)pAC->I2c.SenTable[Index].SenErrFlag;
  75. Offset += sizeof(char);
  76. break;
  77. case OID_SKGE_SENSOR_WAR_CTS:
  78. Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
  79. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  80. Offset += sizeof(SK_U64);
  81. break;
  82. case OID_SKGE_SENSOR_ERR_CTS:
  83. Val64 = pAC->I2c.SenTable[Index].SenErrCts;
  84. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  85. Offset += sizeof(SK_U64);
  86. break;
  87. case OID_SKGE_SENSOR_WAR_TIME:
  88. Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
  89. SenBegWarnTS);
  90. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  91. Offset += sizeof(SK_U64);
  92. break;
  93. case OID_SKGE_SENSOR_ERR_TIME:
  94. Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
  95. SenBegErrTS);
  96. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  97. Offset += sizeof(SK_U64);
  98. break;
  99. default:
  100. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR013,
  101. SK_PNMI_ERR013MSG);
  102. return (SK_PNMI_ERR_GENERAL);
  103. }
  104. }
  105. /*
  106.  * Store used buffer space
  107.  */
  108. *pLen = Offset;
  109. return (SK_PNMI_ERR_OK);
  110. }
  111. /*****************************************************************************
  112.  *
  113.  * Vpd - OID handler function of OID_SKGE_VPD_XXX
  114.  *
  115.  * Description:
  116.  * Get/preset/set of VPD data. As instance the name of a VPD key
  117.  * can be passed. The Instance parameter is a SK_U32 and can be
  118.  * used as a string buffer for the VPD key, because their maximum
  119.  * length is 4 byte.
  120.  *
  121.  * Returns:
  122.  * SK_PNMI_ERR_OK           The request was successfully performed.
  123.  * SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  124.  * SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  125.  *                          the correct data (e.g. a 32bit value is
  126.  *                          needed, but a 16 bit value was passed).
  127.  * SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
  128.  *                          value range.
  129.  * SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
  130.  * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  131.  *                               exist (e.g. port instance 3 on a two port
  132.  *                          adapter.
  133.  */
  134. static int Vpd(
  135. SK_AC *pAC, /* Pointer to adapter context */
  136. SK_IOC IoC, /* IO context handle */
  137. int Action, /* Get/PreSet/Set action */
  138. SK_U32 Id, /* Object ID that is to be processed */
  139. char *pBuf, /* Buffer to which to mgmt data will be retrieved */
  140. unsigned int *pLen, /* On call: buffer length. On return: used buffer */
  141. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  142. unsigned int TableIndex, /* Index to the Id table */
  143. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
  144. {
  145. SK_VPD_STATUS *pVpdStatus;
  146. unsigned int BufLen;
  147. char Buf[256];
  148. char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
  149. char KeyStr[SK_PNMI_VPD_KEY_SIZE];
  150. unsigned int KeyNo;
  151. unsigned int Offset;
  152. unsigned int Index;
  153. unsigned int FirstIndex;
  154. unsigned int LastIndex;
  155. unsigned int Len;
  156. int Ret;
  157. SK_U32 Val32;
  158. /*
  159.  * Get array of all currently stored VPD keys
  160.  */
  161. Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr),
  162. &KeyNo);
  163. if (Ret != SK_PNMI_ERR_OK) {
  164. *pLen = 0;
  165. return (Ret);
  166. }
  167. /*
  168.  * If instance is not -1, try to find the requested VPD key for
  169.  * the multiple instance variables. The other OIDs as for example
  170.  * OID VPD_ACTION are single instance variables and must be
  171.  * handled separatly.
  172.  */
  173. FirstIndex = 0;
  174. LastIndex = KeyNo;
  175. if ((Instance != (SK_U32)(-1))) {
  176. if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
  177. Id == OID_SKGE_VPD_ACCESS) {
  178. SK_STRNCPY(KeyStr, (char *)&Instance, 4);
  179. KeyStr[4] = 0;
  180. for (Index = 0; Index < KeyNo; Index ++) {
  181. if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
  182. FirstIndex = Index;
  183. LastIndex = Index+1;
  184. break;
  185. }
  186. }
  187. if (Index == KeyNo) {
  188. *pLen = 0;
  189. return (SK_PNMI_ERR_UNKNOWN_INST);
  190. }
  191. }
  192. else if (Instance != 1) {
  193. *pLen = 0;
  194. return (SK_PNMI_ERR_UNKNOWN_INST);
  195. }
  196. }
  197. /*
  198.  * Get value, if a query should be performed
  199.  */
  200. if (Action == SK_PNMI_GET) {
  201. switch (Id) {
  202. case OID_SKGE_VPD_FREE_BYTES:
  203. /* Check length of buffer */
  204. if (*pLen < sizeof(SK_U32)) {
  205. *pLen = sizeof(SK_U32);
  206. return (SK_PNMI_ERR_TOO_SHORT);
  207. }
  208. /* Get number of free bytes */
  209. pVpdStatus = VpdStat(pAC, IoC);
  210. if (pVpdStatus == NULL) {
  211. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
  212. SK_PNMI_ERR017MSG);
  213. *pLen = 0;
  214. return (SK_PNMI_ERR_GENERAL);
  215. }
  216. if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
  217. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
  218. SK_PNMI_ERR018MSG);
  219. *pLen = 0;
  220. return (SK_PNMI_ERR_GENERAL);
  221. }
  222. Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
  223. SK_PNMI_STORE_U32(pBuf, Val32);
  224. *pLen = sizeof(SK_U32);
  225. break;
  226. case OID_SKGE_VPD_ENTRIES_LIST:
  227. /* Check length */
  228. for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
  229. Len += SK_STRLEN(KeyArr[Index]) + 1;
  230. }
  231. if (*pLen < Len) {
  232. *pLen = Len;
  233. return (SK_PNMI_ERR_TOO_SHORT);
  234. }
  235. /* Get value */
  236. *(pBuf) = (char)Len - 1;
  237. for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
  238. Len = SK_STRLEN(KeyArr[Index]);
  239. SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
  240. Offset += Len;
  241. if (Index < KeyNo - 1) {
  242. *(pBuf + Offset) = ' ';
  243. Offset ++;
  244. }
  245. }
  246. *pLen = Offset;
  247. break;
  248. case OID_SKGE_VPD_ENTRIES_NUMBER:
  249. /* Check length */
  250. if (*pLen < sizeof(SK_U32)) {
  251. *pLen = sizeof(SK_U32);
  252. return (SK_PNMI_ERR_TOO_SHORT);
  253. }
  254. Val32 = (SK_U32)KeyNo;
  255. SK_PNMI_STORE_U32(pBuf, Val32);
  256. *pLen = sizeof(SK_U32);
  257. break;
  258. case OID_SKGE_VPD_KEY:
  259. /* Check buffer length, if it is large enough */
  260. for (Len = 0, Index = FirstIndex;
  261. Index < LastIndex; Index ++) {
  262. Len += SK_STRLEN(KeyArr[Index]) + 1;
  263. }
  264. if (*pLen < Len) {
  265. *pLen = Len;
  266. return (SK_PNMI_ERR_TOO_SHORT);
  267. }
  268. /*
  269.  * Get the key to an intermediate buffer, because
  270.  * we have to prepend a length byte.
  271.  */
  272. for (Offset = 0, Index = FirstIndex;
  273. Index < LastIndex; Index ++) {
  274. Len = SK_STRLEN(KeyArr[Index]);
  275. *(pBuf + Offset) = (char)Len;
  276. SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
  277. Len);
  278. Offset += Len + 1;
  279. }
  280. *pLen = Offset;
  281. break;
  282. case OID_SKGE_VPD_VALUE:
  283. /* Check the buffer length if it is large enough */
  284. for (Offset = 0, Index = FirstIndex;
  285. Index < LastIndex; Index ++) {
  286. BufLen = 256;
  287. if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
  288. (int *)&BufLen) > 0 ||
  289. BufLen >= SK_PNMI_VPD_DATALEN) {
  290. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  291. SK_PNMI_ERR021,
  292. SK_PNMI_ERR021MSG);
  293. return (SK_PNMI_ERR_GENERAL);
  294. }
  295. Offset += BufLen + 1;
  296. }
  297. if (*pLen < Offset) {
  298. *pLen = Offset;
  299. return (SK_PNMI_ERR_TOO_SHORT);
  300. }
  301. /*
  302.  * Get the value to an intermediate buffer, because
  303.  * we have to prepend a length byte.
  304.  */
  305. for (Offset = 0, Index = FirstIndex;
  306. Index < LastIndex; Index ++) {
  307. BufLen = 256;
  308. if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
  309. (int *)&BufLen) > 0 ||
  310. BufLen >= SK_PNMI_VPD_DATALEN) {
  311. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  312. SK_PNMI_ERR022,
  313. SK_PNMI_ERR022MSG);
  314. *pLen = 0;
  315. return (SK_PNMI_ERR_GENERAL);
  316. }
  317. *(pBuf + Offset) = (char)BufLen;
  318. SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
  319. Offset += BufLen + 1;
  320. }
  321. *pLen = Offset;
  322. break;
  323. case OID_SKGE_VPD_ACCESS:
  324. if (*pLen < LastIndex - FirstIndex) {
  325. *pLen = LastIndex - FirstIndex;
  326. return (SK_PNMI_ERR_TOO_SHORT);
  327. }
  328. for (Offset = 0, Index = FirstIndex;
  329. Index < LastIndex; Index ++) {
  330. if (VpdMayWrite(KeyArr[Index])) {
  331. *(pBuf + Offset) = SK_PNMI_VPD_RW;
  332. }
  333. else {
  334. *(pBuf + Offset) = SK_PNMI_VPD_RO;
  335. }
  336. Offset ++;
  337. }
  338. *pLen = Offset;
  339. break;
  340. case OID_SKGE_VPD_ACTION:
  341. Offset = LastIndex - FirstIndex;
  342. if (*pLen < Offset) {
  343. *pLen = Offset;
  344. return (SK_PNMI_ERR_TOO_SHORT);
  345. }
  346. SK_MEMSET(pBuf, 0, Offset);
  347. *pLen = Offset;
  348. break;
  349. default:
  350. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
  351. SK_PNMI_ERR023MSG);
  352. *pLen = 0;
  353. return (SK_PNMI_ERR_GENERAL);
  354. }
  355. else {
  356. /* The only OID which can be set is VPD_ACTION */
  357. if (Id != OID_SKGE_VPD_ACTION) {
  358. if (Id == OID_SKGE_VPD_FREE_BYTES ||
  359. Id == OID_SKGE_VPD_ENTRIES_LIST ||
  360. Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
  361. Id == OID_SKGE_VPD_KEY ||
  362. Id == OID_SKGE_VPD_VALUE ||
  363. Id == OID_SKGE_VPD_ACCESS) {
  364. *pLen = 0;
  365. return (SK_PNMI_ERR_READ_ONLY);
  366. }
  367. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
  368. SK_PNMI_ERR024MSG);
  369. *pLen = 0;
  370. return (SK_PNMI_ERR_GENERAL);
  371. }
  372. /*
  373.  * From this point we handle VPD_ACTION. Check the buffer
  374.  * length. It should at least have the size of one byte.
  375.  */
  376. if (*pLen < 1) {
  377. *pLen = 1;
  378. return (SK_PNMI_ERR_TOO_SHORT);
  379. }
  380. /*
  381.  * The first byte contains the VPD action type we should
  382.  * perform.
  383.  */
  384. switch (*pBuf) {
  385. case SK_PNMI_VPD_IGNORE:
  386. /* Nothing to do */
  387. break;
  388. case SK_PNMI_VPD_CREATE:
  389. /*
  390.  * We have to create a new VPD entry or we modify
  391.  * an existing one. Check first the buffer length.
  392.  */
  393. if (*pLen < 4) {
  394. *pLen = 4;
  395. return (SK_PNMI_ERR_TOO_SHORT);
  396. }
  397. KeyStr[0] = pBuf[1];
  398. KeyStr[1] = pBuf[2];
  399. KeyStr[2] = 0;
  400. /*
  401.  * Is the entry writable or does it belong to the
  402.  * read-only area?
  403.  */
  404. if (!VpdMayWrite(KeyStr)) {
  405. *pLen = 0;
  406. return (SK_PNMI_ERR_BAD_VALUE);
  407. }
  408. Offset = (int)pBuf[3] & 0xFF;
  409. SK_MEMCPY(Buf, pBuf + 4, Offset);
  410. Buf[Offset] = 0;
  411. /* A preset ends here */
  412. if (Action == SK_PNMI_PRESET) {
  413. return (SK_PNMI_ERR_OK);
  414. }
  415. /* Write the new entry or modify an existing one */
  416. Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
  417. if (Ret == SK_PNMI_VPD_NOWRITE ) {
  418. *pLen = 0;
  419. return (SK_PNMI_ERR_BAD_VALUE);
  420. }
  421. else if (Ret != SK_PNMI_VPD_OK) {
  422. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
  423. SK_PNMI_ERR025MSG);
  424. *pLen = 0;
  425. return (SK_PNMI_ERR_GENERAL);
  426. }
  427. /*
  428.  * Perform an update of the VPD data. This is
  429.  * not mandantory, but just to be sure.
  430.  */
  431. Ret = VpdUpdate(pAC, IoC);
  432. if (Ret != SK_PNMI_VPD_OK) {
  433. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
  434. SK_PNMI_ERR026MSG);
  435. *pLen = 0;
  436. return (SK_PNMI_ERR_GENERAL);
  437. }
  438. break;
  439. case SK_PNMI_VPD_DELETE:
  440. /* Check if the buffer size is plausible */
  441. if (*pLen < 3) {
  442. *pLen = 3;
  443. return (SK_PNMI_ERR_TOO_SHORT);
  444. }
  445. if (*pLen > 3) {
  446. *pLen = 0;
  447. return (SK_PNMI_ERR_BAD_VALUE);
  448. }
  449. KeyStr[0] = pBuf[1];
  450. KeyStr[1] = pBuf[2];
  451. KeyStr[2] = 0;
  452. /* Find the passed key in the array */
  453. for (Index = 0; Index < KeyNo; Index ++) {
  454. if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
  455. break;
  456. }
  457. }
  458. /*
  459.  * If we cannot find the key it is wrong, so we
  460.  * return an appropriate error value.
  461.  */
  462. if (Index == KeyNo) {
  463. *pLen = 0;
  464. return (SK_PNMI_ERR_BAD_VALUE);
  465. }
  466. if (Action == SK_PNMI_PRESET) {
  467. return (SK_PNMI_ERR_OK);
  468. }
  469. /* Ok, you wanted it and you will get it */
  470. Ret = VpdDelete(pAC, IoC, KeyStr);
  471. if (Ret != SK_PNMI_VPD_OK) {
  472. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
  473. SK_PNMI_ERR027MSG);
  474. *pLen = 0;
  475. return (SK_PNMI_ERR_GENERAL);
  476. }
  477. /*
  478.  * Perform an update of the VPD data. This is
  479.  * not mandantory, but just to be sure.
  480.  */
  481. Ret = VpdUpdate(pAC, IoC);
  482. if (Ret != SK_PNMI_VPD_OK) {
  483. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
  484. SK_PNMI_ERR028MSG);
  485. *pLen = 0;
  486. return (SK_PNMI_ERR_GENERAL);
  487. }
  488. break;
  489. default:
  490. *pLen = 0;
  491. return (SK_PNMI_ERR_BAD_VALUE);
  492. }
  493. }
  494. return (SK_PNMI_ERR_OK);
  495. }
  496. /*****************************************************************************
  497.  *
  498.  * General - OID handler function of various single instance OIDs
  499.  *
  500.  * Description:
  501.  * The code is simple. No description necessary.
  502.  *
  503.  * Returns:
  504.  * SK_PNMI_ERR_OK           The request was successfully performed.
  505.  * SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  506.  * SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  507.  *                          the correct data (e.g. a 32bit value is
  508.  *                          needed, but a 16 bit value was passed).
  509.  * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  510.  *                               exist (e.g. port instance 3 on a two port
  511.  *                          adapter.
  512.  */
  513. static int General(
  514. SK_AC *pAC, /* Pointer to adapter context */
  515. SK_IOC IoC, /* IO context handle */
  516. int Action, /* Get/PreSet/Set action */
  517. SK_U32 Id, /* Object ID that is to be processed */
  518. char *pBuf, /* Buffer to which to mgmt data will be retrieved */
  519. unsigned int *pLen, /* On call: buffer length. On return: used buffer */
  520. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  521. unsigned int TableIndex, /* Index to the Id table */
  522. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
  523. {
  524. int Ret;
  525. unsigned int Index;
  526. unsigned int Len;
  527. unsigned int Offset;
  528. unsigned int Val;
  529. SK_U8 Val8;
  530. SK_U16 Val16;
  531. SK_U32 Val32;
  532. SK_U64 Val64;
  533. SK_U64 Val64RxHwErrs = 0;
  534. SK_U64 Val64TxHwErrs = 0;
  535. SK_BOOL Is64BitReq = SK_FALSE;
  536. char Buf[256];
  537. /*
  538.  * Check instance. We only handle single instance variables
  539.  */
  540. if (Instance != (SK_U32)(-1) && Instance != 1) {
  541. *pLen = 0;
  542. return (SK_PNMI_ERR_UNKNOWN_INST);
  543. }
  544. /*
  545.  * Check action. We only allow get requests.
  546.  */
  547. if (Action != SK_PNMI_GET) {
  548. *pLen = 0;
  549. return (SK_PNMI_ERR_READ_ONLY);
  550. }
  551. /*
  552.  * Check length for the various supported OIDs
  553.  */
  554. switch (Id) {
  555. case OID_GEN_XMIT_ERROR:
  556. case OID_GEN_RCV_ERROR:
  557. case OID_GEN_RCV_NO_BUFFER:
  558. #ifndef SK_NDIS_64BIT_CTR
  559. if (*pLen < sizeof(SK_U32)) {
  560. *pLen = sizeof(SK_U32);
  561. return (SK_PNMI_ERR_TOO_SHORT);
  562. }
  563. #else /* SK_NDIS_64BIT_CTR */
  564. /*
  565.  * for compatibility, at least 32bit are required for oid
  566.  */
  567. if (*pLen < sizeof(SK_U32)) {
  568. /*
  569. * but indicate handling for 64bit values,
  570. * if insufficient space is provided
  571. */
  572. *pLen = sizeof(SK_U64);
  573. return (SK_PNMI_ERR_TOO_SHORT);
  574. }
  575. Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
  576. #endif /* SK_NDIS_64BIT_CTR */
  577. break;
  578. case OID_SKGE_PORT_NUMBER:
  579. case OID_SKGE_DEVICE_TYPE:
  580. case OID_SKGE_RESULT:
  581. case OID_SKGE_RLMT_MONITOR_NUMBER:
  582. case OID_GEN_TRANSMIT_QUEUE_LENGTH:
  583. case OID_SKGE_TRAP_NUMBER:
  584. case OID_SKGE_MDB_VERSION:
  585. if (*pLen < sizeof(SK_U32)) {
  586. *pLen = sizeof(SK_U32);
  587. return (SK_PNMI_ERR_TOO_SHORT);
  588. }
  589. break;
  590. case OID_SKGE_CHIPSET:
  591. if (*pLen < sizeof(SK_U16)) {
  592. *pLen = sizeof(SK_U16);
  593. return (SK_PNMI_ERR_TOO_SHORT);
  594. }
  595. break;
  596. case OID_SKGE_BUS_TYPE:
  597. case OID_SKGE_BUS_SPEED:
  598. case OID_SKGE_BUS_WIDTH:
  599. case OID_SKGE_SENSOR_NUMBER:
  600. case OID_SKGE_CHKSM_NUMBER:
  601. if (*pLen < sizeof(SK_U8)) {
  602. *pLen = sizeof(SK_U8);
  603. return (SK_PNMI_ERR_TOO_SHORT);
  604. }
  605. break;
  606. case OID_SKGE_TX_SW_QUEUE_LEN:
  607. case OID_SKGE_TX_SW_QUEUE_MAX:
  608. case OID_SKGE_TX_RETRY:
  609. case OID_SKGE_RX_INTR_CTS:
  610. case OID_SKGE_TX_INTR_CTS:
  611. case OID_SKGE_RX_NO_BUF_CTS:
  612. case OID_SKGE_TX_NO_BUF_CTS:
  613. case OID_SKGE_TX_USED_DESCR_NO:
  614. case OID_SKGE_RX_DELIVERED_CTS:
  615. case OID_SKGE_RX_OCTETS_DELIV_CTS:
  616. case OID_SKGE_RX_HW_ERROR_CTS:
  617. case OID_SKGE_TX_HW_ERROR_CTS:
  618. case OID_SKGE_IN_ERRORS_CTS:
  619. case OID_SKGE_OUT_ERROR_CTS:
  620. case OID_SKGE_ERR_RECOVERY_CTS:
  621. case OID_SKGE_SYSUPTIME:
  622. if (*pLen < sizeof(SK_U64)) {
  623. *pLen = sizeof(SK_U64);
  624. return (SK_PNMI_ERR_TOO_SHORT);
  625. }
  626. break;
  627. default:
  628. /* Checked later */
  629. break;
  630. }
  631. /* Update statistic */
  632. if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
  633. Id == OID_SKGE_TX_HW_ERROR_CTS ||
  634. Id == OID_SKGE_IN_ERRORS_CTS ||
  635. Id == OID_SKGE_OUT_ERROR_CTS ||
  636. Id == OID_GEN_XMIT_ERROR ||
  637. Id == OID_GEN_RCV_ERROR) {
  638. /* Force the XMAC to update its statistic counters and
  639.  * Increment semaphore to indicate that an update was
  640.  * already done.
  641.  */
  642. Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
  643. if (Ret != SK_PNMI_ERR_OK) {
  644. *pLen = 0;
  645. return (Ret);
  646. }
  647. pAC->Pnmi.MacUpdatedFlag ++;
  648. /*
  649.  * Some OIDs consist of multiple hardware counters. Those
  650.  * values which are contained in all of them will be added
  651.  * now.
  652.  */
  653. switch (Id) {
  654. case OID_SKGE_RX_HW_ERROR_CTS:
  655. case OID_SKGE_IN_ERRORS_CTS:
  656. case OID_GEN_RCV_ERROR:
  657. Val64RxHwErrs =
  658. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
  659. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
  660. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex)+
  661. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
  662. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
  663. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex)+
  664. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
  665. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
  666. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
  667. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex)-
  668. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_LONGFRAMES, NetIndex)+
  669. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
  670. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
  671.         break;
  672. case OID_SKGE_TX_HW_ERROR_CTS:
  673. case OID_SKGE_OUT_ERROR_CTS:
  674. case OID_GEN_XMIT_ERROR:
  675. Val64TxHwErrs =
  676. GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
  677. GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex)+
  678. GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex)+
  679. GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex)+
  680. GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex);
  681. break;
  682. }
  683. }
  684. /*
  685.  * Retrieve value
  686.  */
  687. switch (Id) {
  688. case OID_SKGE_SUPPORTED_LIST:
  689. Len = sizeof(IdTable)/sizeof(IdTable[0]) * sizeof(SK_U32);
  690. if (*pLen < Len) {
  691. *pLen = Len;
  692. return (SK_PNMI_ERR_TOO_SHORT);
  693. }
  694. for (Offset = 0, Index = 0; Offset < Len;
  695. Offset += sizeof(SK_U32), Index ++) {
  696. Val32 = (SK_U32)IdTable[Index].Id;
  697. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  698. }
  699. *pLen = Len;
  700. break;
  701. case OID_SKGE_PORT_NUMBER:
  702. Val32 = (SK_U32)pAC->GIni.GIMacsFound;
  703. SK_PNMI_STORE_U32(pBuf, Val32);
  704. *pLen = sizeof(SK_U32);
  705. break;
  706. case OID_SKGE_DEVICE_TYPE:
  707. Val32 = (SK_U32)pAC->Pnmi.DeviceType;
  708. SK_PNMI_STORE_U32(pBuf, Val32);
  709. *pLen = sizeof(SK_U32);
  710. break;
  711. case OID_SKGE_DRIVER_DESCR:
  712. if (pAC->Pnmi.pDriverDescription == NULL) {
  713. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
  714. SK_PNMI_ERR007MSG);
  715. *pLen = 0;
  716. return (SK_PNMI_ERR_GENERAL);
  717. }
  718. Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
  719. if (Len > SK_PNMI_STRINGLEN1) {
  720. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
  721. SK_PNMI_ERR029MSG);
  722. *pLen = 0;
  723. return (SK_PNMI_ERR_GENERAL);
  724. }
  725. if (*pLen < Len) {
  726. *pLen = Len;
  727. return (SK_PNMI_ERR_TOO_SHORT);
  728. }
  729. *pBuf = (char)(Len - 1);
  730. SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
  731. *pLen = Len;
  732. break;
  733. case OID_SKGE_DRIVER_VERSION:
  734. if (pAC->Pnmi.pDriverVersion == NULL) {
  735. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
  736. SK_PNMI_ERR030MSG);
  737. *pLen = 0;
  738. return (SK_PNMI_ERR_GENERAL);
  739. }
  740. Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
  741. if (Len > SK_PNMI_STRINGLEN1) {
  742. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
  743. SK_PNMI_ERR031MSG);
  744. *pLen = 0;
  745. return (SK_PNMI_ERR_GENERAL);
  746. }
  747. if (*pLen < Len) {
  748. *pLen = Len;
  749. return (SK_PNMI_ERR_TOO_SHORT);
  750. }
  751. *pBuf = (char)(Len - 1);
  752. SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
  753. *pLen = Len;
  754. break;
  755. case OID_SKGE_HW_DESCR:
  756. /*
  757.  * The hardware description is located in the VPD. This
  758.  * query may move to the initialisation routine. But
  759.  * the VPD data is cached and therefore a call here
  760.  * will not make much difference.
  761.  */
  762. Len = 256;
  763. if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
  764. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
  765. SK_PNMI_ERR032MSG);
  766. *pLen = 0;
  767. return (SK_PNMI_ERR_GENERAL);
  768. }
  769. Len ++;
  770. if (Len > SK_PNMI_STRINGLEN1) {
  771. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
  772. SK_PNMI_ERR033MSG);
  773. *pLen = 0;
  774. return (SK_PNMI_ERR_GENERAL);
  775. }
  776. if (*pLen < Len) {
  777. *pLen = Len;
  778. return (SK_PNMI_ERR_TOO_SHORT);
  779. }
  780. *pBuf = (char)(Len - 1);
  781. SK_MEMCPY(pBuf + 1, Buf, Len - 1);
  782. *pLen = Len;
  783. break;
  784. case OID_SKGE_HW_VERSION:
  785. /* Oh, I love to do some string manipulation */
  786. if (*pLen < 5) {
  787. *pLen = 5;
  788. return (SK_PNMI_ERR_TOO_SHORT);
  789. }
  790. Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
  791. pBuf[0] = 4;
  792. pBuf[1] = 'v';
  793. pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
  794. pBuf[3] = '.';
  795. pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
  796. *pLen = 5;
  797. break;
  798. case OID_SKGE_CHIPSET:
  799. Val16 = SK_PNMI_CHIPSET;
  800. SK_PNMI_STORE_U16(pBuf, Val16);
  801. *pLen = sizeof(SK_U16);
  802. break;
  803. case OID_SKGE_BUS_TYPE:
  804. *pBuf = (char)SK_PNMI_BUS_PCI;
  805. *pLen = sizeof(char);
  806. break;
  807. case OID_SKGE_BUS_SPEED:
  808. *pBuf = pAC->Pnmi.PciBusSpeed;
  809. *pLen = sizeof(char);
  810. break;
  811. case OID_SKGE_BUS_WIDTH:
  812. *pBuf = pAC->Pnmi.PciBusWidth;
  813. *pLen = sizeof(char);
  814. break;
  815. case OID_SKGE_RESULT:
  816. Val32 = pAC->Pnmi.TestResult;
  817. SK_PNMI_STORE_U32(pBuf, Val32);
  818. *pLen = sizeof(SK_U32);
  819. break;
  820. case OID_SKGE_SENSOR_NUMBER:
  821. *pBuf = (char)pAC->I2c.MaxSens;
  822. *pLen = sizeof(char);
  823. break;
  824. case OID_SKGE_CHKSM_NUMBER:
  825. *pBuf = SKCS_NUM_PROTOCOLS;
  826. *pLen = sizeof(char);
  827. break;
  828. case OID_SKGE_TRAP_NUMBER:
  829. GetTrapQueueLen(pAC, &Len, &Val);
  830. Val32 = (SK_U32)Val;
  831. SK_PNMI_STORE_U32(pBuf, Val32);
  832. *pLen = sizeof(SK_U32);
  833. break;
  834. case OID_SKGE_TRAP:
  835. GetTrapQueueLen(pAC, &Len, &Val);
  836. if (*pLen < Len) {
  837. *pLen = Len;
  838. return (SK_PNMI_ERR_TOO_SHORT);
  839. }
  840. CopyTrapQueue(pAC, pBuf);
  841. *pLen = Len;
  842. break;
  843. case OID_SKGE_RLMT_MONITOR_NUMBER:
  844. /* XXX Not yet implemented by RLMT therefore we return zero elements */
  845. Val32 = 0;
  846. SK_PNMI_STORE_U32(pBuf, Val32);
  847. *pLen = sizeof(SK_U32);
  848. break;
  849. case OID_SKGE_TX_SW_QUEUE_LEN:
  850. /* Dual net mode */
  851. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
  852. Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
  853. }
  854. /* Single net mode */
  855. else {
  856. Val64 =  pAC->Pnmi.Port[0].TxSwQueueLen +
  857. pAC->Pnmi.Port[1].TxSwQueueLen;
  858. }
  859. SK_PNMI_STORE_U64(pBuf, Val64);
  860. *pLen = sizeof(SK_U64);
  861. break;
  862. case OID_SKGE_TX_SW_QUEUE_MAX:
  863. /* Dual net mode */
  864. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
  865. Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
  866. }
  867. /* Single net mode */
  868. else {
  869. Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
  870. pAC->Pnmi.Port[1].TxSwQueueMax;
  871. }
  872. SK_PNMI_STORE_U64(pBuf, Val64);
  873. *pLen = sizeof(SK_U64);
  874. break;
  875. case OID_SKGE_TX_RETRY:
  876. /* Dual net mode */
  877. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
  878. Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
  879. }
  880. /* Single net mode */
  881. else {
  882. Val64 = pAC->Pnmi.Port[0].TxRetryCts +
  883. pAC->Pnmi.Port[1].TxRetryCts;
  884. }
  885. SK_PNMI_STORE_U64(pBuf, Val64);
  886. *pLen = sizeof(SK_U64);
  887. break;
  888. case OID_SKGE_RX_INTR_CTS:
  889. /* Dual net mode */
  890. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
  891. Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
  892. }
  893. /* Single net mode */
  894. else {
  895. Val64 = pAC->Pnmi.Port[0].RxIntrCts +
  896. pAC->Pnmi.Port[1].RxIntrCts;
  897. }
  898. SK_PNMI_STORE_U64(pBuf, Val64);
  899. *pLen = sizeof(SK_U64);
  900. break;
  901. case OID_SKGE_TX_INTR_CTS:
  902. /* Dual net mode */
  903. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
  904. Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
  905. }
  906. /* Single net mode */
  907. else {
  908. Val64 = pAC->Pnmi.Port[0].TxIntrCts +
  909. pAC->Pnmi.Port[1].TxIntrCts;
  910. }
  911. SK_PNMI_STORE_U64(pBuf, Val64);
  912. *pLen = sizeof(SK_U64);
  913. break;
  914. case OID_SKGE_RX_NO_BUF_CTS:
  915. /* Dual net mode */
  916. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
  917. Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
  918. }
  919. /* Single net mode */
  920. else {
  921. Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
  922. pAC->Pnmi.Port[1].RxNoBufCts;
  923. }
  924. SK_PNMI_STORE_U64(pBuf, Val64);
  925. *pLen = sizeof(SK_U64);
  926. break;
  927. case OID_SKGE_TX_NO_BUF_CTS:
  928. /* Dual net mode */
  929. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
  930. Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
  931. }
  932. /* Single net mode */
  933. else {
  934. Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
  935. pAC->Pnmi.Port[1].TxNoBufCts;
  936. }
  937. SK_PNMI_STORE_U64(pBuf, Val64);
  938. *pLen = sizeof(SK_U64);
  939. break;
  940. case OID_SKGE_TX_USED_DESCR_NO:
  941. /* Dual net mode */
  942. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
  943. Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
  944. }
  945. /* Single net mode */
  946. else {
  947. Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
  948. pAC->Pnmi.Port[1].TxUsedDescrNo;
  949. }
  950. SK_PNMI_STORE_U64(pBuf, Val64);
  951. *pLen = sizeof(SK_U64);
  952. break;
  953. case OID_SKGE_RX_DELIVERED_CTS:
  954. /* Dual net mode */
  955. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
  956. Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
  957. }
  958. /* Single net mode */
  959. else {
  960. Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
  961. pAC->Pnmi.Port[1].RxDeliveredCts;
  962. }
  963. SK_PNMI_STORE_U64(pBuf, Val64);
  964. *pLen = sizeof(SK_U64);
  965. break;
  966. case OID_SKGE_RX_OCTETS_DELIV_CTS:
  967. /* Dual net mode */
  968. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
  969. Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
  970. }
  971. /* Single net mode */
  972. else {
  973. Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
  974. pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
  975. }
  976. SK_PNMI_STORE_U64(pBuf, Val64);
  977. *pLen = sizeof(SK_U64);
  978. break;
  979. case OID_SKGE_RX_HW_ERROR_CTS:
  980. SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
  981. *pLen = sizeof(SK_U64);
  982. break;
  983. case OID_SKGE_TX_HW_ERROR_CTS:
  984. SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
  985. *pLen = sizeof(SK_U64);
  986. break;
  987. case OID_SKGE_IN_ERRORS_CTS:
  988. /* Dual net mode */
  989. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
  990. Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
  991. }
  992. /* Single net mode */
  993. else {
  994. Val64 = Val64RxHwErrs + 
  995. pAC->Pnmi.Port[0].RxNoBufCts +
  996. pAC->Pnmi.Port[1].RxNoBufCts;
  997. }
  998. SK_PNMI_STORE_U64(pBuf, Val64);
  999. *pLen = sizeof(SK_U64);
  1000. break;
  1001. case OID_SKGE_OUT_ERROR_CTS:
  1002. /* Dual net mode */
  1003. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
  1004. Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
  1005. }
  1006. /* Single net mode */
  1007. else {
  1008. Val64 = Val64TxHwErrs + 
  1009. pAC->Pnmi.Port[0].TxNoBufCts +
  1010. pAC->Pnmi.Port[1].TxNoBufCts;
  1011. }
  1012. SK_PNMI_STORE_U64(pBuf, Val64);
  1013. *pLen = sizeof(SK_U64);
  1014. break;
  1015. case OID_SKGE_ERR_RECOVERY_CTS:
  1016. /* Dual net mode */
  1017. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
  1018. Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
  1019. }
  1020. /* Single net mode */
  1021. else {
  1022. Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
  1023. pAC->Pnmi.Port[1].ErrRecoveryCts;
  1024. }
  1025. SK_PNMI_STORE_U64(pBuf, Val64);
  1026. *pLen = sizeof(SK_U64);
  1027. break;
  1028. case OID_SKGE_SYSUPTIME:
  1029. Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
  1030. Val64 -= pAC->Pnmi.StartUpTime;
  1031. SK_PNMI_STORE_U64(pBuf, Val64);
  1032. *pLen = sizeof(SK_U64);
  1033. break;
  1034. case OID_SKGE_MDB_VERSION:
  1035. Val32 = SK_PNMI_MDB_VERSION;
  1036. SK_PNMI_STORE_U32(pBuf, Val32);
  1037. *pLen = sizeof(SK_U32);
  1038. break;
  1039. case OID_GEN_RCV_ERROR:
  1040. Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
  1041. /*
  1042.  * by default 32bit values are evaluated
  1043.  */
  1044. if (!Is64BitReq) {
  1045. Val32 = (SK_U32)Val64;
  1046. SK_PNMI_STORE_U32(pBuf, Val32);
  1047. *pLen = sizeof(SK_U32);
  1048. }
  1049. else {
  1050. SK_PNMI_STORE_U64(pBuf, Val64);
  1051. *pLen = sizeof(SK_U64);
  1052. }
  1053. break;
  1054. case OID_GEN_XMIT_ERROR:
  1055. Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
  1056. /*
  1057.  * by default 32bit values are evaluated
  1058.  */
  1059. if (!Is64BitReq) {
  1060. Val32 = (SK_U32)Val64;
  1061. SK_PNMI_STORE_U32(pBuf, Val32);
  1062. *pLen = sizeof(SK_U32);
  1063. }
  1064. else {
  1065. SK_PNMI_STORE_U64(pBuf, Val64);
  1066. *pLen = sizeof(SK_U64);
  1067. }
  1068. break;
  1069. case OID_GEN_RCV_NO_BUFFER:
  1070. Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
  1071. /*
  1072.  * by default 32bit values are evaluated
  1073.  */
  1074. if (!Is64BitReq) {
  1075. Val32 = (SK_U32)Val64;
  1076. SK_PNMI_STORE_U32(pBuf, Val32);
  1077. *pLen = sizeof(SK_U32);
  1078. }
  1079. else {
  1080. SK_PNMI_STORE_U64(pBuf, Val64);
  1081. *pLen = sizeof(SK_U64);
  1082. }
  1083. break;
  1084. case OID_GEN_TRANSMIT_QUEUE_LENGTH:
  1085. Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
  1086. SK_PNMI_STORE_U32(pBuf, Val32);
  1087. *pLen = sizeof(SK_U32);
  1088. break;
  1089. default:
  1090. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
  1091. SK_PNMI_ERR034MSG);
  1092. *pLen = 0;
  1093. return (SK_PNMI_ERR_GENERAL);
  1094. }
  1095. if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
  1096. Id == OID_SKGE_TX_HW_ERROR_CTS ||
  1097. Id == OID_SKGE_IN_ERRORS_CTS ||
  1098. Id == OID_SKGE_OUT_ERROR_CTS ||
  1099. Id == OID_GEN_XMIT_ERROR ||
  1100. Id == OID_GEN_RCV_ERROR) {
  1101. pAC->Pnmi.MacUpdatedFlag --;
  1102. }
  1103. return (SK_PNMI_ERR_OK);
  1104. }
  1105. /*****************************************************************************
  1106.  *
  1107.  * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
  1108.  *
  1109.  * Description:
  1110.  * Get/Presets/Sets the RLMT OIDs.
  1111.  *
  1112.  * Returns:
  1113.  * SK_PNMI_ERR_OK           The request was successfully performed.
  1114.  * SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  1115.  * SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  1116.  *                          the correct data (e.g. a 32bit value is
  1117.  *                          needed, but a 16 bit value was passed).
  1118.  * SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
  1119.  *                          value range.
  1120.  * SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
  1121.  * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  1122.  *                               exist (e.g. port instance 3 on a two port
  1123.  *                          adapter.
  1124.  */
  1125. static int Rlmt(
  1126. SK_AC *pAC, /* Pointer to adapter context */
  1127. SK_IOC IoC, /* IO context handle */
  1128. int Action, /* Get/PreSet/Set action */
  1129. SK_U32 Id, /* Object ID that is to be processed */
  1130. char *pBuf, /* Buffer to which to mgmt data will be retrieved */
  1131. unsigned int *pLen, /* On call: buffer length. On return: used buffer */
  1132. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  1133. unsigned int TableIndex, /* Index to the Id table */
  1134. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
  1135. {
  1136. int Ret;
  1137. unsigned int PhysPortIndex;
  1138. unsigned int PhysPortMax;
  1139. SK_EVPARA EventParam;
  1140. SK_U32 Val32;
  1141. SK_U64 Val64;
  1142. /*
  1143.  * Check instance. Only single instance OIDs are allowed here.
  1144.  */
  1145. if (Instance != (SK_U32)(-1) && Instance != 1) {
  1146. *pLen = 0;
  1147. return (SK_PNMI_ERR_UNKNOWN_INST);
  1148. }
  1149. /*
  1150.  * Perform the requested action
  1151.  */
  1152. if (Action == SK_PNMI_GET) {
  1153. /*
  1154.  * Check if the buffer length is large enough.
  1155.  */
  1156. switch (Id) {
  1157. case OID_SKGE_RLMT_MODE:
  1158. case OID_SKGE_RLMT_PORT_ACTIVE:
  1159. case OID_SKGE_RLMT_PORT_PREFERRED:
  1160. if (*pLen < sizeof(SK_U8)) {
  1161. *pLen = sizeof(SK_U8);
  1162. return (SK_PNMI_ERR_TOO_SHORT);
  1163. }
  1164. break;
  1165. case OID_SKGE_RLMT_PORT_NUMBER:
  1166. if (*pLen < sizeof(SK_U32)) {
  1167. *pLen = sizeof(SK_U32);
  1168. return (SK_PNMI_ERR_TOO_SHORT);
  1169. }
  1170. break;
  1171. case OID_SKGE_RLMT_CHANGE_CTS:
  1172. case OID_SKGE_RLMT_CHANGE_TIME:
  1173. case OID_SKGE_RLMT_CHANGE_ESTIM:
  1174. case OID_SKGE_RLMT_CHANGE_THRES:
  1175. if (*pLen < sizeof(SK_U64)) {
  1176. *pLen = sizeof(SK_U64);
  1177. return (SK_PNMI_ERR_TOO_SHORT);
  1178. }
  1179. break;
  1180. default:
  1181. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
  1182. SK_PNMI_ERR035MSG);
  1183. *pLen = 0;
  1184. return (SK_PNMI_ERR_GENERAL);
  1185. }
  1186. /*
  1187.  * Update RLMT statistic and increment semaphores to indicate
  1188.  * that an update was already done. Maybe RLMT will hold its
  1189.  * statistic always up to date some time. Then we can
  1190.  * remove this type of call.
  1191.  */
  1192. if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
  1193. *pLen = 0;
  1194. return (Ret);
  1195. }
  1196. pAC->Pnmi.RlmtUpdatedFlag ++;
  1197. /*
  1198.  * Retrieve Value
  1199. */
  1200. switch (Id) {
  1201. case OID_SKGE_RLMT_MODE:
  1202. *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
  1203. *pLen = sizeof(char);
  1204. break;
  1205. case OID_SKGE_RLMT_PORT_NUMBER:
  1206. Val32 = (SK_U32)pAC->GIni.GIMacsFound;
  1207. SK_PNMI_STORE_U32(pBuf, Val32);
  1208. *pLen = sizeof(SK_U32);
  1209. break;
  1210. case OID_SKGE_RLMT_PORT_ACTIVE:
  1211. *pBuf = 0;
  1212. /*
  1213.  * If multiple ports may become active this OID
  1214.  * doesn't make sense any more. A new variable in
  1215.  * the port structure should be created. However,
  1216.  * for this variable the first active port is
  1217.  * returned.
  1218.  */
  1219. PhysPortMax = pAC->GIni.GIMacsFound;
  1220. for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
  1221. PhysPortIndex ++) {
  1222. if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
  1223. *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
  1224. break;
  1225. }
  1226. }
  1227. *pLen = sizeof(char);
  1228. break;
  1229. case OID_SKGE_RLMT_PORT_PREFERRED:
  1230. *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
  1231. *pLen = sizeof(char);
  1232. break;
  1233. case OID_SKGE_RLMT_CHANGE_CTS:
  1234. Val64 = pAC->Pnmi.RlmtChangeCts;
  1235. SK_PNMI_STORE_U64(pBuf, Val64);
  1236. *pLen = sizeof(SK_U64);
  1237. break;
  1238. case OID_SKGE_RLMT_CHANGE_TIME:
  1239. Val64 = pAC->Pnmi.RlmtChangeTime;
  1240. SK_PNMI_STORE_U64(pBuf, Val64);
  1241. *pLen = sizeof(SK_U64);
  1242. break;
  1243. case OID_SKGE_RLMT_CHANGE_ESTIM:
  1244. Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
  1245. SK_PNMI_STORE_U64(pBuf, Val64);
  1246. *pLen = sizeof(SK_U64);
  1247. break;
  1248. case OID_SKGE_RLMT_CHANGE_THRES:
  1249. Val64 = pAC->Pnmi.RlmtChangeThreshold;
  1250. SK_PNMI_STORE_U64(pBuf, Val64);
  1251. *pLen = sizeof(SK_U64);
  1252. break;
  1253. default:
  1254. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR036,
  1255. SK_PNMI_ERR036MSG);
  1256. pAC->Pnmi.RlmtUpdatedFlag --;
  1257. *pLen = 0;
  1258. return (SK_PNMI_ERR_GENERAL);
  1259. }
  1260. pAC->Pnmi.RlmtUpdatedFlag --;
  1261. }
  1262. else {
  1263. /* Perform a preset or set */
  1264. switch (Id) {
  1265. case OID_SKGE_RLMT_MODE:
  1266. /* Check if the buffer length is plausible */
  1267. if (*pLen < sizeof(char)) {
  1268. *pLen = sizeof(char);
  1269. return (SK_PNMI_ERR_TOO_SHORT);
  1270. }
  1271. /* Check if the value range is correct */
  1272. if (*pLen != sizeof(char) ||
  1273. (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
  1274. *(SK_U8 *)pBuf > 15) {
  1275. *pLen = 0;
  1276. return (SK_PNMI_ERR_BAD_VALUE);
  1277. }
  1278. /* The preset ends here */
  1279. if (Action == SK_PNMI_PRESET) {
  1280. *pLen = 0;
  1281. return (SK_PNMI_ERR_OK);
  1282. }
  1283. /* Send an event to RLMT to change the mode */
  1284. SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
  1285. EventParam.Para32[0] |= (SK_U32)(*pBuf);
  1286. EventParam.Para32[1] = 0;
  1287. if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
  1288. EventParam) > 0) {
  1289. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
  1290. SK_PNMI_ERR037MSG);
  1291. *pLen = 0;
  1292. return (SK_PNMI_ERR_GENERAL);
  1293. }
  1294. break;
  1295. case OID_SKGE_RLMT_PORT_PREFERRED:
  1296. /* Check if the buffer length is plausible */
  1297. if (*pLen < sizeof(char)) {
  1298. *pLen = sizeof(char);
  1299. return (SK_PNMI_ERR_TOO_SHORT);
  1300. }
  1301. /* Check if the value range is correct */
  1302. if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
  1303. (SK_U8)pAC->GIni.GIMacsFound) {
  1304. *pLen = 0;
  1305. return (SK_PNMI_ERR_BAD_VALUE);
  1306. }
  1307. /* The preset ends here */
  1308. if (Action == SK_PNMI_PRESET) {
  1309. *pLen = 0;
  1310. return (SK_PNMI_ERR_OK);
  1311. }
  1312. /*
  1313.  * Send an event to RLMT change the preferred port.
  1314.  * A param of -1 means automatic mode. RLMT will
  1315.  * make the decision which is the preferred port.
  1316.  */
  1317. SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
  1318. EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
  1319. EventParam.Para32[1] = NetIndex;
  1320. if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
  1321. EventParam) > 0) {
  1322. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
  1323. SK_PNMI_ERR038MSG);
  1324. *pLen = 0;
  1325. return (SK_PNMI_ERR_GENERAL);
  1326. }
  1327. break;
  1328. case OID_SKGE_RLMT_CHANGE_THRES:
  1329. /* Check if the buffer length is plausible */
  1330. if (*pLen < sizeof(SK_U64)) {
  1331. *pLen = sizeof(SK_U64);
  1332. return (SK_PNMI_ERR_TOO_SHORT);
  1333. }
  1334. /*
  1335.  * There are not many restrictions to the
  1336.  * value range.
  1337.  */
  1338. if (*pLen != sizeof(SK_U64)) {
  1339. *pLen = 0;
  1340. return (SK_PNMI_ERR_BAD_VALUE);
  1341. }
  1342. /* A preset ends here */
  1343. if (Action == SK_PNMI_PRESET) {
  1344. *pLen = 0;
  1345. return (SK_PNMI_ERR_OK);
  1346. }
  1347. /*
  1348.  * Store the new threshold, which will be taken
  1349.  * on the next timer event.
  1350.  */
  1351. SK_PNMI_READ_U64(pBuf, Val64);
  1352. pAC->Pnmi.RlmtChangeThreshold = Val64;
  1353. break;
  1354. default:
  1355. /* The other OIDs are not be able for set */
  1356. *pLen = 0;
  1357. return (SK_PNMI_ERR_READ_ONLY);
  1358. }
  1359. }
  1360. return (SK_PNMI_ERR_OK);
  1361. }
  1362. /*****************************************************************************
  1363.  *
  1364.  * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
  1365.  *
  1366.  * Description:
  1367.  * Performs get requests on multiple instance variables.
  1368.  *
  1369.  * Returns:
  1370.  * SK_PNMI_ERR_OK           The request was successfully performed.
  1371.  * SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  1372.  * SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  1373.  *                          the correct data (e.g. a 32bit value is
  1374.  *                          needed, but a 16 bit value was passed).
  1375.  * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  1376.  *                               exist (e.g. port instance 3 on a two port
  1377.  *                          adapter.
  1378.  */
  1379. static int RlmtStat(
  1380. SK_AC *pAC, /* Pointer to adapter context */
  1381. SK_IOC IoC, /* IO context handle */
  1382. int Action, /* Get/PreSet/Set action */
  1383. SK_U32 Id, /* Object ID that is to be processed */
  1384. char *pBuf, /* Buffer to which to mgmt data will be retrieved */
  1385. unsigned int *pLen, /* On call: buffer length. On return: used buffer */
  1386. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  1387. unsigned int TableIndex, /* Index to the Id table */
  1388. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
  1389. {
  1390. unsigned int PhysPortMax;
  1391. unsigned int PhysPortIndex;
  1392. unsigned int Limit;
  1393. unsigned int Offset;
  1394. int Ret;
  1395. SK_U32 Val32;
  1396. SK_U64 Val64;
  1397. /*
  1398.  * Calculate the port indexes from the instance
  1399.  */
  1400. PhysPortMax = pAC->GIni.GIMacsFound;
  1401. if ((Instance != (SK_U32)(-1))) {
  1402. /* Check instance range */
  1403. if ((Instance < 1) || (Instance > PhysPortMax)) {
  1404. *pLen = 0;
  1405. return (SK_PNMI_ERR_UNKNOWN_INST);
  1406. }
  1407. /* Single net mode */
  1408. PhysPortIndex = Instance - 1;
  1409. /* Dual net mode */
  1410. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
  1411. PhysPortIndex = NetIndex;
  1412. }
  1413. /* Both net modes */
  1414. Limit = PhysPortIndex + 1;
  1415. }
  1416. else {
  1417. /* Single net mode */
  1418. PhysPortIndex = 0;
  1419. Limit = PhysPortMax;
  1420. /* Dual net mode */
  1421. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
  1422. PhysPortIndex = NetIndex;
  1423. Limit = PhysPortIndex + 1;
  1424. }
  1425. }
  1426. /*
  1427.  * Currently only get requests are allowed.
  1428.  */
  1429. if (Action != SK_PNMI_GET) {
  1430. *pLen = 0;
  1431. return (SK_PNMI_ERR_READ_ONLY);
  1432. }
  1433. /*
  1434.  * Check if the buffer length is large enough.
  1435.  */
  1436. switch (Id) {
  1437. case OID_SKGE_RLMT_PORT_INDEX:
  1438. case OID_SKGE_RLMT_STATUS:
  1439. if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
  1440. *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
  1441. return (SK_PNMI_ERR_TOO_SHORT);
  1442. }
  1443. break;
  1444. case OID_SKGE_RLMT_TX_HELLO_CTS:
  1445. case OID_SKGE_RLMT_RX_HELLO_CTS:
  1446. case OID_SKGE_RLMT_TX_SP_REQ_CTS:
  1447. case OID_SKGE_RLMT_RX_SP_CTS:
  1448. if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
  1449. *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
  1450. return (SK_PNMI_ERR_TOO_SHORT);
  1451. }
  1452. break;
  1453. default:
  1454. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
  1455. SK_PNMI_ERR039MSG);
  1456. *pLen = 0;
  1457. return (SK_PNMI_ERR_GENERAL);
  1458. }
  1459. /*
  1460.  * Update statistic and increment semaphores to indicate that
  1461.  * an update was already done.
  1462.  */
  1463. if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
  1464. *pLen = 0;
  1465. return (Ret);
  1466. }
  1467. pAC->Pnmi.RlmtUpdatedFlag ++;
  1468. /*
  1469.  * Get value
  1470.  */
  1471. Offset = 0;
  1472. for (; PhysPortIndex < Limit; PhysPortIndex ++) {
  1473. switch (Id) {
  1474. case OID_SKGE_RLMT_PORT_INDEX:
  1475. Val32 = PhysPortIndex;
  1476. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  1477. Offset += sizeof(SK_U32);
  1478. break;
  1479. case OID_SKGE_RLMT_STATUS:
  1480. if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
  1481. SK_RLMT_PS_INIT ||
  1482. pAC->Rlmt.Port[PhysPortIndex].PortState ==
  1483. SK_RLMT_PS_DOWN) {
  1484. Val32 = SK_PNMI_RLMT_STATUS_ERROR;
  1485. }
  1486. else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
  1487. Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
  1488. }
  1489. else {
  1490. Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
  1491. }
  1492. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  1493. Offset += sizeof(SK_U32);
  1494. break;
  1495. case OID_SKGE_RLMT_TX_HELLO_CTS:
  1496. Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
  1497. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  1498. Offset += sizeof(SK_U64);
  1499. break;
  1500. case OID_SKGE_RLMT_RX_HELLO_CTS:
  1501. Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
  1502. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  1503. Offset += sizeof(SK_U64);
  1504. break;
  1505. case OID_SKGE_RLMT_TX_SP_REQ_CTS:
  1506. Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
  1507. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  1508. Offset += sizeof(SK_U64);
  1509. break;
  1510. case OID_SKGE_RLMT_RX_SP_CTS:
  1511. Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
  1512. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  1513. Offset += sizeof(SK_U64);
  1514. break;
  1515. default:
  1516. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040,
  1517. SK_PNMI_ERR040MSG);
  1518. pAC->Pnmi.RlmtUpdatedFlag --;
  1519. *pLen = 0;
  1520. return (SK_PNMI_ERR_GENERAL);
  1521. }
  1522. }
  1523. *pLen = Offset;
  1524. pAC->Pnmi.RlmtUpdatedFlag --;
  1525. return (SK_PNMI_ERR_OK);
  1526. }
  1527. /*****************************************************************************
  1528.  *
  1529.  * MacPrivateConf - OID handler function of OIDs concerning the configuration
  1530.  *
  1531.  * Description:
  1532.  * Get/Presets/Sets the OIDs concerning the configuration.
  1533.  *
  1534.  * Returns:
  1535.  * SK_PNMI_ERR_OK           The request was successfully performed.
  1536.  * SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  1537.  * SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  1538.  *                          the correct data (e.g. a 32bit value is
  1539.  *                          needed, but a 16 bit value was passed).
  1540.  * SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
  1541.  *                          value range.
  1542.  * SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
  1543.  * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  1544.  *                               exist (e.g. port instance 3 on a two port
  1545.  *                          adapter.
  1546.  */
  1547. static int MacPrivateConf(
  1548. SK_AC *pAC, /* Pointer to adapter context */
  1549. SK_IOC IoC, /* IO context handle */
  1550. int Action, /* Get/PreSet/Set action */
  1551. SK_U32 Id, /* Object ID that is to be processed */
  1552. char *pBuf, /* Buffer to which to mgmt data will be retrieved */
  1553. unsigned int *pLen, /* On call: buffer length. On return: used buffer */
  1554. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  1555. unsigned int TableIndex, /* Index to the Id table */
  1556. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
  1557. {
  1558. unsigned int PhysPortMax;
  1559. unsigned int PhysPortIndex;
  1560. unsigned int LogPortMax;
  1561. unsigned int LogPortIndex;
  1562. unsigned int Limit;
  1563. unsigned int Offset;
  1564. char Val8;
  1565. int Ret;
  1566. SK_EVPARA EventParam;
  1567. SK_U32 Val32;
  1568. /*
  1569.  * Calculate instance if wished. MAC index 0 is the virtual
  1570.  * MAC.
  1571.  */
  1572. PhysPortMax = pAC->GIni.GIMacsFound;
  1573. LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
  1574. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ /* Dual net mode */
  1575. LogPortMax--;
  1576. }
  1577. if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
  1578. /* Check instance range */
  1579. if ((Instance < 1) || (Instance > LogPortMax)) {
  1580. *pLen = 0;
  1581. return (SK_PNMI_ERR_UNKNOWN_INST);
  1582. }
  1583. LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
  1584. Limit = LogPortIndex + 1;
  1585. }
  1586. else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
  1587. LogPortIndex = 0;
  1588. Limit = LogPortMax;
  1589. }
  1590. /*
  1591.  * Perform action
  1592.  */
  1593. if (Action == SK_PNMI_GET) {
  1594. /*
  1595.  * Check length
  1596.  */
  1597. switch (Id) {
  1598. case OID_SKGE_PMD:
  1599. case OID_SKGE_CONNECTOR:
  1600. case OID_SKGE_LINK_CAP:
  1601. case OID_SKGE_LINK_MODE:
  1602. case OID_SKGE_LINK_MODE_STATUS:
  1603. case OID_SKGE_LINK_STATUS:
  1604. case OID_SKGE_FLOWCTRL_CAP:
  1605. case OID_SKGE_FLOWCTRL_MODE:
  1606. case OID_SKGE_FLOWCTRL_STATUS:
  1607. case OID_SKGE_PHY_OPERATION_CAP:
  1608. case OID_SKGE_PHY_OPERATION_MODE:
  1609. case OID_SKGE_PHY_OPERATION_STATUS:
  1610. if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
  1611. *pLen = (Limit - LogPortIndex) *
  1612. sizeof(SK_U8);
  1613. return (SK_PNMI_ERR_TOO_SHORT);
  1614. }
  1615. break;
  1616.         case OID_SKGE_MTU:
  1617. if (*pLen < sizeof(SK_U32)) {
  1618. *pLen = sizeof(SK_U32);
  1619. return (SK_PNMI_ERR_TOO_SHORT);
  1620. }
  1621. break;
  1622. default:
  1623. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
  1624. SK_PNMI_ERR041MSG);
  1625. *pLen = 0;
  1626. return (SK_PNMI_ERR_GENERAL);
  1627. }
  1628. /*
  1629.  * Update statistic and increment semaphore to indicate
  1630.  * that an update was already done.
  1631.  */
  1632. if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
  1633. *pLen = 0;
  1634. return (Ret);
  1635. }
  1636. pAC->Pnmi.SirqUpdatedFlag ++;
  1637. /*
  1638.  * Get value
  1639.  */
  1640. Offset = 0;
  1641. for (; LogPortIndex < Limit; LogPortIndex ++) {
  1642. switch (Id) {
  1643. case OID_SKGE_PMD:
  1644. *(pBuf + Offset) = pAC->Pnmi.PMD;
  1645. Offset += sizeof(char);
  1646. break;
  1647. case OID_SKGE_CONNECTOR:
  1648. *(pBuf + Offset) = pAC->Pnmi.Connector;
  1649. Offset += sizeof(char);
  1650. break;
  1651. case OID_SKGE_LINK_CAP:
  1652. if (LogPortIndex == 0) {
  1653. /* Get value for virtual port */
  1654. VirtualConf(pAC, IoC, Id, pBuf +
  1655. Offset);
  1656. }
  1657. else {
  1658. /* Get value for physical ports */
  1659. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  1660. pAC, LogPortIndex);
  1661. *(pBuf + Offset) = pAC->GIni.GP[
  1662. PhysPortIndex].PLinkCap;
  1663. }
  1664. Offset += sizeof(char);
  1665. break;
  1666. case OID_SKGE_LINK_MODE:
  1667. if (LogPortIndex == 0) {
  1668. /* Get value for virtual port */
  1669. VirtualConf(pAC, IoC, Id, pBuf +
  1670. Offset);
  1671. }
  1672. else {
  1673. /* Get value for physical ports */
  1674. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  1675. pAC, LogPortIndex);
  1676. *(pBuf + Offset) = pAC->GIni.GP[
  1677. PhysPortIndex].PLinkModeConf;
  1678. }
  1679. Offset += sizeof(char);
  1680. break;
  1681. case OID_SKGE_LINK_MODE_STATUS:
  1682. if (LogPortIndex == 0) {
  1683. /* Get value for virtual port */
  1684. VirtualConf(pAC, IoC, Id, pBuf +
  1685. Offset);
  1686. }
  1687. else {
  1688. /* Get value for physical port */
  1689. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  1690. pAC, LogPortIndex);
  1691. *(pBuf + Offset) =
  1692. CalculateLinkModeStatus(pAC,
  1693. IoC, PhysPortIndex);
  1694. }
  1695. Offset += sizeof(char);
  1696. break;
  1697. case OID_SKGE_LINK_STATUS:
  1698. if (LogPortIndex == 0) {
  1699. /* Get value for virtual port */
  1700. VirtualConf(pAC, IoC, Id, pBuf +
  1701. Offset);
  1702. }
  1703. else {
  1704. /* Get value for physical ports */
  1705. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  1706. pAC, LogPortIndex);
  1707. *(pBuf + Offset) =
  1708. CalculateLinkStatus(pAC,
  1709. IoC, PhysPortIndex);
  1710. }
  1711. Offset += sizeof(char);
  1712. break;
  1713. case OID_SKGE_FLOWCTRL_CAP:
  1714. if (LogPortIndex == 0) {
  1715. /* Get value for virtual port */
  1716. VirtualConf(pAC, IoC, Id, pBuf +
  1717. Offset);
  1718. }
  1719. else {
  1720. /* Get value for physical ports */
  1721. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  1722. pAC, LogPortIndex);
  1723. *(pBuf + Offset) = pAC->GIni.GP[
  1724. PhysPortIndex].PFlowCtrlCap;
  1725. }
  1726. Offset += sizeof(char);
  1727. break;
  1728. case OID_SKGE_FLOWCTRL_MODE:
  1729. if (LogPortIndex == 0) {
  1730. /* Get value for virtual port */
  1731. VirtualConf(pAC, IoC, Id, pBuf +
  1732. Offset);
  1733. }
  1734. else {
  1735. /* Get value for physical port */
  1736. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  1737. pAC, LogPortIndex);
  1738. *(pBuf + Offset) = pAC->GIni.GP[
  1739. PhysPortIndex].PFlowCtrlMode;
  1740. }
  1741. Offset += sizeof(char);
  1742. break;
  1743. case OID_SKGE_FLOWCTRL_STATUS:
  1744. if (LogPortIndex == 0) {
  1745. /* Get value for virtual port */
  1746. VirtualConf(pAC, IoC, Id, pBuf +
  1747. Offset);
  1748. }
  1749. else {
  1750. /* Get value for physical port */
  1751. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  1752. pAC, LogPortIndex);
  1753. *(pBuf + Offset) = pAC->GIni.GP[
  1754. PhysPortIndex].PFlowCtrlStatus;
  1755. }
  1756. Offset += sizeof(char);
  1757. break;
  1758. case OID_SKGE_PHY_OPERATION_CAP:
  1759. if (LogPortIndex == 0) {
  1760. /* Get value for virtual port */
  1761. VirtualConf(pAC, IoC, Id, pBuf +
  1762. Offset);
  1763. }
  1764. else {
  1765. /* Get value for physical ports */
  1766. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  1767. pAC, LogPortIndex);
  1768. *(pBuf + Offset) = pAC->GIni.GP[
  1769. PhysPortIndex].PMSCap;
  1770. }
  1771. Offset += sizeof(char);
  1772. break;
  1773. case OID_SKGE_PHY_OPERATION_MODE:
  1774. if (LogPortIndex == 0) {
  1775. /* Get value for virtual port */
  1776. VirtualConf(pAC, IoC, Id, pBuf +
  1777. Offset);
  1778. }
  1779. else {
  1780. /* Get value for physical port */
  1781. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  1782. pAC, LogPortIndex);
  1783. *(pBuf + Offset) = pAC->GIni.GP[
  1784. PhysPortIndex].PMSMode;
  1785. }
  1786. Offset += sizeof(char);
  1787. break;
  1788. case OID_SKGE_PHY_OPERATION_STATUS:
  1789. if (LogPortIndex == 0) {
  1790. /* Get value for virtual port */
  1791. VirtualConf(pAC, IoC, Id, pBuf +
  1792. Offset);
  1793. }
  1794. else {
  1795. /* Get value for physical port */
  1796. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  1797. pAC, LogPortIndex);
  1798. *(pBuf + Offset) = pAC->GIni.GP[
  1799. PhysPortIndex].PMSStatus;
  1800. }
  1801. Offset += sizeof(char);
  1802. break;
  1803. case OID_SKGE_MTU:
  1804. Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
  1805. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  1806. Offset += sizeof(SK_U32);
  1807. break;
  1808. default:
  1809. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR042,
  1810. SK_PNMI_ERR042MSG);
  1811. pAC->Pnmi.SirqUpdatedFlag --;
  1812. return (SK_PNMI_ERR_GENERAL);
  1813. }
  1814. }
  1815. *pLen = Offset;
  1816. pAC->Pnmi.SirqUpdatedFlag --;
  1817. return (SK_PNMI_ERR_OK);
  1818. }
  1819. /*
  1820.  * From here SET or PRESET action. Check if the passed
  1821.  * buffer length is plausible.
  1822.  */
  1823. switch (Id) {
  1824. case OID_SKGE_LINK_MODE:
  1825. case OID_SKGE_FLOWCTRL_MODE:
  1826. case OID_SKGE_PHY_OPERATION_MODE:
  1827. if (*pLen < Limit - LogPortIndex) {
  1828. *pLen = Limit - LogPortIndex;
  1829. return (SK_PNMI_ERR_TOO_SHORT);
  1830. }
  1831. if (*pLen != Limit - LogPortIndex) {
  1832. *pLen = 0;
  1833. return (SK_PNMI_ERR_BAD_VALUE);
  1834. }
  1835. break;
  1836. case OID_SKGE_MTU:
  1837. if (*pLen < sizeof(SK_U32)) {
  1838. *pLen = sizeof(SK_U32);
  1839. return (SK_PNMI_ERR_TOO_SHORT);
  1840. }
  1841. if (*pLen != sizeof(SK_U32)) {
  1842. *pLen = 0;
  1843. return (SK_PNMI_ERR_BAD_VALUE);
  1844. }
  1845. break;
  1846.     default:
  1847. *pLen = 0;
  1848. return (SK_PNMI_ERR_READ_ONLY);
  1849. }
  1850. /*
  1851.  * Perform preset or set
  1852.  */
  1853. Offset = 0;
  1854. for (; LogPortIndex < Limit; LogPortIndex ++) {
  1855. switch (Id) {
  1856. case OID_SKGE_LINK_MODE:
  1857. /* Check the value range */
  1858. Val8 = *(pBuf + Offset);
  1859. if (Val8 == 0) {
  1860. Offset += sizeof(char);
  1861. break;
  1862. }
  1863. if (Val8 < SK_LMODE_HALF ||
  1864. (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
  1865. (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
  1866. *pLen = 0;
  1867. return (SK_PNMI_ERR_BAD_VALUE);
  1868. }
  1869. /* The preset ends here */
  1870. if (Action == SK_PNMI_PRESET) {
  1871. return (SK_PNMI_ERR_OK);
  1872. }
  1873. if (LogPortIndex == 0) {
  1874. /*
  1875.  * The virtual port consists of all currently
  1876.  * active ports. Find them and send an event
  1877.  * with the new link mode to SIRQ.
  1878.  */
  1879. for (PhysPortIndex = 0;
  1880. PhysPortIndex < PhysPortMax;
  1881. PhysPortIndex ++) {
  1882. if (!pAC->Pnmi.Port[PhysPortIndex].
  1883. ActiveFlag) {
  1884. continue;
  1885. }
  1886. EventParam.Para32[0] = PhysPortIndex;
  1887. EventParam.Para32[1] = (SK_U32)Val8;
  1888. if (SkGeSirqEvent(pAC, IoC,
  1889. SK_HWEV_SET_LMODE,
  1890. EventParam) > 0) {
  1891. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  1892. SK_PNMI_ERR043,
  1893. SK_PNMI_ERR043MSG);
  1894. *pLen = 0;
  1895. return (SK_PNMI_ERR_GENERAL);
  1896. }
  1897. }
  1898. }
  1899. else {
  1900. /*
  1901.  * Send an event with the new link mode to
  1902.  * the SIRQ module.
  1903.  */
  1904. EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
  1905. pAC, LogPortIndex);
  1906. EventParam.Para32[1] = (SK_U32)Val8;
  1907. if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
  1908. EventParam) > 0) {
  1909. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  1910. SK_PNMI_ERR043,
  1911. SK_PNMI_ERR043MSG);
  1912. *pLen = 0;
  1913. return (SK_PNMI_ERR_GENERAL);
  1914. }
  1915. }
  1916. Offset += sizeof(char);
  1917. break;
  1918. case OID_SKGE_FLOWCTRL_MODE:
  1919. /* Check the value range */
  1920. Val8 = *(pBuf + Offset);
  1921. if (Val8 == 0) {
  1922. Offset += sizeof(char);
  1923. break;
  1924. }
  1925. if (Val8 < SK_FLOW_MODE_NONE ||
  1926. (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
  1927. (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
  1928. *pLen = 0;
  1929. return (SK_PNMI_ERR_BAD_VALUE);
  1930. }
  1931. /* The preset ends here */
  1932. if (Action == SK_PNMI_PRESET) {
  1933. return (SK_PNMI_ERR_OK);
  1934. }
  1935. if (LogPortIndex == 0) {
  1936. /*
  1937.  * The virtual port consists of all currently
  1938.  * active ports. Find them and send an event
  1939.  * with the new flow control mode to SIRQ.
  1940.  */
  1941. for (PhysPortIndex = 0;
  1942. PhysPortIndex < PhysPortMax;
  1943. PhysPortIndex ++) {
  1944. if (!pAC->Pnmi.Port[PhysPortIndex].
  1945. ActiveFlag) {
  1946. continue;
  1947. }
  1948. EventParam.Para32[0] = PhysPortIndex;
  1949. EventParam.Para32[1] = (SK_U32)Val8;
  1950. if (SkGeSirqEvent(pAC, IoC,
  1951. SK_HWEV_SET_FLOWMODE,
  1952. EventParam) > 0) {
  1953. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  1954. SK_PNMI_ERR044,
  1955. SK_PNMI_ERR044MSG);
  1956. *pLen = 0;
  1957. return (SK_PNMI_ERR_GENERAL);
  1958. }
  1959. }
  1960. }
  1961. else {
  1962. /*
  1963.  * Send an event with the new flow control
  1964.  * mode to the SIRQ module.
  1965.  */
  1966. EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
  1967. pAC, LogPortIndex);
  1968. EventParam.Para32[1] = (SK_U32)Val8;
  1969. if (SkGeSirqEvent(pAC, IoC,
  1970. SK_HWEV_SET_FLOWMODE, EventParam)
  1971. > 0) {
  1972. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  1973. SK_PNMI_ERR044,
  1974. SK_PNMI_ERR044MSG);
  1975. *pLen = 0;
  1976. return (SK_PNMI_ERR_GENERAL);
  1977. }
  1978. }
  1979. Offset += sizeof(char);
  1980. break;
  1981. case OID_SKGE_PHY_OPERATION_MODE :
  1982. /* Check the value range */
  1983. Val8 = *(pBuf + Offset);
  1984. if (Val8 == 0) {
  1985. /* mode of this port remains unchanged */
  1986. Offset += sizeof(char);
  1987. break;
  1988. }
  1989. if (Val8 < SK_MS_MODE_AUTO ||
  1990. (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
  1991. (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
  1992. *pLen = 0;
  1993. return (SK_PNMI_ERR_BAD_VALUE);
  1994. }
  1995. /* The preset ends here */
  1996. if (Action == SK_PNMI_PRESET) {
  1997. return (SK_PNMI_ERR_OK);
  1998. }
  1999. if (LogPortIndex == 0) {
  2000. /*
  2001.  * The virtual port consists of all currently
  2002.  * active ports. Find them and send an event
  2003.  * with new master/slave (role) mode to SIRQ.
  2004.  */
  2005. for (PhysPortIndex = 0;
  2006. PhysPortIndex < PhysPortMax;
  2007. PhysPortIndex ++) {
  2008. if (!pAC->Pnmi.Port[PhysPortIndex].
  2009. ActiveFlag) {
  2010. continue;
  2011. }
  2012. EventParam.Para32[0] = PhysPortIndex;
  2013. EventParam.Para32[1] = (SK_U32)Val8;
  2014. if (SkGeSirqEvent(pAC, IoC,
  2015. SK_HWEV_SET_ROLE,
  2016. EventParam) > 0) {
  2017. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  2018. SK_PNMI_ERR052,
  2019. SK_PNMI_ERR052MSG);
  2020. *pLen = 0;
  2021. return (SK_PNMI_ERR_GENERAL);
  2022. }
  2023. }
  2024. }
  2025. else {
  2026. /*
  2027.  * Send an event with the new master/slave
  2028.  * (role) mode to the SIRQ module.
  2029.  */
  2030. EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
  2031. pAC, LogPortIndex);
  2032. EventParam.Para32[1] = (SK_U32)Val8;
  2033. if (SkGeSirqEvent(pAC, IoC,
  2034. SK_HWEV_SET_ROLE, EventParam) > 0) {
  2035. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  2036. SK_PNMI_ERR052,
  2037. SK_PNMI_ERR052MSG);
  2038. *pLen = 0;
  2039. return (SK_PNMI_ERR_GENERAL);
  2040. }
  2041. }
  2042. Offset += sizeof(char);
  2043. break;
  2044. case OID_SKGE_MTU :
  2045. /* Check the value range */
  2046. Val32 = *(SK_U32*)(pBuf + Offset);
  2047. if (Val32 == 0) {
  2048. /* mtu of this port remains unchanged */
  2049. Offset += sizeof(SK_U32);
  2050. break;
  2051. }
  2052. if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
  2053. *pLen = 0;
  2054. return (SK_PNMI_ERR_BAD_VALUE);
  2055. }
  2056. /* The preset ends here */
  2057. if (Action == SK_PNMI_PRESET) {
  2058. return (SK_PNMI_ERR_OK);
  2059. }
  2060. if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
  2061. return (SK_PNMI_ERR_GENERAL);
  2062. }
  2063. Offset += sizeof(SK_U32);
  2064. break;
  2065. default:
  2066. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR045,
  2067. SK_PNMI_ERR045MSG);
  2068. *pLen = 0;
  2069. return (SK_PNMI_ERR_GENERAL);
  2070. }
  2071. }
  2072. return (SK_PNMI_ERR_OK);
  2073. }
  2074. /*****************************************************************************
  2075.  *
  2076.  * Monitor - OID handler function for RLMT_MONITOR_XXX
  2077.  *
  2078.  * Description:
  2079.  * Because RLMT currently does not support the monitoring of
  2080.  * remote adapter cards, we return always an empty table.
  2081.  *
  2082.  * Returns:
  2083.  * SK_PNMI_ERR_OK           The request was successfully performed.
  2084.  * SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  2085.  * SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  2086.  *                          the correct data (e.g. a 32bit value is
  2087.  *                          needed, but a 16 bit value was passed).
  2088.  * SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
  2089.  *                          value range.
  2090.  * SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
  2091.  * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  2092.  *                               exist (e.g. port instance 3 on a two port
  2093.  *                          adapter.
  2094.  */
  2095. static int Monitor(
  2096. SK_AC *pAC, /* Pointer to adapter context */
  2097. SK_IOC IoC, /* IO context handle */
  2098. int Action, /* Get/PreSet/Set action */
  2099. SK_U32 Id, /* Object ID that is to be processed */
  2100. char *pBuf, /* Buffer to which to mgmt data will be retrieved */
  2101. unsigned int *pLen, /* On call: buffer length. On return: used buffer */
  2102. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  2103. unsigned int TableIndex, /* Index to the Id table */
  2104. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
  2105. {
  2106. unsigned int Index;
  2107. unsigned int Limit;
  2108. unsigned int Offset;
  2109. unsigned int Entries;
  2110. /*
  2111.  * Calculate instance if wished.
  2112.  */
  2113. /* XXX Not yet implemented. Return always an empty table. */
  2114. Entries = 0;
  2115. if ((Instance != (SK_U32)(-1))) {
  2116. if ((Instance < 1) || (Instance > Entries)) {
  2117. *pLen = 0;
  2118. return (SK_PNMI_ERR_UNKNOWN_INST);
  2119. }
  2120. Index = (unsigned int)Instance - 1;
  2121. Limit = (unsigned int)Instance;
  2122. }
  2123. else {
  2124. Index = 0;
  2125. Limit = Entries;
  2126. }
  2127. /*
  2128.  * Get/Set value
  2129. */
  2130. if (Action == SK_PNMI_GET) {
  2131. for (Offset=0; Index < Limit; Index ++) {
  2132. switch (Id) {
  2133. case OID_SKGE_RLMT_MONITOR_INDEX:
  2134. case OID_SKGE_RLMT_MONITOR_ADDR:
  2135. case OID_SKGE_RLMT_MONITOR_ERRS:
  2136. case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
  2137. case OID_SKGE_RLMT_MONITOR_ADMIN:
  2138. break;
  2139. default:
  2140. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
  2141. SK_PNMI_ERR046MSG);
  2142. *pLen = 0;
  2143. return (SK_PNMI_ERR_GENERAL);
  2144. }
  2145. }
  2146. *pLen = Offset;
  2147. }
  2148. else {
  2149. /* Only MONITOR_ADMIN can be set */
  2150. if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
  2151. *pLen = 0;
  2152. return (SK_PNMI_ERR_READ_ONLY);
  2153. }
  2154. /* Check if the length is plausible */
  2155. if (*pLen < (Limit - Index)) {
  2156. return (SK_PNMI_ERR_TOO_SHORT);
  2157. }
  2158. /* Okay, we have a wide value range */
  2159. if (*pLen != (Limit - Index)) {
  2160. *pLen = 0;
  2161. return (SK_PNMI_ERR_BAD_VALUE);
  2162. }
  2163. /*
  2164. for (Offset=0; Index < Limit; Index ++) {
  2165. }
  2166. */
  2167. /*
  2168.  * XXX Not yet implemented. Return always BAD_VALUE, because the table
  2169.  * is empty.
  2170.  */
  2171. *pLen = 0;
  2172. return (SK_PNMI_ERR_BAD_VALUE);
  2173. }
  2174. return (SK_PNMI_ERR_OK);
  2175. }
  2176. /*****************************************************************************
  2177.  *
  2178.  * VirtualConf - Calculates the values of configuration OIDs for virtual port
  2179.  *
  2180.  * Description:
  2181.  * We handle here the get of the configuration group OIDs, which are
  2182.  * a little bit complicated. The virtual port consists of all currently
  2183.  * active physical ports. If multiple ports are active and configured
  2184.  * differently we get in some trouble to return a single value. So we
  2185.  * get the value of the first active port and compare it with that of
  2186.  * the other active ports. If they are not the same, we return a value
  2187.  * that indicates that the state is indeterminated.
  2188.  *
  2189.  * Returns:
  2190.  * Nothing
  2191.  */
  2192. static void VirtualConf(
  2193. SK_AC *pAC, /* Pointer to adapter context */
  2194. SK_IOC IoC, /* IO context handle */
  2195. SK_U32 Id, /* Object ID that is to be processed */
  2196. char *pBuf) /* Buffer to which to mgmt data will be retrieved */
  2197. {
  2198. unsigned int PhysPortMax;
  2199. unsigned int PhysPortIndex;
  2200. SK_U8 Val8;
  2201. SK_BOOL PortActiveFlag;
  2202. *pBuf = 0;
  2203. PortActiveFlag = SK_FALSE;
  2204. PhysPortMax = pAC->GIni.GIMacsFound;
  2205. for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
  2206. PhysPortIndex ++) {
  2207. /* Check if the physical port is active */
  2208. if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
  2209. continue;
  2210. }
  2211. PortActiveFlag = SK_TRUE;
  2212. switch (Id) {
  2213. case OID_SKGE_LINK_CAP:
  2214. /*
  2215.  * Different capabilities should not happen, but
  2216.  * in the case of the cases OR them all together.
  2217.  * From a curious point of view the virtual port
  2218.  * is capable of all found capabilities.
  2219.  */
  2220. *pBuf |= pAC->GIni.GP[PhysPortIndex].PLinkCap;
  2221. break;
  2222. case OID_SKGE_LINK_MODE:
  2223. /* Check if it is the first active port */
  2224. if (*pBuf == 0) {
  2225. *pBuf = pAC->GIni.GP[PhysPortIndex].
  2226. PLinkModeConf;
  2227. continue;
  2228. }
  2229. /*
  2230.  * If we find an active port with a different link
  2231.  * mode than the first one we return a value that
  2232.  * indicates that the link mode is indeterminated.
  2233.  */
  2234. if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkModeConf
  2235. ) {
  2236. *pBuf = SK_LMODE_INDETERMINATED;
  2237. }
  2238. break;
  2239. case OID_SKGE_LINK_MODE_STATUS:
  2240. /* Get the link mode of the physical port */
  2241. Val8 = CalculateLinkModeStatus(pAC, IoC,
  2242. PhysPortIndex);
  2243. /* Check if it is the first active port */
  2244. if (*pBuf == 0) {
  2245. *pBuf = Val8;
  2246. continue;
  2247. }
  2248. /*
  2249.  * If we find an active port with a different link
  2250.  * mode status than the first one we return a value
  2251.  * that indicates that the link mode status is
  2252.  * indeterminated.
  2253.  */
  2254. if (*pBuf != Val8) {
  2255. *pBuf = SK_LMODE_STAT_INDETERMINATED;
  2256. }
  2257. break;
  2258. case OID_SKGE_LINK_STATUS:
  2259. /* Get the link status of the physical port */
  2260. Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
  2261. /* Check if it is the first active port */
  2262. if (*pBuf == 0) {
  2263. *pBuf = Val8;
  2264. continue;
  2265. }
  2266. /*
  2267.  * If we find an active port with a different link
  2268.  * status than the first one, we return a value
  2269.  * that indicates that the link status is
  2270.  * indeterminated.
  2271.  */
  2272. if (*pBuf != Val8) {
  2273. *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
  2274. }
  2275. break;
  2276. case OID_SKGE_FLOWCTRL_CAP:
  2277. /* Check if it is the first active port */
  2278. if (*pBuf == 0) {
  2279. *pBuf = pAC->GIni.GP[PhysPortIndex].
  2280. PFlowCtrlCap;
  2281. continue;
  2282. }
  2283. /*
  2284.  * From a curious point of view the virtual port
  2285.  * is capable of all found capabilities.
  2286.  */
  2287. *pBuf |= pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
  2288. break;
  2289. case OID_SKGE_FLOWCTRL_MODE:
  2290. /* Check if it is the first active port */
  2291. if (*pBuf == 0) {
  2292. *pBuf = pAC->GIni.GP[PhysPortIndex].
  2293. PFlowCtrlMode;
  2294. continue;
  2295. }
  2296. /*
  2297.  * If we find an active port with a different flow
  2298.  * control mode than the first one, we return a value
  2299.  * that indicates that the mode is indeterminated.
  2300.  */
  2301. if (*pBuf != pAC->GIni.GP[PhysPortIndex].
  2302. PFlowCtrlMode) {
  2303. *pBuf = SK_FLOW_MODE_INDETERMINATED;
  2304. }
  2305. break;
  2306. case OID_SKGE_FLOWCTRL_STATUS:
  2307. /* Check if it is the first active port */
  2308. if (*pBuf == 0) {
  2309. *pBuf = pAC->GIni.GP[PhysPortIndex].
  2310. PFlowCtrlStatus;
  2311. continue;
  2312. }
  2313. /*
  2314.  * If we find an active port with a different flow
  2315.  * control status than the first one, we return a
  2316.  * value that indicates that the status is
  2317.  * indeterminated.
  2318.  */
  2319. if (*pBuf != pAC->GIni.GP[PhysPortIndex].
  2320. PFlowCtrlStatus) {
  2321. *pBuf = SK_FLOW_STAT_INDETERMINATED;
  2322. }
  2323. break;
  2324. case OID_SKGE_PHY_OPERATION_CAP:
  2325. /* Check if it is the first active port */
  2326. if (*pBuf == 0) {
  2327. *pBuf = pAC->GIni.GP[PhysPortIndex].
  2328. PMSCap;
  2329. continue;
  2330. }
  2331. /*
  2332.  * From a curious point of view the virtual port
  2333.  * is capable of all found capabilities.
  2334.  */
  2335. *pBuf |= pAC->GIni.GP[PhysPortIndex].PMSCap;
  2336. break;
  2337. case OID_SKGE_PHY_OPERATION_MODE:
  2338. /* Check if it is the first active port */
  2339. if (*pBuf == 0) {
  2340. *pBuf = pAC->GIni.GP[PhysPortIndex].
  2341. PMSMode;
  2342. continue;
  2343. }
  2344. /*
  2345.  * If we find an active port with a different master/
  2346.  * slave mode than the first one, we return a value
  2347.  * that indicates that the mode is indeterminated.
  2348.  */
  2349. if (*pBuf != pAC->GIni.GP[PhysPortIndex].
  2350. PMSMode) {
  2351. *pBuf = SK_MS_MODE_INDETERMINATED;
  2352. }
  2353. break;
  2354. case OID_SKGE_PHY_OPERATION_STATUS:
  2355. /* Check if it is the first active port */
  2356. if (*pBuf == 0) {
  2357. *pBuf = pAC->GIni.GP[PhysPortIndex].
  2358. PMSStatus;
  2359. continue;
  2360. }
  2361. /*
  2362.  * If we find an active port with a different master/
  2363.  * slave status than the first one, we return a
  2364.  * value that indicates that the status is
  2365.  * indeterminated.
  2366.  */
  2367. if (*pBuf != pAC->GIni.GP[PhysPortIndex].
  2368. PMSStatus) {
  2369. *pBuf = SK_MS_STAT_INDETERMINATED;
  2370. }
  2371. break;
  2372. }
  2373. }
  2374. /*
  2375.  * If no port is active return an indeterminated answer
  2376.  */
  2377. if (!PortActiveFlag) {
  2378. switch (Id) {
  2379. case OID_SKGE_LINK_CAP:
  2380. *pBuf = SK_LMODE_CAP_INDETERMINATED;
  2381. break;
  2382. case OID_SKGE_LINK_MODE:
  2383. *pBuf = SK_LMODE_INDETERMINATED;
  2384. break;
  2385. case OID_SKGE_LINK_MODE_STATUS:
  2386. *pBuf = SK_LMODE_STAT_INDETERMINATED;
  2387. break;
  2388. case OID_SKGE_LINK_STATUS:
  2389. *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
  2390. break;
  2391. case OID_SKGE_FLOWCTRL_CAP:
  2392. case OID_SKGE_FLOWCTRL_MODE:
  2393. *pBuf = SK_FLOW_MODE_INDETERMINATED;
  2394. break;
  2395. case OID_SKGE_FLOWCTRL_STATUS:
  2396. *pBuf = SK_FLOW_STAT_INDETERMINATED;
  2397. break;
  2398. case OID_SKGE_PHY_OPERATION_CAP:
  2399. *pBuf = SK_MS_CAP_INDETERMINATED;
  2400. break;
  2401. case OID_SKGE_PHY_OPERATION_MODE:
  2402. *pBuf = SK_MS_MODE_INDETERMINATED;
  2403. break;
  2404. case OID_SKGE_PHY_OPERATION_STATUS:
  2405. *pBuf = SK_MS_STAT_INDETERMINATED;
  2406. break;
  2407. }
  2408. }
  2409. }
  2410. /*****************************************************************************
  2411.  *
  2412.  * CalculateLinkStatus - Determins the link status of a physical port
  2413.  *
  2414.  * Description:
  2415.  * Determins the link status the following way:
  2416.  *   LSTAT_PHY_DOWN:  Link is down
  2417.  *   LSTAT_AUTONEG:   Auto-negotiation failed
  2418.  *   LSTAT_LOG_DOWN:  Link is up but RLMT did not yet put the port
  2419.  *                    logically up.
  2420.  *   LSTAT_LOG_UP:    RLMT marked the port as up
  2421.  *
  2422.  * Returns:
  2423.  * Link status of physical port
  2424.  */
  2425. static SK_U8 CalculateLinkStatus(
  2426. SK_AC *pAC, /* Pointer to adapter context */
  2427. SK_IOC IoC, /* IO context handle */
  2428. unsigned int PhysPortIndex) /* Physical port index */
  2429. {
  2430. SK_U8 Result;
  2431. if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
  2432. Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
  2433. }
  2434. else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
  2435. Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
  2436. }
  2437. else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
  2438. Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
  2439. }
  2440. else {
  2441. Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
  2442. }
  2443. return (Result);
  2444. }
  2445. /*****************************************************************************
  2446.  *
  2447.  * CalculateLinkModeStatus - Determins the link mode status of a phys. port
  2448.  *
  2449.  * Description:
  2450.  * The COMMON module only tells us if the mode is half or full duplex.
  2451.  * But in the decade of auto sensing it is usefull for the user to
  2452.  * know if the mode was negotiated or forced. Therefore we have a
  2453.  * look to the mode, which was last used by the negotiation process.
  2454.  *
  2455.  * Returns:
  2456.  * The link mode status
  2457.  */
  2458. static SK_U8 CalculateLinkModeStatus(
  2459. SK_AC *pAC, /* Pointer to adapter context */
  2460. SK_IOC IoC, /* IO context handle */
  2461. unsigned int PhysPortIndex) /* Physical port index */
  2462. {
  2463. SK_U8 Result;
  2464. /* Get the current mode, which can be full or half duplex */
  2465. Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
  2466. /* Check if no valid mode could be found (link is down) */
  2467. if (Result < SK_LMODE_STAT_HALF) {
  2468. Result = SK_LMODE_STAT_UNKNOWN;
  2469. else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
  2470. /*
  2471.  * Auto-negotiation was used to bring up the link. Change
  2472.  * the already found duplex status that it indicates
  2473.  * auto-negotiation was involved.
  2474.  */
  2475. if (Result == SK_LMODE_STAT_HALF) {
  2476. Result = SK_LMODE_STAT_AUTOHALF;
  2477. }
  2478. else if (Result == SK_LMODE_STAT_FULL) {
  2479. Result = SK_LMODE_STAT_AUTOFULL;
  2480. }
  2481. }
  2482. return (Result);
  2483. }
  2484. /*****************************************************************************
  2485.  *
  2486.  * GetVpdKeyArr - Obtain an array of VPD keys
  2487.  *
  2488.  * Description:
  2489.  * Read the VPD keys and build an array of VPD keys, which are
  2490.  * easy to access.
  2491.  *
  2492.  * Returns:
  2493.  * SK_PNMI_ERR_OK      Task successfully performed.
  2494.  * SK_PNMI_ERR_GENERAL  Something went wrong.
  2495.  */
  2496. static int GetVpdKeyArr(
  2497. SK_AC *pAC, /* Pointer to adapter context */
  2498. SK_IOC IoC, /* IO context handle */
  2499. char *pKeyArr, /* Ptr KeyArray */
  2500. unsigned int KeyArrLen, /* Length of array in bytes */
  2501. unsigned int *pKeyNo) /* Number of keys */
  2502. {
  2503. unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
  2504. char BufKeys[SK_PNMI_VPD_BUFSIZE];
  2505. unsigned int StartOffset;
  2506. unsigned int Offset;
  2507. int Index;
  2508. int Ret;
  2509. SK_MEMSET(pKeyArr, 0, KeyArrLen);
  2510. /*
  2511.  * Get VPD key list
  2512.  */
  2513. Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
  2514. (int *)pKeyNo);
  2515. if (Ret > 0) {
  2516. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
  2517. SK_PNMI_ERR014MSG);
  2518. return (SK_PNMI_ERR_GENERAL);
  2519. }
  2520. /* If no keys are available return now */
  2521. if (*pKeyNo == 0 || BufKeysLen == 0) {
  2522. return (SK_PNMI_ERR_OK);
  2523. }
  2524. /*
  2525.  * If the key list is too long for us trunc it and give a
  2526.  * errorlog notification. This case should not happen because
  2527.  * the maximum number of keys is limited due to RAM limitations
  2528.  */
  2529. if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
  2530. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
  2531. SK_PNMI_ERR015MSG);
  2532. *pKeyNo = SK_PNMI_VPD_ENTRIES;
  2533. }
  2534. /*
  2535.  * Now build an array of fixed string length size and copy
  2536.  * the keys together.
  2537.  */
  2538. for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
  2539. Offset ++) {
  2540. if (BufKeys[Offset] != 0) {
  2541. continue;
  2542. }
  2543. if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
  2544. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
  2545. SK_PNMI_ERR016MSG);
  2546. return (SK_PNMI_ERR_GENERAL);
  2547. }
  2548. SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
  2549. &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
  2550. Index ++;
  2551. StartOffset = Offset + 1;
  2552. }
  2553. /* Last key not zero terminated? Get it anyway */
  2554. if (StartOffset < Offset) {
  2555. SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
  2556. &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
  2557. }
  2558. return (SK_PNMI_ERR_OK);
  2559. }
  2560. /*****************************************************************************
  2561.  *
  2562.  * SirqUpdate - Let the SIRQ update its internal values
  2563.  *
  2564.  * Description:
  2565.  * Just to be sure that the SIRQ module holds its internal data
  2566.  * structures up to date, we send an update event before we make
  2567.  * any access.
  2568.  *
  2569.  * Returns:
  2570.  * SK_PNMI_ERR_OK      Task successfully performed.
  2571.  * SK_PNMI_ERR_GENERAL  Something went wrong.
  2572.  */
  2573. static int SirqUpdate(
  2574. SK_AC *pAC, /* Pointer to adapter context */
  2575. SK_IOC IoC) /* IO context handle */
  2576. {
  2577. SK_EVPARA EventParam;
  2578. /* Was the module already updated during the current PNMI call? */
  2579. if (pAC->Pnmi.SirqUpdatedFlag > 0) {
  2580. return (SK_PNMI_ERR_OK);
  2581. }
  2582. /* Send an synchronuous update event to the module */
  2583. SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
  2584. if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
  2585. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
  2586. SK_PNMI_ERR047MSG);
  2587. return (SK_PNMI_ERR_GENERAL);
  2588. }
  2589. return (SK_PNMI_ERR_OK);
  2590. }
  2591. /*****************************************************************************
  2592.  *
  2593.  * RlmtUpdate - Let the RLMT update its internal values
  2594.  *
  2595.  * Description:
  2596.  * Just to be sure that the RLMT module holds its internal data
  2597.  * structures up to date, we send an update event before we make
  2598.  * any access.
  2599.  *
  2600.  * Returns:
  2601.  * SK_PNMI_ERR_OK      Task successfully performed.
  2602.  * SK_PNMI_ERR_GENERAL  Something went wrong.
  2603.  */
  2604. static int RlmtUpdate(
  2605. SK_AC *pAC, /* Pointer to adapter context */
  2606. SK_IOC IoC, /* IO context handle */
  2607. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
  2608. {
  2609. SK_EVPARA EventParam;
  2610. /* Was the module already updated during the current PNMI call? */
  2611. if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
  2612. return (SK_PNMI_ERR_OK);
  2613. }
  2614. /* Send an synchronuous update event to the module */
  2615. SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
  2616. EventParam.Para32[0] = NetIndex;
  2617. EventParam.Para32[1] = (SK_U32)-1;
  2618. if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
  2619. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
  2620. SK_PNMI_ERR048MSG);
  2621. return (SK_PNMI_ERR_GENERAL);
  2622. }
  2623. return (SK_PNMI_ERR_OK);
  2624. }
  2625. /*****************************************************************************
  2626.  *
  2627.  * MacUpdate - Force the XMAC to output the current statistic
  2628.  *
  2629.  * Description:
  2630.  * The XMAC holds its statistic internally. To obtain the current
  2631.  * values we must send a command so that the statistic data will
  2632.  * be written to a predefined memory area on the adapter. 
  2633.  *
  2634.  * Returns:
  2635.  * SK_PNMI_ERR_OK      Task successfully performed.
  2636.  * SK_PNMI_ERR_GENERAL  Something went wrong.
  2637.  */
  2638. static int MacUpdate(
  2639. SK_AC *pAC, /* Pointer to adapter context */
  2640. SK_IOC IoC, /* IO context handle */
  2641. unsigned int FirstMac, /* Index of the first Mac to be updated */
  2642. unsigned int LastMac) /* Index of the last Mac to be updated */
  2643. {
  2644. unsigned int MacIndex;
  2645. SK_U16 StatReg;
  2646. unsigned int WaitIndex;
  2647. /*
  2648.  * Were the statistics already updated during the
  2649.  * current PNMI call?
  2650.  */
  2651. if (pAC->Pnmi.MacUpdatedFlag > 0) {
  2652. return (SK_PNMI_ERR_OK);
  2653. }
  2654. /* Send an update command to all XMACs specified */
  2655. for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
  2656. StatReg = XM_SC_SNP_TXC | XM_SC_SNP_RXC;
  2657. XM_OUT16(IoC, MacIndex, XM_STAT_CMD, StatReg);
  2658. /*
  2659.  * It is an auto-clearing register. If the command bits
  2660.  * went to zero again, the statistics are transfered.
  2661.  * Normally the command should be executed immediately.
  2662.  * But just to be sure we execute a loop.
  2663.  */
  2664. for (WaitIndex = 0; WaitIndex < 10; WaitIndex ++) {
  2665. XM_IN16(IoC, MacIndex, XM_STAT_CMD, &StatReg);
  2666. if ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) ==
  2667. 0) {
  2668. break;
  2669. }
  2670. }
  2671. if (WaitIndex == 10 ) {
  2672. SK_ERR_LOG(pAC, SK_ERRCL_HW, SK_PNMI_ERR050,
  2673. SK_PNMI_ERR050MSG);
  2674. return (SK_PNMI_ERR_GENERAL);
  2675. }
  2676. }
  2677. return (SK_PNMI_ERR_OK);
  2678. }
  2679. /*****************************************************************************
  2680.  *
  2681.  * GetStatVal - Retrieve an XMAC statistic counter
  2682.  *
  2683.  * Description:
  2684.  * Retrieves the statistic counter of a virtual or physical port. The
  2685.  * virtual port is identified by the index 0. It consists of all
  2686.  * currently active ports. To obtain the counter value for this port
  2687.  * we must add the statistic counter of all active ports. To grant
  2688.  * continuous counter values for the virtual port even when port
  2689.  * switches occur we must additionally add a delta value, which was
  2690.  * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
  2691.  *
  2692.  * Returns:
  2693.  * Requested statistic value
  2694.  */
  2695. static SK_U64 GetStatVal(
  2696. SK_AC *pAC, /* Pointer to adapter context */
  2697. SK_IOC IoC, /* IO context handle */
  2698. unsigned int LogPortIndex, /* Index of the logical Port to be processed */
  2699. unsigned int StatIndex, /* Index to statistic value */
  2700. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
  2701. {
  2702. unsigned int PhysPortIndex;
  2703. unsigned int PhysPortMax;
  2704. SK_U64 Val = 0;
  2705. if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ /* Dual net mode */
  2706. PhysPortIndex = NetIndex;
  2707. Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
  2708.     } /* end of dual net mode */
  2709. else { /* single net mode */
  2710. if (LogPortIndex == 0) {
  2711. PhysPortMax = pAC->GIni.GIMacsFound;
  2712. /* Add counter of all active ports */
  2713. for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
  2714. PhysPortIndex ++) {
  2715. if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
  2716. Val += GetPhysStatVal(pAC, IoC, PhysPortIndex,
  2717. StatIndex);
  2718. }
  2719. }
  2720. /* Correct value because of port switches */
  2721. Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
  2722. }
  2723. else {
  2724. /* Get counter value of physical port */
  2725. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
  2726. Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
  2727. }
  2728. } /* end of single net mode */
  2729. return (Val);
  2730. }
  2731. /*****************************************************************************
  2732.  *
  2733.  * GetPhysStatVal - Get counter value for physical port
  2734.  *
  2735.  * Description:
  2736.  * Builds a 64bit counter value. Except for the octet counters
  2737.  * the lower 32bit are counted in hardware and the upper 32bit
  2738.  * in software by monitoring counter overflow interrupts in the
  2739.  * event handler. To grant continous counter values during XMAC
  2740.  * resets (caused by a workaround) we must add a delta value.
  2741.  * The delta was calculated in the event handler when a
  2742.  * SK_PNMI_EVT_XMAC_RESET was received.
  2743.  *
  2744.  * Returns:
  2745.  * Counter value
  2746.  */
  2747. static SK_U64 GetPhysStatVal(
  2748. SK_AC *pAC, /* Pointer to adapter context */
  2749. SK_IOC IoC, /* IO context handle */
  2750. unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
  2751. unsigned int StatIndex) /* Index to statistic value */
  2752. {
  2753. SK_U64 Val = 0;
  2754. SK_U32 LowVal;
  2755. SK_U32 HighVal;
  2756. switch (StatIndex) {
  2757. case SK_PNMI_HTX_OCTET:
  2758. XM_IN32(IoC, PhysPortIndex, XM_TXO_OK_LO, &LowVal);
  2759. XM_IN32(IoC, PhysPortIndex, XM_TXO_OK_HI, &HighVal);
  2760. break;
  2761. case SK_PNMI_HRX_OCTET:
  2762. XM_IN32(IoC, PhysPortIndex, XM_RXO_OK_LO, &LowVal);
  2763. XM_IN32(IoC, PhysPortIndex, XM_RXO_OK_HI, &HighVal);
  2764. break;
  2765. case SK_PNMI_HTX_OCTETLOW:
  2766. case SK_PNMI_HRX_OCTETLOW:
  2767. return (Val);
  2768. case SK_PNMI_HTX_SYNC:
  2769. LowVal = (SK_U32)pAC->Pnmi.Port[PhysPortIndex].StatSyncCts;
  2770. HighVal = (SK_U32)
  2771. (pAC->Pnmi.Port[PhysPortIndex].StatSyncCts >> 32);
  2772. break;
  2773. case SK_PNMI_HTX_SYNC_OCTET:
  2774. LowVal = (SK_U32)pAC->Pnmi.Port[PhysPortIndex].
  2775. StatSyncOctetsCts;
  2776. HighVal = (SK_U32)
  2777. (pAC->Pnmi.Port[PhysPortIndex].StatSyncOctetsCts >>
  2778. 32);
  2779. break;
  2780. case SK_PNMI_HRX_LONGFRAMES:
  2781. LowVal = (SK_U32)pAC->Pnmi.Port[PhysPortIndex].StatRxLongFrameCts;
  2782. HighVal = (SK_U32)
  2783. (pAC->Pnmi.Port[PhysPortIndex].StatRxLongFrameCts >> 32);
  2784. break;
  2785. case SK_PNMI_HRX_FCS:
  2786. /* 
  2787.  * Broadcom filters fcs errors and counts it in 
  2788.  * Receive Error Counter register
  2789.  */
  2790. if (pAC->GIni.GP[PhysPortIndex].PhyType == SK_PHY_BCOM) {
  2791. /* do not read while not initialized (PHY_READ hangs!)*/
  2792. if (pAC->GIni.GP[PhysPortIndex].PState) {
  2793. PHY_READ(IoC, &pAC->GIni.GP[PhysPortIndex],
  2794.  PhysPortIndex, PHY_BCOM_RE_CTR,
  2795. &LowVal);
  2796. }
  2797. else {
  2798. LowVal = 0;
  2799. }
  2800. HighVal = pAC->Pnmi.Port[PhysPortIndex].CounterHigh[StatIndex];
  2801. }
  2802. else {
  2803. XM_IN32(IoC, PhysPortIndex,
  2804. StatAddress[StatIndex].Param, &LowVal);
  2805. HighVal = pAC->Pnmi.Port[PhysPortIndex].CounterHigh[StatIndex];
  2806. }
  2807. default:
  2808. XM_IN32(IoC, PhysPortIndex, StatAddress[StatIndex].Param,
  2809. &LowVal);
  2810. HighVal = pAC->Pnmi.Port[PhysPortIndex].CounterHigh[StatIndex];
  2811. break;
  2812. }
  2813. Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
  2814. /* Correct value because of possible XMAC reset. XMAC Errata #2 */
  2815. Val += pAC->Pnmi.Port[PhysPortIndex].CounterOffset[StatIndex];
  2816. return (Val);
  2817. }
  2818. /*****************************************************************************
  2819.  *
  2820.  * ResetCounter - Set all counters and timestamps to zero
  2821.  *
  2822.  * Description:
  2823.  * Notifies other common modules which store statistic data to
  2824.  * reset their counters and finally reset our own counters.
  2825.  *
  2826.  * Returns:
  2827.  * Nothing
  2828.  */
  2829. static void ResetCounter(
  2830. SK_AC *pAC, /* Pointer to adapter context */
  2831. SK_IOC IoC, /* IO context handle */
  2832. SK_U32 NetIndex)
  2833. {
  2834. unsigned int PhysPortIndex;
  2835. SK_EVPARA EventParam;
  2836. SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
  2837. /* Notify sensor module */
  2838. SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
  2839. /* Notify RLMT module */
  2840. EventParam.Para32[0] = NetIndex;
  2841. EventParam.Para32[1] = (SK_U32)-1;
  2842. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
  2843. EventParam.Para32[1] = 0;
  2844. /* Notify SIRQ module */
  2845. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
  2846. /* Notify CSUM module */
  2847. #ifdef SK_USE_CSUM
  2848. EventParam.Para64 = (SK_U64)(-1);
  2849. SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
  2850. EventParam);
  2851. #endif
  2852. /* Clear XMAC statistic */
  2853. for (PhysPortIndex = 0; PhysPortIndex <
  2854. (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
  2855. XM_OUT16(IoC, PhysPortIndex, XM_STAT_CMD,
  2856. XM_SC_CLR_RXC | XM_SC_CLR_TXC);
  2857. /* Clear two times according to Errata #3 */
  2858. XM_OUT16(IoC, PhysPortIndex, XM_STAT_CMD,
  2859. XM_SC_CLR_RXC | XM_SC_CLR_TXC);
  2860. SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
  2861. 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
  2862. SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
  2863. CounterOffset, 0, sizeof(pAC->Pnmi.Port[
  2864. PhysPortIndex].CounterOffset));
  2865. SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
  2866. 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
  2867. SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
  2868. StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
  2869. PhysPortIndex].StatSyncOctetsCts));
  2870. SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
  2871. StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
  2872. PhysPortIndex].StatRxLongFrameCts));
  2873. }
  2874. /*
  2875.  * Clear local statistics
  2876.  */
  2877. SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
  2878.   sizeof(pAC->Pnmi.VirtualCounterOffset));
  2879. pAC->Pnmi.RlmtChangeCts = 0;
  2880. pAC->Pnmi.RlmtChangeTime = 0;
  2881. SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
  2882. sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
  2883. pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
  2884. pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
  2885. pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
  2886. pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
  2887. pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
  2888. pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
  2889. pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
  2890. pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
  2891. pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
  2892. pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
  2893. pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
  2894. pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
  2895. }
  2896. /*****************************************************************************
  2897.  *
  2898.  * GetTrapEntry - Get an entry in the trap buffer
  2899.  *
  2900.  * Description:
  2901.  * The trap buffer stores various events. A user application somehow
  2902.  * gets notified that an event occured and retrieves the trap buffer
  2903.  * contens (or simply polls the buffer). The buffer is organized as
  2904.  * a ring which stores the newest traps at the beginning. The oldest
  2905.  * traps are overwritten by the newest ones. Each trap entry has a
  2906.  * unique number, so that applications may detect new trap entries.
  2907.  *
  2908.  * Returns:
  2909.  * A pointer to the trap entry
  2910.  */
  2911. static char* GetTrapEntry(
  2912. SK_AC *pAC, /* Pointer to adapter context */
  2913. SK_U32 TrapId, /* SNMP ID of the trap */
  2914. unsigned int Size) /* Space needed for trap entry */
  2915. {
  2916. unsigned int BufPad = pAC->Pnmi.TrapBufPad;
  2917. unsigned int BufFree = pAC->Pnmi.TrapBufFree;
  2918. unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
  2919. unsigned int End = pAC->Pnmi.TrapQueueEnd;
  2920. char *pBuf = &pAC->Pnmi.TrapBuf[0];
  2921. int Wrap;
  2922. unsigned int NeededSpace;
  2923. unsigned int EntrySize;
  2924. SK_U32 Val32;
  2925. SK_U64 Val64;
  2926. /* Last byte of entry will get a copy of the entry length */
  2927. Size ++;
  2928. /*
  2929.  * Calculate needed buffer space */
  2930. if (Beg >= Size) {
  2931. NeededSpace = Size;
  2932. Wrap = FALSE;
  2933. }
  2934. else {
  2935. NeededSpace = Beg + Size;
  2936. Wrap = TRUE;
  2937. }
  2938. /*
  2939.  * Check if enough buffer space is provided. Otherwise
  2940.  * free some entries. Leave one byte space between begin
  2941.  * and end of buffer to make it possible to detect whether
  2942.  * the buffer is full or empty
  2943.  */
  2944. while (BufFree < NeededSpace + 1) {
  2945. if (End == 0) {
  2946. End = SK_PNMI_TRAP_QUEUE_LEN;
  2947. }
  2948. EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
  2949. BufFree += EntrySize;
  2950. End -= EntrySize;
  2951. #ifdef DEBUG
  2952. SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
  2953. #endif
  2954. if (End == BufPad) {
  2955. #ifdef DEBUG
  2956. SK_MEMSET(pBuf, (char)(-1), End);
  2957. #endif
  2958. BufFree += End;
  2959. End = 0;
  2960. BufPad = 0;
  2961. }
  2962. }
  2963. /* 
  2964.  * Insert new entry as first entry. Newest entries are
  2965.  * stored at the beginning of the queue.
  2966.  */
  2967. if (Wrap) {
  2968. BufPad = Beg;
  2969. Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
  2970. }
  2971. else {
  2972. Beg = Beg - Size;
  2973. }
  2974. BufFree -= NeededSpace;
  2975. /* Save the current offsets */
  2976. pAC->Pnmi.TrapQueueBeg = Beg;
  2977. pAC->Pnmi.TrapQueueEnd = End;
  2978. pAC->Pnmi.TrapBufPad = BufPad;
  2979. pAC->Pnmi.TrapBufFree = BufFree;
  2980. /* Initialize the trap entry */
  2981. *(pBuf + Beg + Size - 1) = (char)Size;
  2982. *(pBuf + Beg) = (char)Size;
  2983. Val32 = (pAC->Pnmi.TrapUnique) ++;
  2984. SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
  2985. SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
  2986. Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
  2987. SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
  2988. return (pBuf + Beg);
  2989. }
  2990. /*****************************************************************************
  2991.  *
  2992.  * CopyTrapQueue - Copies the trap buffer for the TRAP OID
  2993.  *
  2994.  * Description:
  2995.  * On a query of the TRAP OID the trap buffer contents will be
  2996.  * copied continuously to the request buffer, which must be large
  2997.  * enough. No length check is performed.
  2998.  *
  2999.  * Returns:
  3000.  * Nothing
  3001.  */
  3002. static void CopyTrapQueue(
  3003. SK_AC *pAC, /* Pointer to adapter context */
  3004. char *pDstBuf) /* Buffer to which the queued traps will be copied */
  3005. {
  3006. unsigned int BufPad = pAC->Pnmi.TrapBufPad;
  3007. unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
  3008. unsigned int End = pAC->Pnmi.TrapQueueEnd;
  3009. char *pBuf = &pAC->Pnmi.TrapBuf[0];
  3010. unsigned int Len;
  3011. unsigned int DstOff = 0;
  3012. while (Trap != End) {
  3013. Len = (unsigned int)*(pBuf + Trap);
  3014. /*
  3015.  * Last byte containing a copy of the length will
  3016.  * not be copied.
  3017.  */
  3018. *(pDstBuf + DstOff) = (char)(Len - 1);
  3019. SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
  3020. DstOff += Len - 1;
  3021. Trap += Len;
  3022. if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
  3023. Trap = BufPad;
  3024. }
  3025. }
  3026. }
  3027. /*****************************************************************************
  3028.  *
  3029.  * GetTrapQueueLen - Get the length of the trap buffer
  3030.  *
  3031.  * Description:
  3032.  * Evaluates the number of currently stored traps and the needed
  3033.  * buffer size to retrieve them.
  3034.  *
  3035.  * Returns:
  3036.  * Nothing
  3037.  */
  3038. static void GetTrapQueueLen(
  3039. SK_AC *pAC, /* Pointer to adapter context */
  3040. unsigned int *pLen, /* Length in Bytes of all queued traps */
  3041. unsigned int *pEntries) /* Returns number of trapes stored in queue */
  3042. {
  3043. unsigned int BufPad = pAC->Pnmi.TrapBufPad;
  3044. unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
  3045. unsigned int End = pAC->Pnmi.TrapQueueEnd;
  3046. char *pBuf = &pAC->Pnmi.TrapBuf[0];
  3047. unsigned int Len;
  3048. unsigned int Entries = 0;
  3049. unsigned int TotalLen = 0;
  3050. while (Trap != End) {
  3051. Len = (unsigned int)*(pBuf + Trap);
  3052. TotalLen += Len - 1;
  3053. Entries ++;
  3054. Trap += Len;
  3055. if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
  3056. Trap = BufPad;
  3057. }
  3058. }
  3059. *pEntries = Entries;
  3060. *pLen = TotalLen;
  3061. }
  3062. /*****************************************************************************
  3063.  *
  3064.  * QueueSimpleTrap - Store a simple trap to the trap buffer
  3065.  *
  3066.  * Description:
  3067.  * A simple trap is a trap with now additional data. It consists
  3068.  * simply of a trap code.
  3069.  *
  3070.  * Returns:
  3071.  * Nothing
  3072.  */
  3073. static void QueueSimpleTrap(
  3074. SK_AC *pAC, /* Pointer to adapter context */
  3075. SK_U32 TrapId) /* Type of sensor trap */
  3076. {
  3077. GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
  3078. }
  3079. /*****************************************************************************
  3080.  *
  3081.  * QueueSensorTrap - Stores a sensor trap in the trap buffer
  3082.  *
  3083.  * Description:
  3084.  * Gets an entry in the trap buffer and fills it with sensor related
  3085.  * data.
  3086.  *
  3087.  * Returns:
  3088.  * Nothing
  3089.  */
  3090. static void QueueSensorTrap(
  3091. SK_AC *pAC, /* Pointer to adapter context */
  3092. SK_U32 TrapId, /* Type of sensor trap */
  3093. unsigned int SensorIndex) /* Index of sensor which caused the trap */
  3094. {
  3095. char *pBuf;
  3096. unsigned int Offset;
  3097. unsigned int DescrLen;
  3098. SK_U32 Val32;
  3099. /* Get trap buffer entry */
  3100. DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
  3101. pBuf = GetTrapEntry(pAC, TrapId,
  3102. SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
  3103. Offset = SK_PNMI_TRAP_SIMPLE_LEN;
  3104. /* Store additionally sensor trap related data */
  3105. Val32 = OID_SKGE_SENSOR_INDEX;
  3106. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  3107. *(pBuf + Offset + 4) = 4;
  3108. Val32 = (SK_U32)SensorIndex;
  3109. SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
  3110. Offset += 9;
  3111. Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
  3112. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  3113. *(pBuf + Offset + 4) = (char)DescrLen;
  3114. SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
  3115. DescrLen);
  3116. Offset += DescrLen + 5;
  3117. Val32 = OID_SKGE_SENSOR_TYPE;
  3118. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  3119. *(pBuf + Offset + 4) = 1;
  3120. *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
  3121. Offset += 6;
  3122. Val32 = OID_SKGE_SENSOR_VALUE;
  3123. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  3124. *(pBuf + Offset + 4) = 4;
  3125. Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
  3126. SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
  3127. }
  3128. /*****************************************************************************
  3129.  *
  3130.  * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
  3131.  *
  3132.  * Description:
  3133.  * Nothing further to explain.
  3134.  *
  3135.  * Returns:
  3136.  * Nothing
  3137.  */
  3138. static void QueueRlmtNewMacTrap(
  3139. SK_AC *pAC, /* Pointer to adapter context */
  3140. unsigned int ActiveMac) /* Index (0..n) of the currently active port */
  3141. {
  3142. char *pBuf;
  3143. SK_U32 Val32;
  3144. pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
  3145. SK_PNMI_TRAP_RLMT_CHANGE_LEN);
  3146. Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
  3147. SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
  3148. *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
  3149. *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
  3150. }
  3151. /*****************************************************************************
  3152.  *
  3153.  * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
  3154.  *
  3155.  * Description:
  3156.  * Nothing further to explain.
  3157.  *
  3158.  * Returns:
  3159.  * Nothing
  3160.  */
  3161. static void QueueRlmtPortTrap(
  3162. SK_AC *pAC, /* Pointer to adapter context */
  3163. SK_U32 TrapId, /* Type of RLMT port trap */
  3164. unsigned int PortIndex) /* Index of the port, which changed its state */
  3165. {
  3166. char *pBuf;
  3167. SK_U32 Val32;
  3168. pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
  3169. Val32 = OID_SKGE_RLMT_PORT_INDEX;
  3170. SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
  3171. *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
  3172. *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
  3173. }
  3174. /*****************************************************************************
  3175.  *
  3176.  * CopyMac - Copies a MAC address
  3177.  *
  3178.  * Description:
  3179.  * Nothing further to explain.
  3180.  *
  3181.  * Returns:
  3182.  * Nothing
  3183.  */
  3184. static void CopyMac(
  3185. char *pDst, /* Pointer to destination buffer */
  3186. SK_MAC_ADDR *pMac) /* Pointer of Source */
  3187. {
  3188. int i;
  3189. for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
  3190. *(pDst + i) = pMac->a[i];
  3191. }
  3192. }