]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - net/nfs.c
freescale: pblimage: refactor CONFIG_SYS_FSL_PBL_{PBI, RCW}
[karo-tx-uboot.git] / net / nfs.c
index 54f56c4611cde41091465cc8fa37401912aa05b5..381b75f1c5b091799876aa77ec8997c97ea14fa9 100644 (file)
--- a/net/nfs.c
+++ b/net/nfs.c
 
 #define HASHES_PER_LINE 65     /* Number of "loading" hashes per line  */
 #define NFS_RETRY_COUNT 30
-#define NFS_TIMEOUT 2000UL
+#ifndef CONFIG_NFS_TIMEOUT
+# define NFS_TIMEOUT 2000UL
+#else
+# define NFS_TIMEOUT CONFIG_NFS_TIMEOUT
+#endif
+
+#define NFS_RPC_ERR    1
+#define NFS_RPC_DROP   124
 
 static int fs_mounted;
 static unsigned long rpc_id;
 static int nfs_offset = -1;
 static int nfs_len;
+static ulong nfs_timeout = NFS_TIMEOUT;
 
 static char dirfh[NFS_FHSIZE]; /* file handle of directory */
 static char filefh[NFS_FHSIZE]; /* file handle of kernel image */
 
-static int     NfsDownloadState;
+static enum net_loop_state nfs_download_state;
 static IPaddr_t NfsServerIP;
 static int     NfsSrvMountPort;
 static int     NfsSrvNfsPort;
@@ -189,7 +197,7 @@ rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen)
 
        pktlen = (char *)p + datalen*sizeof(uint32_t) - (char *)&pkt;
 
-       memcpy((char *)NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE,
+       memcpy((char *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE,
                (char *)&pkt, pktlen);
 
        if (rpc_prog == PROG_PORTMAP)
@@ -395,8 +403,10 @@ rpc_lookup_reply(int prog, uchar *pkt, unsigned len)
 
        debug("%s\n", __func__);
 
-       if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
-               return -1;
+       if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
+               return -NFS_RPC_ERR;
+       else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
+               return -NFS_RPC_DROP;
 
        if (rpc_pkt.u.reply.rstatus  ||
            rpc_pkt.u.reply.verifier ||
@@ -424,8 +434,10 @@ nfs_mount_reply(uchar *pkt, unsigned len)
 
        memcpy((unsigned char *)&rpc_pkt, pkt, len);
 
-       if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
-               return -1;
+       if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
+               return -NFS_RPC_ERR;
+       else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
+               return -NFS_RPC_DROP;
 
        if (rpc_pkt.u.reply.rstatus  ||
            rpc_pkt.u.reply.verifier ||
@@ -448,8 +460,10 @@ nfs_umountall_reply(uchar *pkt, unsigned len)
 
        memcpy((unsigned char *)&rpc_pkt, pkt, len);
 
-       if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
-               return -1;
+       if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
+               return -NFS_RPC_ERR;
+       else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
+               return -NFS_RPC_DROP;
 
        if (rpc_pkt.u.reply.rstatus  ||
            rpc_pkt.u.reply.verifier ||
@@ -471,8 +485,10 @@ nfs_lookup_reply(uchar *pkt, unsigned len)
 
        memcpy((unsigned char *)&rpc_pkt, pkt, len);
 
-       if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
-               return -1;
+       if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
+               return -NFS_RPC_ERR;
+       else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
+               return -NFS_RPC_DROP;
 
        if (rpc_pkt.u.reply.rstatus  ||
            rpc_pkt.u.reply.verifier ||
@@ -495,8 +511,10 @@ nfs_readlink_reply(uchar *pkt, unsigned len)
 
        memcpy((unsigned char *)&rpc_pkt, pkt, len);
 
-       if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
-               return -1;
+       if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
+               return -NFS_RPC_ERR;
+       else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
+               return -NFS_RPC_DROP;
 
        if (rpc_pkt.u.reply.rstatus  ||
            rpc_pkt.u.reply.verifier ||
@@ -530,8 +548,10 @@ nfs_read_reply(uchar *pkt, unsigned len)
 
        memcpy((uchar *)&rpc_pkt, pkt, sizeof(rpc_pkt.u.reply));
 
-       if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
-               return -1;
+       if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
+               return -NFS_RPC_ERR;
+       else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
+               return -NFS_RPC_DROP;
 
        if (rpc_pkt.u.reply.rstatus  ||
            rpc_pkt.u.reply.verifier ||
@@ -570,7 +590,8 @@ NfsTimeout(void)
                NetStartAgain();
        } else {
                puts("T ");
-               NetSetTimeout(NFS_TIMEOUT, NfsTimeout);
+               NetSetTimeout(nfs_timeout + NFS_TIMEOUT * NfsTimeoutCount,
+                             NfsTimeout);
                NfsSend();
        }
 }
@@ -579,6 +600,7 @@ static void
 NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
 {
        int rlen;
+       int reply;
 
        debug("%s\n", __func__);
 
@@ -587,19 +609,24 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
 
        switch (NfsState) {
        case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
-               rpc_lookup_reply(PROG_MOUNT, pkt, len);
+               if (rpc_lookup_reply(PROG_MOUNT, pkt, len) == -NFS_RPC_DROP)
+                       break;
                NfsState = STATE_PRCLOOKUP_PROG_NFS_REQ;
                NfsSend();
                break;
 
        case STATE_PRCLOOKUP_PROG_NFS_REQ:
-               rpc_lookup_reply(PROG_NFS, pkt, len);
+               if (rpc_lookup_reply(PROG_NFS, pkt, len) == -NFS_RPC_DROP)
+                       break;
                NfsState = STATE_MOUNT_REQ;
                NfsSend();
                break;
 
        case STATE_MOUNT_REQ:
-               if (nfs_mount_reply(pkt, len)) {
+               reply = nfs_mount_reply(pkt, len);
+               if (reply == -NFS_RPC_DROP)
+                       break;
+               else if (reply == -NFS_RPC_ERR) {
                        puts("*** ERROR: Cannot mount\n");
                        /* just to be sure... */
                        NfsState = STATE_UMOUNT_REQ;
@@ -611,17 +638,23 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
                break;
 
        case STATE_UMOUNT_REQ:
-               if (nfs_umountall_reply(pkt, len)) {
+               reply = nfs_umountall_reply(pkt, len);
+               if (reply == -NFS_RPC_DROP)
+                       break;
+               else if (reply == -NFS_RPC_ERR) {
                        puts("*** ERROR: Cannot umount\n");
-                       NetState = NETLOOP_FAIL;
+                       net_set_state(NETLOOP_FAIL);
                } else {
                        puts("\ndone\n");
-                       NetState = NfsDownloadState;
+                       net_set_state(nfs_download_state);
                }
                break;
 
        case STATE_LOOKUP_REQ:
-               if (nfs_lookup_reply(pkt, len)) {
+               reply = nfs_lookup_reply(pkt, len);
+               if (reply == -NFS_RPC_DROP)
+                       break;
+               else if (reply == -NFS_RPC_ERR) {
                        puts("*** ERROR: File lookup fail\n");
                        NfsState = STATE_UMOUNT_REQ;
                        NfsSend();
@@ -634,7 +667,10 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
                break;
 
        case STATE_READLINK_REQ:
-               if (nfs_readlink_reply(pkt, len)) {
+               reply = nfs_readlink_reply(pkt, len);
+               if (reply == -NFS_RPC_DROP)
+                       break;
+               else if (reply == -NFS_RPC_ERR) {
                        puts("*** ERROR: Symlink fail\n");
                        NfsState = STATE_UMOUNT_REQ;
                        NfsSend();
@@ -650,7 +686,7 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
 
        case STATE_READ_REQ:
                rlen = nfs_read_reply(pkt, len);
-               NetSetTimeout(NFS_TIMEOUT, NfsTimeout);
+               NetSetTimeout(nfs_timeout, NfsTimeout);
                if (rlen > 0) {
                        nfs_offset += rlen;
                        NfsSend();
@@ -660,7 +696,7 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
                        NfsSend();
                } else {
                        if (!rlen)
-                               NfsDownloadState = NETLOOP_SUCCESS;
+                               nfs_download_state = NETLOOP_SUCCESS;
                        NfsState = STATE_UMOUNT_REQ;
                        NfsSend();
                }
@@ -673,13 +709,13 @@ void
 NfsStart(void)
 {
        debug("%s\n", __func__);
-       NfsDownloadState = NETLOOP_FAIL;
+       nfs_download_state = NETLOOP_FAIL;
 
        NfsServerIP = NetServerIP;
        nfs_path = (char *)nfs_path_buff;
 
        if (nfs_path == NULL) {
-               NetState = NETLOOP_FAIL;
+               net_set_state(NETLOOP_FAIL);
                puts("*** ERROR: Fail allocate memory\n");
                return;
        }
@@ -734,8 +770,8 @@ NfsStart(void)
        printf("\nLoad address: 0x%lx\n"
                "Loading: *\b", load_addr);
 
-       NetSetTimeout(NFS_TIMEOUT, NfsTimeout);
-       NetSetHandler(NfsHandler);
+       NetSetTimeout(nfs_timeout, NfsTimeout);
+       net_set_udp_handler(NfsHandler);
 
        NfsTimeoutCount = 0;
        NfsState = STATE_PRCLOOKUP_PROG_MOUNT_REQ;