;;; -*- Mode:Lisp; Readtable:CL; Package:USER; Base:10; Patch-File:T -*-
;;; Patch file for System version 126.104
;;; Reason:
;;;  The 3COM ethernet hardware interface apparently can sometimes get a
;;;  single, amazingly bogus packet (via microcode); seems to occur when
;;;  other-slot processor is not booted, but is configured. Next packet
;;;  received is always good, when I've reproduced the problem.
;;;  
;;;  Unfortunately, this was causing an error in the cold load stream fro
;;;  SI:SET-FILL-POINTER. Fixed to record (as a new category of) error and
;;;  keep going (booting should proceed!).
;;; Written 13-Oct-88 20:31:59 by fileserver at site Gigamos Cambridge
;;; while running on Djinn from band 1
;;; with Experimental System 126.103, Experimental ZWEI 126.18, Experimental ZMail 74.9, Experimental Local-File 76.0, Experimental File-Server 25.0, Experimental Unix-Interface 14.0, Experimental Tape 25.1, Experimental Lambda-Diag 18.0, microcode 1762, SDU Boot Tape 3.14, SDU ROM 102.



; From modified file DJ: L.NETWORK.DRIVERS; 3COM.LISP#97 at 13-Oct-88 20:32:04
#10R ETHERNET#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "ETHERNET")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; DRIVERS; 3COM  "


(defstream 3com-interface
	   (network-interface)
	   "3COM-"
  (microcode-enabled nil)			  ; T if use lambda microcode
  (transmit-time-outs 0)
  (buffer-not-available 0)
  (jam-count 0)
  (fcs-errors 0)
  (hdr-errors 0)				  ;random bogus header errors
  )

))

; From modified file DJ: L.NETWORK.DRIVERS; 3COM.LISP#97 at 13-Oct-88 20:32:06
#10R ETHERNET#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "ETHERNET")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; DRIVERS; 3COM  "


(defop (3com-interface :peek-special-fields) (ni)
  (list (tv:scroll-parse-item
	  `(:mouse-item
	     (nil :buttons
		  ,(make-list 3 :initial-element
			      `(nil :eval (let ((enabled (3com-microcode-enabled ni)))
					    (funcall ni :disable)
					    (funcall ni :enable :microcode (not enabled)))
				    :bindings ((ni ',ni))))
		  :DOCUMENTATION
		  "Click to toggle usage of microcode"
		  :BINDINGS
		  ((ni ',ni)))
	     :function 3com-microcode-enabled (,ni) NIL ("Microcode enabled: ~A"))
	  `(:function 3com-transmit-time-outs (,ni) NIL (" time outs ~D"))
	  `(:function 3com-buffer-not-available (,ni) NIL (" no buffer ~D"))
	  `(:function 3com-jam-count (,ni) NIL (" jam count ~D"))
	  `(:function 3com-fcs-errors (,ni) NIL (" fcs error ~D"))
	  `(:function 3com-hdr-errors (,ni) NIL (" hdr error ~D")))))

))

; From modified file DJ: L.NETWORK.DRIVERS; 3COM.LISP#97 at 13-Oct-88 20:32:13
#10R ETHERNET#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "ETHERNET")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; DRIVERS; 3COM  "


(defun 3com-get-next-pkt-via-ucode (&aux int-pkt byte-count)
  (declare (values packet type source destination broadcast-p))
  (when (setq int-pkt (int-pkt-list-get net:int-receive-list-pointer))
    (setf (net:int-pkt-thread int-pkt) nil)
    (let* (;;The int-pkt-csr2 is a fixnum that has the buffer-header as the low 16 bits, and the first
	   ;;9 bits of the destination address above them.  The first address bit is the multicast bit.
	   (int-csr2 (net:int-pkt-csr-2 int-pkt))
	   (csr2 (swap-two-bytes int-csr2))
	   (type (swap-two-bytes (net:int-pkt-bit-count int-pkt)))
	   (multicast-p (ldb-test (byte 1 16) int-csr2)))
      (unless (zerop (logand %%3com-buffer-header-error csr2))
	(incf (3com-fcs-errors *3com-ethernet-interface*))
	(return-from 3com-get-next-pkt-via-ucode nil))
      (setf (net:int-pkt-csr-2 int-pkt) csr2)
      (setf (net:int-pkt-bit-count int-pkt) type)
      ;;Header: 2 bytes buffer header 14 bytes ethernet header.  Trailer: 4 bytes FCS
      (setq byte-count (- (ldb %%3com-buffer-header-nbytes csr2) 20.))
      (cond
	((not (plusp byte-count))
	 (incf (3com-hdr-errors *3com-ethernet-interface*))
	 (return-from 3com-get-next-pkt-via-ucode nil))
	(t
	 (setf (fill-pointer int-pkt) (ceiling byte-count 2))
	 (values int-pkt			  ; the packet
		 (net:int-pkt-bit-count int-pkt)  ; the type code
		 0				  ; the sender
		 0				  ; the receiver
		 multicast-p			  ; only multicast address we're enabled on is broadcast address
		 ))))))

))

; From modified file DJ: L.NETWORK.DRIVERS; 3COM.LISP#97 at 13-Oct-88 20:32:16
#10R ETHERNET#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "ETHERNET")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; DRIVERS; 3COM  "


(defun multibus-ethernet-receive-buffer (buffer-base &aux int-pkt)
  (declare (values packet type source destination broadcast-p))
  (let* ((buffer-header (read-3com-buffer-header buffer-base))
	 ;;Header: 2 bytes buffer header 14 bytes ethernet header.  Trailer: 4 bytes FCS
	 (nbytes (- (ldb %%3com-buffer-header-nbytes buffer-header) 20.))
	 (type (read-frame-header-type buffer-base))
	 (source (read-frame-header-source buffer-base))
	 (dest (read-frame-header-destination buffer-base)))
    (unless (zerop (logand %%3com-buffer-header-error buffer-header))
      (incf (3com-fcs-errors *3com-ethernet-interface*))
      (return-from multibus-ethernet-receive-buffer nil))
    (unless (plusp nbytes)
      (incf (3com-hdr-errors *3com-ethernet-interface*))
      (return-from multibus-ethernet-receive-buffer nil))
    (when (setq int-pkt (allocate-packet-for-receive *3com-ethernet-interface*))
      (do ((adr (the fixnum (+ buffer-base 16.))
		(the fixnum (+ adr 2)))
	   (nwords (ceiling nbytes 2))
	   (wd-count 0 (the fixnum (1+ wd-count))))
	  ((>= wd-count nwords))
	(declare (fixnum adr wd-count))
	(setf (aref int-pkt wd-count) (dpb (sys:%multibus-read-8 (the fixnum (+ adr 1)))
					   (byte 8 8)
					   (sys:%multibus-read-8 adr))))
      (setf (fill-pointer int-pkt) (ceiling nbytes 2))
      (values int-pkt
	      type
	      source
	      dest
	      ;;The following SHOULD work, but the 3com board is broken...
	      ;;   (ldb-test %%3com-buffer-header-broadcast buffer-header)
	      (= dest *ethernet-broadcast-address*)
	      ))))

))
