rclanmtl.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:56k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2. ** *************************************************************************
  3. **
  4. **
  5. **     R C L A N M T L . C             $Revision: 6 $
  6. **
  7. **
  8. **  RedCreek I2O LAN Message Transport Layer program module.
  9. **
  10. **  ---------------------------------------------------------------------
  11. **  ---     Copyright (c) 1997-1999, RedCreek Communications Inc.     ---
  12. **  ---                   All rights reserved.                        ---
  13. **  ---------------------------------------------------------------------
  14. **
  15. **  File Description:
  16. **
  17. **  Host side I2O (Intelligent I/O) LAN message transport layer.
  18. **
  19. **  This program is free software; you can redistribute it and/or modify
  20. **  it under the terms of the GNU General Public License as published by
  21. **  the Free Software Foundation; either version 2 of the License, or
  22. **  (at your option) any later version.
  23. **  This program is distributed in the hope that it will be useful,
  24. **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  26. **  GNU General Public License for more details.
  27. **  You should have received a copy of the GNU General Public License
  28. **  along with this program; if not, write to the Free Software
  29. **  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  30. **
  31. ** 1998-1999, LAN API was modified and enhanced by Alice Hennessy.
  32. **
  33. ** Sometime in 1997, LAN API was written from scratch by Wendell Nichols.
  34. ** *************************************************************************
  35. */
  36. #define DEBUG 1
  37. #define RC_LINUX_MODULE
  38. #include "rclanmtl.h"
  39.  /* RedCreek LAN device Target ID */
  40. #define RC_LAN_TARGET_ID  0x10
  41.  /* RedCreek's OSM default LAN receive Initiator */
  42. #define DEFAULT_RECV_INIT_CONTEXT  0xA17
  43. /*
  44. ** I2O message structures
  45. */
  46. #define    I2O_TID_SZ                                  12
  47. #define    I2O_FUNCTION_SZ                             8
  48. /* Transaction Reply Lists (TRL) Control Word structure */
  49. #define    I2O_TRL_FLAGS_SINGLE_FIXED_LENGTH           0x00
  50. #define    I2O_TRL_FLAGS_SINGLE_VARIABLE_LENGTH        0x40
  51. #define    I2O_TRL_FLAGS_MULTIPLE_FIXED_LENGTH         0x80
  52. /* LAN Class specific functions */
  53. #define    I2O_LAN_PACKET_SEND                         0x3B
  54. #define    I2O_LAN_SDU_SEND                            0x3D
  55. #define    I2O_LAN_RECEIVE_POST                        0x3E
  56. #define    I2O_LAN_RESET                               0x35
  57. #define    I2O_LAN_SHUTDOWN                            0x37
  58. /* Private Class specfic function */
  59. #define    I2O_PRIVATE                                 0xFF
  60. /*  I2O Executive Function Codes.  */
  61. #define    I2O_EXEC_ADAPTER_ASSIGN                     0xB3
  62. #define    I2O_EXEC_ADAPTER_READ                       0xB2
  63. #define    I2O_EXEC_ADAPTER_RELEASE                    0xB5
  64. #define    I2O_EXEC_BIOS_INFO_SET                      0xA5
  65. #define    I2O_EXEC_BOOT_DEVICE_SET                    0xA7
  66. #define    I2O_EXEC_CONFIG_VALIDATE                    0xBB
  67. #define    I2O_EXEC_CONN_SETUP                         0xCA
  68. #define    I2O_EXEC_DEVICE_ASSIGN                      0xB7
  69. #define    I2O_EXEC_DEVICE_RELEASE                     0xB9
  70. #define    I2O_EXEC_HRT_GET                            0xA8
  71. #define    I2O_EXEC_IOP_CLEAR                          0xBE
  72. #define    I2O_EXEC_IOP_CONNECT                        0xC9
  73. #define    I2O_EXEC_IOP_RESET                          0xBD
  74. #define    I2O_EXEC_LCT_NOTIFY                         0xA2
  75. #define    I2O_EXEC_OUTBOUND_INIT                      0xA1
  76. #define    I2O_EXEC_PATH_ENABLE                        0xD3
  77. #define    I2O_EXEC_PATH_QUIESCE                       0xC5
  78. #define    I2O_EXEC_PATH_RESET                         0xD7
  79. #define    I2O_EXEC_STATIC_MF_CREATE                   0xDD
  80. #define    I2O_EXEC_STATIC_MF_RELEASE                  0xDF
  81. #define    I2O_EXEC_STATUS_GET                         0xA0
  82. #define    I2O_EXEC_SW_DOWNLOAD                        0xA9
  83. #define    I2O_EXEC_SW_UPLOAD                          0xAB
  84. #define    I2O_EXEC_SW_REMOVE                          0xAD
  85. #define    I2O_EXEC_SYS_ENABLE                         0xD1
  86. #define    I2O_EXEC_SYS_MODIFY                         0xC1
  87. #define    I2O_EXEC_SYS_QUIESCE                        0xC3
  88. #define    I2O_EXEC_SYS_TAB_SET                        0xA3
  89.  /* Init Outbound Q status */
  90. #define    I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS          0x01
  91. #define    I2O_EXEC_OUTBOUND_INIT_REJECTED             0x02
  92. #define    I2O_EXEC_OUTBOUND_INIT_FAILED               0x03
  93. #define    I2O_EXEC_OUTBOUND_INIT_COMPLETE             0x04
  94. #define    I2O_UTIL_NOP                                0x00
  95. /* I2O Get Status State values */
  96. #define    I2O_IOP_STATE_INITIALIZING                  0x01
  97. #define    I2O_IOP_STATE_RESET                         0x02
  98. #define    I2O_IOP_STATE_HOLD                          0x04
  99. #define    I2O_IOP_STATE_READY                         0x05
  100. #define    I2O_IOP_STATE_OPERATIONAL                   0x08
  101. #define    I2O_IOP_STATE_FAILED                        0x10
  102. #define    I2O_IOP_STATE_FAULTED                       0x11
  103. /* Defines for Request Status Codes:  Table 3-1 Reply Status Codes.  */
  104. #define    I2O_REPLY_STATUS_SUCCESS                    0x00
  105. #define    I2O_REPLY_STATUS_ABORT_DIRTY                0x01
  106. #define    I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER     0x02
  107. #define    I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER     0x03
  108. #define    I2O_REPLY_STATUS_ERROR_DIRTY                0x04
  109. #define    I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER     0x05
  110. #define    I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER     0x06
  111. #define    I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY        0x07
  112. #define    I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER   0x08
  113. #define    I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER   0x09
  114. #define    I2O_REPLY_STATUS_TRANSACTION_ERROR          0x0A
  115. #define    I2O_REPLY_STATUS_PROGRESS_REPORT            0x80
  116. /* DetailedStatusCode defines for ALL messages: Table 3-2 Detailed Status Codes.*/
  117. #define    I2O_DETAIL_STATUS_SUCCESS                        0x0000
  118. #define    I2O_DETAIL_STATUS_BAD_KEY                        0x0001
  119. #define    I2O_DETAIL_STATUS_CHAIN_BUFFER_TOO_LARGE         0x0002
  120. #define    I2O_DETAIL_STATUS_DEVICE_BUSY                    0x0003
  121. #define    I2O_DETAIL_STATUS_DEVICE_LOCKED                  0x0004
  122. #define    I2O_DETAIL_STATUS_DEVICE_NOT_AVAILABLE           0x0005
  123. #define    I2O_DETAIL_STATUS_DEVICE_RESET                   0x0006
  124. #define    I2O_DETAIL_STATUS_INAPPROPRIATE_FUNCTION         0x0007
  125. #define    I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_HARD     0x0008
  126. #define    I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_SOFT     0x0009
  127. #define    I2O_DETAIL_STATUS_INVALID_INITIATOR_ADDRESS      0x000A
  128. #define    I2O_DETAIL_STATUS_INVALID_MESSAGE_FLAGS          0x000B
  129. #define    I2O_DETAIL_STATUS_INVALID_OFFSET                 0x000C
  130. #define    I2O_DETAIL_STATUS_INVALID_PARAMETER              0x000D
  131. #define    I2O_DETAIL_STATUS_INVALID_REQUEST                0x000E
  132. #define    I2O_DETAIL_STATUS_INVALID_TARGET_ADDRESS         0x000F
  133. #define    I2O_DETAIL_STATUS_MESSAGE_TOO_LARGE              0x0010
  134. #define    I2O_DETAIL_STATUS_MESSAGE_TOO_SMALL              0x0011
  135. #define    I2O_DETAIL_STATUS_MISSING_PARAMETER              0x0012
  136. #define    I2O_DETAIL_STATUS_NO_SUCH_PAGE                   0x0013
  137. #define    I2O_DETAIL_STATUS_REPLY_BUFFER_FULL              0x0014
  138. #define    I2O_DETAIL_STATUS_TCL_ERROR                      0x0015
  139. #define    I2O_DETAIL_STATUS_TIMEOUT                        0x0016
  140. #define    I2O_DETAIL_STATUS_UNKNOWN_ERROR                  0x0017
  141. #define    I2O_DETAIL_STATUS_UNKNOWN_FUNCTION               0x0018
  142. #define    I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION           0x0019
  143. #define    I2O_DETAIL_STATUS_UNSUPPORTED_VERSION            0x001A
  144.  /* I2O msg header defines for VersionOffset */
  145. #define I2OMSGVER_1_5   0x0001
  146. #define SGL_OFFSET_0    I2OMSGVER_1_5
  147. #define SGL_OFFSET_4    (0x0040 | I2OMSGVER_1_5)
  148. #define TRL_OFFSET_5    (0x0050 | I2OMSGVER_1_5)
  149. #define TRL_OFFSET_6    (0x0060 | I2OMSGVER_1_5)
  150.  /* I2O msg header defines for MsgFlags */
  151. #define MSG_STATIC      0x0100
  152. #define MSG_64BIT_CNTXT 0x0200
  153. #define MSG_MULTI_TRANS 0x1000
  154. #define MSG_FAIL        0x2000
  155. #define MSG_LAST        0x4000
  156. #define MSG_REPLY       0x8000
  157.   /* normal LAN request message MsgFlags and VersionOffset (0x1041) */
  158. #define LAN_MSG_REQST  (MSG_MULTI_TRANS | SGL_OFFSET_4)
  159.  /* minimum size msg */
  160. #define THREE_WORD_MSG_SIZE 0x00030000
  161. #define FOUR_WORD_MSG_SIZE  0x00040000
  162. #define FIVE_WORD_MSG_SIZE  0x00050000
  163. #define SIX_WORD_MSG_SIZE   0x00060000
  164. #define SEVEN_WORD_MSG_SIZE 0x00070000
  165. #define EIGHT_WORD_MSG_SIZE 0x00080000
  166. #define NINE_WORD_MSG_SIZE  0x00090000
  167. /* Special TID Assignments */
  168. #define I2O_IOP_TID   0
  169. #define I2O_HOST_TID  0xB91
  170.  /* RedCreek I2O private message codes */
  171. #define RC_PRIVATE_GET_MAC_ADDR     0x0001/**/ /* OBSOLETE */
  172. #define RC_PRIVATE_SET_MAC_ADDR     0x0002
  173. #define RC_PRIVATE_GET_NIC_STATS    0x0003
  174. #define RC_PRIVATE_GET_LINK_STATUS  0x0004
  175. #define RC_PRIVATE_SET_LINK_SPEED   0x0005
  176. #define RC_PRIVATE_SET_IP_AND_MASK  0x0006
  177. /* #define RC_PRIVATE_GET_IP_AND_MASK  0x0007 *//* OBSOLETE */
  178. #define RC_PRIVATE_GET_LINK_SPEED   0x0008
  179. #define RC_PRIVATE_GET_FIRMWARE_REV 0x0009
  180. /* #define RC_PRIVATE_GET_MAC_ADDR     0x000A */
  181. #define RC_PRIVATE_GET_IP_AND_MASK  0x000B
  182. #define RC_PRIVATE_DEBUG_MSG        0x000C
  183. #define RC_PRIVATE_REPORT_DRIVER_CAPABILITY  0x000D
  184. #define RC_PRIVATE_SET_PROMISCUOUS_MODE  0x000e
  185. #define RC_PRIVATE_GET_PROMISCUOUS_MODE  0x000f
  186. #define RC_PRIVATE_SET_BROADCAST_MODE    0x0010
  187. #define RC_PRIVATE_GET_BROADCAST_MODE    0x0011
  188. #define RC_PRIVATE_REBOOT           0x00FF
  189. /* I2O message header */
  190. typedef struct _I2O_MESSAGE_FRAME {
  191. U8 VersionOffset;
  192. U8 MsgFlags;
  193. U16 MessageSize;
  194. BF TargetAddress:I2O_TID_SZ;
  195. BF InitiatorAddress:I2O_TID_SZ;
  196. BF Function:I2O_FUNCTION_SZ;
  197. U32 InitiatorContext;
  198. /* SGL[] */
  199. } I2O_MESSAGE_FRAME, *PI2O_MESSAGE_FRAME;
  200.  /* assumed a 16K minus 256 byte space for outbound queue message frames */
  201. #define MSG_FRAME_SIZE  512
  202. #define NMBR_MSG_FRAMES 30
  203.  /* 
  204.     ** in reserved space right after PAB in host memory is area for returning
  205.     ** values from card 
  206.   */
  207. /*
  208. ** typedef NICSTAT
  209. **
  210. ** Data structure for NIC statistics retruned from PCI card.  Data copied from
  211. ** here to user allocated RCLINKSTATS (see rclanmtl.h) structure.
  212. */
  213. typedef struct tag_NicStat {
  214. unsigned long TX_good;
  215. unsigned long TX_maxcol;
  216. unsigned long TX_latecol;
  217. unsigned long TX_urun;
  218. unsigned long TX_crs; /* lost carrier sense */
  219. unsigned long TX_def; /* transmit deferred */
  220. unsigned long TX_singlecol; /* single collisions */
  221. unsigned long TX_multcol;
  222. unsigned long TX_totcol;
  223. unsigned long Rcv_good;
  224. unsigned long Rcv_CRCerr;
  225. unsigned long Rcv_alignerr;
  226. unsigned long Rcv_reserr; /* rnr'd pkts */
  227. unsigned long Rcv_orun;
  228. unsigned long Rcv_cdt;
  229. unsigned long Rcv_runt;
  230. unsigned long dump_status; /* last field directly from the chip */
  231. } NICSTAT, *P_NICSTAT;
  232. #define DUMP_DONE   0x0000A005 /* completed statistical dump */
  233. #define DUMP_CLEAR  0x0000A007 /* completed stat dump and clear counters */
  234. static volatile int msgFlag;
  235. /* local function prototypes */
  236. static void ProcessOutboundI2OMsg (PPAB pPab, U32 phyMsgAddr);
  237. static int FillI2OMsgSGLFromTCB (PU32 pMsg, PRCTCB pXmitCntrlBlock);
  238. static int GetI2OStatus (PPAB pPab);
  239. static int SendI2OOutboundQInitMsg (PPAB pPab);
  240. static int SendEnableSysMsg (PPAB pPab);
  241. /*
  242. ** =========================================================================
  243. ** RCInitI2OMsgLayer()
  244. **
  245. ** Initialize the RedCreek I2O Module and adapter.
  246. **
  247. ** Inputs:  dev - the devices net_device struct
  248. **          TransmitCallbackFunction - address of transmit callback function
  249. **          ReceiveCallbackFunction  - address of receive  callback function
  250. **
  251. ** private message block is allocated by user.  It must be in locked pages.
  252. ** p_msgbuf and p_phymsgbuf point to the same location.  Must be contigous
  253. ** memory block of a minimum of 16K byte and long word aligned.
  254. ** =========================================================================
  255. */
  256. RC_RETURN
  257. RCInitI2OMsgLayer (struct net_device *dev,
  258.    PFNTXCALLBACK TransmitCallbackFunction,
  259.    PFNRXCALLBACK ReceiveCallbackFunction,
  260.    PFNCALLBACK RebootCallbackFunction)
  261. {
  262. int result;
  263. PPAB pPab;
  264. PDPA pDpa = dev->priv;
  265. U32 pciBaseAddr = dev->base_addr;
  266. PU8 p_msgbuf = pDpa->PLanApiPA;
  267. PU8 p_phymsgbuf = (PU8) virt_to_bus ((void *) p_msgbuf);
  268. dprintk
  269.     ("InitI2O: Adapter:0x%x ATU:0x%x msgbuf:0x%x phymsgbuf:0x%xn"
  270.      "TransmitCallbackFunction:0x%x  ReceiveCallbackFunction:0x%xn",
  271.      pDpa->id, pciBaseAddr, (u32) p_msgbuf, (u32) p_phymsgbuf,
  272.      (u32) TransmitCallbackFunction, (u32) ReceiveCallbackFunction);
  273. /* Check if this interface already initialized - if so, shut it down */
  274. if (pDpa->pPab != NULL) {
  275. dprintk (KERN_WARNING
  276. "pDpa->pPab [%d] != NULLn",
  277. pDpa->id);
  278. /*          RCResetLANCard(pDpa->id, 0, (PU32)NULL, (PFNCALLBACK)NULL); */
  279. pDpa->pPab = NULL;
  280. }
  281. /* store adapter instance values in adapter block.
  282.  * Adapter block is at beginning of message buffer */
  283. pPab = kmalloc (sizeof (*pPab), GFP_KERNEL);
  284. if (!pPab) {
  285. dprintk (KERN_ERR 
  286. "RCInitI2OMsgLayer: Could not allocate memory for PAB struct!n");
  287. result = RC_RTN_MALLOC_ERROR;
  288. goto err_out;
  289. }
  290. memset (pPab, 0, sizeof (*pPab));
  291. pDpa->pPab = pPab;
  292. pPab->p_atu = (PATU) pciBaseAddr;
  293. pPab->pPci45LinBaseAddr = (PU8) pciBaseAddr;
  294. /* Set outbound message frame addr */
  295. pPab->outMsgBlockPhyAddr = (U32) p_phymsgbuf;
  296. pPab->pLinOutMsgBlock = (PU8) p_msgbuf;
  297. /* store callback function addresses */
  298. pPab->pTransCallbackFunc = TransmitCallbackFunction;
  299. pPab->pRecvCallbackFunc = ReceiveCallbackFunction;
  300. pPab->pRebootCallbackFunc = RebootCallbackFunction;
  301. pPab->pCallbackFunc = (PFNCALLBACK) NULL;
  302. /*
  303.    ** Initialize I2O IOP
  304.  */
  305. result = GetI2OStatus (pPab);
  306. if (result != RC_RTN_NO_ERROR)
  307. goto err_out_dealloc;
  308. if (pPab->IOPState == I2O_IOP_STATE_OPERATIONAL) {
  309. dprintk (KERN_INFO "pPab->IOPState == op: resetting adaptern");
  310. RCResetLANCard (dev, 0, (PU32) NULL, (PFNCALLBACK) NULL);
  311. }
  312. result = SendI2OOutboundQInitMsg (pPab);
  313. if (result != RC_RTN_NO_ERROR)
  314. goto err_out_dealloc;
  315. result = SendEnableSysMsg (pPab);
  316. if (result != RC_RTN_NO_ERROR)
  317. goto err_out_dealloc;
  318. return RC_RTN_NO_ERROR;
  319.       err_out_dealloc:
  320. kfree (pPab);
  321.       err_out:
  322. return result;
  323. }
  324. /*
  325. ** =========================================================================
  326. ** Disable and Enable I2O interrupts.  I2O interrupts are enabled at Init time
  327. ** but can be disabled and re-enabled through these two function calls.
  328. ** Packets will still be put into any posted received buffers and packets will
  329. ** be sent through RCI2OSendPacket() functions.  Disabling I2O interrupts
  330. ** will prevent hardware interrupt to host even though the outbound I2O msg
  331. ** queue is not emtpy.
  332. ** =========================================================================
  333. */
  334. #define i960_OUT_POST_Q_INT_BIT        0x0008 /* bit set masks interrupts */
  335. RC_RETURN
  336. RCDisableI2OInterrupts (struct net_device * dev)
  337. {
  338. PPAB pPab = ((PDPA) dev->priv)->pPab;
  339. if (pPab == NULL)
  340. return RC_RTN_ADPTR_NOT_REGISTERED;
  341. pPab->p_atu->OutIntMask |= i960_OUT_POST_Q_INT_BIT;
  342. return RC_RTN_NO_ERROR;
  343. }
  344. RC_RETURN
  345. RCEnableI2OInterrupts (struct net_device * dev)
  346. {
  347. PPAB pPab = ((PDPA) dev->priv)->pPab;
  348. if (pPab == NULL)
  349. return RC_RTN_ADPTR_NOT_REGISTERED;
  350. pPab->p_atu->OutIntMask &= ~i960_OUT_POST_Q_INT_BIT;
  351. return RC_RTN_NO_ERROR;
  352. }
  353. /*
  354. ** =========================================================================
  355. ** RCI2OSendPacket()
  356. ** =========================================================================
  357. */
  358. RC_RETURN
  359. RCI2OSendPacket (struct net_device * dev, U32 InitiatorContext,
  360.  PRCTCB pTransCtrlBlock)
  361. {
  362. U32 msgOffset;
  363. PU32 pMsg;
  364. int size;
  365. PPAB pPab = ((PDPA) dev->priv)->pPab;
  366. dprintk ("RCI2OSendPacket()...n");
  367. if (pPab == NULL)
  368. return RC_RTN_ADPTR_NOT_REGISTERED;
  369. /* get Inbound free Q entry - reading from In Q gets free Q entry */
  370. /* offset to Msg Frame in PCI msg block */
  371. msgOffset = pPab->p_atu->InQueue;
  372. if (msgOffset == 0xFFFFFFFF) {
  373. dprintk ("RCI2OSendPacket(): Inbound Free Q empty!n");
  374. return RC_RTN_FREE_Q_EMPTY;
  375. }
  376. /* calc virtual address of msg - virtual already mapped to physical */
  377. pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
  378. size = FillI2OMsgSGLFromTCB (pMsg + 4, pTransCtrlBlock);
  379. if (size == -1) { /* error processing TCB - send NOP msg */
  380. dprintk ("RCI2OSendPacket(): Error Rrocess TCB!n");
  381. pMsg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
  382. pMsg[1] =
  383.     I2O_UTIL_NOP << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  384. return RC_RTN_TCB_ERROR;
  385. } else { /* send over msg header */
  386. pMsg[0] = (size + 4) << 16 | LAN_MSG_REQST; /* send over message size and flags */
  387. pMsg[1] =
  388.     I2O_LAN_PACKET_SEND << 24 | I2O_HOST_TID << 12 |
  389.     RC_LAN_TARGET_ID;
  390. pMsg[2] = InitiatorContext;
  391. pMsg[3] = 0; /* batch reply */
  392. /* post to Inbound Post Q */
  393. pPab->p_atu->InQueue = msgOffset;
  394. return RC_RTN_NO_ERROR;
  395. }
  396. }
  397. /*
  398. ** =========================================================================
  399. ** RCI2OPostRecvBuffer()
  400. **
  401. ** inputs:  pBufrCntrlBlock - pointer to buffer control block
  402. **
  403. ** returns TRUE if successful in sending message, else FALSE.
  404. ** =========================================================================
  405. */
  406. RC_RETURN
  407. RCPostRecvBuffers (struct net_device * dev, PRCTCB pTransCtrlBlock)
  408. {
  409. U32 msgOffset;
  410. PU32 pMsg;
  411. int size;
  412. PPAB pPab = ((PDPA) dev->priv)->pPab;
  413. dprintk ("RCPostRecvBuffers()...n");
  414. /* search for DeviceHandle */
  415. if (pPab == NULL)
  416. return RC_RTN_ADPTR_NOT_REGISTERED;
  417. /* get Inbound free Q entry - reading from In Q gets free Q entry */
  418. /* offset to Msg Frame in PCI msg block */
  419. msgOffset = pPab->p_atu->InQueue;
  420. if (msgOffset == 0xFFFFFFFF) {
  421. dprintk ("RCPostRecvBuffers(): Inbound Free Q empty!n");
  422. return RC_RTN_FREE_Q_EMPTY;
  423. }
  424. /* calc virtual address of msg - virtual already mapped to physical */
  425. pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
  426. size = FillI2OMsgSGLFromTCB (pMsg + 4, pTransCtrlBlock);
  427. if (size == -1) { /* error prcessing TCB - send 3 DWORD private msg == NOP */
  428. dprintk
  429.     ("RCPostRecvBuffers(): Error Processing TCB! size = %dn",
  430.      size);
  431. pMsg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
  432. pMsg[1] =
  433.     I2O_UTIL_NOP << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  434. /* post to Post Q */
  435. pPab->p_atu->InQueue = msgOffset;
  436. return RC_RTN_TCB_ERROR;
  437. } else { /* send over size msg header */
  438. pMsg[0] = (size + 4) << 16 | LAN_MSG_REQST; /* send over message size and flags */
  439. pMsg[1] =
  440.     I2O_LAN_RECEIVE_POST << 24 | I2O_HOST_TID << 12 |
  441.     RC_LAN_TARGET_ID;
  442. pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
  443. pMsg[3] = *(PU32) pTransCtrlBlock; /* number of packet buffers */
  444. /* post to Post Q */
  445. pPab->p_atu->InQueue = msgOffset;
  446. return RC_RTN_NO_ERROR;
  447. }
  448. }
  449. /*
  450. ** =========================================================================
  451. ** RCProcI2OMsgQ()
  452. **
  453. ** Process I2O outbound message queue until empty.
  454. ** =========================================================================
  455. */
  456. void
  457. RCProcI2OMsgQ (struct net_device *dev)
  458. {
  459. U32 phyAddrMsg;
  460. PU8 p8Msg;
  461. PU32 p32;
  462. U16 count;
  463. PPAB pPab = ((PDPA) dev->priv)->pPab;
  464. unsigned char debug_msg[20];
  465. if (pPab == NULL)
  466. return;
  467. phyAddrMsg = pPab->p_atu->OutQueue;
  468. while (phyAddrMsg != 0xFFFFFFFF) {
  469. p8Msg =
  470.     pPab->pLinOutMsgBlock + (phyAddrMsg -
  471.      pPab->outMsgBlockPhyAddr);
  472. p32 = (PU32) p8Msg;
  473. dprintk ("msg: 0x%x  0x%x n", p8Msg[7], p32[5]);
  474. /* Send Packet Reply Msg */
  475. if (I2O_LAN_PACKET_SEND == p8Msg[7]) { /* function code byte */
  476. count = *(PU16) (p8Msg + 2);
  477. count -= p8Msg[0] >> 4;
  478. /* status, count, context[], adapter */
  479. (*pPab->pTransCallbackFunc) (p8Msg[19], count, p32 + 5,
  480.      dev);
  481. } else if (I2O_LAN_RECEIVE_POST == p8Msg[7]) { /* Receive Packet Reply Msg */
  482. dprintk
  483.     ("I2O_RECV_REPLY pPab:0x%x p8Msg:0x%x p32:0x%xn",
  484.      (u32) pPab, (u32) p8Msg, (u32) p32);
  485. dprintk ("msg: 0x%x:0x%x:0x%x:0x%xn",
  486.  p32[0], p32[1], p32[2], p32[3]);
  487. dprintk ("     0x%x:0x%x:0x%x:0x%xn",
  488.  p32[4], p32[5], p32[6], p32[7]);
  489. dprintk ("     0x%x:0X%x:0x%x:0x%xn",
  490.  p32[8], p32[9], p32[10], p32[11]);
  491. /*  status, count, buckets remaining, packetParmBlock, adapter */
  492. (*pPab->pRecvCallbackFunc) (p8Msg[19], p8Msg[12],
  493.     p32[5], p32 + 6, dev);
  494. } else if (I2O_LAN_RESET == p8Msg[7]
  495.    || I2O_LAN_SHUTDOWN == p8Msg[7])
  496. if (pPab->pCallbackFunc)
  497. (*pPab->pCallbackFunc) (p8Msg[19], 0, 0, dev);
  498. else
  499. pPab->pCallbackFunc = (PFNCALLBACK) 1;
  500. else if (I2O_PRIVATE == p8Msg[7]) {
  501. dprintk ("i2o private 0x%x, 0x%x n", p8Msg[7], p32[5]);
  502. switch (p32[5]) {
  503. case RC_PRIVATE_DEBUG_MSG:
  504. msgFlag = 1;
  505. dprintk ("Received I2O_PRIVATE msgn");
  506. debug_msg[15] = (p32[6] & 0xff000000) >> 24;
  507. debug_msg[14] = (p32[6] & 0x00ff0000) >> 16;
  508. debug_msg[13] = (p32[6] & 0x0000ff00) >> 8;
  509. debug_msg[12] = (p32[6] & 0x000000ff);
  510. debug_msg[11] = (p32[7] & 0xff000000) >> 24;
  511. debug_msg[10] = (p32[7] & 0x00ff0000) >> 16;
  512. debug_msg[9] = (p32[7] & 0x0000ff00) >> 8;
  513. debug_msg[8] = (p32[7] & 0x000000ff);
  514. debug_msg[7] = (p32[8] & 0xff000000) >> 24;
  515. debug_msg[6] = (p32[8] & 0x00ff0000) >> 16;
  516. debug_msg[5] = (p32[8] & 0x0000ff00) >> 8;
  517. debug_msg[4] = (p32[8] & 0x000000ff);
  518. debug_msg[3] = (p32[9] & 0xff000000) >> 24;
  519. debug_msg[2] = (p32[9] & 0x00ff0000) >> 16;
  520. debug_msg[1] = (p32[9] & 0x0000ff00) >> 8;
  521. debug_msg[0] = (p32[9] & 0x000000ff);
  522. debug_msg[16] = '';
  523. dprintk ("%s", debug_msg);
  524. break;
  525. case RC_PRIVATE_REBOOT:
  526. dprintk ("Adapter reboot initiated...n");
  527. if (pPab->pRebootCallbackFunc)
  528. (*pPab->pRebootCallbackFunc) (0, 0, 0,
  529.       dev);
  530. break;
  531. default:
  532. dprintk (KERN_WARNING
  533. "Unknown private I2O msg received: 0x%xn",
  534. p32[5]);
  535. break;
  536. }
  537. }
  538. /* 
  539.    ** Process other Msg's
  540.  */
  541. else
  542. ProcessOutboundI2OMsg (pPab, phyAddrMsg);
  543. /* return MFA to outbound free Q */
  544. pPab->p_atu->OutQueue = phyAddrMsg;
  545. /* any more msgs? */
  546. phyAddrMsg = pPab->p_atu->OutQueue;
  547. }
  548. }
  549. /*
  550. ** =========================================================================
  551. **  Returns LAN interface statistical counters to space provided by caller at
  552. **  StatsReturnAddr.  Returns 0 if success, else RC_RETURN code.
  553. **  This function will call the WaitCallback function provided by
  554. **  user while waiting for card to respond.
  555. ** =========================================================================
  556. */
  557. RC_RETURN
  558. RCGetLinkStatistics (struct net_device *dev,
  559.      P_RCLINKSTATS StatsReturnAddr,
  560.      PFNWAITCALLBACK WaitCallback)
  561. {
  562. U32 msgOffset;
  563. volatile PU32 pMsg;
  564. volatile PU32 p32, pReturnAddr;
  565. P_NICSTAT pStats;
  566. int i;
  567. PPAB pPab = ((PDPA) dev->priv)->pPab;
  568. /*dprintk("Get82558Stats() StatsReturnAddr:0x%xn", StatsReturnAddr); */
  569. if (pPab == NULL)
  570. return RC_RTN_ADPTR_NOT_REGISTERED;
  571. msgOffset = pPab->p_atu->InQueue;
  572. if (msgOffset == 0xFFFFFFFF) {
  573. dprintk ("Get8255XStats(): Inbound Free Q empty!n");
  574. return RC_RTN_FREE_Q_EMPTY;
  575. }
  576. /* calc virtual address of msg - virtual already mapped to physical */
  577. pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
  578. /*dprintk("Get82558Stats - pMsg = 0x%x, InQ msgOffset = 0x%xn", pMsg, msgOffset);*/
  579. /*dprintk("Get82558Stats - pMsg = 0x%08X, InQ msgOffset = 0x%08Xn", pMsg, msgOffset);*/
  580. pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
  581. pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  582. pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
  583. pMsg[3] = 0x112; /* transaction context */
  584. pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_NIC_STATS;
  585. pMsg[5] = pPab->outMsgBlockPhyAddr;
  586. // p32 = (PU32) pPab->outMsgBlockPhyAddr;
  587. p32 = (PU32)pPab->pLinOutMsgBlock;
  588. pStats = (P_NICSTAT) pPab->pLinOutMsgBlock;
  589. pStats->dump_status = 0xFFFFFFFF;
  590. /* post to Inbound Post Q */
  591. pPab->p_atu->InQueue = msgOffset;
  592. i = 0;
  593. while (pStats->dump_status == 0xFFFFFFFF) {
  594. if (i++ > 0xff) {
  595. dprintk ("Timeout waiting for NIC statisticsn");
  596. return RC_RTN_MSG_REPLY_TIMEOUT;
  597. }
  598. udelay(50);
  599. }
  600. pReturnAddr = (PU32) StatsReturnAddr;
  601. /* copy Nic stats to user's structure */
  602. for (i = 0; i < (int) sizeof (RCLINKSTATS) / 4; i++)
  603. pReturnAddr[i] = p32[i];
  604. return RC_RTN_NO_ERROR;
  605. }
  606. /*
  607. ** =========================================================================
  608. ** Get82558LinkStatus()
  609. ** =========================================================================
  610. */
  611. RC_RETURN
  612. RCGetLinkStatus (struct net_device * dev, PU32 ReturnAddr,
  613.  PFNWAITCALLBACK WaitCallback)
  614. {
  615. int i;
  616. U32 msgOffset;
  617. volatile PU32 pMsg;
  618. volatile PU32 p32;
  619. PPAB pPab = ((PDPA) dev->priv)->pPab;
  620. dprintk ("Get82558LinkStatus() ReturnPhysAddr:0x%xn",
  621.  (u32) ReturnAddr);
  622. if (pPab == NULL)
  623. return RC_RTN_ADPTR_NOT_REGISTERED;
  624. msgOffset = pPab->p_atu->InQueue;
  625. if (msgOffset == 0xFFFFFFFF) {
  626. dprintk ("Get82558LinkStatus(): Inbound Free Q empty!n");
  627. return RC_RTN_FREE_Q_EMPTY;
  628. }
  629. /* calc virtual address of msg - virtual already mapped to physical */
  630. pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
  631. /*dprintk("Get82558LinkStatus - pMsg = 0x%x, InQ msgOffset = 0x%xn", pMsg, msgOffset);*/
  632. /*dprintk("Get82558LinkStatus - pMsg = 0x%08X, InQ msgOffset = 0x%08Xn", pMsg, msgOffset);*/
  633. pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
  634. pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  635. pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
  636. pMsg[3] = 0x112; /* transaction context */
  637. pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_LINK_STATUS;
  638. pMsg[5] = pPab->outMsgBlockPhyAddr;
  639. p32 = (PU32) pPab->pLinOutMsgBlock;
  640. *p32 = 0xFFFFFFFF;
  641. /* post to Inbound Post Q */
  642. pPab->p_atu->InQueue = msgOffset;
  643. i = 0;
  644. while (*p32 == 0xFFFFFFFF) {
  645. if (i++ > 0xff) {
  646. dprintk ("Timeout waiting for link statusn");
  647. return RC_RTN_MSG_REPLY_TIMEOUT;
  648. }
  649. udelay(50);
  650. }
  651. *ReturnAddr = *p32; /* 1 = up 0 = down */
  652. return RC_RTN_NO_ERROR;
  653. }
  654. /*
  655. ** =========================================================================
  656. ** RCGetMAC()
  657. **
  658. ** get the MAC address the adapter is listening for in non-promiscous mode.
  659. ** MAC address is in media format.
  660. ** =========================================================================
  661. */
  662. RC_RETURN
  663. RCGetMAC (struct net_device * dev, PFNWAITCALLBACK WaitCallback)
  664. {
  665. U32 off, i;
  666. PU8 mac = dev->dev_addr;
  667. PU32 p;
  668. U32 temp[2];
  669. PPAB pPab = ((PDPA) dev->priv)->pPab;
  670. PATU p_atu;
  671. if (pPab == NULL)
  672. return RC_RTN_ADPTR_NOT_REGISTERED;
  673. p_atu = pPab->p_atu;
  674. p_atu->EtherMacLow = 0; /* first zero return data */
  675. p_atu->EtherMacHi = 0;
  676. off = p_atu->InQueue; /* get addresss of message */
  677. if (0xFFFFFFFF == off)
  678. return RC_RTN_FREE_Q_EMPTY;
  679. p = (PU32) (pPab->pPci45LinBaseAddr + off);
  680. dprintk ("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08xn",
  681.  (uint) p_atu, (uint) off, (uint) p);
  682. /* setup private message */
  683. p[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
  684. p[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  685. p[2] = 0; /* initiator context */
  686. p[3] = 0x218; /* transaction context */
  687. p[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_MAC_ADDR;
  688. p_atu->InQueue = off; /* send it to the I2O device */
  689. dprintk ("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08xn",
  690.  (uint) p_atu, (uint) off, (uint) p);
  691. /* wait for the rcpci45 board to update the info */
  692. i = 0;
  693. while (0 == p_atu->EtherMacLow) {
  694. if (i++ > 0xff) {
  695. dprintk ("rc_getmac: Timeoutn");
  696. return RC_RTN_MSG_REPLY_TIMEOUT;
  697. }
  698. udelay(50);
  699. }
  700. /* read the mac address  */
  701. temp[0] = p_atu->EtherMacLow;
  702. temp[1] = p_atu->EtherMacHi;
  703. memcpy ((char *) mac, (char *) temp, 6);
  704. dprintk ("rc_getmac: 0x%xn", (u32) mac);
  705. return RC_RTN_NO_ERROR;
  706. }
  707. /*
  708. ** =========================================================================
  709. ** RCSetMAC()
  710. **
  711. ** set MAC address the adapter is listening for in non-promiscous mode.
  712. ** MAC address is in media format.
  713. ** =========================================================================
  714. */
  715. RC_RETURN
  716. RCSetMAC (struct net_device * dev, PU8 mac)
  717. {
  718. U32 off;
  719. PU32 pMsg;
  720. PPAB pPab = ((PDPA) dev->priv)->pPab;
  721. if (pPab == NULL)
  722. return RC_RTN_ADPTR_NOT_REGISTERED;
  723. off = pPab->p_atu->InQueue; /* get addresss of message */
  724. if (0xFFFFFFFF == off)
  725. return RC_RTN_FREE_Q_EMPTY;
  726. pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
  727. /* setup private message */
  728. pMsg[0] = SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0;
  729. pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  730. pMsg[2] = 0; /* initiator context */
  731. pMsg[3] = 0x219; /* transaction context */
  732. pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_MAC_ADDR;
  733. pMsg[5] = *(unsigned *) mac; /* first four bytes */
  734. pMsg[6] = *(unsigned *) (mac + 4); /* last two bytes */
  735. pPab->p_atu->InQueue = off; /* send it to the I2O device */
  736. return RC_RTN_NO_ERROR;
  737. }
  738. /*
  739. ** =========================================================================
  740. ** RCSetLinkSpeed()
  741. **
  742. ** set ethernet link speed. 
  743. ** input: speedControl - determines action to take as follows
  744. **          0 = reset and auto-negotiate (NWay)
  745. **          1 = Full Duplex 100BaseT
  746. **          2 = Half duplex 100BaseT
  747. **          3 = Full Duplex  10BaseT
  748. **          4 = Half duplex  10BaseT
  749. **          all other values are ignore (do nothing)
  750. ** =========================================================================
  751. */
  752. RC_RETURN
  753. RCSetLinkSpeed (struct net_device * dev, U16 LinkSpeedCode)
  754. {
  755. U32 off;
  756. PU32 pMsg;
  757. PPAB pPab = ((PDPA) dev->priv)->pPab;
  758. if (pPab == NULL)
  759. return RC_RTN_ADPTR_NOT_REGISTERED;
  760. off = pPab->p_atu->InQueue; /* get addresss of message */
  761. if (0xFFFFFFFF == off)
  762. return RC_RTN_FREE_Q_EMPTY;
  763. pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
  764. /* setup private message */
  765. pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
  766. pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  767. pMsg[2] = 0; /* initiator context */
  768. pMsg[3] = 0x219; /* transaction context */
  769. pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_LINK_SPEED;
  770. pMsg[5] = LinkSpeedCode; /* link speed code */
  771. pPab->p_atu->InQueue = off; /* send it to the I2O device */
  772. return RC_RTN_NO_ERROR;
  773. }
  774. /*
  775. ** =========================================================================
  776. ** RCSetPromiscuousMode()
  777. **
  778. ** Defined values for Mode:
  779. **  0 - turn off promiscuous mode
  780. **  1 - turn on  promiscuous mode
  781. **
  782. ** =========================================================================
  783. */
  784. RC_RETURN
  785. RCSetPromiscuousMode (struct net_device * dev, U16 Mode)
  786. {
  787. U32 off;
  788. PU32 pMsg;
  789. PPAB pPab = ((PDPA) dev->priv)->pPab;
  790. if (pPab == NULL)
  791. return RC_RTN_ADPTR_NOT_REGISTERED;
  792. off = pPab->p_atu->InQueue; /* get addresss of message */
  793. if (0xFFFFFFFF == off)
  794. return RC_RTN_FREE_Q_EMPTY;
  795. pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
  796. /* setup private message */
  797. pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
  798. pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  799. pMsg[2] = 0; /* initiator context */
  800. pMsg[3] = 0x219; /* transaction context */
  801. pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_PROMISCUOUS_MODE;
  802. pMsg[5] = Mode; /* promiscuous mode setting */
  803. pPab->p_atu->InQueue = off; /* send it to the device */
  804. return RC_RTN_NO_ERROR;
  805. }
  806. /*
  807. ** =========================================================================
  808. ** RCGetPromiscuousMode()
  809. **
  810. ** get promiscuous mode setting
  811. **
  812. ** Possible return values placed in pMode:
  813. **  0 = promisuous mode not set
  814. **  1 = promisuous mode is set
  815. **
  816. ** =========================================================================
  817. */
  818. RC_RETURN
  819. RCGetPromiscuousMode (struct net_device * dev, PU32 pMode,
  820.       PFNWAITCALLBACK WaitCallback)
  821. {
  822. PU32 pMsg;
  823. volatile PU32 p32;
  824. U32 msgOffset, i;
  825. PPAB pPab = ((PDPA) dev->priv)->pPab;
  826. msgOffset = pPab->p_atu->InQueue;
  827. if (msgOffset == 0xFFFFFFFF) {
  828. dprintk (KERN_WARNING
  829. "RCGetLinkSpeed(): Inbound Free Q empty!n");
  830. return RC_RTN_FREE_Q_EMPTY;
  831. }
  832. /* calc virtual address of msg - virtual already mapped to physical */
  833. pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
  834. /* virtual pointer to return buffer - clear first two dwords */
  835. p32 = (volatile PU32) pPab->pLinOutMsgBlock;
  836. p32[0] = 0xff;
  837. /* setup private message */
  838. pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
  839. pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  840. pMsg[2] = 0; /* initiator context */
  841. pMsg[3] = 0x219; /* transaction context */
  842. pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_PROMISCUOUS_MODE;
  843. /* phys address to return status - area right after PAB */
  844. pMsg[5] = pPab->outMsgBlockPhyAddr;
  845. /* post to Inbound Post Q */
  846. pPab->p_atu->InQueue = msgOffset;
  847. i = 0;
  848. /* wait for response */
  849. while (p32[0] == 0xff) {
  850. if (i++ > 0xff) {
  851. dprintk ("Timeout waiting for promiscuous moden");
  852. return RC_RTN_NO_LINK_SPEED;
  853. }
  854. udelay(50);
  855. }
  856. /* get mode */
  857. *pMode = (U8) ((volatile PU8) p32)[0] & 0x0f;
  858. return RC_RTN_NO_ERROR;
  859. }
  860. /*
  861. ** =========================================================================
  862. ** RCSetBroadcastMode()
  863. **
  864. ** Defined values for Mode:
  865. **  0 - turn off promiscuous mode
  866. **  1 - turn on  promiscuous mode
  867. **
  868. ** =========================================================================
  869. */
  870. RC_RETURN
  871. RCSetBroadcastMode (struct net_device * dev, U16 Mode)
  872. {
  873. U32 off;
  874. PU32 pMsg;
  875. PPAB pPab = ((PDPA) dev->priv)->pPab;
  876. if (pPab == NULL)
  877. return RC_RTN_ADPTR_NOT_REGISTERED;
  878. off = pPab->p_atu->InQueue; /* get addresss of message */
  879. if (0xFFFFFFFF == off)
  880. return RC_RTN_FREE_Q_EMPTY;
  881. pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
  882. /* setup private message */
  883. pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
  884. pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  885. pMsg[2] = 0; /* initiator context */
  886. pMsg[3] = 0x219; /* transaction context */
  887. pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_BROADCAST_MODE;
  888. pMsg[5] = Mode; /* promiscuous mode setting */
  889. pPab->p_atu->InQueue = off; /* send it to the device */
  890. return RC_RTN_NO_ERROR;
  891. }
  892. /*
  893. ** =========================================================================
  894. ** RCGetBroadcastMode()
  895. **
  896. ** get promiscuous mode setting
  897. **
  898. ** Possible return values placed in pMode:
  899. **  0 = promisuous mode not set
  900. **  1 = promisuous mode is set
  901. **
  902. ** =========================================================================
  903. */
  904. RC_RETURN
  905. RCGetBroadcastMode (struct net_device * dev, PU32 pMode,
  906.     PFNWAITCALLBACK WaitCallback)
  907. {
  908. U32 msgOffset;
  909. PU32 pMsg;
  910. volatile PU32 p32;
  911. PPAB pPab = ((PDPA) dev->priv)->pPab;
  912. msgOffset = pPab->p_atu->InQueue;
  913. if (msgOffset == 0xFFFFFFFF) {
  914. dprintk (KERN_WARNING
  915. "RCGetLinkSpeed(): Inbound Free Q empty!n");
  916. return RC_RTN_FREE_Q_EMPTY;
  917. }
  918. /* calc virtual address of msg - virtual already mapped to physical */
  919. pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
  920. /* virtual pointer to return buffer - clear first two dwords */
  921. p32 = (volatile PU32) pPab->pLinOutMsgBlock;
  922. p32[0] = 0xff;
  923. /* setup private message */
  924. pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
  925. pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  926. pMsg[2] = 0; /* initiator context */
  927. pMsg[3] = 0x219; /* transaction context */
  928. pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_BROADCAST_MODE;
  929. /* phys address to return status - area right after PAB */
  930. pMsg[5] = pPab->outMsgBlockPhyAddr;
  931. /* post to Inbound Post Q */
  932. pPab->p_atu->InQueue = msgOffset;
  933. /* wait for response */
  934. if (p32[0] == 0xff) {
  935. dprintk (KERN_WARNING
  936. "Timeout waiting for promiscuous moden");
  937. return RC_RTN_NO_LINK_SPEED;
  938. }
  939. /* get mode */
  940. *pMode = (U8) ((volatile PU8) p32)[0] & 0x0f;
  941. return RC_RTN_NO_ERROR;
  942. }
  943. /*
  944. ** =========================================================================
  945. ** RCGetLinkSpeed()
  946. **
  947. ** get ethernet link speed. 
  948. **
  949. ** 0 = Unknown
  950. ** 1 = Full Duplex 100BaseT
  951. ** 2 = Half duplex 100BaseT
  952. ** 3 = Full Duplex  10BaseT
  953. ** 4 = Half duplex  10BaseT
  954. **
  955. ** =========================================================================
  956. */
  957. RC_RETURN
  958. RCGetLinkSpeed (struct net_device * dev, PU32 pLinkSpeedCode,
  959. PFNWAITCALLBACK WaitCallback)
  960. {
  961. U32 msgOffset, i;
  962. PU32 pMsg;
  963. volatile PU32 p32;
  964. U8 IOPLinkSpeed;
  965. PPAB pPab = ((PDPA) dev->priv)->pPab;
  966. msgOffset = pPab->p_atu->InQueue;
  967. if (msgOffset == 0xFFFFFFFF) {
  968. dprintk (KERN_WARNING
  969. "RCGetLinkSpeed(): Inbound Free Q empty!n");
  970. return RC_RTN_FREE_Q_EMPTY;
  971. }
  972. /* calc virtual address of msg - virtual already mapped to physical */
  973. pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
  974. /* virtual pointer to return buffer - clear first two dwords */
  975. p32 = (volatile PU32) pPab->pLinOutMsgBlock;
  976. p32[0] = 0xff;
  977. /* setup private message */
  978. pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
  979. pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  980. pMsg[2] = 0; /* initiator context */
  981. pMsg[3] = 0x219; /* transaction context */
  982. pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_LINK_SPEED;
  983. /* phys address to return status - area right after PAB */
  984. pMsg[5] = pPab->outMsgBlockPhyAddr;
  985. /* post to Inbound Post Q */
  986. pPab->p_atu->InQueue = msgOffset;
  987. /* wait for response */
  988. i = 0;
  989. while (p32[0] == 0xff) {
  990. if (i++ > 0xff) {
  991. dprintk ("Timeout waiting for link speedn");
  992. return RC_RTN_NO_LINK_SPEED;
  993. }
  994. udelay(50);
  995. }
  996. /* get Link speed */
  997. IOPLinkSpeed = (U8) ((volatile PU8) p32)[0] & 0x0f;
  998. *pLinkSpeedCode = IOPLinkSpeed;
  999. return RC_RTN_NO_ERROR;
  1000. }
  1001. /*
  1002. ** =========================================================================
  1003. ** RCReportDriverCapability(struct net_device *dev, U32 capability)
  1004. **
  1005. ** Currently defined bits:
  1006. ** WARM_REBOOT_CAPABLE   0x01
  1007. **
  1008. ** =========================================================================
  1009. */
  1010. RC_RETURN
  1011. RCReportDriverCapability (struct net_device * dev, U32 capability)
  1012. {
  1013. U32 off;
  1014. PU32 pMsg;
  1015. PPAB pPab = ((PDPA) dev->priv)->pPab;
  1016. if (pPab == NULL)
  1017. return RC_RTN_ADPTR_NOT_REGISTERED;
  1018. off = pPab->p_atu->InQueue; /* get addresss of message */
  1019. if (0xFFFFFFFF == off)
  1020. return RC_RTN_FREE_Q_EMPTY;
  1021. pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
  1022. /* setup private message */
  1023. pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
  1024. pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  1025. pMsg[2] = 0; /* initiator context */
  1026. pMsg[3] = 0x219; /* transaction context */
  1027. pMsg[4] =
  1028.     RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_REPORT_DRIVER_CAPABILITY;
  1029. pMsg[5] = capability;
  1030. pPab->p_atu->InQueue = off; /* send it to the I2O device */
  1031. return RC_RTN_NO_ERROR;
  1032. }
  1033. /*
  1034. ** =========================================================================
  1035. ** RCGetFirmwareVer()
  1036. **
  1037. ** Return firmware version in the form "SoftwareVersion : Bt BootVersion"
  1038. **
  1039. ** =========================================================================
  1040. */
  1041. RC_RETURN
  1042. RCGetFirmwareVer (struct net_device * dev, PU8 pFirmString,
  1043.   PFNWAITCALLBACK WaitCallback)
  1044. {
  1045. U32 msgOffset, i;
  1046. PU32 pMsg;
  1047. volatile PU32 p32;
  1048. PPAB pPab = ((PDPA) dev->priv)->pPab;
  1049. msgOffset = pPab->p_atu->InQueue;
  1050. if (msgOffset == 0xFFFFFFFF) {
  1051. dprintk ("RCGetFirmwareVer(): Inbound Free Q empty!n");
  1052. return RC_RTN_FREE_Q_EMPTY;
  1053. }
  1054. /* calc virtual address of msg - virtual already mapped to physical */
  1055. pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
  1056. /* virtual pointer to return buffer - clear first two dwords */
  1057. p32 = (volatile PU32) pPab->pLinOutMsgBlock;
  1058. p32[0] = 0xff;
  1059. /* setup private message */
  1060. pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
  1061. pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  1062. pMsg[2] = 0; /* initiator context */
  1063. pMsg[3] = 0x219; /* transaction context */
  1064. pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_FIRMWARE_REV;
  1065. /* phys address to return status - area right after PAB */
  1066. pMsg[5] = pPab->outMsgBlockPhyAddr;
  1067. /* post to Inbound Post Q */
  1068. pPab->p_atu->InQueue = msgOffset;
  1069. /* wait for response */
  1070. i = 0;
  1071. while (p32[0] == 0xff) {
  1072. if (i++ > 0xff) {
  1073. dprintk ("Timeout waiting for link speedn");
  1074. return RC_RTN_NO_FIRM_VER;
  1075. }
  1076. udelay(50);
  1077. }
  1078. strcpy (pFirmString, (PU8) p32);
  1079. return RC_RTN_NO_ERROR;
  1080. }
  1081. /*
  1082. ** =========================================================================
  1083. ** RCResetLANCard()
  1084. **
  1085. ** ResourceFlags indicates whether to return buffer resource explicitly
  1086. ** to host or keep and reuse.
  1087. ** CallbackFunction (if not NULL) is the function to be called when 
  1088. ** reset is complete.
  1089. ** If CallbackFunction is NULL, ReturnAddr will have a 1 placed in it when
  1090. ** reset is done (if not NULL).
  1091. **
  1092. ** =========================================================================
  1093. */
  1094. RC_RETURN
  1095. RCResetLANCard (struct net_device * dev, U16 ResourceFlags, PU32 ReturnAddr,
  1096. PFNCALLBACK CallbackFunction)
  1097. {
  1098. unsigned long off;
  1099. PU32 pMsg;
  1100. PPAB pPab = ((PDPA) dev->priv)->pPab;
  1101. long timeout = 0;
  1102. if (pPab == NULL)
  1103. return RC_RTN_ADPTR_NOT_REGISTERED;
  1104. off = pPab->p_atu->InQueue; /* get addresss of message */
  1105. if (0xFFFFFFFF == off)
  1106. return RC_RTN_FREE_Q_EMPTY;
  1107. pPab->pCallbackFunc = CallbackFunction;
  1108. pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
  1109. /* setup message */
  1110. pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
  1111. pMsg[1] = I2O_LAN_RESET << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  1112. pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
  1113. pMsg[3] = ResourceFlags << 16; /* resource flags */
  1114. pPab->p_atu->InQueue = off; /* send it to the I2O device */
  1115. if (CallbackFunction == (PFNCALLBACK) NULL) {
  1116. /* call RCProcI2OMsgQ() until something in pPab->pCallbackFunc
  1117.    or until timer goes off */
  1118. while (pPab->pCallbackFunc == (PFNCALLBACK) NULL) {
  1119. RCProcI2OMsgQ (dev);
  1120. mdelay (1);
  1121. timeout++;
  1122. if (timeout > 200) {
  1123. break;
  1124. }
  1125. }
  1126. if (ReturnAddr != (PU32) NULL)
  1127. *ReturnAddr = (U32) pPab->pCallbackFunc;
  1128. }
  1129. return RC_RTN_NO_ERROR;
  1130. }
  1131. /*
  1132. ** =========================================================================
  1133. ** RCResetIOP()
  1134. **
  1135. ** Send StatusGet Msg, wait for results return directly to buffer.
  1136. **
  1137. ** =========================================================================
  1138. */
  1139. RC_RETURN
  1140. RCResetIOP (struct net_device * dev)
  1141. {
  1142. U32 msgOffset, i;
  1143. PU32 pMsg;
  1144. PPAB pPab = ((PDPA) dev->priv)->pPab;
  1145. volatile PU32 p32;
  1146. msgOffset = pPab->p_atu->InQueue;
  1147. if (msgOffset == 0xFFFFFFFF) {
  1148. return RC_RTN_FREE_Q_EMPTY;
  1149. }
  1150. /* calc virtual address of msg - virtual already mapped to physical */
  1151. pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
  1152. pMsg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_0;
  1153. pMsg[1] = I2O_EXEC_IOP_RESET << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
  1154. pMsg[2] = 0; /* universal context */
  1155. pMsg[3] = 0; /* universal context */
  1156. pMsg[4] = 0; /* universal context */
  1157. pMsg[5] = 0; /* universal context */
  1158. /* phys address to return status - area right after PAB */
  1159. pMsg[6] = pPab->outMsgBlockPhyAddr;
  1160. pMsg[7] = 0;
  1161. pMsg[8] = 1; /*  return 1 byte */
  1162. /* virtual pointer to return buffer - clear first two dwords */
  1163. p32 = (volatile PU32) pPab->pLinOutMsgBlock;
  1164. p32[0] = 0;
  1165. p32[1] = 0;
  1166. /* post to Inbound Post Q */
  1167. pPab->p_atu->InQueue = msgOffset;
  1168. /* wait for response */
  1169. i = 0;
  1170. while (!p32[0] && !p32[1]) {
  1171. if (i++ > 0xff) {
  1172. dprintk ("RCResetIOP timeoutn");
  1173. return RC_RTN_MSG_REPLY_TIMEOUT;
  1174. }
  1175. udelay(100);
  1176. }
  1177. return RC_RTN_NO_ERROR;
  1178. }
  1179. /*
  1180. ** =========================================================================
  1181. ** RCShutdownLANCard()
  1182. **
  1183. ** ResourceFlags indicates whether to return buffer resource explicitly
  1184. ** to host or keep and reuse.
  1185. ** CallbackFunction (if not NULL) is the function to be called when 
  1186. ** shutdown is complete.
  1187. ** If CallbackFunction is NULL, ReturnAddr will have a 1 placed in it when
  1188. ** shutdown is done (if not NULL).
  1189. **
  1190. ** =========================================================================
  1191. */
  1192. RC_RETURN
  1193. RCShutdownLANCard (struct net_device * dev, U16 ResourceFlags,
  1194.    PU32 ReturnAddr, PFNCALLBACK CallbackFunction)
  1195. {
  1196. volatile PU32 pMsg;
  1197. U32 off;
  1198. PPAB pPab = ((PDPA) dev->priv)->pPab;
  1199. long timeout = 0;
  1200. if (pPab == NULL)
  1201. return RC_RTN_ADPTR_NOT_REGISTERED;
  1202. off = pPab->p_atu->InQueue; /* get addresss of message */
  1203. if (0xFFFFFFFF == off)
  1204. return RC_RTN_FREE_Q_EMPTY;
  1205. pPab->pCallbackFunc = CallbackFunction;
  1206. pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
  1207. /* setup message */
  1208. pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
  1209. pMsg[1] =
  1210.     I2O_LAN_SHUTDOWN << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  1211. pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
  1212. pMsg[3] = ResourceFlags << 16; /* resource flags */
  1213. pPab->p_atu->InQueue = off; /* send it to the I2O device */
  1214. if (CallbackFunction == (PFNCALLBACK) NULL) {
  1215. /* call RCProcI2OMsgQ() until something in pPab->pCallbackFunc
  1216.    or until timer goes off */
  1217. while (pPab->pCallbackFunc == (PFNCALLBACK) NULL) {
  1218. RCProcI2OMsgQ (dev);
  1219. mdelay (1);
  1220. timeout++;
  1221. if (timeout > 200) {
  1222. dprintk (KERN_WARNING
  1223. "RCShutdownLANCard(): timeoutn");
  1224. break;
  1225. }
  1226. }
  1227. if (ReturnAddr != (PU32) NULL)
  1228. *ReturnAddr = (U32) pPab->pCallbackFunc;
  1229. }
  1230. return RC_RTN_NO_ERROR;
  1231. }
  1232. /*
  1233. ** =========================================================================
  1234. ** RCSetRavlinIPandMask()
  1235. **
  1236. ** Set the Ravlin 45/PCI cards IP address and network mask.
  1237. **
  1238. ** IP address and mask must be in network byte order.
  1239. ** For example, IP address 1.2.3.4 and mask 255.255.255.0 would be
  1240. ** 0x04030201 and 0x00FFFFFF on a little endian machine.
  1241. **
  1242. ** =========================================================================
  1243. */
  1244. RC_RETURN
  1245. RCSetRavlinIPandMask (struct net_device * dev, U32 ipAddr, U32 netMask)
  1246. {
  1247. volatile PU32 pMsg;
  1248. U32 off;
  1249. PPAB pPab = ((PDPA) dev->priv)->pPab;
  1250. if (pPab == NULL)
  1251. return RC_RTN_ADPTR_NOT_REGISTERED;
  1252. off = pPab->p_atu->InQueue; /* get addresss of message */
  1253. if (0xFFFFFFFF == off)
  1254. return RC_RTN_FREE_Q_EMPTY;
  1255. pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
  1256. /* setup private message */
  1257. pMsg[0] = SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0;
  1258. pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  1259. pMsg[2] = 0; /* initiator context */
  1260. pMsg[3] = 0x219; /* transaction context */
  1261. pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_IP_AND_MASK;
  1262. pMsg[5] = ipAddr;
  1263. pMsg[6] = netMask;
  1264. pPab->p_atu->InQueue = off; /* send it to the I2O device */
  1265. return RC_RTN_NO_ERROR;
  1266. }
  1267. /*
  1268. ** =========================================================================
  1269. ** RCGetRavlinIPandMask()
  1270. **
  1271. ** get the IP address and MASK from the card
  1272. ** 
  1273. ** =========================================================================
  1274. */
  1275. RC_RETURN
  1276. RCGetRavlinIPandMask (struct net_device * dev, PU32 pIpAddr, PU32 pNetMask,
  1277.       PFNWAITCALLBACK WaitCallback)
  1278. {
  1279. U32 off, i;
  1280. PU32 pMsg, p32;
  1281. PPAB pPab = ((PDPA) dev->priv)->pPab;
  1282. PATU p_atu;
  1283. dprintk
  1284.     ("RCGetRavlinIPandMask: pIpAddr is 0x%x, *IpAddr is 0x%xn",
  1285.      (u32) pIpAddr, *pIpAddr);
  1286. if (pPab == NULL)
  1287. return RC_RTN_ADPTR_NOT_REGISTERED;
  1288. p_atu = pPab->p_atu;
  1289. off = p_atu->InQueue; /* get addresss of message */
  1290. if (0xFFFFFFFF == off)
  1291. return RC_RTN_FREE_Q_EMPTY;
  1292. p32 = (volatile PU32) pPab->pLinOutMsgBlock;
  1293. *p32 = 0xFFFFFFFF;
  1294. pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
  1295. dprintk
  1296.     ("RCGetRavlinIPandMask: p_atu 0x%x, off 0x%x, p32 0x%xn",
  1297.      (u32) p_atu, off, (u32) p32);
  1298. /* setup private message */
  1299. pMsg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
  1300. pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
  1301. pMsg[2] = 0; /* initiator context */
  1302. pMsg[3] = 0x218; /* transaction context */
  1303. pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_IP_AND_MASK;
  1304. pMsg[5] = pPab->outMsgBlockPhyAddr;
  1305. p_atu->InQueue = off; /* send it to the I2O device */
  1306. dprintk
  1307.     ("RCGetRavlinIPandMask: p_atu 0x%x, off 0x%x, p32 0x%xn",
  1308.      (u32) p_atu, off, (u32) p32);
  1309. /* wait for the rcpci45 board to update the info */
  1310. i = 0;
  1311. while (0xffffffff == *p32) {
  1312. if (i++ > 0xff) {
  1313. dprintk ("RCGetRavlinIPandMask: Timeoutn");
  1314. return RC_RTN_MSG_REPLY_TIMEOUT;
  1315. }
  1316. udelay(50);
  1317. }
  1318. dprintk
  1319.     ("RCGetRavlinIPandMask: after time outnp32[0] (IpAddr) 0x%x, p32[1] (IPmask) 0x%xn",
  1320.      p32[0], p32[1]);
  1321. /* send IP and mask to user's space  */
  1322. *pIpAddr = p32[0];
  1323. *pNetMask = p32[1];
  1324. dprintk
  1325.     ("RCGetRavlinIPandMask: pIpAddr is 0x%x, *IpAddr is 0x%xn",
  1326.      (u32) pIpAddr, *pIpAddr);
  1327. return RC_RTN_NO_ERROR;
  1328. }
  1329. /* 
  1330. ** /////////////////////////////////////////////////////////////////////////
  1331. ** /////////////////////////////////////////////////////////////////////////
  1332. **
  1333. **                        local functions
  1334. **
  1335. ** /////////////////////////////////////////////////////////////////////////
  1336. ** /////////////////////////////////////////////////////////////////////////
  1337. */
  1338. /*
  1339. ** =========================================================================
  1340. ** SendI2OOutboundQInitMsg()
  1341. **
  1342. ** =========================================================================
  1343. */
  1344. static int
  1345. SendI2OOutboundQInitMsg (PPAB pPab)
  1346. {
  1347. U32 msgOffset, phyOutQFrames, i;
  1348. volatile PU32 pMsg;
  1349. volatile PU32 p32;
  1350. msgOffset = pPab->p_atu->InQueue;
  1351. if (msgOffset == 0xFFFFFFFF) {
  1352. dprintk ("SendI2OOutboundQInitMsg(): Inbound Free Q empty!n");
  1353. return RC_RTN_FREE_Q_EMPTY;
  1354. }
  1355. /* calc virtual address of msg - virtual already mapped to physical */
  1356. pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
  1357. dprintk
  1358.     ("SendI2OOutboundQInitMsg - pMsg = 0x%x, InQ msgOffset = 0x%xn",
  1359.      (u32) pMsg, msgOffset);
  1360. pMsg[0] = EIGHT_WORD_MSG_SIZE | TRL_OFFSET_6;
  1361. pMsg[1] =
  1362.     I2O_EXEC_OUTBOUND_INIT << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
  1363. pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
  1364. pMsg[3] = 0x106; /* transaction context */
  1365. pMsg[4] = 4096; /* Host page frame size */
  1366. pMsg[5] = MSG_FRAME_SIZE << 16 | 0x80; /* outbound msg frame size and Initcode */
  1367. pMsg[6] = 0xD0000004; /* simple sgl element LE, EOB */
  1368. /* phys address to return status - area right after PAB */
  1369. pMsg[7] = pPab->outMsgBlockPhyAddr;
  1370. /* virtual pointer to return buffer - clear first two dwords */
  1371. p32 = (PU32) pPab->pLinOutMsgBlock;
  1372. p32[0] = 0;
  1373. /* post to Inbound Post Q */
  1374. pPab->p_atu->InQueue = msgOffset;
  1375. /* wait for response */
  1376. i = 0;
  1377. while (!p32[0]) {
  1378. if (i++ > 0xff) {
  1379. printk("rc: InitOutQ timeoutn");
  1380. return RC_RTN_NO_I2O_STATUS;
  1381. }
  1382. udelay(50);
  1383. }
  1384. if (p32[0] != I2O_EXEC_OUTBOUND_INIT_COMPLETE) {
  1385. printk("rc: exec outbound init failed (%x)n",
  1386. p32[0]);
  1387. return RC_RTN_NO_I2O_STATUS;
  1388. }
  1389. /* load PCI outbound free Q with MF physical addresses */
  1390. phyOutQFrames = pPab->outMsgBlockPhyAddr;
  1391. for (i = 0; i < NMBR_MSG_FRAMES; i++) {
  1392. pPab->p_atu->OutQueue = phyOutQFrames;
  1393. phyOutQFrames += MSG_FRAME_SIZE;
  1394. }
  1395. return RC_RTN_NO_ERROR;
  1396. }
  1397. /*
  1398. ** =========================================================================
  1399. ** GetI2OStatus()
  1400. **
  1401. ** Send StatusGet Msg, wait for results return directly to buffer.
  1402. **
  1403. ** =========================================================================
  1404. */
  1405. static int
  1406. GetI2OStatus (PPAB pPab)
  1407. {
  1408. U32 msgOffset, i;
  1409. PU32 pMsg;
  1410. volatile PU32 p32;
  1411. msgOffset = pPab->p_atu->InQueue;
  1412. dprintk ("GetI2OStatus: msg offset = 0x%xn", msgOffset);
  1413. if (msgOffset == 0xFFFFFFFF) {
  1414. dprintk ("GetI2OStatus(): Inbound Free Q empty!n");
  1415. return RC_RTN_FREE_Q_EMPTY;
  1416. }
  1417. /* calc virtual address of msg - virtual already mapped to physical */
  1418. pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
  1419. pMsg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_0;
  1420. pMsg[1] = I2O_EXEC_STATUS_GET << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
  1421. pMsg[2] = 0; /* universal context */
  1422. pMsg[3] = 0; /* universal context */
  1423. pMsg[4] = 0; /* universal context */
  1424. pMsg[5] = 0; /* universal context */
  1425. /* phys address to return status - area right after PAB */
  1426. pMsg[6] = pPab->outMsgBlockPhyAddr;
  1427. pMsg[7] = 0;
  1428. pMsg[8] = 88; /*  return 88 bytes */
  1429. /* virtual pointer to return buffer - clear first two dwords */
  1430. p32 = (volatile PU32) pPab->pLinOutMsgBlock;
  1431. p32[0] = 0;
  1432. p32[1] = 0;
  1433. dprintk
  1434.     ("GetI2OStatus - pMsg:0x%x, msgOffset:0x%x, [1]:0x%x, [6]:0x%xn",
  1435.      (u32) pMsg, msgOffset, pMsg[1], pMsg[6]);
  1436. /* post to Inbound Post Q */
  1437. pPab->p_atu->InQueue = msgOffset;
  1438. dprintk ("Return status to p32 = 0x%xn", (u32) p32);
  1439. /* wait for response */
  1440. i = 0;
  1441. while (!p32[0] || !p32[1]) {
  1442. if (i++ > 0xff) {
  1443. dprintk ("Timeout waiting for status from IOPn");
  1444. return RC_RTN_NO_I2O_STATUS;
  1445. }
  1446. udelay(50);
  1447. }
  1448. dprintk ("0x%x:0x%x:0x%x:0x%xn", p32[0], p32[1],
  1449.  p32[2], p32[3]);
  1450. dprintk ("0x%x:0x%x:0x%x:0x%xn", p32[4], p32[5],
  1451.  p32[6], p32[7]);
  1452. dprintk ("0x%x:0x%x:0x%x:0x%xn", p32[8], p32[9],
  1453.  p32[10], p32[11]);
  1454. /* get IOP state */
  1455. pPab->IOPState = ((volatile PU8) p32)[10];
  1456. pPab->InboundMFrameSize = ((volatile PU16) p32)[6];
  1457. dprintk ("IOP state 0x%x InFrameSize = 0x%xn",
  1458.  pPab->IOPState, pPab->InboundMFrameSize);
  1459. return RC_RTN_NO_ERROR;
  1460. }
  1461. /*
  1462. ** =========================================================================
  1463. ** SendEnableSysMsg()
  1464. **
  1465. **
  1466. ** =========================================================================
  1467. */
  1468. static int
  1469. SendEnableSysMsg (PPAB pPab)
  1470. {
  1471. U32 msgOffset;
  1472. volatile PU32 pMsg;
  1473. msgOffset = pPab->p_atu->InQueue;
  1474. if (msgOffset == 0xFFFFFFFF) {
  1475. dprintk ("SendEnableSysMsg(): Inbound Free Q empty!n");
  1476. return RC_RTN_FREE_Q_EMPTY;
  1477. }
  1478. /* calc virtual address of msg - virtual already mapped to physical */
  1479. pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
  1480. dprintk
  1481.     ("SendEnableSysMsg - pMsg = 0x%x, InQ msgOffset = 0x%xn",
  1482.      (u32) pMsg, msgOffset);
  1483. pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
  1484. pMsg[1] = I2O_EXEC_SYS_ENABLE << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
  1485. pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
  1486. pMsg[3] = 0x110; /* transaction context */
  1487. pMsg[4] = 0x50657465; /*  RedCreek Private */
  1488. /* post to Inbound Post Q */
  1489. pPab->p_atu->InQueue = msgOffset;
  1490. return RC_RTN_NO_ERROR;
  1491. }
  1492. /*
  1493. ** =========================================================================
  1494. ** FillI2OMsgFromTCB()
  1495. **
  1496. ** inputs   pMsgU32 - virtual pointer (mapped to physical) of message frame
  1497. **          pXmitCntrlBlock - pointer to caller buffer control block.
  1498. **
  1499. ** fills in LAN SGL after Transaction Control Word or Bucket Count.
  1500. ** =========================================================================
  1501. */
  1502. static int
  1503. FillI2OMsgSGLFromTCB (PU32 pMsgFrame, PRCTCB pTransCtrlBlock)
  1504. {
  1505. unsigned int nmbrBuffers, nmbrSeg, nmbrDwords, context, flags;
  1506. PU32 pTCB, pMsg;
  1507. /* SGL element flags */
  1508. #define EOB        0x40000000
  1509. #define LE         0x80000000
  1510. #define SIMPLE_SGL 0x10000000
  1511. #define BC_PRESENT 0x01000000
  1512. pTCB = (PU32) pTransCtrlBlock;
  1513. pMsg = pMsgFrame;
  1514. nmbrDwords = 0;
  1515. dprintk ("FillI2OMsgSGLFromTCBXn");
  1516. dprintk ("TCB  0x%x:0x%x:0x%x:0x%x:0x%xn",
  1517.  pTCB[0], pTCB[1], pTCB[2], pTCB[3], pTCB[4]);
  1518. dprintk ("pTCB 0x%x, pMsg 0x%xn", (u32) pTCB, (u32) pMsg);
  1519. nmbrBuffers = *pTCB++;
  1520. if (!nmbrBuffers) {
  1521. return -1;
  1522. }
  1523. do {
  1524. context = *pTCB++; /* buffer tag (context) */
  1525. nmbrSeg = *pTCB++; /* number of segments */
  1526. if (!nmbrSeg) {
  1527. return -1;
  1528. }
  1529. flags = SIMPLE_SGL | BC_PRESENT;
  1530. if (1 == nmbrSeg) {
  1531. flags |= EOB;
  1532. if (1 == nmbrBuffers)
  1533. flags |= LE;
  1534. }
  1535. /* 1st SGL buffer element has context */
  1536. pMsg[0] = pTCB[0] | flags; /* send over count (segment size) */
  1537. pMsg[1] = context;
  1538. pMsg[2] = pTCB[1]; /* send buffer segment physical address */
  1539. nmbrDwords += 3;
  1540. pMsg += 3;
  1541. pTCB += 2;
  1542. if (--nmbrSeg) {
  1543. do {
  1544. flags = SIMPLE_SGL;
  1545. if (1 == nmbrSeg) {
  1546. flags |= EOB;
  1547. if (1 == nmbrBuffers)
  1548. flags |= LE;
  1549. }
  1550. pMsg[0] = pTCB[0] | flags; /* send over count */
  1551. pMsg[1] = pTCB[1]; /* send buffer segment physical address */
  1552. nmbrDwords += 2;
  1553. pTCB += 2;
  1554. pMsg += 2;
  1555. } while (--nmbrSeg);
  1556. }
  1557. } while (--nmbrBuffers);
  1558. return nmbrDwords;
  1559. }
  1560. /*
  1561. ** =========================================================================
  1562. ** ProcessOutboundI2OMsg()
  1563. **
  1564. ** process I2O reply message
  1565. ** * change to msg structure *
  1566. ** =========================================================================
  1567. */
  1568. static void
  1569. ProcessOutboundI2OMsg (PPAB pPab, U32 phyAddrMsg)
  1570. {
  1571. PU8 p8Msg;
  1572. PU32 p32;
  1573. /*      U16 count; */
  1574. p8Msg = pPab->pLinOutMsgBlock + (phyAddrMsg - pPab->outMsgBlockPhyAddr);
  1575. p32 = (PU32) p8Msg;
  1576. dprintk
  1577.     ("VXD: ProcessOutboundI2OMsg - pPab 0x%x, phyAdr 0x%x, linAdr 0x%xn",
  1578.      (u32) pPab, phyAddrMsg, (u32) p8Msg);
  1579. dprintk ("msg :0x%x:0x%x:0x%x:0x%xn", p32[0], p32[1],
  1580.  p32[2], p32[3]);
  1581. dprintk ("msg :0x%x:0x%x:0x%x:0x%xn", p32[4], p32[5],
  1582.  p32[6], p32[7]);
  1583. if (p32[4] >> 24 != I2O_REPLY_STATUS_SUCCESS) {
  1584. dprintk ("Message reply status not successn");
  1585. return;
  1586. }
  1587. switch (p8Msg[7]) { /* function code byte */
  1588. case I2O_EXEC_SYS_TAB_SET:
  1589. msgFlag = 1;
  1590. dprintk ("Received I2O_EXEC_SYS_TAB_SET replyn");
  1591. break;
  1592. case I2O_EXEC_HRT_GET:
  1593. msgFlag = 1;
  1594. dprintk ("Received I2O_EXEC_HRT_GET replyn");
  1595. break;
  1596. case I2O_EXEC_LCT_NOTIFY:
  1597. msgFlag = 1;
  1598. dprintk ("Received I2O_EXEC_LCT_NOTIFY replyn");
  1599. break;
  1600. case I2O_EXEC_SYS_ENABLE:
  1601. msgFlag = 1;
  1602. dprintk ("Received I2O_EXEC_SYS_ENABLE replyn");
  1603. break;
  1604. default:
  1605. dprintk ("Received UNKNOWN replyn");
  1606. break;
  1607. }
  1608. }