11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	(C)Copyright 1998,1999 SysKonnect,
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	See the file "skfddi.c" for further information.
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	This program is free software; you can redistribute it and/or modify
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	it under the terms of the GNU General Public License as published by
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	the Free Software Foundation; either version 2 of the License, or
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	(at your option) any later version.
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	The information in this file is provided "AS IS" without warranty.
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef	lint
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char const ID_sccs[] = "@(#)hwmtm.c	1.40 99/05/31 (C) SK" ;
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	HWMTM
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef FDDI
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	FDDI
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "h/types.h"
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "h/fddi.h"
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "h/smc.h"
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "h/supern_2.h"
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "h/skfbiinc.h"
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DOCUMENTATION
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	BEGIN_MANUAL_ENTRY(DOCUMENTATION)
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			T B D
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	END_MANUAL_ENTRY
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	LOCAL VARIABLES:
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef COMMON_MB_POOL
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic	SMbuf *mb_start = 0 ;
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic	SMbuf *mb_free = 0 ;
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic	int mb_init = FALSE ;
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic	int call_count = 0 ;
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	EXTERNE VARIABLES:
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	DEBUG
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef	DEBUG_BRD
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern	struct smt_debug	debug ;
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	NDIS_OS2
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern	u_char	offDepth ;
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern	u_char	force_irq_pending ;
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	LOCAL FUNCTIONS:
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void queue_llc_rx(struct s_smc *smc, SMbuf *mb);
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void smt_to_llc(struct s_smc *smc, SMbuf *mb);
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void init_txd_ring(struct s_smc *smc);
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void init_rxd_ring(struct s_smc *smc);
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void queue_txd_mb(struct s_smc *smc, SMbuf *mb);
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u_long init_descr_ring(struct s_smc *smc, union s_fp_descr volatile *start,
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			      int count);
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u_long repair_txd_ring(struct s_smc *smc, struct s_smt_tx_queue *queue);
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u_long repair_rxd_ring(struct s_smc *smc, struct s_smt_rx_queue *queue);
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic SMbuf* get_llc_rx(struct s_smc *smc);
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic SMbuf* get_txd_mb(struct s_smc *smc);
897aa55fcec236daed20dd362c99229184691d0e7fAdrian Bunkstatic void mac_drv_clear_txd(struct s_smc *smc);
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	EXTERNAL FUNCTIONS:
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*	The external SMT functions are listed in cmtdef.h */
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void* mac_drv_get_space(struct s_smc *smc, unsigned int size);
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void* mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size);
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void mac_drv_fill_rxd(struct s_smc *smc);
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void mac_drv_tx_complete(struct s_smc *smc,
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				volatile struct s_smt_fp_txd *txd);
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void mac_drv_rx_complete(struct s_smc *smc,
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				volatile struct s_smt_fp_rxd *rxd,
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				int frag_count, int len);
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void mac_drv_requeue_rxd(struct s_smc *smc,
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				volatile struct s_smt_fp_rxd *rxd,
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				int frag_count);
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void mac_drv_clear_rxd(struct s_smc *smc,
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			      volatile struct s_smt_fp_rxd *rxd, int frag_count);
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	USE_OS_CPY
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void hwm_cpy_rxd2mb(void);
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void hwm_cpy_txd2mb(void);
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	ALL_RX_COMPLETE
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void mac_drv_all_receives_complete(void);
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern u_long mac_drv_virt2phys(struct s_smc *smc, void *virt);
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern u_long dma_master(struct s_smc *smc, void *virt, int len, int flag);
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	NDIS_OS2
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void post_proc(void);
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void dma_complete(struct s_smc *smc, volatile union s_fp_descr *descr,
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 int flag);
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern int mac_drv_rx_init(struct s_smc *smc, int len, int fc, char *look_ahead,
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   int la_len);
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	PUBLIC FUNCTIONS:
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid process_receive(struct s_smc *smc);
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid fddi_isr(struct s_smc *smc);
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid smt_free_mbuf(struct s_smc *smc, SMbuf *mb);
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid init_driver_fplus(struct s_smc *smc);
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid mac_drv_rx_mode(struct s_smc *smc, int mode);
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid init_fddi_driver(struct s_smc *smc, u_char *mac_addr);
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid mac_drv_clear_tx_queue(struct s_smc *smc);
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid mac_drv_clear_rx_queue(struct s_smc *smc);
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid hwm_tx_frag(struct s_smc *smc, char far *virt, u_long phys, int len,
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 int frame_status);
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid hwm_rx_frag(struct s_smc *smc, char far *virt, u_long phys, int len,
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 int frame_status);
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint mac_drv_init(struct s_smc *smc);
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count, int frame_len,
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int frame_status);
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsu_int mac_drv_check_space(void);
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsSMbuf* smt_get_mbuf(struct s_smc *smc);
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef DEBUG
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	void mac_drv_debug_lev(void);
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	MACROS:
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef	UNUSED
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	lint
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define UNUSED(x)	(x) = (x)
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define UNUSED(x)
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	USE_CAN_ADDR
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MA		smc->hw.fddi_canon_addr.a
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	GROUP_ADDR_BIT	0x01
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	MA		smc->hw.fddi_home_addr.a
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	GROUP_ADDR_BIT	0x80
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RXD_TXD_COUNT	(HWM_ASYNC_TXD_COUNT+HWM_SYNC_TXD_COUNT+\
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			SMT_R1_RXD_COUNT+SMT_R2_RXD_COUNT)
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	MB_OUTSIDE_SMC
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	EXT_VIRT_MEM	((RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd) +\
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			MAX_MBUF*sizeof(SMbuf))
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	EXT_VIRT_MEM_2	((RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd))
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	EXT_VIRT_MEM	((RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd))
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * define critical read for 16 Bit drivers
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if	defined(NDIS_OS2) || defined(ODI2)
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CR_READ(var)	((var) & 0xffff0000 | ((var) & 0xffff))
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
2022f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro#define CR_READ(var)	(__le32)(var)
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IMASK_SLOW	(IS_PLINT1 | IS_PLINT2 | IS_TIMINT | IS_TOKEN | \
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 IS_MINTR1 | IS_MINTR2 | IS_MINTR3 | IS_R1_P | \
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 IS_R1_C | IS_XA_C | IS_XS_C)
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	INIT- AND SMT FUNCTIONS:
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	BEGIN_MANUAL_ENTRY(mac_drv_check_space)
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	u_int mac_drv_check_space()
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	function	DOWNCALL	(drvsr.c)
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			This function calculates the needed non virtual
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			memory for MBufs, RxD and TxD descriptors etc.
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			needed by the driver.
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	return		u_int	memory in bytes
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	END_MANUAL_ENTRY
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsu_int mac_drv_check_space(void)
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	MB_OUTSIDE_SMC
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	COMMON_MB_POOL
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	call_count++ ;
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (call_count == 1) {
235807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet		return EXT_VIRT_MEM;
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else {
238807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet		return EXT_VIRT_MEM_2;
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
241807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return EXT_VIRT_MEM;
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
244807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return 0;
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	BEGIN_MANUAL_ENTRY(mac_drv_init)
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	void mac_drv_init(smc)
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	function	DOWNCALL	(drvsr.c)
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			In this function the hardware module allocates it's
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			memory.
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			The operating system dependent module should call
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			mac_drv_init once, after the adatper is detected.
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	END_MANUAL_ENTRY
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint mac_drv_init(struct s_smc *smc)
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (sizeof(struct s_smt_fp_rxd) % 16) {
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SMT_PANIC(smc,HWM_E0001,HWM_E0001_MSG) ;
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (sizeof(struct s_smt_fp_txd) % 16) {
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SMT_PANIC(smc,HWM_E0002,HWM_E0002_MSG) ;
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * get the required memory for the RxDs and TxDs
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!(smc->os.hwm.descr_p = (union s_fp_descr volatile *)
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mac_drv_get_desc_mem(smc,(u_int)
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		(RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd)))) {
274807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet		return 1;	/* no space the hwm modul can't work */
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * get the memory for the SMT MBufs
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef	MB_OUTSIDE_SMC
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.mbuf_pool.mb_start=(SMbuf *)(&smc->os.hwm.mbuf_pool.mb[0]) ;
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef	COMMON_MB_POOL
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!(smc->os.hwm.mbuf_pool.mb_start = (SMbuf *) mac_drv_get_space(smc,
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		MAX_MBUF*sizeof(SMbuf)))) {
286807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet		return 1;	/* no space the hwm modul can't work */
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!mb_start) {
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!(mb_start = (SMbuf *) mac_drv_get_space(smc,
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			MAX_MBUF*sizeof(SMbuf)))) {
292807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet			return 1;	/* no space the hwm modul can't work */
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
297807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return 0;
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	BEGIN_MANUAL_ENTRY(init_driver_fplus)
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	init_driver_fplus(smc)
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Sets hardware modul specific values for the mode register 2
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (e.g. the byte alignment for the received frames, the position of the
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	 least significant byte etc.)
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	END_MANUAL_ENTRY
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid init_driver_fplus(struct s_smc *smc)
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->hw.fp.mdr2init = FM_LSB | FM_BMMODE | FM_ENNPRQ | FM_ENHSRQ | 3 ;
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	PCI
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->hw.fp.mdr2init |= FM_CHKPAR | FM_PARITY ;
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->hw.fp.mdr3init = FM_MENRQAUNLCK | FM_MENRS ;
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	USE_CAN_ADDR
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* enable address bit swapping */
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->hw.fp.frselreg_init = FM_ENXMTADSWAP | FM_ENRCVADSWAP ;
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u_long init_descr_ring(struct s_smc *smc,
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			      union s_fp_descr volatile *start,
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			      int count)
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i ;
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	union s_fp_descr volatile *d1 ;
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	union s_fp_descr volatile *d2 ;
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long	phys ;
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_GEN("descr ring starts at = %x ",(void *)start,0,3) ;
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i=count-1, d1=start; i ; i--) {
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		d2 = d1 ;
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		d1++ ;		/* descr is owned by the host */
3372f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro		d2->r.rxd_rbctrl = cpu_to_le32(BMU_CHECK) ;
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		d2->r.rxd_next = &d1->r ;
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		phys = mac_drv_virt2phys(smc,(void *)d1) ;
3402f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro		d2->r.rxd_nrdadr = cpu_to_le32(phys) ;
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_GEN("descr ring ends at = %x ",(void *)d1,0,3) ;
3432f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro	d1->r.rxd_rbctrl = cpu_to_le32(BMU_CHECK) ;
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	d1->r.rxd_next = &start->r ;
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	phys = mac_drv_virt2phys(smc,(void *)start) ;
3462f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro	d1->r.rxd_nrdadr = cpu_to_le32(phys) ;
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i=count, d1=start; i ; i--) {
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRV_BUF_FLUSH(&d1->r,DDI_DMA_SYNC_FORDEV) ;
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		d1++;
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
352807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return phys;
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void init_txd_ring(struct s_smc *smc)
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_fp_txd volatile *ds ;
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_tx_queue *queue ;
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long	phys ;
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * initialize the transmit descriptors
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ds = (struct s_smt_fp_txd volatile *) ((char *)smc->os.hwm.descr_p +
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SMT_R1_RXD_COUNT*sizeof(struct s_smt_fp_rxd)) ;
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue = smc->hw.fp.tx[QUEUE_A0] ;
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_GEN("Init async TxD ring, %d TxDs ",HWM_ASYNC_TXD_COUNT,0,3) ;
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	(void)init_descr_ring(smc,(union s_fp_descr volatile *)ds,
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		HWM_ASYNC_TXD_COUNT) ;
3702f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro	phys = le32_to_cpu(ds->txd_ntdadr) ;
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ds++ ;
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue->tx_curr_put = queue->tx_curr_get = ds ;
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ds-- ;
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue->tx_free = HWM_ASYNC_TXD_COUNT ;
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue->tx_used = 0 ;
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	outpd(ADDR(B5_XA_DA),phys) ;
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ds = (struct s_smt_fp_txd volatile *) ((char *)ds +
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		HWM_ASYNC_TXD_COUNT*sizeof(struct s_smt_fp_txd)) ;
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue = smc->hw.fp.tx[QUEUE_S] ;
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_GEN("Init sync TxD ring, %d TxDs ",HWM_SYNC_TXD_COUNT,0,3) ;
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	(void)init_descr_ring(smc,(union s_fp_descr volatile *)ds,
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		HWM_SYNC_TXD_COUNT) ;
3842f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro	phys = le32_to_cpu(ds->txd_ntdadr) ;
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ds++ ;
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue->tx_curr_put = queue->tx_curr_get = ds ;
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue->tx_free = HWM_SYNC_TXD_COUNT ;
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue->tx_used = 0 ;
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	outpd(ADDR(B5_XS_DA),phys) ;
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void init_rxd_ring(struct s_smc *smc)
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_fp_rxd volatile *ds ;
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_rx_queue *queue ;
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long	phys ;
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * initialize the receive descriptors
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ds = (struct s_smt_fp_rxd volatile *) smc->os.hwm.descr_p ;
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue = smc->hw.fp.rx[QUEUE_R1] ;
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_GEN("Init RxD ring, %d RxDs ",SMT_R1_RXD_COUNT,0,3) ;
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	(void)init_descr_ring(smc,(union s_fp_descr volatile *)ds,
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SMT_R1_RXD_COUNT) ;
4062f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro	phys = le32_to_cpu(ds->rxd_nrdadr) ;
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ds++ ;
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue->rx_curr_put = queue->rx_curr_get = ds ;
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue->rx_free = SMT_R1_RXD_COUNT ;
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue->rx_used = 0 ;
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	outpd(ADDR(B4_R1_DA),phys) ;
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	BEGIN_MANUAL_ENTRY(init_fddi_driver)
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	void init_fddi_driver(smc,mac_addr)
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * initializes the driver and it's variables
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	END_MANUAL_ENTRY
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid init_fddi_driver(struct s_smc *smc, u_char *mac_addr)
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	SMbuf	*mb ;
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int	i ;
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	init_board(smc,mac_addr) ;
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	(void)init_fplus(smc) ;
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * initialize the SMbufs for the SMT
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef	COMMON_MB_POOL
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mb = smc->os.hwm.mbuf_pool.mb_start ;
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.mbuf_pool.mb_free = (SMbuf *)NULL ;
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < MAX_MBUF; i++) {
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mb->sm_use_count = 1 ;
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smt_free_mbuf(smc,mb)	;
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mb++ ;
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mb = mb_start ;
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!mb_init) {
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mb_free = 0 ;
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (i = 0; i < MAX_MBUF; i++) {
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mb->sm_use_count = 1 ;
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			smt_free_mbuf(smc,mb)	;
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mb++ ;
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mb_init = TRUE ;
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * initialize the other variables
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.llc_rx_pipe = smc->os.hwm.llc_rx_tail = (SMbuf *)NULL ;
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.txd_tx_pipe = smc->os.hwm.txd_tx_tail = NULL ;
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.pass_SMT = smc->os.hwm.pass_NSA = smc->os.hwm.pass_DB = 0 ;
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.pass_llc_promisc = TRUE ;
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.queued_rx_frames = smc->os.hwm.queued_txd_mb = 0 ;
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.detec_count = 0 ;
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.rx_break = 0 ;
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.rx_len_error = 0 ;
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.isr_flag = FALSE ;
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * make sure that the start pointer is 16 byte aligned
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	i = 16 - ((long)smc->os.hwm.descr_p & 0xf) ;
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (i != 16) {
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_GEN("i = %d",i,0,3) ;
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.descr_p = (union s_fp_descr volatile *)
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			((char *)smc->os.hwm.descr_p+i) ;
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_GEN("pt to descr area = %x",(void *)smc->os.hwm.descr_p,0,3) ;
4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	init_txd_ring(smc) ;
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	init_rxd_ring(smc) ;
4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mac_drv_fill_rxd(smc) ;
4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	init_plc(smc) ;
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsSMbuf *smt_get_mbuf(struct s_smc *smc)
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	register SMbuf	*mb ;
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef	COMMON_MB_POOL
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mb = smc->os.hwm.mbuf_pool.mb_free ;
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mb = mb_free ;
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (mb) {
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef	COMMON_MB_POOL
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.mbuf_pool.mb_free = mb->sm_next ;
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mb_free = mb->sm_next ;
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mb->sm_off = 8 ;
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mb->sm_use_count = 1 ;
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_GEN("get SMbuf: mb = %x",(void *)mb,0,3) ;
505807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return mb;	/* May be NULL */
5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid smt_free_mbuf(struct s_smc *smc, SMbuf *mb)
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (mb) {
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mb->sm_use_count-- ;
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_GEN("free_mbuf: sm_use_count = %d",mb->sm_use_count,0,3) ;
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * If the use_count is != zero the MBuf is queued
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * more than once and must not queued into the
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * free MBuf queue
5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!mb->sm_use_count) {
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_GEN("free SMbuf: mb = %x",(void *)mb,0,3) ;
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef	COMMON_MB_POOL
5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mb->sm_next = smc->os.hwm.mbuf_pool.mb_free ;
5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			smc->os.hwm.mbuf_pool.mb_free = mb ;
5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mb->sm_next = mb_free ;
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mb_free = mb ;
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SMT_PANIC(smc,HWM_E0003,HWM_E0003_MSG) ;
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	BEGIN_MANUAL_ENTRY(mac_drv_repair_descr)
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	void mac_drv_repair_descr(smc)
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * function	called from SMT	(HWM / hwmtm.c)
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		The BMU is idle when this function is called.
5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		Mac_drv_repair_descr sets up the physical address
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		for all receive and transmit queues where the BMU
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		should continue.
5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		It may be that the BMU was reseted during a fragmented
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		transfer. In this case there are some fragments which will
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		never completed by the BMU. The OWN bit of this fragments
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		must be switched to be owned by the host.
5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		Give a start command to the receive BMU.
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		Start the transmit BMUs if transmit frames pending.
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	END_MANUAL_ENTRY
5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid mac_drv_repair_descr(struct s_smc *smc)
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long	phys ;
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (smc->hw.hw_state != STOPPED) {
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SK_BREAK() ;
5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SMT_PANIC(smc,HWM_E0013,HWM_E0013_MSG) ;
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ;
5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * repair tx queues: don't start
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	phys = repair_txd_ring(smc,smc->hw.fp.tx[QUEUE_A0]) ;
5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	outpd(ADDR(B5_XA_DA),phys) ;
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (smc->hw.fp.tx_q[QUEUE_A0].tx_used) {
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		outpd(ADDR(B0_XA_CSR),CSR_START) ;
5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	phys = repair_txd_ring(smc,smc->hw.fp.tx[QUEUE_S]) ;
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	outpd(ADDR(B5_XS_DA),phys) ;
5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (smc->hw.fp.tx_q[QUEUE_S].tx_used) {
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		outpd(ADDR(B0_XS_CSR),CSR_START) ;
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * repair rx queues
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	phys = repair_rxd_ring(smc,smc->hw.fp.rx[QUEUE_R1]) ;
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	outpd(ADDR(B4_R1_DA),phys) ;
5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	outpd(ADDR(B0_R1_CSR),CSR_START) ;
5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u_long repair_txd_ring(struct s_smc *smc, struct s_smt_tx_queue *queue)
5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i ;
5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int tx_used ;
5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long phys ;
5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long tbctrl ;
5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_fp_txd volatile *t ;
5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	SK_UNUSED(smc) ;
5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	t = queue->tx_curr_get ;
5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tx_used = queue->tx_used ;
5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = tx_used+queue->tx_free-1 ; i ; i-- ) {
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		t = t->txd_next ;
6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6012f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro	phys = le32_to_cpu(t->txd_ntdadr) ;
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	t = queue->tx_curr_get ;
6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (tx_used) {
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORCPU) ;
6062f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro		tbctrl = le32_to_cpu(t->txd_tbctrl) ;
6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (tbctrl & BMU_OWN) {
6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (tbctrl & BMU_STF) {
6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break ;		/* exit the loop */
6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else {
6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/*
6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * repair the descriptor
6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 */
6162f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro				t->txd_tbctrl &= ~cpu_to_le32(BMU_OWN) ;
6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
6192f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro		phys = le32_to_cpu(t->txd_ntdadr) ;
6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		t = t->txd_next ;
6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		tx_used-- ;
6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
624807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return phys;
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Repairs the receive descriptor ring and returns the physical address
6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * where the BMU should continue working.
6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	o The physical address where the BMU was stopped has to be
6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	  determined. This is the next RxD after rx_curr_get with an OWN
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	  bit set.
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	o The BMU should start working at beginning of the next frame.
6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	  RxDs with an OWN bit set but with a reset STF bit should be
6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	  skipped and owned by the driver (OWN = 0).
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u_long repair_rxd_ring(struct s_smc *smc, struct s_smt_rx_queue *queue)
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i ;
6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int rx_used ;
6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long phys ;
6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long rbctrl ;
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_fp_rxd volatile *r ;
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	SK_UNUSED(smc) ;
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	r = queue->rx_curr_get ;
6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	rx_used = queue->rx_used ;
6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = SMT_R1_RXD_COUNT-1 ; i ; i-- ) {
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		r = r->rxd_next ;
6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6532f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro	phys = le32_to_cpu(r->rxd_nrdadr) ;
6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	r = queue->rx_curr_get ;
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (rx_used) {
6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
6582f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro		rbctrl = le32_to_cpu(r->rxd_rbctrl) ;
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (rbctrl & BMU_OWN) {
6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (rbctrl & BMU_STF) {
6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break ;		/* exit the loop */
6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else {
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/*
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * repair the descriptor
6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 */
6682f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro				r->rxd_rbctrl &= ~cpu_to_le32(BMU_OWN) ;
6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
6712f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro		phys = le32_to_cpu(r->rxd_nrdadr) ;
6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ;
6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		r = r->rxd_next ;
6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		rx_used-- ;
6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
676807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return phys;
6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	INTERRUPT SERVICE ROUTINE:
6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	BEGIN_MANUAL_ENTRY(fddi_isr)
6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	void fddi_isr(smc)
6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * function	DOWNCALL	(drvsr.c)
6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		interrupt service routine, handles the interrupt requests
6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		generated by the FDDI adapter.
6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
69425985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * NOTE:	The operating system dependent module must guarantee that the
6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		interrupts of the adapter are disabled when it calls fddi_isr.
6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	About the USE_BREAK_ISR mechanismn:
6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	The main requirement of this mechanismn is to force an timer IRQ when
7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	leaving process_receive() with leave_isr set. process_receive() may
7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	be called at any time from anywhere!
7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	To be sure we don't miss such event we set 'force_irq' per default.
7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	We have to force and Timer IRQ if 'smc->os.hwm.leave_isr' AND
7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	'force_irq' are set. 'force_irq' may be reset if a receive complete
7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	IRQ is pending.
7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	END_MANUAL_ENTRY
7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid fddi_isr(struct s_smc *smc)
7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long		is ;		/* ISR source */
7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_short		stu, stl ;
7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	SMbuf		*mb ;
7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	USE_BREAK_ISR
7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int	force_irq ;
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	ODI2
7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (smc->os.hwm.rx_break) {
7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mac_drv_fill_rxd(smc) ;
7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (smc->hw.fp.rx_q[QUEUE_R1].rx_used > 0) {
7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			smc->os.hwm.rx_break = 0 ;
7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			process_receive(smc) ;
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else {
7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			smc->os.hwm.detec_count = 0 ;
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			smt_force_irq(smc) ;
7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.isr_flag = TRUE ;
7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	USE_BREAK_ISR
7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	force_irq = TRUE ;
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (smc->os.hwm.leave_isr) {
7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.leave_isr = FALSE ;
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		process_receive(smc) ;
7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while ((is = GET_ISR() & ISR_MASK)) {
7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		NDD_TRACE("CH0B",is,0,0) ;
7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_GEN("ISA = 0x%x",is,0,7) ;
7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (is & IMASK_SLOW) {
7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			NDD_TRACE("CH1b",is,0,0) ;
7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (is & IS_PLINT1) {	/* PLC1 */
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				plc1_irq(smc) ;
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (is & IS_PLINT2) {	/* PLC2 */
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				plc2_irq(smc) ;
7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (is & IS_MINTR1) {	/* FORMAC+ STU1(U/L) */
7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				stu = inpw(FM_A(FM_ST1U)) ;
7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				stl = inpw(FM_A(FM_ST1L)) ;
7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_GEN("Slow transmit complete",0,0,6) ;
7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				mac1_irq(smc,stu,stl) ;
7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (is & IS_MINTR2) {	/* FORMAC+ STU2(U/L) */
7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				stu= inpw(FM_A(FM_ST2U)) ;
7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				stl= inpw(FM_A(FM_ST2L)) ;
7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_GEN("Slow receive complete",0,0,6) ;
7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_GEN("stl = %x : stu = %x",stl,stu,7) ;
7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				mac2_irq(smc,stu,stl) ;
7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (is & IS_MINTR3) {	/* FORMAC+ STU3(U/L) */
7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				stu= inpw(FM_A(FM_ST3U)) ;
7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				stl= inpw(FM_A(FM_ST3L)) ;
7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_GEN("FORMAC Mode Register 3",0,0,6) ;
7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				mac3_irq(smc,stu,stl) ;
7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (is & IS_TIMINT) {	/* Timer 82C54-2 */
7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				timer_irq(smc) ;
7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	NDIS_OS2
7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				force_irq_pending = 0 ;
7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/*
7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * out of RxD detection
7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 */
7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (++smc->os.hwm.detec_count > 4) {
7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					/*
7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					 * check out of RxD condition
7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					 */
7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					 process_receive(smc) ;
7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (is & IS_TOKEN) {	/* Restricted Token Monitor */
7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				rtm_irq(smc) ;
7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (is & IS_R1_P) {	/* Parity error rx queue 1 */
7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* clear IRQ */
7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_P) ;
7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				SMT_PANIC(smc,HWM_E0004,HWM_E0004_MSG) ;
7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (is & IS_R1_C) {	/* Encoding error rx queue 1 */
7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* clear IRQ */
7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_C) ;
7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				SMT_PANIC(smc,HWM_E0005,HWM_E0005_MSG) ;
8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (is & IS_XA_C) {	/* Encoding error async tx q */
8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* clear IRQ */
8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				outpd(ADDR(B5_XA_CSR),CSR_IRQ_CL_C) ;
8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				SMT_PANIC(smc,HWM_E0006,HWM_E0006_MSG) ;
8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (is & IS_XS_C) {	/* Encoding error sync tx q */
8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* clear IRQ */
8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				outpd(ADDR(B5_XS_CSR),CSR_IRQ_CL_C) ;
8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				SMT_PANIC(smc,HWM_E0007,HWM_E0007_MSG) ;
8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 *	Fast Tx complete Async/Sync Queue (BMU service)
8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (is & (IS_XS_F|IS_XA_F)) {
8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_GEN("Fast tx complete queue",0,0,6) ;
8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * clear IRQ, Note: no IRQ is lost, because
8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * 	we always service both queues
8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			outpd(ADDR(B5_XS_CSR),CSR_IRQ_CL_F) ;
8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			outpd(ADDR(B5_XA_CSR),CSR_IRQ_CL_F) ;
8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mac_drv_clear_txd(smc) ;
8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			llc_restart_tx(smc) ;
8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 *	Fast Rx Complete (BMU service)
8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (is & IS_R1_F) {
8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_GEN("Fast receive complete",0,0,6) ;
8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* clear IRQ */
8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef USE_BREAK_ISR
8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_F) ;
8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			process_receive(smc) ;
8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			process_receive(smc) ;
8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (smc->os.hwm.leave_isr) {
8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				force_irq = FALSE ;
8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			} else {
8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_F) ;
8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				process_receive(smc) ;
8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef	NDIS_OS2
8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while ((mb = get_llc_rx(smc))) {
8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			smt_to_llc(smc,mb) ;
8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (offDepth)
8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			post_proc() ;
8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (!offDepth && (mb = get_llc_rx(smc))) {
8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			smt_to_llc(smc,mb) ;
8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!offDepth && smc->os.hwm.rx_break) {
8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			process_receive(smc) ;
8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (smc->q.ev_get != smc->q.ev_put) {
8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			NDD_TRACE("CH2a",0,0,0) ;
8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ev_dispatcher(smc) ;
8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	NDIS_OS2
8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		post_proc() ;
8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (offDepth) {		/* leave fddi_isr because */
8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break ;		/* indications not allowed */
8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	USE_BREAK_ISR
8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (smc->os.hwm.leave_isr) {
8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break ;		/* leave fddi_isr */
8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* NOTE: when the isr is left, no rx is pending */
8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}	/* end of interrupt source polling loop */
8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	USE_BREAK_ISR
8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (smc->os.hwm.leave_isr && force_irq) {
8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smt_force_irq(smc) ;
8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.isr_flag = FALSE ;
8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	NDD_TRACE("CH0E",0,0,0) ;
8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	RECEIVE FUNCTIONS:
8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef	NDIS_OS2
9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	BEGIN_MANUAL_ENTRY(mac_drv_rx_mode)
9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	void mac_drv_rx_mode(smc,mode)
9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * function	DOWNCALL	(fplus.c)
9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		Corresponding to the parameter mode, the operating system
9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		dependent module can activate several receive modes.
9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * para	mode	= 1:	RX_ENABLE_ALLMULTI	enable all multicasts
9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		= 2:	RX_DISABLE_ALLMULTI	disable "enable all multicasts"
9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		= 3:	RX_ENABLE_PROMISC	enable promiscuous
9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		= 4:	RX_DISABLE_PROMISC	disable promiscuous
9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		= 5:	RX_ENABLE_NSA		enable rec. of all NSA frames
9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			(disabled after 'driver reset' & 'set station address')
9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		= 6:	RX_DISABLE_NSA		disable rec. of all NSA frames
9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		= 21:	RX_ENABLE_PASS_SMT	( see description )
9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		= 22:	RX_DISABLE_PASS_SMT	(  "	   "	  )
9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		= 23:	RX_ENABLE_PASS_NSA	(  "	   "	  )
9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		= 24:	RX_DISABLE_PASS_NSA	(  "	   "	  )
9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		= 25:	RX_ENABLE_PASS_DB	(  "	   "	  )
9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		= 26:	RX_DISABLE_PASS_DB	(  "	   "	  )
9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		= 27:	RX_DISABLE_PASS_ALL	(  "	   "	  )
9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		= 28:	RX_DISABLE_LLC_PROMISC	(  "	   "	  )
9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		= 29:	RX_ENABLE_LLC_PROMISC	(  "	   "	  )
9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		RX_ENABLE_PASS_SMT / RX_DISABLE_PASS_SMT
9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		If the operating system dependent module activates the
9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		mode RX_ENABLE_PASS_SMT, the hardware module
9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		duplicates all SMT frames with the frame control
9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		FC_SMT_INFO and passes them to the LLC receive channel
9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		by calling mac_drv_rx_init.
9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		The SMT Frames which are sent by the local SMT and the NSA
9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		frames whose A- and C-Indicator is not set are also duplicated
9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		and passed.
9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		The receive mode RX_DISABLE_PASS_SMT disables the passing
9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		of SMT frames.
9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		RX_ENABLE_PASS_NSA / RX_DISABLE_PASS_NSA
9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		If the operating system dependent module activates the
9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		mode RX_ENABLE_PASS_NSA, the hardware module
9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		duplicates all NSA frames with frame control FC_SMT_NSA
9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		and a set A-Indicator and passed them to the LLC
9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		receive channel by calling mac_drv_rx_init.
9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		All NSA Frames which are sent by the local SMT
9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		are also duplicated and passed.
9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		The receive mode RX_DISABLE_PASS_NSA disables the passing
9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		of NSA frames with the A- or C-Indicator set.
9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE:	For fear that the hardware module receives NSA frames with
9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		a reset A-Indicator, the operating system dependent module
9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		has to call mac_drv_rx_mode with the mode RX_ENABLE_NSA
9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		before activate the RX_ENABLE_PASS_NSA mode and after every
9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		'driver reset' and 'set station address'.
9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		RX_ENABLE_PASS_DB / RX_DISABLE_PASS_DB
9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		If the operating system dependent module activates the
9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		mode RX_ENABLE_PASS_DB, direct BEACON frames
9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		(FC_BEACON frame control) are passed to the LLC receive
9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		channel by mac_drv_rx_init.
9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		The receive mode RX_DISABLE_PASS_DB disables the passing
9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		of direct BEACON frames.
9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		RX_DISABLE_PASS_ALL
9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		Disables all special receives modes. It is equal to
9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		call mac_drv_set_rx_mode successively with the
9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		parameters RX_DISABLE_NSA, RX_DISABLE_PASS_SMT,
9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		RX_DISABLE_PASS_NSA and RX_DISABLE_PASS_DB.
9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		RX_ENABLE_LLC_PROMISC
9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		(default) all received LLC frames and all SMT/NSA/DBEACON
9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		frames depending on the attitude of the flags
9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		PASS_SMT/PASS_NSA/PASS_DBEACON will be delivered to the
9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		LLC layer
9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		RX_DISABLE_LLC_PROMISC
9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		all received SMT/NSA/DBEACON frames depending on the
9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		attitude of the flags PASS_SMT/PASS_NSA/PASS_DBEACON
9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		will be delivered to the LLC layer.
9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		all received LLC frames with a directed address, Multicast
9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		or Broadcast address will be delivered to the LLC
9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		layer too.
9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	END_MANUAL_ENTRY
9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid mac_drv_rx_mode(struct s_smc *smc, int mode)
9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch(mode) {
9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case RX_ENABLE_PASS_SMT:
9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.pass_SMT = TRUE ;
9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case RX_DISABLE_PASS_SMT:
9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.pass_SMT = FALSE ;
10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case RX_ENABLE_PASS_NSA:
10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.pass_NSA = TRUE ;
10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case RX_DISABLE_PASS_NSA:
10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.pass_NSA = FALSE ;
10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case RX_ENABLE_PASS_DB:
10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.pass_DB = TRUE ;
10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case RX_DISABLE_PASS_DB:
10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.pass_DB = FALSE ;
10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case RX_DISABLE_PASS_ALL:
10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.pass_SMT = smc->os.hwm.pass_NSA = FALSE ;
10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.pass_DB = FALSE ;
10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.pass_llc_promisc = TRUE ;
10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mac_set_rx_mode(smc,RX_DISABLE_NSA) ;
10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case RX_DISABLE_LLC_PROMISC:
10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.pass_llc_promisc = FALSE ;
10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case RX_ENABLE_LLC_PROMISC:
10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.pass_llc_promisc = TRUE ;
10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case RX_ENABLE_ALLMULTI:
10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case RX_DISABLE_ALLMULTI:
10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case RX_ENABLE_PROMISC:
10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case RX_DISABLE_PROMISC:
10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case RX_ENABLE_NSA:
10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case RX_DISABLE_NSA:
10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mac_set_rx_mode(smc,mode) ;
10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif	/* ifndef NDIS_OS2 */
10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * process receive queue
10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid process_receive(struct s_smc *smc)
10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i ;
10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int n ;
10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int frag_count ;		/* number of RxDs of the curr rx buf */
10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int used_frags ;		/* number of RxDs of the curr frame */
10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_rx_queue *queue ;	/* points to the queue ctl struct */
10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_fp_rxd volatile *r ;	/* rxd pointer */
10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_fp_rxd volatile *rxd ;	/* first rxd of rx frame */
10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long rbctrl ;			/* receive buffer control word */
10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long rfsw ;			/* receive frame status word */
10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_short rx_used ;
10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_char far *virt ;
10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char far *data ;
10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	SMbuf *mb ;
10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_char fc ;			/* Frame control */
10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int len ;			/* Frame length */
10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.detec_count = 0 ;
10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue = smc->hw.fp.rx[QUEUE_R1] ;
10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	NDD_TRACE("RHxB",0,0,0) ;
10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for ( ; ; ) {
10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		r = queue->rx_curr_get ;
10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		rx_used = queue->rx_used ;
10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frag_count = 0 ;
10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	USE_BREAK_ISR
10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (smc->os.hwm.leave_isr) {
10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto rx_end ;
10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	NDIS_OS2
10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (offDepth) {
10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			smc->os.hwm.rx_break = 1 ;
10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto rx_end ;
10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.rx_break = 0 ;
10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	ODI2
10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (smc->os.hwm.rx_break) {
10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto rx_end ;
10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		n = 0 ;
10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		do {
10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_RX("Check RxD %x for OWN and EOF",(void *)r,0,5) ;
10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
10882f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro			rbctrl = le32_to_cpu(CR_READ(r->rxd_rbctrl));
10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (rbctrl & BMU_OWN) {
10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				NDD_TRACE("RHxE",r,rfsw,rbctrl) ;
10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_RX("End of RxDs",0,0,4) ;
10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				goto rx_end ;
10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * out of RxD detection
10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (!rx_used) {
10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				SK_BREAK() ;
11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				SMT_PANIC(smc,HWM_E0009,HWM_E0009_MSG) ;
11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* Either we don't have an RxD or all
11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * RxDs are filled. Therefore it's allowed
11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * for to set the STOPPED flag */
11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smc->hw.hw_state = STOPPED ;
11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				mac_drv_clear_rx_queue(smc) ;
11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smc->hw.hw_state = STARTED ;
11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				mac_drv_fill_rxd(smc) ;
11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smc->os.hwm.detec_count = 0 ;
11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				goto rx_end ;
11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
11112f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro			rfsw = le32_to_cpu(r->rxd_rfsw) ;
11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if ((rbctrl & BMU_STF) != ((rbctrl & BMU_ST_BUF) <<5)) {
11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/*
11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * The BMU_STF bit is deleted, 1 frame is
11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * placed into more than 1 rx buffer
11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 *
11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * skip frame by setting the rx len to 0
11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 *
11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * if fragment count == 0
11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 *	The missing STF bit belongs to the
11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 *	current frame, search for the
11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 *	EOF bit to complete the frame
11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * else
11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 *	the fragment belongs to the next frame,
11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 *	exit the loop and process the frame
11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 */
11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				SK_BREAK() ;
11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				rfsw = 0 ;
11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (frag_count) {
11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					break ;
11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			n += rbctrl & 0xffff ;
11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			r = r->rxd_next ;
11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			frag_count++ ;
11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			rx_used-- ;
11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} while (!(rbctrl & BMU_EOF)) ;
11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		used_frags = frag_count ;
11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_RX("EOF set in RxD, used_frags = %d ",used_frags,0,5) ;
11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* may be next 2 DRV_BUF_FLUSH() can be skipped, because */
11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* BMU_ST_BUF will not be changed by the ASIC */
11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
11442f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro		while (rx_used && !(r->rxd_rbctrl & cpu_to_le32(BMU_ST_BUF))) {
11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_RX("Check STF bit in %x",(void *)r,0,5) ;
11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			r = r->rxd_next ;
11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			frag_count++ ;
11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			rx_used-- ;
11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_RX("STF bit found",0,0,5) ;
11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
11541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * The received frame is finished for the process receive
11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		rxd = queue->rx_curr_get ;
11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue->rx_curr_get = r ;
11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue->rx_free += frag_count ;
11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue->rx_used = rx_used ;
11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * ASIC Errata no. 7 (STF - Bit Bug)
11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
11642f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro		rxd->rxd_rbctrl &= cpu_to_le32(~BMU_STF) ;
11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (r=rxd, i=frag_count ; i ; r=r->rxd_next, i--){
11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_RX("dma_complete for RxD %x",(void *)r,0,5) ;
11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			dma_complete(smc,(union s_fp_descr volatile *)r,DMA_WR);
11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->hw.fp.err_stats.err_valid++ ;
11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->mib.m[MAC0].fddiMACCopied_Ct++ ;
11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* the length of the data including the FC */
11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		len = (rfsw & RD_LENGTH) - 4 ;
11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_RX("frame length = %d",len,0,4) ;
11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
1178efad798b9f01300565f65058b153250cc49d58f2Paulius Zaleckas		 * check the frame_length and all error flags
11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (rfsw & (RX_MSRABT|RX_FS_E|RX_FS_CRC|RX_FS_IMPL)){
11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (rfsw & RD_S_MSRABT) {
11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_RX("Frame aborted by the FORMAC",0,0,2) ;
11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smc->hw.fp.err_stats.err_abort++ ;
11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * check frame status
11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (rfsw & RD_S_SEAC2) {
11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_RX("E-Indicator set",0,0,2) ;
11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smc->hw.fp.err_stats.err_e_indicator++ ;
11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (rfsw & RD_S_SFRMERR) {
11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_RX("CRC error",0,0,2) ;
11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smc->hw.fp.err_stats.err_crc++ ;
11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (rfsw & RX_FS_IMPL) {
11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_RX("Implementer frame",0,0,2) ;
11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smc->hw.fp.err_stats.err_imp_frame++ ;
11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto abort_frame ;
12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (len > FDDI_RAW_MTU-4) {
12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_RX("Frame too long error",0,0,2) ;
12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			smc->hw.fp.err_stats.err_too_long++ ;
12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto abort_frame ;
12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * SUPERNET 3 Bug: FORMAC delivers status words
12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * of aborded frames to the BMU
12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (len <= 4) {
12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_RX("Frame length = 0",0,0,2) ;
12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto abort_frame ;
12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (len != (n-4)) {
12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_RX("BMU: rx len differs: [%d:%d]",len,n,4);
12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			smc->os.hwm.rx_len_error++ ;
12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto abort_frame ;
12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Check SA == MA
12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		virt = (u_char far *) rxd->rxd_virt ;
12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_RX("FC = %x",*virt,0,2) ;
12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (virt[12] == MA[5] &&
12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    virt[11] == MA[4] &&
12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    virt[10] == MA[3] &&
12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    virt[9] == MA[2] &&
12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    virt[8] == MA[1] &&
12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    (virt[7] & ~GROUP_ADDR_BIT) == MA[0]) {
12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto abort_frame ;
12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * test if LLC frame
12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (rfsw & RX_FS_LLC) {
12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * if pass_llc_promisc is disable
12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 *	if DA != Multicast or Broadcast or DA!=MA
12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 *		abort the frame
12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (!smc->os.hwm.pass_llc_promisc) {
12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if(!(virt[1] & GROUP_ADDR_BIT)) {
12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					if (virt[6] != MA[5] ||
12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					    virt[5] != MA[4] ||
12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					    virt[4] != MA[3] ||
12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					    virt[3] != MA[2] ||
12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					    virt[2] != MA[1] ||
12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					    virt[1] != MA[0]) {
12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						DB_RX("DA != MA and not multi- or broadcast",0,0,2) ;
12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						goto abort_frame ;
12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					}
12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * LLC frame received
12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_RX("LLC - receive",0,0,4) ;
12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mac_drv_rx_complete(smc,rxd,frag_count,len) ;
12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else {
12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (!(mb = smt_get_mbuf(smc))) {
12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smc->hw.fp.err_stats.err_no_buf++ ;
12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_RX("No SMbuf; receive terminated",0,0,4) ;
12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				goto abort_frame ;
12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			data = smtod(mb,char *) - 1 ;
12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * copy the frame into a SMT_MBuf
12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef USE_OS_CPY
12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			hwm_cpy_rxd2mb(rxd,data,len) ;
12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for (r=rxd, i=used_frags ; i ; r=r->rxd_next, i--){
12802f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro				n = le32_to_cpu(r->rxd_rbctrl) & RD_LENGTH ;
12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_RX("cp SMT frame to mb: len = %d",n,0,6) ;
12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				memcpy(data,r->rxd_virt,n) ;
12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				data += n ;
12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			data = smtod(mb,char *) - 1 ;
12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			fc = *(char *)mb->sm_data = *data ;
12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mb->sm_len = len - 1 ;		/* len - fc */
12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			data++ ;
12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * SMT frame received
12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			switch(fc) {
12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case FC_SMT_INFO :
12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smc->hw.fp.err_stats.err_smt_frame++ ;
12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_RX("SMT frame received ",0,0,5) ;
12981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (smc->os.hwm.pass_SMT) {
13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					DB_RX("pass SMT frame ",0,0,5) ;
13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					mac_drv_rx_complete(smc, rxd,
13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						frag_count,len) ;
13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				else {
13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					DB_RX("requeue RxD",0,0,5) ;
13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					mac_drv_requeue_rxd(smc,rxd,frag_count);
13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smt_received_pack(smc,mb,(int)(rfsw>>25)) ;
13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break ;
13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case FC_SMT_NSA :
13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smc->hw.fp.err_stats.err_smt_frame++ ;
13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_RX("SMT frame received ",0,0,5) ;
13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* if pass_NSA set pass the NSA frame or */
13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* pass_SMT set and the A-Indicator */
13171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* is not set, pass the NSA frame */
13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (smc->os.hwm.pass_NSA ||
13191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					(smc->os.hwm.pass_SMT &&
13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					!(rfsw & A_INDIC))) {
13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					DB_RX("pass SMT frame ",0,0,5) ;
13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					mac_drv_rx_complete(smc, rxd,
13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						frag_count,len) ;
13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
13251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				else {
13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					DB_RX("requeue RxD",0,0,5) ;
13271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					mac_drv_requeue_rxd(smc,rxd,frag_count);
13281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
13291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smt_received_pack(smc,mb,(int)(rfsw>>25)) ;
13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break ;
13321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case FC_BEACON :
13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (smc->os.hwm.pass_DB) {
13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					DB_RX("pass DB frame ",0,0,5) ;
13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					mac_drv_rx_complete(smc, rxd,
13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						frag_count,len) ;
13371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				else {
13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					DB_RX("requeue RxD",0,0,5) ;
13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					mac_drv_requeue_rxd(smc,rxd,frag_count);
13411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
13421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smt_free_mbuf(smc,mb) ;
13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break ;
13441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			default :
13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/*
13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * unknown FC abord the frame
13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 */
13481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_RX("unknown FC error",0,0,2) ;
13491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smt_free_mbuf(smc,mb) ;
13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_RX("requeue RxD",0,0,5) ;
13511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				mac_drv_requeue_rxd(smc,rxd,frag_count) ;
13521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if ((fc & 0xf0) == FC_MAC)
13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					smc->hw.fp.err_stats.err_mac_frame++ ;
13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				else
13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					smc->hw.fp.err_stats.err_imp_frame++ ;
13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break ;
13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_RX("next RxD is %x ",queue->rx_curr_get,0,3) ;
13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		NDD_TRACE("RHx1",queue->rx_curr_get,0,0) ;
13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		continue ;
13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*--------------------------------------------------------------------*/
13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsabort_frame:
13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_RX("requeue RxD",0,0,5) ;
13681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mac_drv_requeue_rxd(smc,rxd,frag_count) ;
13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_RX("next RxD is %x ",queue->rx_curr_get,0,3) ;
13711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		NDD_TRACE("RHx2",queue->rx_curr_get,0,0) ;
13721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsrx_end:
13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	ALL_RX_COMPLETE
13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mac_drv_all_receives_complete(smc) ;
13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
13771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ;	/* lint bug: needs return detect end of function */
13781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
13791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void smt_to_llc(struct s_smc *smc, SMbuf *mb)
13811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_char	fc ;
13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_RX("send a queued frame to the llc layer",0,0,4) ;
13851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.r.len = mb->sm_len ;
13861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.r.mb_pos = smtod(mb,char *) ;
13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fc = *smc->os.hwm.r.mb_pos ;
13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	(void)mac_drv_rx_init(smc,(int)mb->sm_len,(int)fc,
13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.r.mb_pos,(int)mb->sm_len) ;
13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smt_free_mbuf(smc,mb) ;
13911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
13921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	BEGIN_MANUAL_ENTRY(hwm_rx_frag)
13951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	void hwm_rx_frag(smc,virt,phys,len,frame_status)
13961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
13971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * function	MACRO		(hardware module, hwmtm.h)
13981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		This function calls dma_master for preparing the
13991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		system hardware for the DMA transfer and initializes
14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		the current RxD with the length and the physical and
14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		virtual address of the fragment. Furthermore, it sets the
14021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		STF and EOF bits depending on the frame status byte,
14031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		switches the OWN flag of the RxD, so that it is owned by the
14041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		adapter and issues an rx_start.
14051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
14061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * para	virt	virtual pointer to the fragment
14071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	len	the length of the fragment
14081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	frame_status	status of the frame, see design description
14091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
14101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE:	It is possible to call this function with a fragment length
14111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		of zero.
14121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
14131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	END_MANUAL_ENTRY
14141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid hwm_rx_frag(struct s_smc *smc, char far *virt, u_long phys, int len,
14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 int frame_status)
14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_fp_rxd volatile *r ;
14192f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro	__le32	rbctrl;
14201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	NDD_TRACE("RHfB",virt,len,frame_status) ;
14221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_RX("hwm_rx_frag: len = %d, frame_status = %x\n",len,frame_status,2) ;
14231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	r = smc->hw.fp.rx_q[QUEUE_R1].rx_curr_put ;
14241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	r->rxd_virt = virt ;
14252f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro	r->rxd_rbadr = cpu_to_le32(phys) ;
14262f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro	rbctrl = cpu_to_le32( (((__u32)frame_status &
14271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		(FIRST_FRAG|LAST_FRAG))<<26) |
14281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		(((u_long) frame_status & FIRST_FRAG) << 21) |
14291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		BMU_OWN | BMU_CHECK | BMU_EN_IRQ_EOF | len) ;
14301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	r->rxd_rbctrl = rbctrl ;
14311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ;
14331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	outpd(ADDR(B0_R1_CSR),CSR_START) ;
14341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->hw.fp.rx_q[QUEUE_R1].rx_free-- ;
14351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->hw.fp.rx_q[QUEUE_R1].rx_used++ ;
14361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->hw.fp.rx_q[QUEUE_R1].rx_curr_put = r->rxd_next ;
14372f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro	NDD_TRACE("RHfE",r,le32_to_cpu(r->rxd_rbadr),0) ;
14381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
14391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
14411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	BEGINN_MANUAL_ENTRY(mac_drv_clear_rx_queue)
14421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
14431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void mac_drv_clear_rx_queue(smc)
14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * struct s_smc *smc ;
14451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
14461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * function	DOWNCALL	(hardware module, hwmtm.c)
14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		mac_drv_clear_rx_queue is called by the OS-specific module
14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		after it has issued a card_stop.
14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		In this case, the frames in the receive queue are obsolete and
14501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		should be removed. For removing mac_drv_clear_rx_queue
14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		calls dma_master for each RxD and mac_drv_clear_rxd for each
14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		receive buffer.
14531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
14541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE:	calling sequence card_stop:
14551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		CLI_FBI(), card_stop(),
14561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		mac_drv_clear_tx_queue(), mac_drv_clear_rx_queue(),
14571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE:	The caller is responsible that the BMUs are idle
14591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		when this function is called.
14601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	END_MANUAL_ENTRY
14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid mac_drv_clear_rx_queue(struct s_smc *smc)
14641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
14651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_fp_rxd volatile *r ;
14661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_fp_rxd volatile *next_rxd ;
14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_rx_queue *queue ;
14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int frag_count ;
14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i ;
14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (smc->hw.hw_state != STOPPED) {
14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SK_BREAK() ;
14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SMT_PANIC(smc,HWM_E0012,HWM_E0012_MSG) ;
14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ;
14751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue = smc->hw.fp.rx[QUEUE_R1] ;
14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_RX("clear_rx_queue",0,0,5) ;
14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
14811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * dma_complete and mac_drv_clear_rxd for all RxDs / receive buffers
14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	r = queue->rx_curr_get ;
14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (queue->rx_used) {
14851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
14861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_RX("switch OWN bit of RxD 0x%x ",r,0,5) ;
14872f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro		r->rxd_rbctrl &= ~cpu_to_le32(BMU_OWN) ;
14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frag_count = 1 ;
14891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ;
14901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		r = r->rxd_next ;
14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (r != queue->rx_curr_put &&
14932f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro			!(r->rxd_rbctrl & cpu_to_le32(BMU_ST_BUF))) {
14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_RX("Check STF bit in %x",(void *)r,0,5) ;
14952f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro			r->rxd_rbctrl &= ~cpu_to_le32(BMU_OWN) ;
14961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ;
14971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			r = r->rxd_next ;
14981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
14991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			frag_count++ ;
15001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
15011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_RX("STF bit found",0,0,5) ;
15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		next_rxd = r ;
15031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (r=queue->rx_curr_get,i=frag_count; i ; r=r->rxd_next,i--){
15051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_RX("dma_complete for RxD %x",(void *)r,0,5) ;
15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			dma_complete(smc,(union s_fp_descr volatile *)r,DMA_WR);
15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
15081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_RX("mac_drv_clear_rxd: RxD %x frag_count %d ",
15101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			(void *)queue->rx_curr_get,frag_count,5) ;
15111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mac_drv_clear_rxd(smc,queue->rx_curr_get,frag_count) ;
15121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue->rx_curr_get = next_rxd ;
15141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue->rx_used -= frag_count ;
15151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue->rx_free += frag_count ;
15161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
15171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
15181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
15211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
15221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	SEND FUNCTIONS:
15231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
15241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
15251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
15271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	BEGIN_MANUAL_ENTRY(hwm_tx_init)
15281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	int hwm_tx_init(smc,fc,frag_count,frame_len,frame_status)
15291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
15301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * function	DOWN_CALL	(hardware module, hwmtm.c)
15311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		hwm_tx_init checks if the frame can be sent through the
15321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		corresponding send queue.
15331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
15341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * para	fc	the frame control. To determine through which
15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		send queue the frame should be transmitted.
15361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		0x50 - 0x57:	asynchronous LLC frame
15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		0xD0 - 0xD7:	synchronous LLC frame
15381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		0x41, 0x4F:	SMT frame to the network
15391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		0x42:		SMT frame to the network and to the local SMT
15401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		0x43:		SMT frame to the local SMT
15411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	frag_count	count of the fragments for this frame
15421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	frame_len	length of the frame
15431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	frame_status	status of the frame, the send queue bit is already
15441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			specified
15451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
15461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return		frame_status
15471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
15481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	END_MANUAL_ENTRY
15491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
15501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count, int frame_len,
15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int frame_status)
15521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	NDD_TRACE("THiB",fc,frag_count,frame_len) ;
15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.tx_p = smc->hw.fp.tx[frame_status & QUEUE_A0] ;
15551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.tx_descr = TX_DESCRIPTOR | (((u_long)(frame_len-1)&3)<<27) ;
15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.tx_len = frame_len ;
15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_TX("hwm_tx_init: fc = %x, len = %d",fc,frame_len,3) ;
15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((fc & ~(FC_SYNC_BIT|FC_LLC_PRIOR)) == FC_ASYNC_LLC) {
15591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frame_status |= LAN_TX ;
15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else {
15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		switch (fc) {
15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case FC_SMT_INFO :
15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case FC_SMT_NSA :
15651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			frame_status |= LAN_TX ;
15661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break ;
15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case FC_SMT_LOC :
15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			frame_status |= LOC_TX ;
15691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break ;
15701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case FC_SMT_LAN_LOC :
15711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			frame_status |= LAN_TX | LOC_TX ;
15721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break ;
15731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default :
15741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			SMT_PANIC(smc,HWM_E0010,HWM_E0010_MSG) ;
15751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
15761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
15771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!smc->hw.mac_ring_is_up) {
15781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frame_status &= ~LAN_TX ;
15791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frame_status |= RING_DOWN ;
15801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_TX("Ring is down: terminate LAN_TX",0,0,2) ;
15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
15821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (frag_count > smc->os.hwm.tx_p->tx_free) {
15831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef	NDIS_OS2
15841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mac_drv_clear_txd(smc) ;
15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (frag_count > smc->os.hwm.tx_p->tx_free) {
15861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_TX("Out of TxDs, terminate LAN_TX",0,0,2) ;
15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			frame_status &= ~LAN_TX ;
15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			frame_status |= OUT_OF_TXD ;
15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
15911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_TX("Out of TxDs, terminate LAN_TX",0,0,2) ;
15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frame_status &= ~LAN_TX ;
15931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frame_status |= OUT_OF_TXD ;
15941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
15951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
15961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_TX("frame_status = %x",frame_status,0,3) ;
15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	NDD_TRACE("THiE",frame_status,smc->os.hwm.tx_p->tx_free,0) ;
1598807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return frame_status;
15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	BEGIN_MANUAL_ENTRY(hwm_tx_frag)
16031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	void hwm_tx_frag(smc,virt,phys,len,frame_status)
16041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * function	DOWNCALL	(hardware module, hwmtm.c)
16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		If the frame should be sent to the LAN, this function calls
16071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		dma_master, fills the current TxD with the virtual and the
16081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		physical address, sets the STF and EOF bits dependent on
16091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		the frame status, and requests the BMU to start the
16101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		transmit.
16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		If the frame should be sent to the local SMT, an SMT_MBuf
16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		is allocated if the FIRST_FRAG bit is set in the frame_status.
16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		The fragment of the frame is copied into the SMT MBuf.
16141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		The function smt_received_pack is called if the LAST_FRAG
16151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		bit is set in the frame_status word.
16161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * para	virt	virtual pointer to the fragment
16181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	len	the length of the fragment
16191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	frame_status	status of the frame, see design description
16201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
16211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return	nothing returned, no parameter is modified
16221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
16231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE:	It is possible to invoke this macro with a fragment length
16241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		of zero.
16251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
16261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	END_MANUAL_ENTRY
16271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
16281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid hwm_tx_frag(struct s_smc *smc, char far *virt, u_long phys, int len,
16291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 int frame_status)
16301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
16311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_fp_txd volatile *t ;
16321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_tx_queue *queue ;
16332f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro	__le32	tbctrl ;
16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue = smc->os.hwm.tx_p ;
16361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	NDD_TRACE("THfB",virt,len,frame_status) ;
16381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Bug fix: AF / May 31 1999 (#missing)
16391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * snmpinfo problem reported by IBM is caused by invalid
16401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * t-pointer (txd) if LAN_TX is not set but LOC_TX only.
16411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Set: t = queue->tx_curr_put  here !
16421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
16431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	t = queue->tx_curr_put ;
16441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_TX("hwm_tx_frag: len = %d, frame_status = %x ",len,frame_status,2) ;
16461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (frame_status & LAN_TX) {
16471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* '*t' is already defined */
16481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_TX("LAN_TX: TxD = %x, virt = %x ",t,virt,3) ;
16491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		t->txd_virt = virt ;
16502f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro		t->txd_txdscr = cpu_to_le32(smc->os.hwm.tx_descr) ;
16512f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro		t->txd_tbadr = cpu_to_le32(phys) ;
16522f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro		tbctrl = cpu_to_le32((((__u32)frame_status &
16531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			(FIRST_FRAG|LAST_FRAG|EN_IRQ_EOF))<< 26) |
16541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			BMU_OWN|BMU_CHECK |len) ;
16551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		t->txd_tbctrl = tbctrl ;
16561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef	AIX
16581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
16591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		outpd(queue->tx_bmu_ctl,CSR_START) ;
16601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else	/* ifndef AIX */
16611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
16621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (frame_status & QUEUE_A0) {
16631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			outpd(ADDR(B0_XA_CSR),CSR_START) ;
16641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
16651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else {
16661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			outpd(ADDR(B0_XS_CSR),CSR_START) ;
16671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
16681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
16691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue->tx_free-- ;
16701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue->tx_used++ ;
16711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue->tx_curr_put = t->txd_next ;
16721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (frame_status & LAST_FRAG) {
16731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			smc->mib.m[MAC0].fddiMACTransmit_Ct++ ;
16741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
16751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
16761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (frame_status & LOC_TX) {
16771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_TX("LOC_TX: ",0,0,3) ;
16781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (frame_status & FIRST_FRAG) {
16791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if(!(smc->os.hwm.tx_mb = smt_get_mbuf(smc))) {
16801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smc->hw.fp.err_stats.err_no_buf++ ;
16811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_TX("No SMbuf; transmit terminated",0,0,4) ;
16821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
16831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else {
16841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smc->os.hwm.tx_data =
16851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					smtod(smc->os.hwm.tx_mb,char *) - 1 ;
16861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef USE_OS_CPY
16871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef PASS_1ST_TXD_2_TX_COMP
16881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				hwm_cpy_txd2mb(t,smc->os.hwm.tx_data,
16891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					smc->os.hwm.tx_len) ;
16901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
16911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
16921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
16931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
16941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (smc->os.hwm.tx_mb) {
16951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef	USE_OS_CPY
16961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_TX("copy fragment into MBuf ",0,0,3) ;
16971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			memcpy(smc->os.hwm.tx_data,virt,len) ;
16981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			smc->os.hwm.tx_data += len ;
16991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
17001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (frame_status & LAST_FRAG) {
17011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	USE_OS_CPY
17021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef PASS_1ST_TXD_2_TX_COMP
17031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/*
17041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * hwm_cpy_txd2mb(txd,data,len) copies 'len'
17051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * bytes from the virtual pointer in 'rxd'
17061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * to 'data'. The virtual pointer of the
17071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * os-specific tx-buffer should be written
17081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * in the LAST txd.
17091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 */
17101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				hwm_cpy_txd2mb(t,smc->os.hwm.tx_data,
17111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					smc->os.hwm.tx_len) ;
17121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif	/* nPASS_1ST_TXD_2_TX_COMP */
17131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif	/* USE_OS_CPY */
17141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smc->os.hwm.tx_data =
17151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					smtod(smc->os.hwm.tx_mb,char *) - 1 ;
17161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				*(char *)smc->os.hwm.tx_mb->sm_data =
17171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					*smc->os.hwm.tx_data ;
17181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smc->os.hwm.tx_data++ ;
17191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smc->os.hwm.tx_mb->sm_len =
17201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					smc->os.hwm.tx_len - 1 ;
17211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_TX("pass LLC frame to SMT ",0,0,3) ;
17221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smt_received_pack(smc,smc->os.hwm.tx_mb,
17231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						RD_FS_LOCAL) ;
17241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
17251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
17261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
17271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	NDD_TRACE("THfE",t,queue->tx_free,0) ;
17281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
17291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
17321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * queues a receive for later send
17331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
17341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void queue_llc_rx(struct s_smc *smc, SMbuf *mb)
17351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
17361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_GEN("queue_llc_rx: mb = %x",(void *)mb,0,4) ;
17371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.queued_rx_frames++ ;
17381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mb->sm_next = (SMbuf *)NULL ;
173979ea13ce07c951bb4d95471e7300baa0f1be9e78Al Viro	if (smc->os.hwm.llc_rx_pipe == NULL) {
17401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.llc_rx_pipe = mb ;
17411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
17421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else {
17431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.llc_rx_tail->sm_next = mb ;
17441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
17451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.llc_rx_tail = mb ;
17461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
17481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * force an timer IRQ to receive the data
17491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
17501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!smc->os.hwm.isr_flag) {
17511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smt_force_irq(smc) ;
17521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
17531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
17541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
17561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * get a SMbuf from the llc_rx_queue
17571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
17581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic SMbuf *get_llc_rx(struct s_smc *smc)
17591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
17601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	SMbuf	*mb ;
17611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((mb = smc->os.hwm.llc_rx_pipe)) {
17631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.queued_rx_frames-- ;
17641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.llc_rx_pipe = mb->sm_next ;
17651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
17661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_GEN("get_llc_rx: mb = 0x%x",(void *)mb,0,4) ;
1767807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return mb;
17681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
17691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
17711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * queues a transmit SMT MBuf during the time were the MBuf is
17721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * queued the TxD ring
17731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
17741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void queue_txd_mb(struct s_smc *smc, SMbuf *mb)
17751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
17761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_GEN("_rx: queue_txd_mb = %x",(void *)mb,0,4) ;
17771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.queued_txd_mb++ ;
17781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mb->sm_next = (SMbuf *)NULL ;
177979ea13ce07c951bb4d95471e7300baa0f1be9e78Al Viro	if (smc->os.hwm.txd_tx_pipe == NULL) {
17801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.txd_tx_pipe = mb ;
17811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
17821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else {
17831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.txd_tx_tail->sm_next = mb ;
17841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
17851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	smc->os.hwm.txd_tx_tail = mb ;
17861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
17871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
17891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * get a SMbuf from the txd_tx_queue
17901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
17911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic SMbuf *get_txd_mb(struct s_smc *smc)
17921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
17931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	SMbuf *mb ;
17941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((mb = smc->os.hwm.txd_tx_pipe)) {
17961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.queued_txd_mb-- ;
17971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->os.hwm.txd_tx_pipe = mb->sm_next ;
17981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
17991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_GEN("get_txd_mb: mb = 0x%x",(void *)mb,0,4) ;
1800807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return mb;
18011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
18021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
18041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	SMT Send function
18051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
18061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid smt_send_mbuf(struct s_smc *smc, SMbuf *mb, int fc)
18071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
18081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char far *data ;
18091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int	len ;
18101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int	n ;
18111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int	i ;
18121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int	frag_count ;
18131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int	frame_status ;
18141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	SK_LOC_DECL(char far,*virt[3]) ;
18151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int	frag_len[3] ;
18161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_tx_queue *queue ;
18171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_fp_txd volatile *t ;
18181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long	phys ;
18192f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro	__le32	tbctrl;
18201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	NDD_TRACE("THSB",mb,fc,0) ;
18221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_TX("smt_send_mbuf: mb = 0x%x, fc = 0x%x",mb,fc,4) ;
18231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mb->sm_off-- ;	/* set to fc */
18251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mb->sm_len++ ;	/* + fc */
18261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data = smtod(mb,char *) ;
18271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*data = fc ;
18281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (fc == FC_SMT_LOC)
18291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*data = FC_SMT_INFO ;
18301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
18321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * determine the frag count and the virt addresses of the frags
18331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
18341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	frag_count = 0 ;
18351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	len = mb->sm_len ;
18361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (len) {
18371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		n = SMT_PAGESIZE - ((long)data & (SMT_PAGESIZE-1)) ;
18381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (n >= len) {
18391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			n = len ;
18401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
18411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_TX("frag: virt/len = 0x%x/%d ",(void *)data,n,5) ;
18421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		virt[frag_count] = data ;
18431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frag_len[frag_count] = n ;
18441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frag_count++ ;
18451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		len -= n ;
18461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		data += n ;
18471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
18481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
18501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * determine the frame status
18511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
18521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	queue = smc->hw.fp.tx[QUEUE_A0] ;
18531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (fc == FC_BEACON || fc == FC_SMT_LOC) {
18541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frame_status = LOC_TX ;
18551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
18561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else {
18571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frame_status = LAN_TX ;
18581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((smc->os.hwm.pass_NSA &&(fc == FC_SMT_NSA)) ||
18591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   (smc->os.hwm.pass_SMT &&(fc == FC_SMT_INFO)))
18601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			frame_status |= LOC_TX ;
18611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
18621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!smc->hw.mac_ring_is_up || frag_count > queue->tx_free) {
18641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frame_status &= ~LAN_TX;
18651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (frame_status) {
18661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_TX("Ring is down: terminate LAN_TX",0,0,2) ;
18671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
18681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else {
18691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_TX("Ring is down: terminate transmission",0,0,2) ;
18701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			smt_free_mbuf(smc,mb) ;
18711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return ;
18721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
18731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
18741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DB_TX("frame_status = 0x%x ",frame_status,0,5) ;
18751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((frame_status & LAN_TX) && (frame_status & LOC_TX)) {
18771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mb->sm_use_count = 2 ;
18781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
18791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (frame_status & LAN_TX) {
18811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		t = queue->tx_curr_put ;
18821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frame_status |= FIRST_FRAG ;
18831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (i = 0; i < frag_count; i++) {
18841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_TX("init TxD = 0x%x",(void *)t,0,5) ;
18851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (i == frag_count-1) {
18861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				frame_status |= LAST_FRAG ;
18872f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro				t->txd_txdscr = cpu_to_le32(TX_DESCRIPTOR |
18882f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro					(((__u32)(mb->sm_len-1)&3) << 27)) ;
18891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
18901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			t->txd_virt = virt[i] ;
18911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			phys = dma_master(smc, (void far *)virt[i],
18921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				frag_len[i], DMA_RD|SMT_BUF) ;
18932f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro			t->txd_tbadr = cpu_to_le32(phys) ;
18942f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro			tbctrl = cpu_to_le32((((__u32)frame_status &
18951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				(FIRST_FRAG|LAST_FRAG)) << 26) |
18961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				BMU_OWN | BMU_CHECK | BMU_SMT_TX |frag_len[i]) ;
18971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			t->txd_tbctrl = tbctrl ;
18981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef	AIX
18991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
19001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			outpd(queue->tx_bmu_ctl,CSR_START) ;
19011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
19021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
19031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			outpd(ADDR(B0_XA_CSR),CSR_START) ;
19041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
19051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			frame_status &= ~FIRST_FRAG ;
19061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			queue->tx_curr_put = t = t->txd_next ;
19071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			queue->tx_free-- ;
19081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			queue->tx_used++ ;
19091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
19101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		smc->mib.m[MAC0].fddiMACTransmit_Ct++ ;
19111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue_txd_mb(smc,mb) ;
19121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
19131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (frame_status & LOC_TX) {
19151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_TX("pass Mbuf to LLC queue",0,0,5) ;
19161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue_llc_rx(smc,mb) ;
19171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
19181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
19201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * We need to unqueue the free SMT_MBUFs here, because it may
19211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * be that the SMT want's to send more than 1 frame for one down call
19221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
19231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mac_drv_clear_txd(smc) ;
19241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	NDD_TRACE("THSE",t,queue->tx_free,frag_count) ;
19251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
19261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*	BEGIN_MANUAL_ENTRY(mac_drv_clear_txd)
19281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	void mac_drv_clear_txd(smc)
19291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
19301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * function	DOWNCALL	(hardware module, hwmtm.c)
19311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		mac_drv_clear_txd searches in both send queues for TxD's
19321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		which were finished by the adapter. It calls dma_complete
19331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		for each TxD. If the last fragment of an LLC frame is
19341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		reached, it calls mac_drv_tx_complete to release the
19351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		send buffer.
19361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
19371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return	nothing
19381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
19391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	END_MANUAL_ENTRY
19401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
19417aa55fcec236daed20dd362c99229184691d0e7fAdrian Bunkstatic void mac_drv_clear_txd(struct s_smc *smc)
19421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
19431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_tx_queue *queue ;
19441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_fp_txd volatile *t1 ;
19451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_fp_txd volatile *t2 = NULL ;
19461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	SMbuf *mb ;
19471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long	tbctrl ;
19481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i ;
19491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int frag_count ;
19501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int n ;
19511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	NDD_TRACE("THcB",0,0,0) ;
19531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = QUEUE_S; i <= QUEUE_A0; i++) {
19541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue = smc->hw.fp.tx[i] ;
19551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		t1 = queue->tx_curr_get ;
19561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_TX("clear_txd: QUEUE = %d (0=sync/1=async)",i,0,5) ;
19571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for ( ; ; ) {
19591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			frag_count = 0 ;
19601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			do {
19621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DRV_BUF_FLUSH(t1,DDI_DMA_SYNC_FORCPU) ;
19631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_TX("check OWN/EOF bit of TxD 0x%x",t1,0,5) ;
19642f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro				tbctrl = le32_to_cpu(CR_READ(t1->txd_tbctrl));
19651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (tbctrl & BMU_OWN || !queue->tx_used){
19671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					DB_TX("End of TxDs queue %d",i,0,4) ;
19681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					goto free_next_queue ;	/* next queue */
19691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
19701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				t1 = t1->txd_next ;
19711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				frag_count++ ;
19721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			} while (!(tbctrl & BMU_EOF)) ;
19731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			t1 = queue->tx_curr_get ;
19751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for (n = frag_count; n; n--) {
19762f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro				tbctrl = le32_to_cpu(t1->txd_tbctrl) ;
19771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				dma_complete(smc,
19781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					(union s_fp_descr volatile *) t1,
19791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					(int) (DMA_RD |
19801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((tbctrl & BMU_SMT_TX) >> 18))) ;
19811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				t2 = t1 ;
19821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				t1 = t1->txd_next ;
19831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
19841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (tbctrl & BMU_SMT_TX) {
19861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				mb = get_txd_mb(smc) ;
19871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				smt_free_mbuf(smc,mb) ;
19881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
19891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else {
19901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef PASS_1ST_TXD_2_TX_COMP
19911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_TX("mac_drv_tx_comp for TxD 0x%x",t2,0,4) ;
19921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				mac_drv_tx_complete(smc,t2) ;
19931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
19941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DB_TX("mac_drv_tx_comp for TxD 0x%x",
19951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					queue->tx_curr_get,0,4) ;
19961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				mac_drv_tx_complete(smc,queue->tx_curr_get) ;
19971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
19981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
19991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			queue->tx_curr_get = t1 ;
20001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			queue->tx_free += frag_count ;
20011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			queue->tx_used -= frag_count ;
20021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
20031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsfree_next_queue: ;
20041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
20051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	NDD_TRACE("THcE",0,0,0) ;
20061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
20071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
20091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	BEGINN_MANUAL_ENTRY(mac_drv_clear_tx_queue)
20101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
20111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void mac_drv_clear_tx_queue(smc)
20121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * struct s_smc *smc ;
20131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
20141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * function	DOWNCALL	(hardware module, hwmtm.c)
20151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		mac_drv_clear_tx_queue is called from the SMT when
20161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		the RMT state machine has entered the ISOLATE state.
20171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		This function is also called by the os-specific module
20181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		after it has called the function card_stop().
20191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		In this case, the frames in the send queues are obsolete and
20201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		should be removed.
20211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
20221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * note		calling sequence:
20231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		CLI_FBI(), card_stop(),
20241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		mac_drv_clear_tx_queue(), mac_drv_clear_rx_queue(),
20251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
20261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE:	The caller is responsible that the BMUs are idle
20271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		when this function is called.
20281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
20291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	END_MANUAL_ENTRY
20301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
20311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid mac_drv_clear_tx_queue(struct s_smc *smc)
20321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
20331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_fp_txd volatile *t ;
20341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct s_smt_tx_queue *queue ;
20351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int tx_used ;
20361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i ;
20371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (smc->hw.hw_state != STOPPED) {
20391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SK_BREAK() ;
20401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SMT_PANIC(smc,HWM_E0011,HWM_E0011_MSG) ;
20411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ;
20421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
20431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = QUEUE_S; i <= QUEUE_A0; i++) {
20451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue = smc->hw.fp.tx[i] ;
20461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_TX("clear_tx_queue: QUEUE = %d (0=sync/1=async)",i,0,5) ;
20471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
20491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * switch the OWN bit of all pending frames to the host
20501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
20511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		t = queue->tx_curr_get ;
20521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		tx_used = queue->tx_used ;
20531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (tx_used) {
20541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORCPU) ;
20551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DB_TX("switch OWN bit of TxD 0x%x ",t,0,5) ;
20562f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro			t->txd_tbctrl &= ~cpu_to_le32(BMU_OWN) ;
20571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
20581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			t = t->txd_next ;
20591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			tx_used-- ;
20601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
20611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
20621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
20641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * release all TxD's for both send queues
20651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
20661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mac_drv_clear_txd(smc) ;
20671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = QUEUE_S; i <= QUEUE_A0; i++) {
20691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue = smc->hw.fp.tx[i] ;
20701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		t = queue->tx_curr_get ;
20711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
20731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * write the phys pointer of the NEXT descriptor into the
20741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * BMU's current address descriptor pointer and set
20751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * tx_curr_get and tx_curr_put to this position
20761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
20771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (i == QUEUE_S) {
20782f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro			outpd(ADDR(B5_XS_DA),le32_to_cpu(t->txd_ntdadr)) ;
20791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
20801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else {
20812f220e305b23ab277aa0f91e2a65978f5cc1a785Al Viro			outpd(ADDR(B5_XA_DA),le32_to_cpu(t->txd_ntdadr)) ;
20821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
20831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue->tx_curr_put = queue->tx_curr_get->txd_next ;
20851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		queue->tx_curr_get = queue->tx_curr_put ;
20861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
20871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
20881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
20911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
20921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	TEST FUNCTIONS:
20931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	-------------------------------------------------------------
20941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
20951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	DEBUG
20971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
20981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	BEGIN_MANUAL_ENTRY(mac_drv_debug_lev)
20991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	void mac_drv_debug_lev(smc,flag,lev)
21001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
21011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * function	DOWNCALL	(drvsr.c)
21021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		To get a special debug info the user can assign a debug level
21031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		to any debug flag.
21041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
21051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * para	flag	debug flag, possible values are:
21061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			= 0:	reset all debug flags (the defined level is
21071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *				ignored)
21081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			= 1:	debug.d_smtf
21091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			= 2:	debug.d_smt
21101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			= 3:	debug.d_ecm
21111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			= 4:	debug.d_rmt
21121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			= 5:	debug.d_cfm
21131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			= 6:	debug.d_pcm
21141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
21151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			= 10:	debug.d_os.hwm_rx (hardware module receive path)
21161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			= 11:	debug.d_os.hwm_tx(hardware module transmit path)
21171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *			= 12:	debug.d_os.hwm_gen(hardware module general flag)
21181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
21191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	lev	debug level
21201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
21211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	END_MANUAL_ENTRY
21221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
21231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid mac_drv_debug_lev(struct s_smc *smc, int flag, int lev)
21241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
21251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch(flag) {
21261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case (int)NULL:
21271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_smtf = DB_P.d_smt = DB_P.d_ecm = DB_P.d_rmt = 0 ;
21281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_cfm = 0 ;
21291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_os.hwm_rx = DB_P.d_os.hwm_tx = DB_P.d_os.hwm_gen = 0 ;
21301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	SBA
21311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_sba = 0 ;
21321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
21331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	ESS
21341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_ess = 0 ;
21351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
21361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
21371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DEBUG_SMTF:
21381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_smtf = lev ;
21391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
21401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DEBUG_SMT:
21411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_smt = lev ;
21421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
21431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DEBUG_ECM:
21441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_ecm = lev ;
21451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
21461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DEBUG_RMT:
21471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_rmt = lev ;
21481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
21491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DEBUG_CFM:
21501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_cfm = lev ;
21511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
21521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DEBUG_PCM:
21531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_pcm = lev ;
21541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
21551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DEBUG_SBA:
21561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	SBA
21571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_sba = lev ;
21581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
21591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
21601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DEBUG_ESS:
21611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	ESS
21621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_ess = lev ;
21631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
21641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
21651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DB_HWM_RX:
21661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_os.hwm_rx = lev ;
21671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
21681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DB_HWM_TX:
21691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_os.hwm_tx = lev ;
21701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
21711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DB_HWM_GEN:
21721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DB_P.d_os.hwm_gen = lev ;
21731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
21741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
21751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break ;
21761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
21771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
21781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
2179