11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * smctr.c: A network driver for the SMC Token Ring Adapters. 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Written by Jay Schulist <jschlst@samba.org> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This software may be used and distributed according to the terms 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the GNU General Public License, incorporated herein by reference. 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This device driver works with the following SMC adapters: 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - SMC TokenCard Elite (8115T, chips 825/584) 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - SMC TokenCard Elite/A MCA (8115T/A, chips 825/594) 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Source(s): 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - SMC TokenCard SDK. 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Maintainer(s): 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * JS Jay Schulist <jschlst@samba.org> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Changes: 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 07102000 JS Fixed a timing problem in smctr_wait_cmd(); 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Also added a bit more discriptive error msgs. 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 07122000 JS Fixed problem with detecting a card with 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * module io/irq/mem specified. 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * To do: 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. Multicast support. 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 28113aa838ec3a235d883f8357d31d90e16c47fc89Alan Cox * Initial 2.5 cleanup Alan Cox <alan@lxorguk.ukuu.org.uk> 2002/10/28 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fcntl.h> 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h> 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ptrace.h> 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ioport.h> 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/in.h> 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h> 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/time.h> 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mca-legacy.h> 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/netdevice.h> 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/etherdevice.h> 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/skbuff.h> 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/trdevice.h> 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/bitops.h> 500f805b86c9492c294c710de8539a8be68b521a86David Woodhouse#include <linux/firmware.h> 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/dma.h> 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/irq.h> 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if BITS_PER_LONG == 64 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#error FIXME: driver does not support 64-bit platforms 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "smctr.h" /* Our Stuff */ 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 621770e430ca1361fb8143c328037d1a3f34391602Hannes Ederstatic const char version[] __initdata = 631770e430ca1361fb8143c328037d1a3f34391602Hannes Eder KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n"; 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const char cardname[] = "smctr"; 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMCTR_IO_EXTENT 20 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_MCA_LEGACY 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int smctr_posid = 0x6ec6; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int ringspeed; 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* SMC Name of the Adapter. */ 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char smctr_name[] = "SMC TokenCard"; 77de70b4c87b8f1d484cf533536c0c6ce2e05101cfAdrian Bunkstatic char *smctr_model = "Unknown"; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Use 0 for production, 1 for verification, 2 for debug, and 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3 for very verbose debug. 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef SMCTR_DEBUG 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMCTR_DEBUG 1 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int smctr_debug = SMCTR_DEBUG; 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* smctr.c prototypes and functions are arranged alphabeticly 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for clearity, maintainability and pure old fashion fun. 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* A */ 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_alloc_shared_memory(struct net_device *dev); 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* B */ 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_bypass_state(struct net_device *dev); 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* C */ 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_checksum_firmware(struct net_device *dev); 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init smctr_chk_isa(struct net_device *dev); 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_chg_rx_mask(struct net_device *dev); 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_clear_int(struct net_device *dev); 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_clear_trc_reset(int ioaddr); 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_close(struct net_device *dev); 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* D */ 1050f805b86c9492c294c710de8539a8be68b521a86David Woodhousestatic int smctr_decode_firmware(struct net_device *dev, 1060f805b86c9492c294c710de8539a8be68b521a86David Woodhouse const struct firmware *fw); 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_disable_16bit(struct net_device *dev); 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_disable_adapter_ctrl_store(struct net_device *dev); 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_disable_bic_int(struct net_device *dev); 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* E */ 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_enable_16bit(struct net_device *dev); 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_enable_adapter_ctrl_store(struct net_device *dev); 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_enable_adapter_ram(struct net_device *dev); 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_enable_bic_int(struct net_device *dev); 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* G */ 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init smctr_get_boardid(struct net_device *dev, int mca); 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_get_group_address(struct net_device *dev); 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_get_functional_address(struct net_device *dev); 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int smctr_get_num_rx_bdbs(struct net_device *dev); 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_get_physical_drop_number(struct net_device *dev); 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic __u8 *smctr_get_rx_pointer(struct net_device *dev, short queue); 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_get_station_id(struct net_device *dev); 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 bytes_count); 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_get_upstream_neighbor_addr(struct net_device *dev); 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* H */ 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_hardware_send_packet(struct net_device *dev, 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp); 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* I */ 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_acbs(struct net_device *dev); 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_adapter(struct net_device *dev); 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_card_real(struct net_device *dev); 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_rx_bdbs(struct net_device *dev); 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_rx_fcbs(struct net_device *dev); 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_shared_memory(struct net_device *dev); 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_tx_bdbs(struct net_device *dev); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_tx_fcbs(struct net_device *dev); 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_internal_self_test(struct net_device *dev); 1427d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t smctr_interrupt(int irq, void *dev_id); 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_enable_int_cmd(struct net_device *dev, 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 interrupt_enable_mask); 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 ibits); 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_init_timers_cmd(struct net_device *dev); 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_init_txrx_cmd(struct net_device *dev); 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_insert_cmd(struct net_device *dev); 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_read_ring_status_cmd(struct net_device *dev); 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt); 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_remove_cmd(struct net_device *dev); 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_resume_acb_cmd(struct net_device *dev); 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue); 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue); 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue); 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_test_internal_rom_cmd(struct net_device *dev); 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_test_hic_cmd(struct net_device *dev); 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_test_mac_reg_cmd(struct net_device *dev); 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_trc_loopback_cmd(struct net_device *dev); 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_tri_loopback_cmd(struct net_device *dev); 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_write_byte_cmd(struct net_device *dev, 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds short aword_cnt, void *byte); 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_write_word_cmd(struct net_device *dev, 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds short aword_cnt, void *word); 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* J */ 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_join_complete_state(struct net_device *dev); 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* L */ 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev); 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_load_firmware(struct net_device *dev); 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_load_node_addr(struct net_device *dev); 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_lobe_media_test(struct net_device *dev); 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_lobe_media_test_cmd(struct net_device *dev); 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_lobe_media_test_state(struct net_device *dev); 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* M */ 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_8025_hdr(struct net_device *dev, 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_HEADER *rmf, MAC_HEADER *tmf, __u16 ac_fc); 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_access_pri(struct net_device *dev, 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv); 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv); 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_auth_funct_class(struct net_device *dev, 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv); 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_corr(struct net_device *dev, 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv, __u16 correlator); 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_funct_addr(struct net_device *dev, 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv); 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_group_addr(struct net_device *dev, 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv); 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_phy_drop_num(struct net_device *dev, 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv); 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv); 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv); 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_ring_station_status(struct net_device *dev, 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv); 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_ring_station_version(struct net_device *dev, 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv); 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_tx_status_code(struct net_device *dev, 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv, __u16 tx_fstatus); 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_upstream_neighbor_addr(struct net_device *dev, 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv); 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_wrap_data(struct net_device *dev, 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv); 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* O */ 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_open(struct net_device *dev); 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_open_tr(struct net_device *dev); 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* P */ 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct net_device *smctr_probe(int unit); 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init smctr_probe1(struct net_device *dev, int ioaddr); 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_device *dev, __u16 rx_status); 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* R */ 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_ram_memory_test(struct net_device *dev); 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf, 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 *correlator); 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf, 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 *correlator); 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf); 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_rcv_rq_addr_state_attch(struct net_device *dev, 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_HEADER *rmf, __u16 *correlator); 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf, 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 *correlator); 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_reset_adapter(struct net_device *dev); 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_restart_tx_chain(struct net_device *dev, short queue); 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_ring_status_chg(struct net_device *dev); 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_rx_frame(struct net_device *dev); 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* S */ 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_dat(struct net_device *dev); 23561a84108547c1c017683f15311ccbede249fc6faStephen Hemmingerstatic netdev_tx_t smctr_send_packet(struct sk_buff *skb, 23661a84108547c1c017683f15311ccbede249fc6faStephen Hemminger struct net_device *dev); 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_lobe_media_test(struct net_device *dev); 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf, 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 correlator); 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf, 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 correlator); 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf, 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 correlator); 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_rpt_tx_forward(struct net_device *dev, 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_HEADER *rmf, __u16 tx_fstatus); 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf, 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 rcode, __u16 correlator); 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_rq_init(struct net_device *dev); 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 *tx_fstatus); 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_auth_access_pri(struct net_device *dev, 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv); 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_auth_funct_class(struct net_device *dev, 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv); 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv, 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 *correlator); 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_error_timer_value(struct net_device *dev, 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv); 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_frame_forward(struct net_device *dev, 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv, __u8 dc_sc); 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_local_ring_num(struct net_device *dev, 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv); 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned short smctr_set_ctrl_attention(struct net_device *dev); 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void smctr_set_multicast_list(struct net_device *dev); 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_page(struct net_device *dev, __u8 *buf); 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_phy_drop(struct net_device *dev, 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv); 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_ring_speed(struct net_device *dev); 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_rx_look_ahead(struct net_device *dev); 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_trc_reset(int ioaddr); 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_setup_single_cmd(struct net_device *dev, 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 command, __u16 subcommand); 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_setup_single_cmd_w_data(struct net_device *dev, 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 command, __u16 subcommand); 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *smctr_malloc(struct net_device *dev, __u16 size); 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_status_chg(struct net_device *dev); 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* T */ 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void smctr_timeout(struct net_device *dev); 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb, 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 queue); 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic __u16 smctr_tx_complete(struct net_device *dev, __u16 queue); 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned short smctr_tx_move_frame(struct net_device *dev, 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb, __u8 *pbuff, unsigned int bytes); 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* U */ 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_update_err_stats(struct net_device *dev); 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_update_rx_chain(struct net_device *dev, __u16 queue); 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 queue); 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* W */ 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_wait_cmd(struct net_device *dev); 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_wait_while_cbusy(struct net_device *dev); 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TO_256_BYTE_BOUNDRY(X) (((X + 0xff) & 0xff00) - X) 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TO_PARAGRAPH_BOUNDRY(X) (((X + 0x0f) & 0xfff0) - X) 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PARAGRAPH_BOUNDRY(X) smctr_malloc(dev, TO_PARAGRAPH_BOUNDRY(X)) 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Allocate Adapter Shared Memory. 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IMPORTANT NOTE: Any changes to this function MUST be mirrored in the 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * function "get_num_rx_bdbs" below!!! 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Order of memory allocation: 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0. Initial System Configuration Block Pointer 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. System Configuration Block 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. System Control Block 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. Action Command Block 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4. Interrupt Status Block 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5. MAC TX FCB'S 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6. NON-MAC TX FCB'S 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7. MAC TX BDB'S 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8. NON-MAC TX BDB'S 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9. MAC RX FCB'S 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 10. NON-MAC RX FCB'S 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 11. MAC RX BDB'S 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 12. NON-MAC RX BDB'S 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 13. MAC TX Data Buffer( 1, 256 byte buffer) 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 14. MAC RX Data Buffer( 1, 256 byte buffer) 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 15. NON-MAC TX Data Buffer 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 16. NON-MAC RX Data Buffer 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_alloc_shared_memory(struct net_device *dev) 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_alloc_shared_memory\n", dev->name); 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate initial System Control Block pointer. 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This pointer is located in the last page, last offset - 4. 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->iscpb_ptr = (ISCPBlock *)(tp->ram_access + ((__u32)64 * 0x400) 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds - (long)ISCP_BLOCK_SIZE); 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate System Control Blocks. */ 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->scgb_ptr = (SCGBlock *)smctr_malloc(dev, sizeof(SCGBlock)); 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PARAGRAPH_BOUNDRY(tp->sh_mem_used); 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr = (SCLBlock *)smctr_malloc(dev, sizeof(SCLBlock)); 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PARAGRAPH_BOUNDRY(tp->sh_mem_used); 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->acb_head = (ACBlock *)smctr_malloc(dev, 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(ACBlock)*tp->num_acbs); 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PARAGRAPH_BOUNDRY(tp->sh_mem_used); 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->isb_ptr = (ISBlock *)smctr_malloc(dev, sizeof(ISBlock)); 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PARAGRAPH_BOUNDRY(tp->sh_mem_used); 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->misc_command_data = (__u16 *)smctr_malloc(dev, MISC_DATA_SIZE); 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PARAGRAPH_BOUNDRY(tp->sh_mem_used); 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate transmit FCBs. */ 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_fcb_head[MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(FCBlock) * tp->num_tx_fcbs[MAC_QUEUE]); 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_fcb_head[NON_MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(FCBlock) * tp->num_tx_fcbs[NON_MAC_QUEUE]); 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_fcb_head[BUG_QUEUE] = (FCBlock *)smctr_malloc(dev, 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(FCBlock) * tp->num_tx_fcbs[BUG_QUEUE]); 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate transmit BDBs. */ 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_bdb_head[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(BDBlock) * tp->num_tx_bdbs[MAC_QUEUE]); 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_bdb_head[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(BDBlock) * tp->num_tx_bdbs[NON_MAC_QUEUE]); 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_bdb_head[BUG_QUEUE] = (BDBlock *)smctr_malloc(dev, 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(BDBlock) * tp->num_tx_bdbs[BUG_QUEUE]); 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate receive FCBs. */ 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_fcb_head[MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(FCBlock) * tp->num_rx_fcbs[MAC_QUEUE]); 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_fcb_head[NON_MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(FCBlock) * tp->num_rx_fcbs[NON_MAC_QUEUE]); 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate receive BDBs. */ 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_bdb_head[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(BDBlock) * tp->num_rx_bdbs[MAC_QUEUE]); 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_bdb_end[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 0); 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_bdb_head[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(BDBlock) * tp->num_rx_bdbs[NON_MAC_QUEUE]); 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_bdb_end[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 0); 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate MAC transmit buffers. 39525985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * MAC Tx Buffers doen't have to be on an ODD Boundary. 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_head[MAC_QUEUE] 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[MAC_QUEUE]); 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_curr[MAC_QUEUE] = tp->tx_buff_head[MAC_QUEUE]; 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_end [MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate BUG transmit buffers. */ 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_head[BUG_QUEUE] 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[BUG_QUEUE]); 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_curr[BUG_QUEUE] = tp->tx_buff_head[BUG_QUEUE]; 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_end[BUG_QUEUE] = (__u16 *)smctr_malloc(dev, 0); 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate MAC receive data buffers. 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MAC Rx buffer doesn't have to be on a 256 byte boundary. 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_buff_head[MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[MAC_QUEUE]); 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_buff_end[MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate Non-MAC transmit buffers. 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ?? For maximum Netware performance, put Tx Buffers on 41725985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * ODD Boundary and then restore malloc to Even Boundrys. 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_malloc(dev, 1L); 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_head[NON_MAC_QUEUE] 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[NON_MAC_QUEUE]); 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_curr[NON_MAC_QUEUE] = tp->tx_buff_head[NON_MAC_QUEUE]; 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_end [NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_malloc(dev, 1L); 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate Non-MAC receive data buffers. 427af901ca181d92aac3a7dc265144a9081a86d8f39André Goddard Rosa * To guarantee a minimum of 256 contiguous memory to 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * UM_Receive_Packet's lookahead pointer, before a page 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * change or ring end is encountered, place each rx buffer on 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a 256 byte boundary. 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_malloc(dev, TO_256_BYTE_BOUNDRY(tp->sh_mem_used)); 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_buff_head[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[NON_MAC_QUEUE]); 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_buff_end[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 437807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Enter Bypass state. */ 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_bypass_state(struct net_device *dev) 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_bypass_state\n", dev->name); 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, JS_BYPASS_STATE); 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 450807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_checksum_firmware(struct net_device *dev) 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 i, checksum = 0; 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_checksum_firmware\n", dev->name); 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_adapter_ctrl_store(dev); 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < CS_RAM_SIZE; i += 2) 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds checksum += *((__u16 *)(tp->ram_access + i)); 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->microcode_version = *(__u16 *)(tp->ram_access 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + CS_RAM_VERSION_OFFSET); 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->microcode_version >>= 8; 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_adapter_ctrl_store(dev); 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(checksum) 473807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return checksum; 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 475807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init smctr_chk_mca(struct net_device *dev) 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_MCA_LEGACY 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int current_slot; 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 r1, r2, r3, r4, r5; 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds current_slot = mca_find_unused_adapter(smctr_posid, 0); 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(current_slot == MCA_NOTFOUND) 487807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -ENODEV; 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mca_set_adapter_name(current_slot, smctr_name); 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mca_mark_as_used(current_slot); 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->slot_num = current_slot; 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = mca_read_stored_pos(tp->slot_num, 2); 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r2 = mca_read_stored_pos(tp->slot_num, 3); 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->slot_num) 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num - 1) | CNFG_SLOT_ENABLE_BIT)); 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num) | CNFG_SLOT_ENABLE_BIT)); 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(CNFG_POS_REG1); 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r2 = inb(CNFG_POS_REG0); 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->bic_type = BIC_594_CHIP; 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* IO */ 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r2 = mca_read_stored_pos(tp->slot_num, 2); 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r2 &= 0xF0; 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->base_addr = ((__u16)r2 << 8) + (__u16)0x800; 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds request_region(dev->base_addr, SMCTR_IO_EXTENT, smctr_name); 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* IRQ */ 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r5 = mca_read_stored_pos(tp->slot_num, 5); 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r5 &= 0xC; 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(r5) 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->irq = 3; 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x4: 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->irq = 4; 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x8: 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->irq = 10; 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->irq = 15; 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5331fb9df5d3069064c037c81c0ab8bf783ffa5e373Thomas Gleixner if (request_irq(dev->irq, smctr_interrupt, IRQF_SHARED, smctr_name, dev)) { 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_region(dev->base_addr, SMCTR_IO_EXTENT); 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get RAM base */ 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r3 = mca_read_stored_pos(tp->slot_num, 3); 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0x0C0000; 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (r3 & 0x8) 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ram_base += 0x010000; 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (r3 & 0x80) 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ram_base += 0xF00000; 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get Ram Size */ 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r3 &= 0x30; 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r3 >>= 4; 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ram_usable = (__u16)CNFG_SIZE_8KB << r3; 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ram_size = (__u16)CNFG_SIZE_64KB; 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->board_id |= TOKEN_MEDIA; 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r4 = mca_read_stored_pos(tp->slot_num, 4); 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rom_base = ((__u32)(r4 & 0x7) << 13) + 0x0C0000; 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (r4 & 0x8) 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rom_base += 0x010000; 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get ROM size. */ 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r4 >>= 4; 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (r4) { 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rom_size = CNFG_SIZE_8KB; 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rom_size = CNFG_SIZE_16KB; 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rom_size = CNFG_SIZE_32KB; 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rom_size = ROM_DISABLE; 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get Media Type. */ 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r5 = mca_read_stored_pos(tp->slot_num, 5); 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r5 &= CNFG_MEDIA_TYPE_MASK; 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(r5) 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (0): 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->media_type = MEDIA_STP_4; 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (1): 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->media_type = MEDIA_STP_16; 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (3): 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->media_type = MEDIA_UTP_16; 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->media_type = MEDIA_UTP_4; 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->media_menu = 14; 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r2 = mca_read_stored_pos(tp->slot_num, 2); 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(r2 & 0x02)) 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->mode_bits |= EARLY_TOKEN_REL; 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Disable slot */ 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(CNFG_POS_CONTROL_REG, 0); 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->board_id = smctr_get_boardid(dev, 1); 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(tp->board_id & 0xffff) 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case WD8115TA: 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_model = "8115T/A"; 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case WD8115T: 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->extra_info & CHIP_REV_MASK) 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_model = "8115T rev XE"; 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_model = "8115T rev XD"; 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_model = "Unknown"; 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 624807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 626807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -1; 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_MCA_LEGACY */ 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_chg_rx_mask(struct net_device *dev) 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err = 0; 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_chg_rx_mask\n", dev->name); 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_16bit(dev); 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_page(dev, (__u8 *)tp->ram_access); 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->mode_bits & LOOPING_MODE_MASK) 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 |= RX_OWN_BIT; 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 &= ~RX_OWN_BIT; 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->receive_mask & PROMISCUOUS_MODE) 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 |= PROMISCUOUS_BIT; 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 &= ~PROMISCUOUS_BIT; 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->receive_mask & ACCEPT_ERR_PACKETS) 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 |= SAVBAD_BIT; 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 &= ~SAVBAD_BIT; 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES) 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 |= RXATMAC; 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 &= ~RXATMAC; 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->receive_mask & ACCEPT_MULTI_PROM) 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word1 |= MULTICAST_ADDRESS_BIT; 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word1 &= ~MULTICAST_ADDRESS_BIT; 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->receive_mask & ACCEPT_SOURCE_ROUTING_SPANNING) 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word1 |= SOURCE_ROUTING_SPANNING_BITS; 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->receive_mask & ACCEPT_SOURCE_ROUTING) 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word1 |= SOURCE_ROUTING_EXPLORER_BIT; 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word1 &= ~SOURCE_ROUTING_SPANNING_BITS; 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_0, 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &tp->config_word0))) 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 679807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_1, 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &tp->config_word1))) 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 685807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 690807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_clear_int(struct net_device *dev) 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb((tp->trc_mask | CSR_CLRTINT), dev->base_addr + CSR); 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 699807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_clear_trc_reset(int ioaddr) 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 r; 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = inb(ioaddr + MSR); 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(~MSR_RST & r, ioaddr + MSR); 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 709807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The inverse routine to smctr_open(). 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_close(struct net_device *dev) 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb; 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds netif_stop_queue(dev); 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->cleanup = 1; 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Check to see if adapter is already in a closed state. */ 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->status != OPEN) 727807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_16bit(dev); 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_page(dev, (__u8 *)tp->ram_access); 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_remove_cmd(dev))) 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 735807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(;;) 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb = skb_dequeue(&tp->SendSkbQueue); 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(skb == NULL) 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->QueueSkb++; 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(skb); 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 748807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7510f805b86c9492c294c710de8539a8be68b521a86David Woodhousestatic int smctr_decode_firmware(struct net_device *dev, 7520f805b86c9492c294c710de8539a8be68b521a86David Woodhouse const struct firmware *fw) 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds short bit = 0x80, shift = 12; 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DECODE_TREE_NODE *tree; 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds short branch, tsize; 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 buff = 0; 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long weight; 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *ucode; 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 *mem; 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_decode_firmware\n", dev->name); 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7660f805b86c9492c294c710de8539a8be68b521a86David Woodhouse weight = *(long *)(fw->data + WEIGHT_OFFSET); 7670f805b86c9492c294c710de8539a8be68b521a86David Woodhouse tsize = *(__u8 *)(fw->data + TREE_SIZE_OFFSET); 7680f805b86c9492c294c710de8539a8be68b521a86David Woodhouse tree = (DECODE_TREE_NODE *)(fw->data + TREE_OFFSET); 7690f805b86c9492c294c710de8539a8be68b521a86David Woodhouse ucode = (__u8 *)(fw->data + TREE_OFFSET 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + (tsize * sizeof(DECODE_TREE_NODE))); 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem = (__u16 *)(tp->ram_access); 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while(weight) 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds branch = ROOT; 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while((tree + branch)->tag != LEAF && weight) 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds branch = *ucode & bit ? (tree + branch)->llink 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds : (tree + branch)->rlink; 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bit >>= 1; 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds weight--; 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(bit == 0) 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bit = 0x80; 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ucode++; 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buff |= (tree + branch)->info << shift; 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds shift -= 4; 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(shift < 0) 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(mem++) = SWAP_BYTES(buff); 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buff = 0; 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds shift = 12; 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* The following assumes the Control Store Memory has 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * been initialized to zero. If the last partial word 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is zero, it will not be written. 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(buff) 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(mem++) = SWAP_BYTES(buff); 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 809807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_disable_16bit(struct net_device *dev) 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 814807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * On Exit, Adapter is: 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. TRC is in a reset state and un-initialized. 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. Adapter memory is enabled. 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. Control Store memory is out of context (-WCSS is 1). 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_disable_adapter_ctrl_store(struct net_device *dev) 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ioaddr = dev->base_addr; 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_disable_adapter_ctrl_store\n", dev->name); 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->trc_mask |= CSR_WCSS; 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(tp->trc_mask, ioaddr + CSR); 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 834807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_disable_bic_int(struct net_device *dev) 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ioaddr = dev->base_addr; 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->trc_mask = CSR_MSK_ALL | CSR_MSKCBUSY 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | CSR_MSKTINT | CSR_WCSS; 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(tp->trc_mask, ioaddr + CSR); 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 846807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_enable_16bit(struct net_device *dev) 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 r; 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->adapter_bus == BUS_ISA16_TYPE) 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = inb(dev->base_addr + LAAR); 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb((r | LAAR_MEM16ENB), dev->base_addr + LAAR); 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 860807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * To enable the adapter control store memory: 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. Adapter must be in a RESET state. 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. Adapter memory must be enabled. 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. Control Store Memory is in context (-WCSS is 0). 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_enable_adapter_ctrl_store(struct net_device *dev) 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ioaddr = dev->base_addr; 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_enable_adapter_ctrl_store\n", dev->name); 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_trc_reset(ioaddr); 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_adapter_ram(dev); 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->trc_mask &= ~CSR_WCSS; 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(tp->trc_mask, ioaddr + CSR); 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 883807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_enable_adapter_ram(struct net_device *dev) 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ioaddr = dev->base_addr; 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 r; 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_enable_adapter_ram\n", dev->name); 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = inb(ioaddr + MSR); 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(MSR_MEMB | r, ioaddr + MSR); 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 897807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_enable_bic_int(struct net_device *dev) 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ioaddr = dev->base_addr; 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 r; 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(tp->bic_type) 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (BIC_584_CHIP): 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->trc_mask = CSR_MSKCBUSY | CSR_WCSS; 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(tp->trc_mask, ioaddr + CSR); 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = inb(ioaddr + IRR); 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(r | IRR_IEN, ioaddr + IRR); 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (BIC_594_CHIP): 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->trc_mask = CSR_MSKCBUSY | CSR_WCSS; 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(tp->trc_mask, ioaddr + CSR); 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = inb(ioaddr + IMCCR); 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(r | IMCCR_EIL, ioaddr + IMCCR); 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 923807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init smctr_chk_isa(struct net_device *dev) 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ioaddr = dev->base_addr; 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 r1, r2, b, chksum = 0; 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 r; 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err = -ENODEV; 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_chk_isa %#4x\n", dev->name, ioaddr); 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((ioaddr & 0x1F) != 0) 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Grab the region so that no one else tries to probe our ioports. */ 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!request_region(ioaddr, SMCTR_IO_EXTENT, smctr_name)) { 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = -EBUSY; 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Checksum SMC node address */ 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < 8; i++) 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds b = inb(ioaddr + LAR0 + i); 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chksum += b; 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chksum != NODE_ADDR_CKSUM) 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out2; 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds b = inb(ioaddr + BDID); 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(b != BRD_ID_8115T) 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "%s: The adapter found is not supported\n", dev->name); 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out2; 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Check for 8115T Board ID */ 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r2 = 0; 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(r = 0; r < 8; r++) 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + 0x8 + r); 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r2 += r1; 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* value of RegF adds up the sum to 0xFF */ 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((r2 != 0xFF) && (r2 != 0xEE)) 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out2; 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get adapter ID */ 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->board_id = smctr_get_boardid(dev, 0); 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(tp->board_id & 0xffff) 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case WD8115TA: 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_model = "8115T/A"; 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case WD8115T: 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->extra_info & CHIP_REV_MASK) 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_model = "8115T rev XE"; 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_model = "8115T rev XD"; 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_model = "Unknown"; 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Store BIC type. */ 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->bic_type = BIC_584_CHIP; 9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->nic_type = NIC_825_CHIP; 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Copy Ram Size */ 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ram_usable = CNFG_SIZE_16KB; 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ram_size = CNFG_SIZE_64KB; 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get 58x Ram Base */ 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr); 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 &= 0x3F; 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r2 = inb(ioaddr + CNFG_LAAR_584); 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r2 &= CNFG_LAAR_MASK; 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r2 <<= 3; 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r2 |= ((r1 & 0x38) >> 3); 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ram_base = ((__u32)r2 << 16) + (((__u32)(r1 & 0x7)) << 13); 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get 584 Irq */ 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = 0; 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + CNFG_ICR_583); 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 &= CNFG_ICR_IR2_584; 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r2 = inb(ioaddr + CNFG_IRR_583); 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r2 &= CNFG_IRR_IRQS; /* 0x60 */ 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r2 >>= 5; 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(r2) 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(r1 == 0) 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->irq = 2; 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->irq = 10; 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(r1 == 0) 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->irq = 3; 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->irq = 11; 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(r1 == 0) 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->extra_info & ALTERNATE_IRQ_BIT) 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->irq = 5; 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->irq = 4; 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->irq = 15; 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 3: 10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(r1 == 0) 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->irq = 7; 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->irq = 4; 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "%s: No IRQ found aborting\n", dev->name); 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out2; 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10641fb9df5d3069064c037c81c0ab8bf783ffa5e373Thomas Gleixner if (request_irq(dev->irq, smctr_interrupt, IRQF_SHARED, smctr_name, dev)) 10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out2; 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get 58x Rom Base */ 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + CNFG_BIO_583); 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 &= 0x3E; 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 |= 0x40; 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rom_base = (__u32)r1 << 13; 10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get 58x Rom Size */ 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + CNFG_BIO_583); 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 &= 0xC0; 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(r1 == 0) 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rom_size = ROM_DISABLE; 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 >>= 6; 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rom_size = (__u16)CNFG_SIZE_8KB << r1; 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get 58x Boot Status */ 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + CNFG_GP2); 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->mode_bits &= (~BOOT_STATUS_MASK); 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(r1 & CNFG_GP2_BOOT_NIBBLE) 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->mode_bits |= BOOT_TYPE_1; 10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get 58x Zero Wait State */ 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->mode_bits &= (~ZERO_WAIT_STATE_MASK); 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + CNFG_IRR_583); 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(r1 & CNFG_IRR_ZWS) 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->mode_bits |= ZERO_WAIT_STATE_8_BIT; 11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->board_id & BOARD_16BIT) 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + CNFG_LAAR_584); 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(r1 & CNFG_LAAR_ZWS) 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->mode_bits |= ZERO_WAIT_STATE_16_BIT; 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get 584 Media Menu */ 11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->media_menu = 14; 11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + CNFG_IRR_583); 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->mode_bits &= 0xf8ff; /* (~CNFG_INTERFACE_TYPE_MASK) */ 11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((tp->board_id & TOKEN_MEDIA) == TOKEN_MEDIA) 11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get Advanced Features */ 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(((r1 & 0x6) >> 1) == 0x3) 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->media_type |= MEDIA_UTP_16; 11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(((r1 & 0x6) >> 1) == 0x2) 11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->media_type |= MEDIA_STP_16; 11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(((r1 & 0x6) >> 1) == 0x1) 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->media_type |= MEDIA_UTP_4; 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->media_type |= MEDIA_STP_4; 11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + CNFG_GP2); 11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(r1 & 0x2) ) /* GP2_ETRD */ 11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->mode_bits |= EARLY_TOKEN_REL; 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* see if the chip is corrupted 11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_read_584_chksum(ioaddr)) 11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "%s: EEPROM Checksum Failure\n", dev->name); 11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_irq(dev->irq, dev); 11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out2; 11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1147807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout2: 11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_region(ioaddr, SMCTR_IO_EXTENT); 11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 11531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init smctr_get_boardid(struct net_device *dev, int mca) 11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ioaddr = dev->base_addr; 11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 r, r1, IdByte; 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 BoardIdMask; 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->board_id = BoardIdMask = 0; 11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(mca) 11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BoardIdMask |= (MICROCHANNEL+INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT); 11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->extra_info |= (INTERFACE_594_CHIP+RAM_SIZE_64K+NIC_825_BIT+ALTERNATE_IRQ_BIT+SLOT_16BIT); 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BoardIdMask|=(INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT); 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->extra_info |= (INTERFACE_584_CHIP + RAM_SIZE_64K 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + NIC_825_BIT + ALTERNATE_IRQ_BIT); 11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!mca) 11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = inb(ioaddr + BID_REG_1); 11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r &= 0x0c; 11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(r, ioaddr + BID_REG_1); 11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = inb(ioaddr + BID_REG_1); 11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(r & BID_SIXTEEN_BIT_BIT) 11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->extra_info |= SLOT_16BIT; 11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->adapter_bus = BUS_ISA16_TYPE; 11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->adapter_bus = BUS_ISA8_TYPE; 11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->adapter_bus = BUS_MCA_TYPE; 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get Board Id Byte */ 11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IdByte = inb(ioaddr + BID_BOARD_ID_BYTE); 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* if Major version > 1.0 then 11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return; 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(IdByte & 0xF8) 1201807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -1; 12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + BID_REG_1); 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 &= BID_ICR_MASK; 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 |= BID_OTHER_BIT; 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(r1, ioaddr + BID_REG_1); 12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + BID_REG_3); 12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 &= BID_EAR_MASK; 12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 |= BID_ENGR_PAGE; 12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(r1, ioaddr + BID_REG_3); 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + BID_REG_1); 12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 &= BID_ICR_MASK; 12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 |= (BID_RLA | BID_OTHER_BIT); 12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(r1, ioaddr + BID_REG_1); 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + BID_REG_1); 12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while(r1 & BID_RECALL_DONE_MASK) 12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + BID_REG_1); 12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = inb(ioaddr + BID_LAR_0 + BID_REG_6); 12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* clear chip rev bits */ 12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->extra_info &= ~CHIP_REV_MASK; 12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->extra_info |= ((r & BID_EEPROM_CHIP_REV_MASK) << 6); 12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + BID_REG_1); 12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 &= BID_ICR_MASK; 12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 |= BID_OTHER_BIT; 12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(r1, ioaddr + BID_REG_1); 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + BID_REG_3); 12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 &= BID_EAR_MASK; 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 |= BID_EA6; 12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(r1, ioaddr + BID_REG_3); 12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + BID_REG_1); 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 &= BID_ICR_MASK; 12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 |= BID_RLA; 12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(r1, ioaddr + BID_REG_1); 12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + BID_REG_1); 12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while(r1 & BID_RECALL_DONE_MASK) 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r1 = inb(ioaddr + BID_REG_1); 12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1252807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return BoardIdMask; 12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_get_group_address(struct net_device *dev) 12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_GROUP_ADDR); 12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1259807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_wait_cmd(dev); 12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_get_functional_address(struct net_device *dev) 12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_issue_read_word_cmd(dev, RW_FUNCTIONAL_ADDR); 12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1266807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_wait_cmd(dev); 12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Calculate number of Non-MAC receive BDB's and data buffers. 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This function must simulate allocateing shared memory exactly 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * as the allocate_shared_memory function above. 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int smctr_get_num_rx_bdbs(struct net_device *dev) 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mem_used = 0; 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate System Control Blocks. */ 12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += sizeof(SCGBlock); 12801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); 12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += sizeof(SCLBlock); 12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); 12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += sizeof(ACBlock) * tp->num_acbs; 12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); 12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += sizeof(ISBlock); 12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += MISC_DATA_SIZE; 12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate transmit FCB's. */ 12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); 12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[MAC_QUEUE]; 12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[NON_MAC_QUEUE]; 12981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[BUG_QUEUE]; 12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate transmit BDBs. */ 13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[MAC_QUEUE]; 13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[NON_MAC_QUEUE]; 13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[BUG_QUEUE]; 13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate receive FCBs. */ 13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += sizeof(FCBlock) * tp->num_rx_fcbs[MAC_QUEUE]; 13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += sizeof(FCBlock) * tp->num_rx_fcbs[NON_MAC_QUEUE]; 13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate receive BDBs. */ 13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += sizeof(BDBlock) * tp->num_rx_bdbs[MAC_QUEUE]; 13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate MAC transmit buffers. 131325985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * MAC transmit buffers don't have to be on an ODD Boundary. 13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += tp->tx_buff_size[MAC_QUEUE]; 13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate BUG transmit buffers. */ 13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += tp->tx_buff_size[BUG_QUEUE]; 13191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate MAC receive data buffers. 13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MAC receive buffers don't have to be on a 256 byte boundary. 13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[MAC_QUEUE]; 13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate Non-MAC transmit buffers. 13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * For maximum Netware performance, put Tx Buffers on 132725985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * ODD Boundary,and then restore malloc to Even Boundrys. 13281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += 1L; 13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += tp->tx_buff_size[NON_MAC_QUEUE]; 13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += 1L; 13321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* CALCULATE NUMBER OF NON-MAC RX BDB'S 13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * AND NON-MAC RX DATA BUFFERS 13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Make sure the mem_used offset at this point is the 13371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * same as in allocate_shared memory or the following 13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * boundary adjustment will be incorrect (i.e. not allocating 13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the non-mac receive buffers above cannot change the 256 13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte offset). 13411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 13421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Since this cannot be guaranteed, adding the full 256 bytes 13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to the amount of shared memory used at this point will guaranteed 13441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that the rx data buffers do not overflow shared memory. 13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem_used += 0x100; 13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1348807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return (0xffff - mem_used) / (RX_DATA_BUFFER_SIZE + sizeof(BDBlock)); 13491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_get_physical_drop_number(struct net_device *dev) 13521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_issue_read_word_cmd(dev, RW_PHYSICAL_DROP_NUMBER); 13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1355807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_wait_cmd(dev); 13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic __u8 * smctr_get_rx_pointer(struct net_device *dev, short queue) 13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BDBlock *bdb; 13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb = (BDBlock *)((__u32)tp->ram_access 13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + (__u32)(tp->rx_fcb_curr[queue]->trc_bdb_ptr)); 13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_fcb_curr[queue]->bdb_ptr = bdb; 13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1368807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return (__u8 *)bdb->data_block_ptr; 13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_get_station_id(struct net_device *dev) 13721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_MAC_ADDRESS); 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1375807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_wait_cmd(dev); 13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 13791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Get the current statistics. This may be called with the card open 13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * or closed. 13811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct net_device_stats *smctr_get_stats(struct net_device *dev) 13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 13851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1386807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return (struct net_device_stats *)&tp->MacStat; 13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, 13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 bytes_count) 13911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FCBlock *pFCB; 13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BDBlock *pbdb; 13951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short alloc_size; 13961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short *temp; 13971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 20) 13991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "smctr_get_tx_fcb\n"); 14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if there is enough FCB blocks */ 14021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->num_tx_fcbs_used[queue] >= tp->num_tx_fcbs[queue]) 1403807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return (FCBlock *)(-1L); 14041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* round off the input pkt size to the nearest even number */ 14061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds alloc_size = (bytes_count + 1) & 0xfffe; 14071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if enough mem */ 14091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((tp->tx_buff_used[queue] + alloc_size) > tp->tx_buff_size[queue]) 1410807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return (FCBlock *)(-1L); 14111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if past the end ; 14131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * if exactly enough mem to end of ring, alloc from front. 14141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * this avoids update of curr when curr = end 14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(((unsigned long)(tp->tx_buff_curr[queue]) + alloc_size) 14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds >= (unsigned long)(tp->tx_buff_end[queue])) 14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 14191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if enough memory from ring head */ 14201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds alloc_size = alloc_size + 14211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (__u16)((__u32)tp->tx_buff_end[queue] 14221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds - (__u32)tp->tx_buff_curr[queue]); 14231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((tp->tx_buff_used[queue] + alloc_size) 14251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds > tp->tx_buff_size[queue]) 14261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1427807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return (FCBlock *)(-1L); 14281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* ring wrap */ 14311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_curr[queue] = tp->tx_buff_head[queue]; 14321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_used[queue] += alloc_size; 14351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_tx_fcbs_used[queue]++; 14361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_fcb_curr[queue]->frame_length = bytes_count; 14371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_fcb_curr[queue]->memory_alloc = alloc_size; 14381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds temp = tp->tx_buff_curr[queue]; 14391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_curr[queue] 14401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = (__u16 *)((__u32)temp + (__u32)((bytes_count + 1) & 0xfffe)); 14411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbdb = tp->tx_fcb_curr[queue]->bdb_ptr; 14431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbdb->buffer_length = bytes_count; 14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbdb->data_block_ptr = temp; 14451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbdb->trc_data_block_ptr = TRC_POINTER(temp); 14461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pFCB = tp->tx_fcb_curr[queue]; 14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_fcb_curr[queue] = tp->tx_fcb_curr[queue]->next_ptr; 14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1450807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return pFCB; 14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_get_upstream_neighbor_addr(struct net_device *dev) 14541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_issue_read_word_cmd(dev, RW_UPSTREAM_NEIGHBOR_ADDRESS); 14561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1457807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_wait_cmd(dev); 14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_hardware_send_packet(struct net_device *dev, 14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp) 14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct tr_statistics *tstat = &tp->MacStat; 14641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb; 14651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FCBlock *fcb; 14661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG"%s: smctr_hardware_send_packet\n", dev->name); 14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->status != OPEN) 1471807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -1; 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->monitor_state_ready != 1) 1474807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -1; 14751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(;;) 14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Send first buffer from queue */ 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb = skb_dequeue(&tp->SendSkbQueue); 14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(skb == NULL) 1481807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -1; 14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->QueueSkb++; 14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1485807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet if(skb->len < SMC_HEADER_SIZE || skb->len > tp->max_packet_size) 1486807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -1; 14871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_16bit(dev); 14891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_page(dev, (__u8 *)tp->ram_access); 14901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((fcb = smctr_get_tx_fcb(dev, NON_MAC_QUEUE, skb->len)) 14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds == (FCBlock *)(-1L)) 14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 1495807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -1; 14961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_tx_move_frame(dev, skb, 14991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (__u8 *)fcb->bdb_ptr->data_block_ptr, skb->len); 15001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_page(dev, (__u8 *)fcb); 15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_trc_send_packet(dev, fcb, NON_MAC_QUEUE); 15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(skb); 15051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tstat->tx_packets++; 15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 15091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1511807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 15121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_acbs(struct net_device *dev) 15151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 15171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i; 15181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACBlock *acb; 15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 15211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_init_acbs\n", dev->name); 15221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb = tp->acb_head; 15241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->cmd_done_status = (ACB_COMMAND_DONE | ACB_COMMAND_SUCCESSFUL); 15251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->cmd_info = ACB_CHAIN_END; 15261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->cmd = 0; 15271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->subcmd = 0; 15281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->data_offset_lo = 0; 15291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->data_offset_hi = 0; 15301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->next_ptr 15311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = (ACBlock *)(((char *)acb) + sizeof(ACBlock)); 15321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->trc_next_ptr = TRC_POINTER(acb->next_ptr); 15331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 1; i < tp->num_acbs; i++) 15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 15361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb = acb->next_ptr; 15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->cmd_done_status 15381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = (ACB_COMMAND_DONE | ACB_COMMAND_SUCCESSFUL); 15391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->cmd_info = ACB_CHAIN_END; 15401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->cmd = 0; 15411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->subcmd = 0; 15421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->data_offset_lo = 0; 15431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->data_offset_hi = 0; 15441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->next_ptr 15451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = (ACBlock *)(((char *)acb) + sizeof(ACBlock)); 15461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->trc_next_ptr = TRC_POINTER(acb->next_ptr); 15471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->next_ptr = tp->acb_head; 15501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acb->trc_next_ptr = TRC_POINTER(tp->acb_head); 15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->acb_next = tp->acb_head->next_ptr; 15521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->acb_curr = tp->acb_head->next_ptr; 15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_acbs_used = 0; 15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1555807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_adapter(struct net_device *dev) 15591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_init_adapter\n", dev->name); 15651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->status = CLOSED; 15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->page_offset_mask = (tp->ram_usable * 1024) - 1; 15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_head_init(&tp->SendSkbQueue); 15691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->QueueSkb = MAX_TX_QUEUE; 15701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(tp->group_address_0 & 0x0080)) 15721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->group_address_0 |= 0x00C0; 15731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(tp->functional_address_0 & 0x00C0)) 15751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->functional_address_0 |= 0x00C0; 15761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->functional_address[0] &= 0xFF7F; 15781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->authorized_function_classes == 0) 15801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->authorized_function_classes = 0x7FFF; 15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->authorized_access_priority == 0) 15831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->authorized_access_priority = 0x06; 15841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_bic_int(dev); 15861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_trc_reset(dev->base_addr); 15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_16bit(dev); 15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_page(dev, (__u8 *)tp->ram_access); 15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_checksum_firmware(dev)) 15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1593807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet printk(KERN_ERR "%s: Previously loaded firmware is missing\n",dev->name); 1594807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -ENOENT; 15951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_ram_memory_test(dev))) 15981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "%s: RAM memory test failed.\n", dev->name); 1600807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -EIO; 16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_rx_look_ahead(dev); 16041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_load_node_addr(dev); 16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize adapter for Internal Self Test. */ 16071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_reset_adapter(dev); 16081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_init_card_real(dev))) 16091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 16101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "%s: Initialization of card failed (%d)\n", 16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->name, err); 1612807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -EINVAL; 16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* This routine clobbers the TRC's internal registers. */ 16161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_internal_self_test(dev))) 16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 16181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "%s: Card failed internal self test (%d)\n", 16191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->name, err); 1620807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -EINVAL; 16211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Re-Initialize adapter's internal registers */ 16241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_reset_adapter(dev); 16251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_init_card_real(dev))) 16261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 16271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "%s: Initialization of card failed (%d)\n", 16281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->name, err); 1629807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -EINVAL; 16301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_bic_int(dev); 16331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK))) 1635807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 16361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 16381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1639807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 16401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_card_real(struct net_device *dev) 16431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 16451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err = 0; 16461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 16481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_init_card_real\n", dev->name); 16491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sh_mem_used = 0; 16511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_acbs = NUM_OF_ACBS; 16521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Range Check Max Packet Size */ 16541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->max_packet_size < 256) 16551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->max_packet_size = 256; 16561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 16571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 16581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->max_packet_size > NON_MAC_TX_BUFFER_MEMORY) 16591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->max_packet_size = NON_MAC_TX_BUFFER_MEMORY; 16601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_of_tx_buffs = (NON_MAC_TX_BUFFER_MEMORY 16631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds / tp->max_packet_size) - 1; 16641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->num_of_tx_buffs > NUM_NON_MAC_TX_FCBS) 16661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_of_tx_buffs = NUM_NON_MAC_TX_FCBS; 16671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 16681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 16691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->num_of_tx_buffs == 0) 16701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_of_tx_buffs = 1; 16711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Tx queue constants */ 16741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_tx_fcbs [BUG_QUEUE] = NUM_BUG_TX_FCBS; 16751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_tx_bdbs [BUG_QUEUE] = NUM_BUG_TX_BDBS; 16761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_size [BUG_QUEUE] = BUG_TX_BUFFER_MEMORY; 16771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_used [BUG_QUEUE] = 0; 16781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_queue_status [BUG_QUEUE] = NOT_TRANSMITING; 16791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_tx_fcbs [MAC_QUEUE] = NUM_MAC_TX_FCBS; 16811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_tx_bdbs [MAC_QUEUE] = NUM_MAC_TX_BDBS; 16821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_size [MAC_QUEUE] = MAC_TX_BUFFER_MEMORY; 16831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_used [MAC_QUEUE] = 0; 16841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_queue_status [MAC_QUEUE] = NOT_TRANSMITING; 16851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_tx_fcbs [NON_MAC_QUEUE] = NUM_NON_MAC_TX_FCBS; 16871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_tx_bdbs [NON_MAC_QUEUE] = NUM_NON_MAC_TX_BDBS; 16881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_size [NON_MAC_QUEUE] = NON_MAC_TX_BUFFER_MEMORY; 16891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_used [NON_MAC_QUEUE] = 0; 16901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_queue_status [NON_MAC_QUEUE] = NOT_TRANSMITING; 16911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Receive Queue Constants */ 16931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_rx_fcbs[MAC_QUEUE] = NUM_MAC_RX_FCBS; 16941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_rx_bdbs[MAC_QUEUE] = NUM_MAC_RX_BDBS; 16951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->extra_info & CHIP_REV_MASK) 16971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_rx_fcbs[NON_MAC_QUEUE] = 78; /* 825 Rev. XE */ 16981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 16991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_rx_fcbs[NON_MAC_QUEUE] = 7; /* 825 Rev. XD */ 17001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_rx_bdbs[NON_MAC_QUEUE] = smctr_get_num_rx_bdbs(dev); 17021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_alloc_shared_memory(dev); 17041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_init_shared_memory(dev); 17051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_init_timers_cmd(dev))) 1707807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 17081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_init_txrx_cmd(dev))) 17101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 17111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "%s: Hardware failure\n", dev->name); 1712807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 17131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1715807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 17161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_rx_bdbs(struct net_device *dev) 17191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 17211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i, j; 17221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BDBlock *bdb; 17231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 *buf; 17241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 17261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_init_rx_bdbs\n", dev->name); 17271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < NUM_RX_QS_USED; i++) 17291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 17301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb = tp->rx_bdb_head[i]; 17311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf = tp->rx_buff_head[i]; 17321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->info = (BDB_CHAIN_END | BDB_NO_WARNING); 17331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->buffer_length = RX_DATA_BUFFER_SIZE; 17341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock)); 17351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->data_block_ptr = buf; 17361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); 17371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(i == NON_MAC_QUEUE) 17391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->trc_data_block_ptr = RX_BUFF_TRC_POINTER(buf); 17401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 17411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->trc_data_block_ptr = TRC_POINTER(buf); 17421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(j = 1; j < tp->num_rx_bdbs[i]; j++) 17441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 17451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->next_ptr->back_ptr = bdb; 17461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb = bdb->next_ptr; 17471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf = (__u16 *)((char *)buf + RX_DATA_BUFFER_SIZE); 17481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING); 17491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->buffer_length = RX_DATA_BUFFER_SIZE; 17501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock)); 17511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->data_block_ptr = buf; 17521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); 17531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(i == NON_MAC_QUEUE) 17551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->trc_data_block_ptr = RX_BUFF_TRC_POINTER(buf); 17561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 17571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->trc_data_block_ptr = TRC_POINTER(buf); 17581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->next_ptr = tp->rx_bdb_head[i]; 17611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->trc_next_ptr = TRC_POINTER(tp->rx_bdb_head[i]); 17621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_bdb_head[i]->back_ptr = bdb; 17641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_bdb_curr[i] = tp->rx_bdb_head[i]->next_ptr; 17651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1767807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 17681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_rx_fcbs(struct net_device *dev) 17711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 17731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i, j; 17741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FCBlock *fcb; 17751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < NUM_RX_QS_USED; i++) 17771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 17781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb = tp->rx_fcb_head[i]; 17791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->frame_status = 0; 17801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->frame_length = 0; 17811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->info = FCB_CHAIN_END; 17821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->next_ptr = (FCBlock *)(((char*)fcb) + sizeof(FCBlock)); 17831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(i == NON_MAC_QUEUE) 17841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->trc_next_ptr = RX_FCB_TRC_POINTER(fcb->next_ptr); 17851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 17861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); 17871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(j = 1; j < tp->num_rx_fcbs[i]; j++) 17891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 17901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->next_ptr->back_ptr = fcb; 17911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb = fcb->next_ptr; 17921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->frame_status = 0; 17931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->frame_length = 0; 17941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->info = FCB_WARNING; 17951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->next_ptr 17961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = (FCBlock *)(((char *)fcb) + sizeof(FCBlock)); 17971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(i == NON_MAC_QUEUE) 17991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->trc_next_ptr 18001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = RX_FCB_TRC_POINTER(fcb->next_ptr); 18011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 18021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->trc_next_ptr 18031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = TRC_POINTER(fcb->next_ptr); 18041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->next_ptr = tp->rx_fcb_head[i]; 18071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(i == NON_MAC_QUEUE) 18091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->trc_next_ptr = RX_FCB_TRC_POINTER(fcb->next_ptr); 18101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 18111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); 18121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_fcb_head[i]->back_ptr = fcb; 18141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_fcb_curr[i] = tp->rx_fcb_head[i]->next_ptr; 18151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1817807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 18181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_shared_memory(struct net_device *dev) 18211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 18231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i; 18241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 *iscpb; 18251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 18271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_init_shared_memory\n", dev->name); 18281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_page(dev, (__u8 *)(unsigned int)tp->iscpb_ptr); 18301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize Initial System Configuration Point. (ISCP) */ 18321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iscpb = (__u32 *)PAGE_POINTER(&tp->iscpb_ptr->trc_scgb_ptr); 18331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *iscpb = (__u32)(SWAP_WORDS(TRC_POINTER(tp->scgb_ptr))); 18341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_page(dev, (__u8 *)tp->ram_access); 18361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize System Configuration Pointers. (SCP) */ 18381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->scgb_ptr->config = (SCGB_ADDRESS_POINTER_FORMAT 18391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | SCGB_MULTI_WORD_CONTROL | SCGB_DATA_FORMAT 18401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | SCGB_BURST_LENGTH); 18411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->scgb_ptr->trc_sclb_ptr = TRC_POINTER(tp->sclb_ptr); 18431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->scgb_ptr->trc_acb_ptr = TRC_POINTER(tp->acb_head); 18441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->scgb_ptr->trc_isb_ptr = TRC_POINTER(tp->isb_ptr); 18451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->scgb_ptr->isbsiz = (sizeof(ISBlock)) - 2; 18461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize System Control Block. (SCB) */ 18481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_NOP; 18491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->iack_code = 0; 18501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->resume_control = 0; 18511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->int_mask_control = 0; 18521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->int_mask_state = 0; 18531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize Interrupt Status Block. (ISB) */ 18551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < NUM_OF_INTERRUPTS; i++) 18561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 18571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->isb_ptr->IStatus[i].IType = 0xf0; 18581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->isb_ptr->IStatus[i].ISubtype = 0; 18591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->current_isb_index = 0; 18621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize Action Command Block. (ACB) */ 18641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_init_acbs(dev); 18651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize transmit FCB's and BDB's. */ 18671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_link_tx_fcbs_to_bdbs(dev); 18681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_init_tx_bdbs(dev); 18691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_init_tx_fcbs(dev); 18701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize receive FCB's and BDB's. */ 18721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_init_rx_bdbs(dev); 18731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_init_rx_fcbs(dev); 18741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1875807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 18761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_tx_bdbs(struct net_device *dev) 18791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 18811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i, j; 18821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BDBlock *bdb; 18831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < NUM_TX_QS_USED; i++) 18851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 18861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb = tp->tx_bdb_head[i]; 18871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING); 18881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock)); 18891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); 18901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(j = 1; j < tp->num_tx_bdbs[i]; j++) 18921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 18931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->next_ptr->back_ptr = bdb; 18941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb = bdb->next_ptr; 18951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING); 18961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->next_ptr 18971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = (BDBlock *)(((char *)bdb) + sizeof( BDBlock)); bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); 18981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->next_ptr = tp->tx_bdb_head[i]; 19011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->trc_next_ptr = TRC_POINTER(tp->tx_bdb_head[i]); 19021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_bdb_head[i]->back_ptr = bdb; 19031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 19041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1905807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 19061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 19071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_init_tx_fcbs(struct net_device *dev) 19091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 19101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 19111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i, j; 19121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FCBlock *fcb; 19131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < NUM_TX_QS_USED; i++) 19151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 19161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb = tp->tx_fcb_head[i]; 19171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->frame_status = 0; 19181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->frame_length = 0; 19191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->info = FCB_CHAIN_END; 19201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->next_ptr = (FCBlock *)(((char *)fcb) + sizeof(FCBlock)); 19211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); 19221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(j = 1; j < tp->num_tx_fcbs[i]; j++) 19241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 19251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->next_ptr->back_ptr = fcb; 19261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb = fcb->next_ptr; 19271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->frame_status = 0; 19281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->frame_length = 0; 19291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->info = FCB_CHAIN_END; 19301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->next_ptr 19311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = (FCBlock *)(((char *)fcb) + sizeof(FCBlock)); 19321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); 19331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 19341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->next_ptr = tp->tx_fcb_head[i]; 19361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->trc_next_ptr = TRC_POINTER(tp->tx_fcb_head[i]); 19371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_fcb_head[i]->back_ptr = fcb; 19391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_fcb_end[i] = tp->tx_fcb_head[i]->next_ptr; 19401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_fcb_curr[i] = tp->tx_fcb_head[i]->next_ptr; 19411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_tx_fcbs_used[i] = 0; 19421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 19431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1944807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 19451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 19461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_internal_self_test(struct net_device *dev) 19481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 19491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 19501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 19511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_test_internal_rom_cmd(dev))) 1953807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 19541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_cmd(dev))) 1956807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 19571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->acb_head->cmd_done_status & 0xff) 1959807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -1; 19601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_test_hic_cmd(dev))) 1962807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 19631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_cmd(dev))) 1965807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 19661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->acb_head->cmd_done_status & 0xff) 1968807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -1; 19691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_test_mac_reg_cmd(dev))) 1971807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 19721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_cmd(dev))) 1974807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 19751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->acb_head->cmd_done_status & 0xff) 1977807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -1; 19781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1979807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 19801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 19811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 19831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The typical workload of the driver: Handle the network interface interrupts. 19841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 19857d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t smctr_interrupt(int irq, void *dev_id) 19861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 19871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_device *dev = dev_id; 19881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp; 19891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ioaddr; 19901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 interrupt_unmask_bits = 0, interrupt_ack_code = 0xff00; 19911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 err1, err = NOT_MY_INTERRUPT; 19921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 isb_type, isb_subtype; 19931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 isb_index; 19941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ioaddr = dev->base_addr; 19961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp = netdev_priv(dev); 19971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->status == NOT_INITIALIZED) 19991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return IRQ_NONE; 20001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock(&tp->lock); 20021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_bic_int(dev); 20041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_16bit(dev); 20051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_clear_int(dev); 20071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* First read the LSB */ 20091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while((tp->isb_ptr->IStatus[tp->current_isb_index].IType & 0xf0) == 0) 20101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 20111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds isb_index = tp->current_isb_index; 20121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds isb_type = tp->isb_ptr->IStatus[isb_index].IType; 20131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds isb_subtype = tp->isb_ptr->IStatus[isb_index].ISubtype; 20141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (tp->current_isb_index)++; 20161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->current_isb_index == NUM_OF_INTERRUPTS) 20171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->current_isb_index = 0; 20181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(isb_type >= 0x10) 20201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 20211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 20221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock(&tp->lock); 20231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return IRQ_HANDLED; 20241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 20251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = HARDWARE_FAILED; 20271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds interrupt_ack_code = isb_index; 20281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->isb_ptr->IStatus[isb_index].IType |= 0xf0; 20291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds interrupt_unmask_bits |= (1 << (__u16)isb_type); 20311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(isb_type) 20331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 20341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISB_IMC_MAC_TYPE_3: 20351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 20361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(isb_subtype) 20381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 20391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 20401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->monitor_state = MS_MONITOR_FSM_INACTIVE; 20411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 20421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 20441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->monitor_state = MS_REPEAT_BEACON_STATE; 20451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 20461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 20481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->monitor_state = MS_REPEAT_CLAIM_TOKEN_STATE; 20491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 20501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 3: 20521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->monitor_state = MS_TRANSMIT_CLAIM_TOKEN_STATE; break; 20531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 4: 20551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->monitor_state = MS_STANDBY_MONITOR_STATE; 20561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 20571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 5: 20591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->monitor_state = MS_TRANSMIT_BEACON_STATE; 20601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 20611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 6: 20631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->monitor_state = MS_ACTIVE_MONITOR_STATE; 20641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 20651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 7: 20671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->monitor_state = MS_TRANSMIT_RING_PURGE_STATE; 20681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 20691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 8: /* diagnostic state */ 20711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 20721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 9: 20741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->monitor_state = MS_BEACON_TEST_STATE; 20751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_lobe_media_test(dev)) 20761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 20771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ring_status_flags = RING_STATUS_CHANGED; 20781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ring_status = AUTO_REMOVAL_ERROR; 20791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_ring_status_chg(dev); 20801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_bypass_state(dev); 20811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 20821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 20831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_issue_insert_cmd(dev); 20841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 20851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* case 0x0a-0xff, illegal states */ 20871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 20881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 20891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 20901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ring_status_flags = MONITOR_STATE_CHANGED; 20921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_ring_status_chg(dev); 20931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_16bit(dev); 20951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 20961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Type 0x02 - MAC Error Counters Interrupt 20981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * One or more MAC Error Counter is half full 20991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MAC Error Counters 21001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Lost_FR_Error_Counter 21011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RCV_Congestion_Counter 21021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FR_copied_Error_Counter 21031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FREQ_Error_Counter 21041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Token_Error_Counter 21051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Line_Error_Counter 21061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Internal_Error_Count 21071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 21081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISB_IMC_MAC_ERROR_COUNTERS: 21091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Read 802.5 Error Counters */ 21101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_issue_read_ring_status_cmd(dev); 21111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 21121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Type 0x04 - MAC Type 2 Interrupt 21141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOST needs to enqueue MAC Frame for transmission 21151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SubType Bit 15 - RQ_INIT_PDU( Request Initialization) * Changed from RQ_INIT_PDU to 21161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * TRC_Status_Changed_Indicate 21171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 21181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISB_IMC_MAC_TYPE_2: 21191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_issue_read_ring_status_cmd(dev); 21201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 21211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Type 0x05 - TX Frame Interrupt (FI). */ 21241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISB_IMC_TX_FRAME: 21251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* BUG QUEUE for TRC stuck receive BUG */ 21261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(isb_subtype & TX_PENDING_PRIORITY_2) 21271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 21281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_tx_complete(dev, BUG_QUEUE)) != SUCCESS) 21291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 21301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 21311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* NON-MAC frames only */ 21331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(isb_subtype & TX_PENDING_PRIORITY_1) 21341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 21351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_tx_complete(dev, NON_MAC_QUEUE)) != SUCCESS) 21361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 21371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 21381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* MAC frames only */ 21401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(isb_subtype & TX_PENDING_PRIORITY_0) 21411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_tx_complete(dev, MAC_QUEUE); break; 21421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Type 0x06 - TX END OF QUEUE (FE) */ 21441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISB_IMC_END_OF_TX_QUEUE: 21451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* BUG queue */ 21461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(isb_subtype & TX_PENDING_PRIORITY_2) 21471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 21481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* ok to clear Receive FIFO overrun 21491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * imask send_BUG now completes. 21501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 21511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds interrupt_unmask_bits |= 0x800; 21521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_queue_status[BUG_QUEUE] = NOT_TRANSMITING; 21541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_tx_complete(dev, BUG_QUEUE)) != SUCCESS) 21551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 21561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_restart_tx_chain(dev, BUG_QUEUE)) != SUCCESS) 21571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 21581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 21591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* NON-MAC queue only */ 21611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(isb_subtype & TX_PENDING_PRIORITY_1) 21621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 21631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_queue_status[NON_MAC_QUEUE] = NOT_TRANSMITING; 21641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_tx_complete(dev, NON_MAC_QUEUE)) != SUCCESS) 21651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 21661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_restart_tx_chain(dev, NON_MAC_QUEUE)) != SUCCESS) 21671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 21681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 21691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* MAC queue only */ 21711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(isb_subtype & TX_PENDING_PRIORITY_0) 21721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 21731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; 21741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_tx_complete(dev, MAC_QUEUE)) != SUCCESS) 21751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 21761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_restart_tx_chain(dev, MAC_QUEUE); 21781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 21791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 21801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Type 0x07 - NON-MAC RX Resource Interrupt 21821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Subtype bit 12 - (BW) BDB warning 21831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Subtype bit 13 - (FW) FCB warning 21841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Subtype bit 14 - (BE) BDB End of chain 21851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Subtype bit 15 - (FE) FCB End of chain 21861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 21871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISB_IMC_NON_MAC_RX_RESOURCE: 21881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_fifo_overrun_count = 0; 21891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->receive_queue_number = NON_MAC_QUEUE; 21901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err1 = smctr_rx_frame(dev); 21911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(isb_subtype & NON_MAC_RX_RESOURCE_FE) 21931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 21941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_resume_rx_fcb_cmd( dev, NON_MAC_QUEUE)) != SUCCESS) break; 21951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->ptr_rx_fcb_overruns) 21971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (*tp->ptr_rx_fcb_overruns)++; 21981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 21991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(isb_subtype & NON_MAC_RX_RESOURCE_BE) 22011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 22021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_resume_rx_bdb_cmd( dev, NON_MAC_QUEUE)) != SUCCESS) break; 22031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->ptr_rx_bdb_overruns) 22051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (*tp->ptr_rx_bdb_overruns)++; 22061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = err1; 22081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Type 0x08 - MAC RX Resource Interrupt 22111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Subtype bit 12 - (BW) BDB warning 22121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Subtype bit 13 - (FW) FCB warning 22131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Subtype bit 14 - (BE) BDB End of chain 22141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Subtype bit 15 - (FE) FCB End of chain 22151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 22161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISB_IMC_MAC_RX_RESOURCE: 22171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->receive_queue_number = MAC_QUEUE; 22181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err1 = smctr_rx_frame(dev); 22191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(isb_subtype & MAC_RX_RESOURCE_FE) 22211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 22221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_resume_rx_fcb_cmd( dev, MAC_QUEUE)) != SUCCESS) 22231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->ptr_rx_fcb_overruns) 22261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (*tp->ptr_rx_fcb_overruns)++; 22271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(isb_subtype & MAC_RX_RESOURCE_BE) 22301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 22311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_resume_rx_bdb_cmd( dev, MAC_QUEUE)) != SUCCESS) 22321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->ptr_rx_bdb_overruns) 22351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (*tp->ptr_rx_bdb_overruns)++; 22361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = err1; 22381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Type 0x09 - NON_MAC RX Frame Interrupt */ 22411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISB_IMC_NON_MAC_RX_FRAME: 22421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_fifo_overrun_count = 0; 22431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->receive_queue_number = NON_MAC_QUEUE; 22441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_rx_frame(dev); 22451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Type 0x0A - MAC RX Frame Interrupt */ 22481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISB_IMC_MAC_RX_FRAME: 22491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->receive_queue_number = MAC_QUEUE; 22501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_rx_frame(dev); 22511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Type 0x0B - TRC status 22541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * TRC has encountered an error condition 22551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * subtype bit 14 - transmit FIFO underrun 22561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * subtype bit 15 - receive FIFO overrun 22571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 22581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISB_IMC_TRC_FIFO_STATUS: 22591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(isb_subtype & TRC_FIFO_STATUS_TX_UNDERRUN) 22601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 22611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->ptr_tx_fifo_underruns) 22621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (*tp->ptr_tx_fifo_underruns)++; 22631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(isb_subtype & TRC_FIFO_STATUS_RX_OVERRUN) 22661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 22671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* update overrun stuck receive counter 22681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * if >= 3, has to clear it by sending 22691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * back to back frames. We pick 22701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DAT(duplicate address MAC frame) 22711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 22721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_fifo_overrun_count++; 22731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->rx_fifo_overrun_count >= 3) 22751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 22761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_fifo_overrun_count = 0; 22771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* delay clearing fifo overrun 22791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * imask till send_BUG tx 22801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * complete posted 22811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 22821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds interrupt_unmask_bits &= (~0x800); 22831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_CRIT "Jay please send bug\n");// smctr_send_bug(dev); 22841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->ptr_rx_fifo_overruns) 22871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (*tp->ptr_rx_fifo_overruns)++; 22881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = SUCCESS; 22911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Type 0x0C - Action Command Status Interrupt 22941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Subtype bit 14 - CB end of command chain (CE) 22951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Subtype bit 15 - CB command interrupt (CI) 22961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 22971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISB_IMC_COMMAND_STATUS: 22981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = SUCCESS; 22991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->acb_head->cmd == ACB_CMD_HIC_NOP) 23001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 23011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "i1\n"); 23021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 23031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* XXXXXXXXXXXXXXXXX */ 23051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* err = UM_Interrupt(dev); */ 23061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_16bit(dev); 23081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 23101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 23111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((tp->acb_head->cmd 23128e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches == ACB_CMD_READ_TRC_STATUS) && 23138e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (tp->acb_head->subcmd 23148e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches == RW_TRC_STATUS_BLOCK)) 23151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 231679ea13ce07c951bb4d95471e7300baa0f1be9e78Al Viro if(tp->ptr_bcn_type) 23171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 23181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(tp->ptr_bcn_type) 23191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = (__u32)((SBlock *)tp->misc_command_data)->BCN_Type; 23201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & ERROR_COUNTERS_CHANGED) 23231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 23241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_update_err_stats(dev); 23251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & TI_NDIS_RING_STATUS_CHANGED) 23281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 23291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ring_status 23301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = ((SBlock*)tp->misc_command_data)->TI_NDIS_Ring_Status; 23311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 23321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_ring_status_chg(dev); 23331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_16bit(dev); 23348e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if((tp->ring_status & REMOVE_RECEIVED) && 23358e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (tp->config_word0 & NO_AUTOREMOVE)) 23361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 23371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_issue_remove_cmd(dev); 23381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(err != SUCCESS) 23411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 23421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->acb_pending = 0; 23431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 23441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & UNA_CHANGED) 23481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 23491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->ptr_una) 23501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 23511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ptr_una[0] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[0]); 23521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ptr_una[1] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[1]); 23531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ptr_una[2] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[2]); 23541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & READY_TO_SEND_RQ_INIT) { 23591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_send_rq_init(dev); 23601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->acb_pending = 0; 23651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 23661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Type 0x0D - MAC Type 1 interrupt 23681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Subtype -- 00 FR_BCN received at S12 23691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 01 FR_BCN received at S21 23701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 02 FR_DAT(DA=MA, A<>0) received at S21 23711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 03 TSM_EXP at S21 23721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 04 FR_REMOVE received at S42 23731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 05 TBR_EXP, BR_FLAG_SET at S42 23741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 06 TBT_EXP at S53 23751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 23761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISB_IMC_MAC_TYPE_1: 23771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(isb_subtype > 8) 23781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 23791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = HARDWARE_FAILED; 23801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 23811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = SUCCESS; 23841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(isb_subtype) 23851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 23861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 23871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->join_state = JS_BYPASS_STATE; 23881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->status != CLOSED) 23891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 23901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->status = CLOSED; 23911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_status_chg(dev); 23921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 23941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 23961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->join_state = JS_LOBE_TEST_STATE; 23971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 23981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 24001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->join_state = JS_DETECT_MONITOR_PRESENT_STATE; 24011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 24021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 3: 24041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->join_state = JS_AWAIT_NEW_MONITOR_STATE; 24051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 24061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 4: 24081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->join_state = JS_DUPLICATE_ADDRESS_TEST_STATE; 24091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 24101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 5: 24121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->join_state = JS_NEIGHBOR_NOTIFICATION_STATE; 24131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 24141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 6: 24161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->join_state = JS_REQUEST_INITIALIZATION_STATE; 24171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 24181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 7: 24201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->join_state = JS_JOIN_COMPLETE_STATE; 24211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->status = OPEN; 24221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_status_chg(dev); 24231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 24241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 8: 24261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->join_state = JS_BYPASS_WAIT_STATE; 24271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 24281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 24291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break ; 24301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Type 0x0E - TRC Initialization Sequence Interrupt 24321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Subtype -- 00-FF Initializatin sequence complete 24331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 24341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISB_IMC_TRC_INTRNL_TST_STATUS: 24351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->status = INITIALIZED; 24361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 24371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_status_chg(dev); 24381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_16bit(dev); 24391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 24401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* other interrupt types, illegal */ 24421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 24431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 24441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 24451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(err != SUCCESS) 24471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 24481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 24491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Checking the ack code instead of the unmask bits here is because : 24511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * while fixing the stuck receive, DAT frame are sent and mask off 24521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FIFO overrun interrupt temporarily (interrupt_unmask_bits = 0) 24531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * but we still want to issue ack to ISB 24541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 24551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(interrupt_ack_code & 0xff00)) 24561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_issue_int_ack(dev, interrupt_ack_code, interrupt_unmask_bits); 24571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 24591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_bic_int(dev); 24601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock(&tp->lock); 24611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return IRQ_HANDLED; 24631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 24641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_enable_int_cmd(struct net_device *dev, 24661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 interrupt_enable_mask) 24671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 24681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 24691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 24701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_while_cbusy(dev))) 2472807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 24731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->int_mask_control = interrupt_enable_mask; 24751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_CLEAR_INTERRUPT_MASK; 24761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_ctrl_attention(dev); 24781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2479807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 24801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 24811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ibits) 24831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 24841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 24851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_wait_while_cbusy(dev)) 2487807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -1; 24881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->int_mask_control = ibits; 24901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->iack_code = iack_code << 1; /* use the offset from base */ tp->sclb_ptr->resume_control = 0; 24911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_IACK_CODE_VALID | SCLB_CMD_CLEAR_INTERRUPT_MASK; 24921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_ctrl_attention(dev); 24941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2495807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 24961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 24971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_init_timers_cmd(struct net_device *dev) 24991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 25001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 25011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i; 25021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 25031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 *pTimer_Struc = (__u16 *)tp->misc_command_data; 25041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_while_cbusy(dev))) 2506807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 25071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_cmd(dev))) 2509807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 25101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 = THDREN | DMA_TRIGGER | USETPT | NO_AUTOREMOVE; 25121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word1 = 0; 25131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25148e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if((tp->media_type == MEDIA_STP_16) || 25158e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (tp->media_type == MEDIA_UTP_16) || 25168e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (tp->media_type == MEDIA_STP_16_UTP_16)) 25171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 25181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 |= FREQ_16MB_BIT; 25191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->mode_bits & EARLY_TOKEN_REL) 25221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 |= ETREN; 25231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->mode_bits & LOOPING_MODE_MASK) 25251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 |= RX_OWN_BIT; 25261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 25271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 &= ~RX_OWN_BIT; 25281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->receive_mask & PROMISCUOUS_MODE) 25301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 |= PROMISCUOUS_BIT; 25311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 25321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 &= ~PROMISCUOUS_BIT; 25331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->receive_mask & ACCEPT_ERR_PACKETS) 25351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 |= SAVBAD_BIT; 25361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 25371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 &= ~SAVBAD_BIT; 25381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES) 25401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 |= RXATMAC; 25411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 25421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word0 &= ~RXATMAC; 25431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->receive_mask & ACCEPT_MULTI_PROM) 25451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word1 |= MULTICAST_ADDRESS_BIT; 25461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 25471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word1 &= ~MULTICAST_ADDRESS_BIT; 25481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->receive_mask & ACCEPT_SOURCE_ROUTING_SPANNING) 25501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word1 |= SOURCE_ROUTING_SPANNING_BITS; 25511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 25521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 25531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->receive_mask & ACCEPT_SOURCE_ROUTING) 25541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word1 |= SOURCE_ROUTING_EXPLORER_BIT; 25551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 25561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word1 &= ~SOURCE_ROUTING_SPANNING_BITS; 25571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25598e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if((tp->media_type == MEDIA_STP_16) || 25608e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (tp->media_type == MEDIA_UTP_16) || 25618e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (tp->media_type == MEDIA_STP_16_UTP_16)) 25621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 25631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word1 |= INTERFRAME_SPACING_16; 25641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 25661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->config_word1 |= INTERFRAME_SPACING_4; 25671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = tp->config_word0; 25691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = tp->config_word1; 25701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25718e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if((tp->media_type == MEDIA_STP_4) || 25728e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (tp->media_type == MEDIA_UTP_4) || 25738e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (tp->media_type == MEDIA_STP_4_UTP_4)) 25741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 25751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x00FA; /* prescale */ 25761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x2710; /* TPT_limit */ 25771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x2710; /* TQP_limit */ 25781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x0A28; /* TNT_limit */ 25791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x3E80; /* TBT_limit */ 25801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x3A98; /* TSM_limit */ 25811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x1B58; /* TAM_limit */ 25821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x00C8; /* TBR_limit */ 25831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x07D0; /* TER_limit */ 25841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x000A; /* TGT_limit */ 25851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x1162; /* THT_limit */ 25861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x07D0; /* TRR_limit */ 25871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x1388; /* TVX_limit */ 25881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x0000; /* reserved */ 25891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 25911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 25921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x03E8; /* prescale */ 25931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x9C40; /* TPT_limit */ 25941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x9C40; /* TQP_limit */ 25951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x0A28; /* TNT_limit */ 25961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x3E80; /* TBT_limit */ 25971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x3A98; /* TSM_limit */ 25981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x1B58; /* TAM_limit */ 25991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x00C8; /* TBR_limit */ 26001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x07D0; /* TER_limit */ 26011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x000A; /* TGT_limit */ 26021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x4588; /* THT_limit */ 26031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x1F40; /* TRR_limit */ 26041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x4E20; /* TVX_limit */ 26051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = 0x0000; /* reserved */ 26061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 26071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set node address. */ 26091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = dev->dev_addr[0] << 8 26101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | (dev->dev_addr[1] & 0xFF); 26111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = dev->dev_addr[2] << 8 26121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | (dev->dev_addr[3] & 0xFF); 26131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = dev->dev_addr[4] << 8 26141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | (dev->dev_addr[5] & 0xFF); 26151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set group address. */ 26171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = tp->group_address_0 << 8 26181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | tp->group_address_0 >> 8; 26191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = tp->group_address[0] << 8 26201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | tp->group_address[0] >> 8; 26211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = tp->group_address[1] << 8 26221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | tp->group_address[1] >> 8; 26231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set functional address. */ 26251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = tp->functional_address_0 << 8 26261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | tp->functional_address_0 >> 8; 26271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = tp->functional_address[0] << 8 26281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | tp->functional_address[0] >> 8; 26291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = tp->functional_address[1] << 8 26301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | tp->functional_address[1] >> 8; 26311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set Bit-Wise group address. */ 26331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = tp->bitwise_group_address[0] << 8 26341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | tp->bitwise_group_address[0] >> 8; 26351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = tp->bitwise_group_address[1] << 8 26361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | tp->bitwise_group_address[1] >> 8; 26371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set ring number address. */ 26391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = tp->source_ring_number; 26401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = tp->target_ring_number; 26411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Physical drop number. */ 26431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = (unsigned short)0; 26441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = (unsigned short)0; 26451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Product instance ID. */ 26471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < 9; i++) 26481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pTimer_Struc++ = (unsigned short)0; 26491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TRC_TIMERS, 0); 26511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2652807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 26531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 26541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_init_txrx_cmd(struct net_device *dev) 26561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 26571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 26581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i; 26591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 26601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void **txrx_ptrs = (void *)tp->misc_command_data; 26611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_while_cbusy(dev))) 2663807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 26641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_cmd(dev))) 26661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 26671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "%s: Hardware failure\n", dev->name); 2668807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 26691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 26701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize Transmit Queue Pointers that are used, to point to 26721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a single FCB. 26731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 26741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < NUM_TX_QS_USED; i++) 26751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *txrx_ptrs++ = (void *)TRC_POINTER(tp->tx_fcb_head[i]); 26761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize Transmit Queue Pointers that are NOT used to ZERO. */ 26781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(; i < MAX_TX_QS; i++) 26791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *txrx_ptrs++ = (void *)0; 26801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize Receive Queue Pointers (MAC and Non-MAC) that are 26821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * used, to point to a single FCB and a BDB chain of buffers. 26831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 26841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < NUM_RX_QS_USED; i++) 26851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 26861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *txrx_ptrs++ = (void *)TRC_POINTER(tp->rx_fcb_head[i]); 26871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *txrx_ptrs++ = (void *)TRC_POINTER(tp->rx_bdb_head[i]); 26881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 26891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize Receive Queue Pointers that are NOT used to ZERO. */ 26911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(; i < MAX_RX_QS; i++) 26921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 26931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *txrx_ptrs++ = (void *)0; 26941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *txrx_ptrs++ = (void *)0; 26951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 26961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TX_RX, 0); 26981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2699807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 27001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 27011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_insert_cmd(struct net_device *dev) 27031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 27041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 27051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_setup_single_cmd(dev, ACB_CMD_INSERT, ACB_SUB_CMD_NOP); 27071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2708807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 27091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 27101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_read_ring_status_cmd(struct net_device *dev) 27121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 27131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 27141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_while_cbusy(dev))) 2716807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 27171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_cmd(dev))) 2719807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 27201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_READ_TRC_STATUS, 27221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds RW_TRC_STATUS_BLOCK); 27231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2724807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 27251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 27261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt) 27281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 27291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 27301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_while_cbusy(dev))) 2732807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 27331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_cmd(dev))) 2735807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 27361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_READ_VALUE, 27381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aword_cnt); 27391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2740807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 27411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 27421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_remove_cmd(struct net_device *dev) 27441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 27451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 27461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 27471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_while_cbusy(dev))) 2749807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 27501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->resume_control = 0; 27521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_REMOVE; 27531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_ctrl_attention(dev); 27551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2756807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 27571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 27581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_resume_acb_cmd(struct net_device *dev) 27601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 27611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 27621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 27631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_while_cbusy(dev))) 2765807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 27661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->resume_control = SCLB_RC_ACB; 27681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID; 27691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->acb_pending = 1; 27711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_ctrl_attention(dev); 27731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2774807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 27751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 27761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue) 27781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 27791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 27801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 27811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_while_cbusy(dev))) 2783807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 27841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(queue == MAC_QUEUE) 27861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_BDB; 27871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 27881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->resume_control = SCLB_RC_RX_NON_MAC_BDB; 27891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID; 27911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_ctrl_attention(dev); 27931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2794807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 27951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 27961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue) 27981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 27991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 28001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 28021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_issue_resume_rx_fcb_cmd\n", dev->name); 28031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_wait_while_cbusy(dev)) 2805807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -1; 28061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(queue == MAC_QUEUE) 28081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_FCB; 28091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 28101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->resume_control = SCLB_RC_RX_NON_MAC_FCB; 28111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID; 28131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_ctrl_attention(dev); 28151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2816807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 28171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 28181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue) 28201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 28211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 28221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 28241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_issue_resume_tx_fcb_cmd\n", dev->name); 28251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_wait_while_cbusy(dev)) 2827807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -1; 28281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->resume_control = (SCLB_RC_TFCB0 << queue); 28301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sclb_ptr->valid_command = SCLB_RESUME_CONTROL_VALID | SCLB_VALID; 28311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_ctrl_attention(dev); 28331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2834807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 28351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 28361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_test_internal_rom_cmd(struct net_device *dev) 28381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 28391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 28401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, 28421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TRC_INTERNAL_ROM_TEST); 28431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2844807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 28451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 28461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_test_hic_cmd(struct net_device *dev) 28481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 28491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 28501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_setup_single_cmd(dev, ACB_CMD_HIC_TEST, 28521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TRC_HOST_INTERFACE_REG_TEST); 28531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2854807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 28551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 28561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_test_mac_reg_cmd(struct net_device *dev) 28581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 28591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 28601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, 28621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TRC_MAC_REGISTERS_TEST); 28631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2864807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 28651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 28661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_trc_loopback_cmd(struct net_device *dev) 28681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 28691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 28701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, 28721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TRC_INTERNAL_LOOPBACK); 28731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2874807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 28751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 28761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_tri_loopback_cmd(struct net_device *dev) 28781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 28791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 28801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, 28821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TRC_TRI_LOOPBACK); 28831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2884807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 28851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 28861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_write_byte_cmd(struct net_device *dev, 28881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds short aword_cnt, void *byte) 28891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 28901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 28911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int iword, ibyte; 28921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 28931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_while_cbusy(dev))) 2895807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 28961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_cmd(dev))) 2898807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 28991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(iword = 0, ibyte = 0; iword < (unsigned int)(aword_cnt & 0xff); 29011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iword++, ibyte += 2) 29021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 29031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->misc_command_data[iword] = (*((__u8 *)byte + ibyte) << 8) 29041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | (*((__u8 *)byte + ibyte + 1)); 29051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2907807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE, 2908807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet aword_cnt); 29091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 29101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_issue_write_word_cmd(struct net_device *dev, 29121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds short aword_cnt, void *word) 29131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 29141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 29151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i, err; 29161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_while_cbusy(dev))) 2918807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 29191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_cmd(dev))) 2921807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 29221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < (unsigned int)(aword_cnt & 0xff); i++) 29241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->misc_command_data[i] = *((__u16 *)word + i); 29251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE, 29271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aword_cnt); 29281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2929807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 29301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 29311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_join_complete_state(struct net_device *dev) 29331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 29341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 29351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, 29371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds JS_JOIN_COMPLETE_STATE); 29381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2939807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 29401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 29411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev) 29431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 29441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 29451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i, j; 29461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FCBlock *fcb; 29471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BDBlock *bdb; 29481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < NUM_TX_QS_USED; i++) 29501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 29511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb = tp->tx_fcb_head[i]; 29521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb = tp->tx_bdb_head[i]; 29531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(j = 0; j < tp->num_tx_fcbs[i]; j++) 29551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 29561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->bdb_ptr = bdb; 29571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->trc_bdb_ptr = TRC_POINTER(bdb); 29581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb = (FCBlock *)((char *)fcb + sizeof(FCBlock)); 29591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb = (BDBlock *)((char *)bdb + sizeof(BDBlock)); 29601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2963807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 29641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 29651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_load_firmware(struct net_device *dev) 29671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 29681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 29690f805b86c9492c294c710de8539a8be68b521a86David Woodhouse const struct firmware *fw; 29701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 i, checksum = 0; 29711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err = 0; 29721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 29741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_load_firmware\n", dev->name); 29751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29760f805b86c9492c294c710de8539a8be68b521a86David Woodhouse if (request_firmware(&fw, "tr_smctr.bin", &dev->dev)) { 29770f805b86c9492c294c710de8539a8be68b521a86David Woodhouse printk(KERN_ERR "%s: firmware not found\n", dev->name); 2978807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return UCODE_NOT_PRESENT; 29790f805b86c9492c294c710de8539a8be68b521a86David Woodhouse } 29800f805b86c9492c294c710de8539a8be68b521a86David Woodhouse 29811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_of_tx_buffs = 4; 29821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->mode_bits |= UMAC; 29831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->receive_mask = 0; 29841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->max_packet_size = 4177; 29851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Can only upload the firmware once per adapter reset. */ 29870f805b86c9492c294c710de8539a8be68b521a86David Woodhouse if (tp->microcode_version != 0) { 29880f805b86c9492c294c710de8539a8be68b521a86David Woodhouse err = (UCODE_PRESENT); 29890f805b86c9492c294c710de8539a8be68b521a86David Woodhouse goto out; 29900f805b86c9492c294c710de8539a8be68b521a86David Woodhouse } 29911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Verify the firmware exists and is there in the right amount. */ 29938e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if (!fw->data || 29948e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (*(fw->data + UCODE_VERSION_OFFSET) < UCODE_VERSION)) 29951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 29960f805b86c9492c294c710de8539a8be68b521a86David Woodhouse err = (UCODE_NOT_PRESENT); 29970f805b86c9492c294c710de8539a8be68b521a86David Woodhouse goto out; 29981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* UCODE_SIZE is not included in Checksum. */ 30010f805b86c9492c294c710de8539a8be68b521a86David Woodhouse for(i = 0; i < *((__u16 *)(fw->data + UCODE_SIZE_OFFSET)); i += 2) 30020f805b86c9492c294c710de8539a8be68b521a86David Woodhouse checksum += *((__u16 *)(fw->data + 2 + i)); 30030f805b86c9492c294c710de8539a8be68b521a86David Woodhouse if (checksum) { 30040f805b86c9492c294c710de8539a8be68b521a86David Woodhouse err = (UCODE_NOT_PRESENT); 30050f805b86c9492c294c710de8539a8be68b521a86David Woodhouse goto out; 30060f805b86c9492c294c710de8539a8be68b521a86David Woodhouse } 30071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* At this point we have a valid firmware image, lets kick it on up. */ 30091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_adapter_ram(dev); 30101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_16bit(dev); 30111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_page(dev, (__u8 *)tp->ram_access); 30121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30138e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if((smctr_checksum_firmware(dev)) || 30148e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (*(fw->data + UCODE_VERSION_OFFSET) > tp->microcode_version)) 30151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 30161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_adapter_ctrl_store(dev); 30171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Zero out ram space for firmware. */ 30191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < CS_RAM_SIZE; i += 2) 30201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *((__u16 *)(tp->ram_access + i)) = 0; 30211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30220f805b86c9492c294c710de8539a8be68b521a86David Woodhouse smctr_decode_firmware(dev, fw); 30231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30240f805b86c9492c294c710de8539a8be68b521a86David Woodhouse tp->microcode_version = *(fw->data + UCODE_VERSION_OFFSET); *((__u16 *)(tp->ram_access + CS_RAM_VERSION_OFFSET)) 30251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = (tp->microcode_version << 8); 30261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *((__u16 *)(tp->ram_access + CS_RAM_CHECKSUM_OFFSET)) 30271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = ~(tp->microcode_version << 8) + 1; 30281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_adapter_ctrl_store(dev); 30301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_checksum_firmware(dev)) 30321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = HARDWARE_FAILED; 30331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 30341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 30351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = UCODE_PRESENT; 30361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 30380f805b86c9492c294c710de8539a8be68b521a86David Woodhouse out: 30390f805b86c9492c294c710de8539a8be68b521a86David Woodhouse release_firmware(fw); 3040807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 30411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 30421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_load_node_addr(struct net_device *dev) 30441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 30451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ioaddr = dev->base_addr; 30461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i; 30471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 r; 30481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < 6; i++) 30501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 30511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = inb(ioaddr + LAR0 + i); 30521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->dev_addr[i] = (char)r; 30531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 30541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->addr_len = 6; 30551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3056807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 30571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 30581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Lobe Media Test. 30601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * During the transmission of the initial 1500 lobe media MAC frames, 30611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the phase lock loop in the 805 chip may lock, and then un-lock, causing 30621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the 825 to go into a PURGE state. When performing a PURGE, the MCT 30631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * microcode will not transmit any frames given to it by the host, and 30641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * will consequently cause a timeout. 30651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 30661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE 1: If the monitor_state is MS_BEACON_TEST_STATE, all transmit 3067025dfdafe77f20b3890981a394774baab7b9c827Frederik Schwarzer * queues other than the one used for the lobe_media_test should be 30681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * disabled.!? 30691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 30701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE 2: If the monitor_state is MS_BEACON_TEST_STATE and the receive_mask 307125985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * has any multi-cast or promiscuous bits set, the receive_mask needs to 307225985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * be changed to clear the multi-cast or promiscuous mode bits, the lobe_test 30731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * run, and then the receive mask set back to its original value if the test 30741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is successful. 30751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 30761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_lobe_media_test(struct net_device *dev) 30771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 30781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 30791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i, perror = 0; 30801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short saved_rcv_mask; 30811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 30831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_lobe_media_test\n", dev->name); 30841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Clear receive mask for lobe test. */ 30861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saved_rcv_mask = tp->receive_mask; 30871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->receive_mask = 0; 30881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_chg_rx_mask(dev); 30901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Setup the lobe media test. */ 30921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_lobe_media_test_cmd(dev); 30931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_wait_cmd(dev)) 3094582b95c2709cd58913ec2a31b0266ba0aa67b03dJulia Lawall goto err; 30951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Tx lobe media test frames. */ 30971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < 1500; ++i) 30981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 30991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_send_lobe_media_test(dev)) 31001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 31011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(perror) 3102582b95c2709cd58913ec2a31b0266ba0aa67b03dJulia Lawall goto err; 31031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 31041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 31051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds perror = 1; 31061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_lobe_media_test_cmd(dev)) 3107582b95c2709cd58913ec2a31b0266ba0aa67b03dJulia Lawall goto err; 31081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 31091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 31101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 31111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_send_dat(dev)) 31131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 31141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_send_dat(dev)) 3115582b95c2709cd58913ec2a31b0266ba0aa67b03dJulia Lawall goto err; 31161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 31171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Check if any frames received during test. */ 31198e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if((tp->rx_fcb_curr[MAC_QUEUE]->frame_status) || 31208e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (tp->rx_fcb_curr[NON_MAC_QUEUE]->frame_status)) 31218e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches goto err; 31221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set receive mask to "Promisc" mode. */ 31241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->receive_mask = saved_rcv_mask; 31251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_chg_rx_mask(dev); 31271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3128582b95c2709cd58913ec2a31b0266ba0aa67b03dJulia Lawall return 0; 3129582b95c2709cd58913ec2a31b0266ba0aa67b03dJulia Lawallerr: 3130582b95c2709cd58913ec2a31b0266ba0aa67b03dJulia Lawall smctr_reset_adapter(dev); 3131582b95c2709cd58913ec2a31b0266ba0aa67b03dJulia Lawall tp->status = CLOSED; 3132582b95c2709cd58913ec2a31b0266ba0aa67b03dJulia Lawall return LOBE_MEDIA_TEST_FAILED; 31331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 31341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_lobe_media_test_cmd(struct net_device *dev) 31361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 31371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 31381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 31391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 31411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_lobe_media_test_cmd\n", dev->name); 31421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Change to lobe media test state. */ 31441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->monitor_state != MS_BEACON_TEST_STATE) 31451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 31461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_lobe_media_test_state(dev); 31471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_wait_cmd(dev)) 31481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 31491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "Lobe Failed test state\n"); 3150807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return LOBE_MEDIA_TEST_FAILED; 31511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 31521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 31531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, 31551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TRC_LOBE_MEDIA_TEST); 31561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3157807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 31581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 31591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_lobe_media_test_state(struct net_device *dev) 31611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 31621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 31631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, 31651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds JS_LOBE_TEST_STATE); 31661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3167807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 31681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 31691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_8025_hdr(struct net_device *dev, 31711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_HEADER *rmf, MAC_HEADER *tmf, __u16 ac_fc) 31721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 31731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->ac = MSB(ac_fc); /* msb is access control */ 31741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->fc = LSB(ac_fc); /* lsb is frame control */ 31751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->sa[0] = dev->dev_addr[0]; 31771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->sa[1] = dev->dev_addr[1]; 31781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->sa[2] = dev->dev_addr[2]; 31791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->sa[3] = dev->dev_addr[3]; 31801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->sa[4] = dev->dev_addr[4]; 31811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->sa[5] = dev->dev_addr[5]; 31821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(tmf->vc) 31841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 31851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Send RQ_INIT to RPS */ 31861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RQ_INIT: 31871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[0] = 0xc0; 31881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[1] = 0x00; 31891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[2] = 0x00; 31901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[3] = 0x00; 31911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[4] = 0x00; 31921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[5] = 0x02; 31931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 31941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Send RPT_TX_FORWARD to CRS */ 31961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_TX_FORWARD: 31971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[0] = 0xc0; 31981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[1] = 0x00; 31991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[2] = 0x00; 32001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[3] = 0x00; 32011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[4] = 0x00; 32021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[5] = 0x10; 32031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 32041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Everything else goes to sender */ 32061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 32071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[0] = rmf->sa[0]; 32081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[1] = rmf->sa[1]; 32091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[2] = rmf->sa[2]; 32101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[3] = rmf->sa[3]; 32111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[4] = rmf->sa[4]; 32121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[5] = rmf->sa[5]; 32131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 32141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 32151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3216807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 32171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 32181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_access_pri(struct net_device *dev, MAC_SUB_VECTOR *tsv) 32201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 32211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 32221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svi = AUTHORIZED_ACCESS_PRIORITY; 32241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svl = S_AUTHORIZED_ACCESS_PRIORITY; 32251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[0] = MSB(tp->authorized_access_priority); 32271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[1] = LSB(tp->authorized_access_priority); 32281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3229807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 32301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 32311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv) 32331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 32341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svi = ADDRESS_MODIFER; 32351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svl = S_ADDRESS_MODIFER; 32361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[0] = 0; 32381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[1] = 0; 32391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3240807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 32411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 32421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_auth_funct_class(struct net_device *dev, 32441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv) 32451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 32461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 32471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svi = AUTHORIZED_FUNCTION_CLASS; 32491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svl = S_AUTHORIZED_FUNCTION_CLASS; 32501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[0] = MSB(tp->authorized_function_classes); 32521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[1] = LSB(tp->authorized_function_classes); 32531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3254807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 32551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 32561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_corr(struct net_device *dev, 32581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv, __u16 correlator) 32591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 32601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svi = CORRELATOR; 32611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svl = S_CORRELATOR; 32621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[0] = MSB(correlator); 32641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[1] = LSB(correlator); 32651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3266807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 32671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 32681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_funct_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) 32701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 32711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 32721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_get_functional_address(dev); 32741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svi = FUNCTIONAL_ADDRESS; 32761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svl = S_FUNCTIONAL_ADDRESS; 32771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[0] = MSB(tp->misc_command_data[0]); 32791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[1] = LSB(tp->misc_command_data[0]); 32801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[2] = MSB(tp->misc_command_data[1]); 32821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[3] = LSB(tp->misc_command_data[1]); 32831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3284807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 32851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 32861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_group_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) 32881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 32891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 32901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_get_group_address(dev); 32921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svi = GROUP_ADDRESS; 32941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svl = S_GROUP_ADDRESS; 32951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[0] = MSB(tp->misc_command_data[0]); 32971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[1] = LSB(tp->misc_command_data[0]); 32981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[2] = MSB(tp->misc_command_data[1]); 33001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[3] = LSB(tp->misc_command_data[1]); 33011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set Group Address Sub-vector to all zeros if only the 33031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Group Address/Functional Address Indicator is set. 33041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 33058e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if(tsv->svv[0] == 0x80 && tsv->svv[1] == 0x00 && 33068e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches tsv->svv[2] == 0x00 && tsv->svv[3] == 0x00) 33071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[0] = 0x00; 33081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3309807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 33101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 33111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_phy_drop_num(struct net_device *dev, 33131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv) 33141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 33151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 33161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_get_physical_drop_number(dev); 33181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svi = PHYSICAL_DROP; 33201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svl = S_PHYSICAL_DROP; 33211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[0] = MSB(tp->misc_command_data[0]); 33231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[1] = LSB(tp->misc_command_data[0]); 33241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[2] = MSB(tp->misc_command_data[1]); 33261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[3] = LSB(tp->misc_command_data[1]); 33271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3328807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 33291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 33301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) 33321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 33331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 33341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svi = PRODUCT_INSTANCE_ID; 33361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svl = S_PRODUCT_INSTANCE_ID; 33371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < 18; i++) 33391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[i] = 0xF0; 33401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3341807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 33421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 33431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) 33451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 33461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 33471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_get_station_id(dev); 33491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svi = STATION_IDENTIFER; 33511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svl = S_STATION_IDENTIFER; 33521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[0] = MSB(tp->misc_command_data[0]); 33541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[1] = LSB(tp->misc_command_data[0]); 33551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[2] = MSB(tp->misc_command_data[1]); 33571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[3] = LSB(tp->misc_command_data[1]); 33581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[4] = MSB(tp->misc_command_data[2]); 33601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[5] = LSB(tp->misc_command_data[2]); 33611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3362807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 33631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 33641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_ring_station_status(struct net_device *dev, 33661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR * tsv) 33671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 33681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svi = RING_STATION_STATUS; 33691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svl = S_RING_STATION_STATUS; 33701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[0] = 0; 33721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[1] = 0; 33731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[2] = 0; 33741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[3] = 0; 33751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[4] = 0; 33761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[5] = 0; 33771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3378807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 33791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 33801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_ring_station_version(struct net_device *dev, 33821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv) 33831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 33841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 33851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svi = RING_STATION_VERSION_NUMBER; 33871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svl = S_RING_STATION_VERSION_NUMBER; 33881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[0] = 0xe2; /* EBCDIC - S */ 33901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[1] = 0xd4; /* EBCDIC - M */ 33911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[2] = 0xc3; /* EBCDIC - C */ 33921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[3] = 0x40; /* EBCDIC - */ 33931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[4] = 0xe5; /* EBCDIC - V */ 33941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[5] = 0xF0 + (tp->microcode_version >> 4); 33951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[6] = 0xF0 + (tp->microcode_version & 0x0f); 33961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[7] = 0x40; /* EBCDIC - */ 33971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[8] = 0xe7; /* EBCDIC - X */ 33981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->extra_info & CHIP_REV_MASK) 34001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[9] = 0xc5; /* EBCDIC - E */ 34011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 34021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[9] = 0xc4; /* EBCDIC - D */ 34031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3404807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 34051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 34061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_tx_status_code(struct net_device *dev, 34081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv, __u16 tx_fstatus) 34091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 34101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svi = TRANSMIT_STATUS_CODE; 34111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svl = S_TRANSMIT_STATUS_CODE; 34121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341326c080bf8308449330037f91daa3ac0a7c41023eJay Schulist tsv->svv[0] = ((tx_fstatus & 0x0100 >> 6) | IBM_PASS_SOURCE_ADDR); 34141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Stripped frame status of Transmitted Frame */ 34161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[1] = tx_fstatus & 0xff; 34171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3418807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 34191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 34201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_upstream_neighbor_addr(struct net_device *dev, 34221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv) 34231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 34241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 34251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_get_upstream_neighbor_addr(dev); 34271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svi = UPSTREAM_NEIGHBOR_ADDRESS; 34291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svl = S_UPSTREAM_NEIGHBOR_ADDRESS; 34301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[0] = MSB(tp->misc_command_data[0]); 34321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[1] = LSB(tp->misc_command_data[0]); 34331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[2] = MSB(tp->misc_command_data[1]); 34351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[3] = LSB(tp->misc_command_data[1]); 34361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[4] = MSB(tp->misc_command_data[2]); 34381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svv[5] = LSB(tp->misc_command_data[2]); 34391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3440807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 34411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 34421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_make_wrap_data(struct net_device *dev, MAC_SUB_VECTOR *tsv) 34441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 34451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svi = WRAP_DATA; 34461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv->svl = S_WRAP_DATA; 34471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3448807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 34491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 34501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 34521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Open/initialize the board. This is called sometime after 34531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * booting when the 'ifconfig' program is run. 34541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 34551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This routine should set everything up anew at each open, even 34561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * registers that "should" only need to be set once at boot, so that 34571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * there is non-reboot way to recover if something goes wrong. 34581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 34591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_open(struct net_device *dev) 34601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 34611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 34621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 34641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_open\n", dev->name); 34651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_init_adapter(dev); 34671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(err < 0) 3468807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 34691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3470807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 34711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 34721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Interrupt driven open of Token card. */ 34741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_open_tr(struct net_device *dev) 34751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 34761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 34771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 34781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 34791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 34811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_open_tr\n", dev->name); 34821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Now we can actually open the adapter. */ 34841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->status == OPEN) 3485807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 34861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->status != INITIALIZED) 3487807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return -1; 34881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* FIXME: it would work a lot better if we masked the irq sources 34901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds on the card here, then we could skip the locking and poll nicely */ 34911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&tp->lock, flags); 34921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_page(dev, (__u8 *)tp->ram_access); 34941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_resume_rx_fcb_cmd(dev, (short)MAC_QUEUE))) 34961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 34971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_resume_rx_bdb_cmd(dev, (short)MAC_QUEUE))) 34991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 35001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_resume_rx_fcb_cmd(dev, (short)NON_MAC_QUEUE))) 35021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 35031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_resume_rx_bdb_cmd(dev, (short)NON_MAC_QUEUE))) 35051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 35061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->status = CLOSED; 35081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Insert into the Ring or Enter Loopback Mode. */ 35101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((tp->mode_bits & LOOPING_MODE_MASK) == LOOPBACK_MODE_1) 35111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 35121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->status = CLOSED; 35131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(err = smctr_issue_trc_loopback_cmd(dev))) 35151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 35161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(err = smctr_wait_cmd(dev))) 35171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->status = OPEN; 35181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 35191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_status_chg(dev); 35211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 35221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 35231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 35241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((tp->mode_bits & LOOPING_MODE_MASK) == LOOPBACK_MODE_2) 35251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 35261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->status = CLOSED; 35271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(err = smctr_issue_tri_loopback_cmd(dev))) 35281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 35291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(err = smctr_wait_cmd(dev))) 35301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->status = OPEN; 35311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 35321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_status_chg(dev); 35341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 35351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 35361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 35371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((tp->mode_bits & LOOPING_MODE_MASK) 35381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds == LOOPBACK_MODE_3) 35391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 35401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->status = CLOSED; 35411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(err = smctr_lobe_media_test_cmd(dev))) 35421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 35431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(err = smctr_wait_cmd(dev))) 35441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->status = OPEN; 35451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 35461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_status_chg(dev); 35471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 35481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 35491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 35501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(err = smctr_lobe_media_test(dev))) 35511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_issue_insert_cmd(dev); 35521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 35531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 35541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(err == LOBE_MEDIA_TEST_FAILED) 35551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "%s: Lobe Media Test Failure - Check cable?\n", dev->name); 35561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 35571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 35581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 35591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 35601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 35621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&tp->lock, flags); 35631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3564807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 35651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 35661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Check for a network adapter of this type, 35681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and return device structure if one exists. 35691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 35701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct net_device __init *smctr_probe(int unit) 35711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 35721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_device *dev = alloc_trdev(sizeof(struct net_local)); 35731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static const unsigned ports[] = { 35741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300, 35751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x320, 0x340, 0x360, 0x380, 0 35761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }; 35771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const unsigned *port; 35781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err = 0; 35791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev) 35811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ERR_PTR(-ENOMEM); 35821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (unit >= 0) { 35841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sprintf(dev->name, "tr%d", unit); 35851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds netdev_boot_setup_check(dev); 35861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 35871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->base_addr > 0x1ff) /* Check a single specified location. */ 35891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_probe1(dev, dev->base_addr); 35901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if(dev->base_addr != 0) /* Don't probe at all. */ 35911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err =-ENXIO; 35921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 35931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (port = ports; *port; port++) { 35941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_probe1(dev, *port); 35951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!err) 35961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 35971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 35981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 35991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err) 36001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 36011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = register_netdev(dev); 36021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err) 36031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out1; 36041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dev; 36051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout1: 36061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_MCA_LEGACY 36071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { struct net_local *tp = netdev_priv(dev); 36081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tp->slot_num) 36091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mca_mark_as_unused(tp->slot_num); 36101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 36111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 36121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_region(dev->base_addr, SMCTR_IO_EXTENT); 36131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_irq(dev->irq, dev); 36141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 36151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_netdev(dev); 36161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ERR_PTR(err); 36171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 36181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3619f70d59492ed8bc1d74b364ebe2b97ef6705910b1Stephen Hemmingerstatic const struct net_device_ops smctr_netdev_ops = { 3620f70d59492ed8bc1d74b364ebe2b97ef6705910b1Stephen Hemminger .ndo_open = smctr_open, 3621f70d59492ed8bc1d74b364ebe2b97ef6705910b1Stephen Hemminger .ndo_stop = smctr_close, 3622f70d59492ed8bc1d74b364ebe2b97ef6705910b1Stephen Hemminger .ndo_start_xmit = smctr_send_packet, 3623f70d59492ed8bc1d74b364ebe2b97ef6705910b1Stephen Hemminger .ndo_tx_timeout = smctr_timeout, 3624f70d59492ed8bc1d74b364ebe2b97ef6705910b1Stephen Hemminger .ndo_get_stats = smctr_get_stats, 3625afc4b13df143122f99a0eb10bfefb216c2806de0Jiri Pirko .ndo_set_rx_mode = smctr_set_multicast_list, 3626f70d59492ed8bc1d74b364ebe2b97ef6705910b1Stephen Hemminger}; 36271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 36281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init smctr_probe1(struct net_device *dev, int ioaddr) 36291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 36301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static unsigned version_printed; 36311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 36321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 36331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 *ram; 36341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 36351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug && version_printed++ == 0) 36361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(version); 36371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 36381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_init(&tp->lock); 36391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->base_addr = ioaddr; 36401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 36411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Actually detect an adapter now. */ 36421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_chk_isa(dev); 36431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(err < 0) 36441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 36451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((err = smctr_chk_mca(dev)) < 0) { 36461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = -ENODEV; 36471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 36481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 36491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 36501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 36511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp = netdev_priv(dev); 36521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->mem_start = tp->ram_base; 36531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->mem_end = dev->mem_start + 0x10000; 36541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ram = (__u32 *)phys_to_virt(dev->mem_start); 36551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->ram_access = *(__u32 *)&ram; 36561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->status = NOT_INITIALIZED; 36571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 36581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_load_firmware(dev); 36591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(err != UCODE_PRESENT && err != SUCCESS) 36601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 36611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "%s: Firmware load failed (%d)\n", dev->name, err); 36621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = -EIO; 36631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 36641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 36651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 36661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allow user to specify ring speed on module insert. */ 36671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(ringspeed == 4) 36681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->media_type = MEDIA_UTP_4; 36691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 36701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->media_type = MEDIA_UTP_16; 36711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 36721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "%s: %s %s at Io %#4x, Irq %d, Rom %#4x, Ram %#4x.\n", 36731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->name, smctr_name, smctr_model, 36741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (unsigned int)dev->base_addr, 36751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->irq, tp->rom_base, tp->ram_base); 36761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3677f70d59492ed8bc1d74b364ebe2b97ef6705910b1Stephen Hemminger dev->netdev_ops = &smctr_netdev_ops; 36781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->watchdog_timeo = HZ; 3679807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 36801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 36811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 36821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 36831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 36841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 36851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, 36861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_device *dev, __u16 rx_status) 36871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 36881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 36891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb; 36901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 rcode, correlator; 36911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err = 0; 36921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 xframe = 1; 36931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 36941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rmf->vl = SWAP_BYTES(rmf->vl); 36951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rx_status & FCB_RX_STATUS_DA_MATCHED) 36961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 36971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(rmf->vc) 36981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 36991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Received MAC Frames Processed by RS. */ 37001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case INIT: 37011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((rcode = smctr_rcv_init(dev, rmf, &correlator)) == HARDWARE_FAILED) 37021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3703807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return rcode; 37041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 37051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_send_rsp(dev, rmf, rcode, 37071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds correlator))) 37081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3709807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 37101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 37111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 37121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CHG_PARM: 37141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((rcode = smctr_rcv_chg_param(dev, rmf, 37151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &correlator)) ==HARDWARE_FAILED) 37161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3717807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return rcode; 37181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 37191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_send_rsp(dev, rmf, rcode, 37211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds correlator))) 37221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3723807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 37241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 37251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 37261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RQ_ADDR: 37281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((rcode = smctr_rcv_rq_addr_state_attch(dev, 37291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rmf, &correlator)) != POSITIVE_ACK) 37301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 37311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rcode == HARDWARE_FAILED) 3732807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return rcode; 37331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3734807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_send_rsp(dev, rmf, 3735807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet rcode, correlator); 37361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 37371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_send_rpt_addr(dev, rmf, 37391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds correlator))) 37401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3741807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 37421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 37431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 37441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RQ_ATTCH: 37461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((rcode = smctr_rcv_rq_addr_state_attch(dev, 37471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rmf, &correlator)) != POSITIVE_ACK) 37481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 37491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rcode == HARDWARE_FAILED) 3750807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return rcode; 37511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3752807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_send_rsp(dev, rmf, 37531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode, 3754807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet correlator); 37551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 37561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_send_rpt_attch(dev, rmf, 37581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds correlator))) 37591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3760807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 37611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 37621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 37631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RQ_STATE: 37651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((rcode = smctr_rcv_rq_addr_state_attch(dev, 37661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rmf, &correlator)) != POSITIVE_ACK) 37671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 37681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rcode == HARDWARE_FAILED) 3769807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return rcode; 37701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3771807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_send_rsp(dev, rmf, 37721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode, 3773807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet correlator); 37741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 37751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_send_rpt_state(dev, rmf, 37771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds correlator))) 37781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3779807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 37801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 37811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 37821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3783a6343afb6e16b65b9f0b264f94f8207212e7e3aeJeff Garzik case TX_FORWARD: { 3784a6343afb6e16b65b9f0b264f94f8207212e7e3aeJeff Garzik __u16 uninitialized_var(tx_fstatus); 3785a6343afb6e16b65b9f0b264f94f8207212e7e3aeJeff Garzik 37861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((rcode = smctr_rcv_tx_forward(dev, rmf)) 37871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds != POSITIVE_ACK) 37881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 37891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rcode == HARDWARE_FAILED) 3790807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return rcode; 37911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3792807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_send_rsp(dev, rmf, 37931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode, 3794807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet correlator); 37951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 37961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_send_tx_forward(dev, rmf, 37981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &tx_fstatus)) == HARDWARE_FAILED) 37991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3800807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 38011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 38021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 38031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(err == A_FRAME_WAS_FORWARDED) 38041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 38051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_send_rpt_tx_forward(dev, 38061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rmf, tx_fstatus)) 38071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds == HARDWARE_FAILED) 38081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3809807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 38101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 38111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 38121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3813a6343afb6e16b65b9f0b264f94f8207212e7e3aeJeff Garzik } 38141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 38151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Received MAC Frames Processed by CRS/REM/RPS. */ 38161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RSP: 38171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RQ_INIT: 38181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_NEW_MON: 38191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_SUA_CHG: 38201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_ACTIVE_ERR: 38211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_NN_INCMP: 38221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_ERROR: 38231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_ATTCH: 38241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_STATE: 38251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_ADDR: 38261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 38271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 38281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Rcvd Att. MAC Frame (if RXATMAC set) or UNKNOWN */ 38291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 38301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xframe = 0; 38311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES)) 38321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 38331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = smctr_rcv_unknown(dev, rmf, 38341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &correlator); 38351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_send_rsp(dev, rmf,rcode, 38361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds correlator))) 38371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3838807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 38391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 38401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 38411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 38421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 38431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 38441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 38451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 38461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 38471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1. DA doesn't match (Promiscuous Mode). 38481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. Parse for Extended MAC Frame Type. 38491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 38501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(rmf->vc) 38511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 38521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RSP: 38531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case INIT: 38541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RQ_INIT: 38551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RQ_ADDR: 38561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RQ_ATTCH: 38571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RQ_STATE: 38581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CHG_PARM: 38591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_ADDR: 38601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_ERROR: 38611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_ATTCH: 38621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_STATE: 38631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_NEW_MON: 38641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_SUA_CHG: 38651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_NN_INCMP: 38661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RPT_ACTIVE_ERR: 38671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 38681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 38691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 38701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xframe = 0; 38711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 38721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 38731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 38741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 38751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* NOTE: UNKNOWN MAC frames will NOT be passed up unless 38761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ACCEPT_ATT_MAC_FRAMES is set. 38771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 38788e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if(((tp->receive_mask & ACCEPT_ATT_MAC_FRAMES) && 38798e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (xframe == (__u8)0)) || 38808e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches ((tp->receive_mask & ACCEPT_EXT_MAC_FRAMES) && 38818e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (xframe == (__u8)1))) 38821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 38831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rmf->vl = SWAP_BYTES(rmf->vl); 38841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 38851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(skb = dev_alloc_skb(size))) 38861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 38871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb->len = size; 38881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 38891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Slide data into a sleek skb. */ 38901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(skb, skb->len); 389127d7ff46a3498d3debc6ba68fb8014c702b81170Arnaldo Carvalho de Melo skb_copy_to_linear_data(skb, rmf, skb->len); 38921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 38931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Update Counters */ 38941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->MacStat.rx_packets++; 38951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->MacStat.rx_bytes += skb->len; 38961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 38971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Kick the packet on up. */ 38981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb->protocol = tr_type_trans(skb, dev); 38991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds netif_rx(skb); 39001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = 0; 39011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 39021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3903807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 39041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 39051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Adapter RAM test. Incremental word ODD boundary data test. */ 39071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_ram_memory_test(struct net_device *dev) 39081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 39091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 39101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 page, pages_of_ram, start_pattern = 0, word_pattern = 0, 39111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds word_read = 0, err_word = 0, err_pattern = 0; 39121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int err_offset; 39131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 j, pword; 39141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 err = 0; 39151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 39171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_ram_memory_test\n", dev->name); 39181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start_pattern = 0x0001; 39201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pages_of_ram = tp->ram_size / tp->ram_usable; 39211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pword = tp->ram_access; 39221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Incremental word ODD boundary test. */ 39241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(page = 0; (page < pages_of_ram) && (~err); 39251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds page++, start_pattern += 0x8000) 39261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 39271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_page(dev, (__u8 *)(tp->ram_access 39281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + (page * tp->ram_usable * 1024) + 1)); 39291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds word_pattern = start_pattern; 39301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(j = 1; j < (__u32)(tp->ram_usable * 1024) - 1; j += 2) 39321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(__u16 *)(pword + j) = word_pattern++; 39331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds word_pattern = start_pattern; 39351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39368e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches for(j = 1; j < (__u32)(tp->ram_usable * 1024) - 1 && (~err); 39378e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches j += 2, word_pattern++) 39381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 39391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds word_read = *(__u16 *)(pword + j); 39401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(word_read != word_pattern) 39411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 39421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = (__u8)1; 39431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_offset = j; 39441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_word = word_read; 39451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_pattern = word_pattern; 3946807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return RAM_TEST_FAILED; 39471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 39481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 39491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 39501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Zero out memory. */ 39521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(page = 0; page < pages_of_ram && (~err); page++) 39531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 39541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_page(dev, (__u8 *)(tp->ram_access 39551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + (page * tp->ram_usable * 1024))); 39561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds word_pattern = 0; 39571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(j = 0; j < (__u32)tp->ram_usable * 1024; j +=2) 39591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(__u16 *)(pword + j) = word_pattern; 39601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39618e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches for(j =0; j < (__u32)tp->ram_usable * 1024 && (~err); j += 2) 39621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 39631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds word_read = *(__u16 *)(pword + j); 39641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(word_read != word_pattern) 39651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 39661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = (__u8)1; 39671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_offset = j; 39681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_word = word_read; 39691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_pattern = word_pattern; 3970807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return RAM_TEST_FAILED; 39711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 39721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 39731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 39741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_page(dev, (__u8 *)tp->ram_access); 39761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3977807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 39781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 39791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf, 39811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 *correlator) 39821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 39831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv; 39841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds signed short vlen; 39851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 rcode = POSITIVE_ACK; 39861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int svectors = F_NO_SUB_VECTORS_FOUND; 39871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* This Frame can only come from a CRS */ 39891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((rmf->dc_sc & SC_MASK) != SC_CRS) 3990807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return E_INAPPROPRIATE_SOURCE_CLASS; 39911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Remove MVID Length from total length. */ 39931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vlen = (signed short)rmf->vl - 4; 39941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Point to First SVID */ 39961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); 39971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Search for Appropriate SVID's. */ 39991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while((vlen > 0) && (rcode == POSITIVE_ACK)) 40001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 40011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(rsv->svi) 40021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 40031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CORRELATOR: 40041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds svectors |= F_CORRELATOR; 40051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = smctr_set_corr(dev, rsv, correlator); 40061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 40071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case LOCAL_RING_NUMBER: 40091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds svectors |= F_LOCAL_RING_NUMBER; 40101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = smctr_set_local_ring_num(dev, rsv); 40111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 40121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ASSIGN_PHYSICAL_DROP: 40141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds svectors |= F_ASSIGN_PHYSICAL_DROP; 40151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = smctr_set_phy_drop(dev, rsv); 40161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 40171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ERROR_TIMER_VALUE: 40191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds svectors |= F_ERROR_TIMER_VALUE; 40201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = smctr_set_error_timer_value(dev, rsv); 40211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 40221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUTHORIZED_FUNCTION_CLASS: 40241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds svectors |= F_AUTHORIZED_FUNCTION_CLASS; 40251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = smctr_set_auth_funct_class(dev, rsv); 40261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 40271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUTHORIZED_ACCESS_PRIORITY: 40291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds svectors |= F_AUTHORIZED_ACCESS_PRIORITY; 40301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = smctr_set_auth_access_pri(dev, rsv); 40311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 40321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 40341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_SUB_VECTOR_UNKNOWN; 40351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 40361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 40371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Let Sender Know if SUM of SV length's is 40391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * larger then length in MVID length field 40401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 40411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((vlen -= rsv->svl) < 0) 40421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_VECTOR_LENGTH_ERROR; 40431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); 40451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 40461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rcode == POSITIVE_ACK) 40481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 40491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Let Sender Know if MVID length field 40501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is larger then SUM of SV length's 40511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 40521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(vlen != 0) 40531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_VECTOR_LENGTH_ERROR; 40541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 40551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 40561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Let Sender Know if Expected SVID Missing */ 40571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((svectors & R_CHG_PARM) ^ R_CHG_PARM) 40581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_MISSING_SUB_VECTOR; 40591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 40601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 40611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4062807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return rcode; 40631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 40641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf, 40661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 *correlator) 40671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 40681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv; 40691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds signed short vlen; 40701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 rcode = POSITIVE_ACK; 40711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int svectors = F_NO_SUB_VECTORS_FOUND; 40721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* This Frame can only come from a RPS */ 40741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((rmf->dc_sc & SC_MASK) != SC_RPS) 4075807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return E_INAPPROPRIATE_SOURCE_CLASS; 40761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Remove MVID Length from total length. */ 40781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vlen = (signed short)rmf->vl - 4; 40791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Point to First SVID */ 40811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); 40821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Search for Appropriate SVID's */ 40841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while((vlen > 0) && (rcode == POSITIVE_ACK)) 40851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 40861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(rsv->svi) 40871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 40881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CORRELATOR: 40891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds svectors |= F_CORRELATOR; 40901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = smctr_set_corr(dev, rsv, correlator); 40911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 40921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case LOCAL_RING_NUMBER: 40941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds svectors |= F_LOCAL_RING_NUMBER; 40951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = smctr_set_local_ring_num(dev, rsv); 40961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 40971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ASSIGN_PHYSICAL_DROP: 40991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds svectors |= F_ASSIGN_PHYSICAL_DROP; 41001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = smctr_set_phy_drop(dev, rsv); 41011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 41021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ERROR_TIMER_VALUE: 41041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds svectors |= F_ERROR_TIMER_VALUE; 41051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = smctr_set_error_timer_value(dev, rsv); 41061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 41071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 41091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_SUB_VECTOR_UNKNOWN; 41101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 41111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 41121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Let Sender Know if SUM of SV length's is 41141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * larger then length in MVID length field 41151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 41161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((vlen -= rsv->svl) < 0) 41171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_VECTOR_LENGTH_ERROR; 41181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); 41201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 41211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rcode == POSITIVE_ACK) 41231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 41241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Let Sender Know if MVID length field 41251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is larger then SUM of SV length's 41261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 41271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(vlen != 0) 41281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_VECTOR_LENGTH_ERROR; 41291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 41301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 41311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Let Sender Know if Expected SV Missing */ 41321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((svectors & R_INIT) ^ R_INIT) 41331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_MISSING_SUB_VECTOR; 41341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 41351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 41361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4137807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return rcode; 41381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 41391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf) 41411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 41421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv; 41431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds signed short vlen; 41441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 rcode = POSITIVE_ACK; 41451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int svectors = F_NO_SUB_VECTORS_FOUND; 41461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* This Frame can only come from a CRS */ 41481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((rmf->dc_sc & SC_MASK) != SC_CRS) 4149807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return E_INAPPROPRIATE_SOURCE_CLASS; 41501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Remove MVID Length from total length */ 41521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vlen = (signed short)rmf->vl - 4; 41531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Point to First SVID */ 41551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); 41561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Search for Appropriate SVID's */ 41581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while((vlen > 0) && (rcode == POSITIVE_ACK)) 41591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 41601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(rsv->svi) 41611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 41621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case FRAME_FORWARD: 41631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds svectors |= F_FRAME_FORWARD; 41641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = smctr_set_frame_forward(dev, rsv, 41651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rmf->dc_sc); 41661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 41671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 41691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_SUB_VECTOR_UNKNOWN; 41701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 41711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 41721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Let Sender Know if SUM of SV length's is 41741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * larger then length in MVID length field 41751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 41761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((vlen -= rsv->svl) < 0) 41771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_VECTOR_LENGTH_ERROR; 41781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); 41801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 41811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rcode == POSITIVE_ACK) 41831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 41841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Let Sender Know if MVID length field 41851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is larger then SUM of SV length's 41861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 41871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(vlen != 0) 41881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_VECTOR_LENGTH_ERROR; 41891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 41901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 41911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Let Sender Know if Expected SV Missing */ 41921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((svectors & R_TX_FORWARD) ^ R_TX_FORWARD) 41931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_MISSING_SUB_VECTOR; 41941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 41951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 41961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4197807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return rcode; 41981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 41991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_rcv_rq_addr_state_attch(struct net_device *dev, 42011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_HEADER *rmf, __u16 *correlator) 42021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 42031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv; 42041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds signed short vlen; 42051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 rcode = POSITIVE_ACK; 42061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int svectors = F_NO_SUB_VECTORS_FOUND; 42071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Remove MVID Length from total length */ 42091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vlen = (signed short)rmf->vl - 4; 42101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Point to First SVID */ 42121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); 42131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Search for Appropriate SVID's */ 42151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while((vlen > 0) && (rcode == POSITIVE_ACK)) 42161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 42171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(rsv->svi) 42181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 42191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CORRELATOR: 42201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds svectors |= F_CORRELATOR; 42211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = smctr_set_corr(dev, rsv, correlator); 42221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 42231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 42251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_SUB_VECTOR_UNKNOWN; 42261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 42271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 42281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Let Sender Know if SUM of SV length's is 42301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * larger then length in MVID length field 42311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 42321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((vlen -= rsv->svl) < 0) 42331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_VECTOR_LENGTH_ERROR; 42341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); 42361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 42371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rcode == POSITIVE_ACK) 42391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 42401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Let Sender Know if MVID length field 42411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is larger then SUM of SV length's 42421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 42431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(vlen != 0) 42441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_VECTOR_LENGTH_ERROR; 42451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 42461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 42471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Let Sender Know if Expected SVID Missing */ 42481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((svectors & R_RQ_ATTCH_STATE_ADDR) 42491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ^ R_RQ_ATTCH_STATE_ADDR) 42501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcode = E_MISSING_SUB_VECTOR; 42511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 42521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 42531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4254807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return rcode; 42551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 42561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf, 42581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 *correlator) 42591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 42601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv; 42611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds signed short vlen; 42621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *correlator = 0; 42641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Remove MVID Length from total length */ 42661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vlen = (signed short)rmf->vl - 4; 42671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Point to First SVID */ 42691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); 42701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Search for CORRELATOR for RSP to UNKNOWN */ 42721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while((vlen > 0) && (*correlator == 0)) 42731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 42741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(rsv->svi) 42751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 42761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CORRELATOR: 42771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_corr(dev, rsv, correlator); 42781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 42791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 42811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 42821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 42831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vlen -= rsv->svl; 42851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); 42861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 42871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4288807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return E_UNRECOGNIZED_VECTOR_ID; 42891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 42901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 42921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Reset the 825 NIC and exit w: 42931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. The NIC reset cleared (non-reset state), halted and un-initialized. 42941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. TINT masked. 42951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. CBUSY masked. 42961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4. TINT clear. 42971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5. CBUSY clear. 42981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 42991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_reset_adapter(struct net_device *dev) 43001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 43011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 43021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ioaddr = dev->base_addr; 43031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reseting the NIC will put it in a halted and un-initialized state. */ smctr_set_trc_reset(ioaddr); 43051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mdelay(200); /* ~2 ms */ 43061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_clear_trc_reset(ioaddr); 43081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mdelay(200); /* ~2 ms */ 43091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Remove any latched interrupts that occurred prior to reseting the 43111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * adapter or possibily caused by line glitches due to the reset. 43121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 43131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(tp->trc_mask | CSR_CLRTINT | CSR_CLRCBUSY, ioaddr + CSR); 43141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4315807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 43161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 43171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_restart_tx_chain(struct net_device *dev, short queue) 43191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 43201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 43211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err = 0; 43221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 43241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_restart_tx_chain\n", dev->name); 43251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43268e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if(tp->num_tx_fcbs_used[queue] != 0 && 43278e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches tp->tx_queue_status[queue] == NOT_TRANSMITING) 43281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 43291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_queue_status[queue] = TRANSMITING; 43301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_issue_resume_tx_fcb_cmd(dev, queue); 43311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 43321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4333807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 43341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 43351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_ring_status_chg(struct net_device *dev) 43371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 43381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 43391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 43411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_ring_status_chg\n", dev->name); 43421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Check for ring_status_flag: whenever MONITOR_STATE_BIT 43441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit is set, check value of monitor_state, only then we 43451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * enable and start transmit/receive timeout (if and only 43461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * if it is MS_ACTIVE_MONITOR_STATE or MS_STANDBY_MONITOR_STATE) 43471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 43481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->ring_status_flags == MONITOR_STATE_CHANGED) 43491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 43508e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if((tp->monitor_state == MS_ACTIVE_MONITOR_STATE) || 43518e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (tp->monitor_state == MS_STANDBY_MONITOR_STATE)) 43521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 43531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->monitor_state_ready = 1; 43541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 43551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 43561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 43571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* if adapter is NOT in either active monitor 43581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * or standby monitor state => Disable 43591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * transmit/receive timeout. 43601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 43611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->monitor_state_ready = 0; 43621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Ring speed problem, switching to auto mode. */ 43648e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if(tp->monitor_state == MS_MONITOR_FSM_INACTIVE && 43658e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches !tp->cleanup) 43661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 43671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "%s: Incorrect ring speed switching.\n", 43681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->name); 43691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_ring_speed(dev); 43701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 43711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 43721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 43731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(tp->ring_status_flags & RING_STATUS_CHANGED)) 4375807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 43761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(tp->ring_status) 43781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 43791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RING_RECOVERY: 43801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "%s: Ring Recovery\n", dev->name); 43811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 43821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SINGLE_STATION: 43841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "%s: Single Statinon\n", dev->name); 43851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 43861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case COUNTER_OVERFLOW: 43881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "%s: Counter Overflow\n", dev->name); 43891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 43901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case REMOVE_RECEIVED: 43921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "%s: Remove Received\n", dev->name); 43931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 43941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUTO_REMOVAL_ERROR: 43961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "%s: Auto Remove Error\n", dev->name); 43971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 43981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case LOBE_WIRE_FAULT: 44001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "%s: Lobe Wire Fault\n", dev->name); 44011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 44021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case TRANSMIT_BEACON: 44041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "%s: Transmit Beacon\n", dev->name); 44051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 44061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SOFT_ERROR: 44081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "%s: Soft Error\n", dev->name); 44091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 44101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case HARD_ERROR: 44121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "%s: Hard Error\n", dev->name); 44131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 44141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SIGNAL_LOSS: 44161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "%s: Signal Loss\n", dev->name); 44171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 44181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 44201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "%s: Unknown ring status change\n", 44211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->name); 44221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 44231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 44241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4425807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 44261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 44271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_rx_frame(struct net_device *dev) 44291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 44301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 44311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 queue, status, rx_size, err = 0; 44321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *pbuff; 44331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 44351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_rx_frame\n", dev->name); 44361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds queue = tp->receive_queue_number; 44381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while((status = tp->rx_fcb_curr[queue]->frame_status) != SUCCESS) 44401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 44411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = HARDWARE_FAILED; 44421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44438e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if(((status & 0x007f) == 0) || 44448e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches ((tp->receive_mask & ACCEPT_ERR_PACKETS) != 0)) 44451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 44461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* frame length less the CRC (4 bytes) + FS (1 byte) */ 44471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rx_size = tp->rx_fcb_curr[queue]->frame_length - 5; 44481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbuff = smctr_get_rx_pointer(dev, queue); 44501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_page(dev, pbuff); 44521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 44531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* pbuff points to addr within one page */ 44551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbuff = (__u8 *)PAGE_POINTER(pbuff); 44561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(queue == NON_MAC_QUEUE) 44581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 44591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb; 44601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb = dev_alloc_skb(rx_size); 44621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb) { 44631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(skb, rx_size); 44641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 446527d7ff46a3498d3debc6ba68fb8014c702b81170Arnaldo Carvalho de Melo skb_copy_to_linear_data(skb, pbuff, rx_size); 44661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Update Counters */ 44681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->MacStat.rx_packets++; 44691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->MacStat.rx_bytes += skb->len; 44701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Kick the packet on up. */ 44721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb->protocol = tr_type_trans(skb, dev); 44731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds netif_rx(skb); 44741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 44751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 44761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 44771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 44781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_process_rx_packet((MAC_HEADER *)pbuff, 44791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rx_size, dev, status); 44801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 44811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_16bit(dev); 44831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_page(dev, (__u8 *)tp->ram_access); 44841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_update_rx_chain(dev, queue); 44851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(err != SUCCESS) 44871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 44881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 44891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4490807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 44911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 44921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_dat(struct net_device *dev) 44941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 44951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 44961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i, err; 44971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_HEADER *tmf; 44981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FCBlock *fcb; 44991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 45011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_send_dat\n", dev->name); 45021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, 45041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(MAC_HEADER))) == (FCBlock *)(-1L)) 45051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4506807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return OUT_OF_RESOURCES; 45071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 45081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize DAT Data Fields. */ 45101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; 45111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->ac = MSB(AC_FC_DAT); 45121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->fc = LSB(AC_FC_DAT); 45131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < 6; i++) 45151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 45161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->sa[i] = dev->dev_addr[i]; 45171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[i] = dev->dev_addr[i]; 45181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 45201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vc = DAT; 45221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->dc_sc = DC_RS | SC_RS; 45231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl = 4; 45241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl = SWAP_BYTES(tmf->vl); 45251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Start Transmit. */ 45271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) 4528807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 45291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Wait for Transmit to Complete */ 45311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < 10000; i++) 45321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 45331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(fcb->frame_status & FCB_COMMAND_DONE) 45341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 45351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mdelay(1); 45361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 45371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Check if GOOD frame Tx'ed. */ 45398e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if(!(fcb->frame_status & FCB_COMMAND_DONE) || 45408e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS)) 45411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4542807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return INITIALIZE_FAILED; 45431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 45441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* De-allocated Tx FCB and Frame Buffer 45461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The FCB must be de-allocated manually if executing with 45471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * interrupts disabled, other wise the ISR (LM_Service_Events) 45481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * will de-allocate it when the interrupt occurs. 45491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 45501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; 45511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_update_tx_chain(dev, fcb, MAC_QUEUE); 45521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4553807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 45541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 45551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void smctr_timeout(struct net_device *dev) 45571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 45581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 45591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If we get here, some higher level has decided we are broken. 45601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * There should really be a "kick me" function call instead. 45611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 45621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Resetting the token ring adapter takes a long time so just 45631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * fake transmission time and go on trying. Our own timeout 45641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * routine is in sktr_timer_chk() 45651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 45661ae5dc342ac78d7a42965fd1f323815f6f5ef2c1Eric Dumazet dev->trans_start = jiffies; /* prevent tx timeout */ 45671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds netif_wake_queue(dev); 45681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 45691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 45711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Gets skb from system, queues it and checks if it can be sent 45721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 457361a84108547c1c017683f15311ccbede249fc6faStephen Hemmingerstatic netdev_tx_t smctr_send_packet(struct sk_buff *skb, 457461a84108547c1c017683f15311ccbede249fc6faStephen Hemminger struct net_device *dev) 45751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 45761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 45771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 45791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_send_packet\n", dev->name); 45801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 45821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Block a transmit overlap 45831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 45841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds netif_stop_queue(dev); 45861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->QueueSkb == 0) 45885b548140225c6bbbbd560551dd1048b2c0ce58bePatrick McHardy return NETDEV_TX_BUSY; /* Return with tbusy set: queue full */ 45891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->QueueSkb--; 45911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&tp->SendSkbQueue, skb); 45921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_hardware_send_packet(dev, tp); 45931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->QueueSkb > 0) 45941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds netif_wake_queue(dev); 45951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4596ec634fe328182a1a098585bfc7b69e5042bdb08dPatrick McHardy return NETDEV_TX_OK; 45971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 45981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_lobe_media_test(struct net_device *dev) 46001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 46011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 46021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv; 46031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_HEADER *tmf; 46041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FCBlock *fcb; 46051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 i; 46061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 46071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 15) 46091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_send_lobe_media_test\n", dev->name); 46101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(struct trh_hdr) 46121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + S_WRAP_DATA + S_WRAP_DATA)) == (FCBlock *)(-1L)) 46131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4614807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return OUT_OF_RESOURCES; 46151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 46161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize DAT Data Fields. */ 46181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; 46191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->ac = MSB(AC_FC_LOBE_MEDIA_TEST); 46201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->fc = LSB(AC_FC_LOBE_MEDIA_TEST); 46211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < 6; i++) 46231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 46241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->da[i] = 0; 46251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->sa[i] = dev->dev_addr[i]; 46261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 46271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vc = LOBE_MEDIA_TEST; 46291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->dc_sc = DC_RS | SC_RS; 46301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl = 4; 46311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); 46331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_wrap_data(dev, tsv); 46341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 46351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 46371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_wrap_data(dev, tsv); 46381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 46391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Start Transmit. */ 46411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl = SWAP_BYTES(tmf->vl); 46421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) 4643807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 46441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Wait for Transmit to Complete. (10 ms). */ 46461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i=0; i < 10000; i++) 46471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 46481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(fcb->frame_status & FCB_COMMAND_DONE) 46491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 46501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mdelay(1); 46511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 46521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Check if GOOD frame Tx'ed */ 46548e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if(!(fcb->frame_status & FCB_COMMAND_DONE) || 46558e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS)) 46561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4657807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return LOBE_MEDIA_TEST_FAILED; 46581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 46591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* De-allocated Tx FCB and Frame Buffer 46611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The FCB must be de-allocated manually if executing with 46621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * interrupts disabled, other wise the ISR (LM_Service_Events) 46631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * will de-allocate it when the interrupt occurs. 46641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 46651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; 46661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_update_tx_chain(dev, fcb, MAC_QUEUE); 46671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4668807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 46691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 46701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf, 46721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 correlator) 46731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 46741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_HEADER *tmf; 46751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv; 46761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FCBlock *fcb; 46771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) 46791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + S_CORRELATOR + S_PHYSICAL_DROP + S_UPSTREAM_NEIGHBOR_ADDRESS 46801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + S_ADDRESS_MODIFER + S_GROUP_ADDRESS + S_FUNCTIONAL_ADDRESS)) 46811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds == (FCBlock *)(-1L)) 46821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4683807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 46841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 46851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; 46871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vc = RPT_ADDR; 46881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; 46891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl = 4; 46901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_ADDR); 46921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); 46941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_corr(dev, tsv, correlator); 46951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 46971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 46981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_phy_drop_num(dev, tsv); 46991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 47011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 47021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_upstream_neighbor_addr(dev, tsv); 47031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 47051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 47061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_addr_mod(dev, tsv); 47071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 47091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 47101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_group_addr(dev, tsv); 47111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 47131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 47141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_funct_addr(dev, tsv); 47151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 47171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Subtract out MVID and MVL which is 47191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * include in both vl and MAC_HEADER 47201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 47211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; 47221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; 47231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 47241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl = SWAP_BYTES(tmf->vl); 47251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4726807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); 47271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 47281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf, 47301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 correlator) 47311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 47321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_HEADER *tmf; 47331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv; 47341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FCBlock *fcb; 47351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) 47371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + S_CORRELATOR + S_PRODUCT_INSTANCE_ID + S_FUNCTIONAL_ADDRESS 47381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + S_AUTHORIZED_FUNCTION_CLASS + S_AUTHORIZED_ACCESS_PRIORITY)) 47391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds == (FCBlock *)(-1L)) 47401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4741807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 47421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 47431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; 47451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vc = RPT_ATTCH; 47461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; 47471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl = 4; 47481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_ATTCH); 47501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); 47521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_corr(dev, tsv, correlator); 47531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 47551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 47561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_product_id(dev, tsv); 47571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 47591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 47601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_funct_addr(dev, tsv); 47611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 47631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 47641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_auth_funct_class(dev, tsv); 47651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 47671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 47681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_access_pri(dev, tsv); 47691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 47711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Subtract out MVID and MVL which is 47731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * include in both vl and MAC_HEADER 47741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 47751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; 47761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; 47771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 47781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl = SWAP_BYTES(tmf->vl); 47791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4780807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); 47811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 47821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf, 47841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 correlator) 47851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 47861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_HEADER *tmf; 47871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv; 47881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FCBlock *fcb; 47891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) 47911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + S_CORRELATOR + S_RING_STATION_VERSION_NUMBER 47921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + S_RING_STATION_STATUS + S_STATION_IDENTIFER)) 47931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds == (FCBlock *)(-1L)) 47941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4795807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 47961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 47971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; 47991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vc = RPT_STATE; 48001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; 48011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl = 4; 48021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_STATE); 48041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); 48061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_corr(dev, tsv, correlator); 48071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 48091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 48101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_ring_station_version(dev, tsv); 48111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 48131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 48141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_ring_station_status(dev, tsv); 48151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 48171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 48181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_station_id(dev, tsv); 48191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 48211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Subtract out MVID and MVL which is 48231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * include in both vl and MAC_HEADER 48241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 48251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; 48261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; 48271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 48281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl = SWAP_BYTES(tmf->vl); 48291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4830807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); 48311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 48321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_rpt_tx_forward(struct net_device *dev, 48341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_HEADER *rmf, __u16 tx_fstatus) 48351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 48361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_HEADER *tmf; 48371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv; 48381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FCBlock *fcb; 48391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) 48411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + S_TRANSMIT_STATUS_CODE)) == (FCBlock *)(-1L)) 48421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4843807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 48441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 48451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; 48471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vc = RPT_TX_FORWARD; 48481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; 48491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl = 4; 48501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_TX_FORWARD); 48521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); 48541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_tx_status_code(dev, tsv, tx_fstatus); 48551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 48571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Subtract out MVID and MVL which is 48591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * include in both vl and MAC_HEADER 48601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 48611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; 48621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; 48631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 48641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl = SWAP_BYTES(tmf->vl); 48651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4866807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); 48671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 48681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf, 48701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 rcode, __u16 correlator) 48711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 48721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_HEADER *tmf; 48731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv; 48741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FCBlock *fcb; 48751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) 48771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + S_CORRELATOR + S_RESPONSE_CODE)) == (FCBlock *)(-1L)) 48781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4879807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 48801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 48811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; 48831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vc = RSP; 48841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; 48851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl = 4; 48861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RSP); 48881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); 48901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_corr(dev, tsv, correlator); 48911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4892807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 48931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 48941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_rq_init(struct net_device *dev) 48961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 48971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 48981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_HEADER *tmf; 48991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *tsv; 49001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FCBlock *fcb; 49011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i, count = 0; 49021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 fstatus; 49031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 49041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do { 49061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) 49071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + S_PRODUCT_INSTANCE_ID + S_UPSTREAM_NEIGHBOR_ADDRESS 49081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + S_RING_STATION_VERSION_NUMBER + S_ADDRESS_MODIFER)) 49091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds == (FCBlock *)(-1L))) 49101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4911807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 49121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 49131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; 49151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vc = RQ_INIT; 49161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->dc_sc = DC_RPS | SC_RS; 49171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl = 4; 49181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_8025_hdr(dev, NULL, tmf, AC_FC_RQ_INIT); 49201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); 49221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_product_id(dev, tsv); 49231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 49251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 49261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_upstream_neighbor_addr(dev, tsv); 49271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 49291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 49301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_ring_station_version(dev, tsv); 49311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 49331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); 49341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_make_addr_mod(dev, tsv); 49351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl += tsv->svl; 49371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Subtract out MVID and MVL which is 49391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * include in both vl and MAC_HEADER 49401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 49411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; 49421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; 49431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 49441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmf->vl = SWAP_BYTES(tmf->vl); 49451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) 4947807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 49481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Wait for Transmit to Complete */ 49501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < 10000; i++) 49511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 49521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(fcb->frame_status & FCB_COMMAND_DONE) 49531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 49541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mdelay(1); 49551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 49561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Check if GOOD frame Tx'ed */ 49581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fstatus = fcb->frame_status; 49591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(fstatus & FCB_COMMAND_DONE)) 4961807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return HARDWARE_FAILED; 49621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(fstatus & FCB_TX_STATUS_E)) 49641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count++; 49651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* De-allocated Tx FCB and Frame Buffer 49671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The FCB must be de-allocated manually if executing with 49681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * interrupts disabled, other wise the ISR (LM_Service_Events) 49691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * will de-allocate it when the interrupt occurs. 49701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 49711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; 49721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_update_tx_chain(dev, fcb, MAC_QUEUE); 49731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } while(count < 4 && ((fstatus & FCB_TX_AC_BITS) ^ FCB_TX_AC_BITS)); 49741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4975807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_join_complete_state(dev); 49761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 49771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, 49791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 *tx_fstatus) 49801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 49811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 49821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FCBlock *fcb; 49831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i; 49841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 49851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Check if this is the END POINT of the Transmit Forward Chain. */ 49871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rmf->vl <= 18) 4988807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 49891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate Transmit FCB only by requesting 0 bytes 49911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of data buffer. 49921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 49931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, 0)) == (FCBlock *)(-1L)) 4994807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 49951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set pointer to Transmit Frame Buffer to the data 49971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * portion of the received TX Forward frame, making 49981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sure to skip over the Vector Code (vc) and Vector 49991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * length (vl). 50001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 50011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->bdb_ptr->trc_data_block_ptr = TRC_POINTER((__u32)rmf 50021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + sizeof(MAC_HEADER) + 2); 50031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->bdb_ptr->data_block_ptr = (__u16 *)((__u32)rmf 50041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + sizeof(MAC_HEADER) + 2); 50051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->frame_length = rmf->vl - 4 - 2; 50071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->bdb_ptr->buffer_length = rmf->vl - 4 - 2; 50081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) 5010807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 50111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Wait for Transmit to Complete */ 50131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < 10000; i++) 50141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 50151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(fcb->frame_status & FCB_COMMAND_DONE) 50161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 50171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mdelay(1); 50181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 50191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Check if GOOD frame Tx'ed */ 50211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(fcb->frame_status & FCB_COMMAND_DONE)) 50221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 50231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_resume_tx_fcb_cmd(dev, MAC_QUEUE))) 5024807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 50251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < 10000; i++) 50271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 50281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(fcb->frame_status & FCB_COMMAND_DONE) 50291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 50301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mdelay(1); 50311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 50321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(fcb->frame_status & FCB_COMMAND_DONE)) 5034807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return HARDWARE_FAILED; 50351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 50361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *tx_fstatus = fcb->frame_status; 50381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5039807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return A_FRAME_WAS_FORWARDED; 50401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 50411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_auth_access_pri(struct net_device *dev, 50431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv) 50441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 50451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 50461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rsv->svl != S_AUTHORIZED_ACCESS_PRIORITY) 5048807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return E_SUB_VECTOR_LENGTH_ERROR; 50491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->authorized_access_priority = (rsv->svv[0] << 8 | rsv->svv[1]); 50511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5052807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return POSITIVE_ACK; 50531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 50541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_auth_funct_class(struct net_device *dev, 50561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv) 50571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 50581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 50591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rsv->svl != S_AUTHORIZED_FUNCTION_CLASS) 5061807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return E_SUB_VECTOR_LENGTH_ERROR; 50621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->authorized_function_classes = (rsv->svv[0] << 8 | rsv->svv[1]); 50641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5065807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return POSITIVE_ACK; 50661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 50671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv, 50691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 *correlator) 50701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 50711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rsv->svl != S_CORRELATOR) 5072807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return E_SUB_VECTOR_LENGTH_ERROR; 50731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *correlator = (rsv->svv[0] << 8 | rsv->svv[1]); 50751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5076807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return POSITIVE_ACK; 50771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 50781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_error_timer_value(struct net_device *dev, 50801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv) 50811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 50821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 err_tval; 50831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 50841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rsv->svl != S_ERROR_TIMER_VALUE) 5086807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return E_SUB_VECTOR_LENGTH_ERROR; 50871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_tval = (rsv->svv[0] << 8 | rsv->svv[1])*10; 50891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_issue_write_word_cmd(dev, RW_TER_THRESHOLD, &err_tval); 50911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_cmd(dev))) 5093807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 50941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5095807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return POSITIVE_ACK; 50961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 50971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_frame_forward(struct net_device *dev, 50991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv, __u8 dc_sc) 51001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 51011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((rsv->svl < 2) || (rsv->svl > S_FRAME_FORWARD)) 5102807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return E_SUB_VECTOR_LENGTH_ERROR; 51031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((dc_sc & DC_MASK) != DC_CRS) 51051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 51061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rsv->svl >= 2 && rsv->svl < 20) 5107807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return E_TRANSMIT_FORWARD_INVALID; 51081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((rsv->svv[0] != 0) || (rsv->svv[1] != 0)) 5110807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return E_TRANSMIT_FORWARD_INVALID; 51111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 51121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5113807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return POSITIVE_ACK; 51141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 51151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_local_ring_num(struct net_device *dev, 51171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAC_SUB_VECTOR *rsv) 51181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 51191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 51201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rsv->svl != S_LOCAL_RING_NUMBER) 5122807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return E_SUB_VECTOR_LENGTH_ERROR; 51231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->ptr_local_ring_num) 51251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(__u16 *)(tp->ptr_local_ring_num) 51261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = (rsv->svv[0] << 8 | rsv->svv[1]); 51271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5128807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return POSITIVE_ACK; 51291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 51301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned short smctr_set_ctrl_attention(struct net_device *dev) 51321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 51331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 51341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ioaddr = dev->base_addr; 51351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->bic_type == BIC_585_CHIP) 51371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb((tp->trc_mask | HWR_CA), ioaddr + HWR); 51381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 51391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 51401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb((tp->trc_mask | CSR_CA), ioaddr + CSR); 51411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(tp->trc_mask, ioaddr + CSR); 51421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 51431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5144807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 51451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 51461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void smctr_set_multicast_list(struct net_device *dev) 51481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 51491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 51501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_set_multicast_list\n", dev->name); 51511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 51521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_page(struct net_device *dev, __u8 *buf) 51541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 51551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 51561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 amask; 51571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 tptr; 51581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tptr = (__u32)buf - (__u32)tp->ram_access; 51601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds amask = (__u8)((tptr & PR_PAGE_MASK) >> 8); 51611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(amask, dev->base_addr + PR); 51621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5163807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 51641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 51651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_phy_drop(struct net_device *dev, MAC_SUB_VECTOR *rsv) 51671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 51681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 51691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rsv->svl != S_PHYSICAL_DROP) 5171807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return E_SUB_VECTOR_LENGTH_ERROR; 51721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_issue_write_byte_cmd(dev, RW_PHYSICAL_DROP_NUMBER, &rsv->svv[0]); 51741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_cmd(dev))) 5175807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 51761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5177807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return POSITIVE_ACK; 51781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 51791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Reset the ring speed to the opposite of what it was. This auto-pilot 51811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mode requires a complete reset and re-init of the adapter. 51821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 51831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_ring_speed(struct net_device *dev) 51841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 51851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 51861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 51871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->media_type == MEDIA_UTP_16) 51891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->media_type = MEDIA_UTP_4; 51901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 51911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->media_type = MEDIA_UTP_16; 51921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_16bit(dev); 51941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Re-Initialize adapter's internal registers */ 51961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_reset_adapter(dev); 51971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_init_card_real(dev))) 5199807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 52001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_bic_int(dev); 52021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK))) 5204807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 52051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 52071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5208807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 52091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 52101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_rx_look_ahead(struct net_device *dev) 52121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 52131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 52141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 sword, rword; 52151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 52171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_set_rx_look_ahead_flag\n", dev->name); 52181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->adapter_flags &= ~(FORCED_16BIT_MODE); 52201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->adapter_flags |= RX_VALID_LOOKAHEAD; 52211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->adapter_bus == BUS_ISA16_TYPE) 52231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 52241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sword = *((__u16 *)(tp->ram_access)); 52251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *((__u16 *)(tp->ram_access)) = 0x1234; 52261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 52281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rword = *((__u16 *)(tp->ram_access)); 52291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_16bit(dev); 52301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(rword != 0x1234) 52321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->adapter_flags |= FORCED_16BIT_MODE; 52331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *((__u16 *)(tp->ram_access)) = sword; 52351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 52361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5237807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 52381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 52391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_set_trc_reset(int ioaddr) 52411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 52421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 r; 52431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = inb(ioaddr + MSR); 52451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(MSR_RST | r, ioaddr + MSR); 52461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5247807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 52481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 52491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 52511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This function can be called if the adapter is busy or not. 52521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 52531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_setup_single_cmd(struct net_device *dev, 52541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 command, __u16 subcommand) 52551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 52561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 52571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int err; 52581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 52601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_setup_single_cmd\n", dev->name); 52611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_wait_while_cbusy(dev))) 5263807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 52641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = (unsigned int)smctr_wait_cmd(dev))) 5266807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 52671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->acb_head->cmd_done_status = 0; 52691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->acb_head->cmd = command; 52701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->acb_head->subcmd = subcommand; 52711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_issue_resume_acb_cmd(dev); 52731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5274807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 52751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 52761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 52781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This function can not be called with the adapter busy. 52791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 52801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_setup_single_cmd_w_data(struct net_device *dev, 52811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 command, __u16 subcommand) 52821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 52831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 52841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->acb_head->cmd_done_status = ACB_COMMAND_NOT_DONE; 52861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->acb_head->cmd = command; 52871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->acb_head->subcmd = subcommand; 52881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->acb_head->data_offset_lo 52891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = (__u16)TRC_POINTER(tp->misc_command_data); 52901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5291807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return smctr_issue_resume_acb_cmd(dev); 52921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 52931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *smctr_malloc(struct net_device *dev, __u16 size) 52951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 52961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 52971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *m; 52981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds m = (char *)(tp->ram_access + tp->sh_mem_used); 53001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->sh_mem_used += (__u32)size; 53011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5302807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return m; 53031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 53041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_status_chg(struct net_device *dev) 53061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 53071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 53081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 53101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_status_chg\n", dev->name); 53111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(tp->status) 53131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 53141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case OPEN: 53151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 53161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CLOSED: 53181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 53191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Interrupt driven open() completion. XXX */ 53211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case INITIALIZED: 53221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->group_address_0 = 0; 53231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->group_address[0] = 0; 53241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->group_address[1] = 0; 53251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->functional_address_0 = 0; 53261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->functional_address[0] = 0; 53271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->functional_address[1] = 0; 53281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_open_tr(dev); 53291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 53301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 53321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "%s: status change unknown %x\n", 53331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->name, tp->status); 53341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 53351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 53361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5337807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 53381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 53391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb, 53411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 queue) 53421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 53431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 53441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err = 0; 53451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 53471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_trc_send_packet\n", dev->name); 53481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->info = FCB_CHAIN_END | FCB_ENABLE_TFS; 53501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->num_tx_fcbs[queue] != 1) 53511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->back_ptr->info = FCB_INTERRUPT_ENABLE | FCB_ENABLE_TFS; 53521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->tx_queue_status[queue] == NOT_TRANSMITING) 53541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 53551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_queue_status[queue] = TRANSMITING; 53561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_issue_resume_tx_fcb_cmd(dev, queue); 53571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 53581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5359807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 53601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 53611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic __u16 smctr_tx_complete(struct net_device *dev, __u16 queue) 53631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 53641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 53651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 status, err = 0; 53661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cstatus; 53671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 53691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_tx_complete\n", dev->name); 53701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while((status = tp->tx_fcb_end[queue]->frame_status) != SUCCESS) 53721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 53731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(status & 0x7e00 ) 53741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 53751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = HARDWARE_FAILED; 53761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 53771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 53781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((err = smctr_update_tx_chain(dev, tp->tx_fcb_end[queue], 53801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds queue)) != SUCCESS) 53811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 53821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_disable_16bit(dev); 53841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->mode_bits & UMAC) 53861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 53871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(status & (FCB_TX_STATUS_AR1 | FCB_TX_STATUS_AR2))) 53881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cstatus = NO_SUCH_DESTINATION; 53891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 53901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 53911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(status & (FCB_TX_STATUS_CR1 | FCB_TX_STATUS_CR2))) 53921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cstatus = DEST_OUT_OF_RESOURCES; 53931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 53941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 53951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(status & FCB_TX_STATUS_E) 53961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cstatus = MAX_COLLISIONS; 53971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 53981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cstatus = SUCCESS; 53991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 54001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 54011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 54021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 54031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cstatus = SUCCESS; 54041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(queue == BUG_QUEUE) 54061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = SUCCESS; 54071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_enable_16bit(dev); 54091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(err != SUCCESS) 54101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 54111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 54121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5413807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return err; 54141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 54151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned short smctr_tx_move_frame(struct net_device *dev, 54171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb, __u8 *pbuff, unsigned int bytes) 54181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 54191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 54201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int ram_usable; 54211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 flen, len, offset = 0; 54221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *frag, *page; 54231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 54251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_tx_move_frame\n", dev->name); 54261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ram_usable = ((unsigned int)tp->ram_usable) << 10; 54281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frag = skb->data; 54291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flen = skb->len; 54301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while(flen > 0 && bytes > 0) 54321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 54331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smctr_set_page(dev, pbuff); 54341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds offset = SMC_PAGE_OFFSET(pbuff); 54361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(offset + flen > ram_usable) 54381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = ram_usable - offset; 54391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 54401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = flen; 54411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(len > bytes) 54431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = bytes; 54441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds page = (char *) (offset + tp->ram_access); 54461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(page, frag, len); 54471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flen -=len; 54491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bytes -= len; 54501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frag += len; 54511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbuff += len; 54521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 54531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5454807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 54551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 54561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Update the error statistic counters for this adapter. */ 54581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_update_err_stats(struct net_device *dev) 54591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 54601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 54611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct tr_statistics *tstat = &tp->MacStat; 54621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tstat->internal_errors) 54641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tstat->internal_errors 54651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds += *(tp->misc_command_data + 0) & 0x00ff; 54661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tstat->line_errors) 54681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tstat->line_errors += *(tp->misc_command_data + 0) >> 8; 54691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tstat->A_C_errors) 54711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tstat->A_C_errors += *(tp->misc_command_data + 1) & 0x00ff; 54721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tstat->burst_errors) 54741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tstat->burst_errors += *(tp->misc_command_data + 1) >> 8; 54751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tstat->abort_delimiters) 54771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tstat->abort_delimiters += *(tp->misc_command_data + 2) >> 8; 54781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tstat->recv_congest_count) 54801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tstat->recv_congest_count 54811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds += *(tp->misc_command_data + 3) & 0x00ff; 54821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tstat->lost_frames) 54841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tstat->lost_frames 54851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds += *(tp->misc_command_data + 3) >> 8; 54861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tstat->frequency_errors) 54881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tstat->frequency_errors += *(tp->misc_command_data + 4) & 0x00ff; 54891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tstat->frame_copied_errors) 54911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tstat->frame_copied_errors 54921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds += *(tp->misc_command_data + 4) >> 8; 54931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tstat->token_errors) 54951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tstat->token_errors += *(tp->misc_command_data + 5) >> 8; 54961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5497807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 54981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 54991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_update_rx_chain(struct net_device *dev, __u16 queue) 55011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 55021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 55031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FCBlock *fcb; 55041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BDBlock *bdb; 55051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 size, len; 55061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb = tp->rx_fcb_curr[queue]; 55081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = fcb->frame_length; 55091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->frame_status = 0; 55111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->info = FCB_CHAIN_END; 55121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->back_ptr->info = FCB_WARNING; 55131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_fcb_curr[queue] = tp->rx_fcb_curr[queue]->next_ptr; 55151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* update RX BDBs */ 55171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = (len >> RX_BDB_SIZE_SHIFT); 55181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(len & RX_DATA_BUFFER_SIZE_MASK) 55191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size += sizeof(BDBlock); 55201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size &= (~RX_BDB_SIZE_MASK); 55211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if wrap around */ 55231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb = (BDBlock *)((__u32)(tp->rx_bdb_curr[queue]) + (__u32)(size)); 55241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((__u32)bdb >= (__u32)tp->rx_bdb_end[queue]) 55251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 55261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb = (BDBlock *)((__u32)(tp->rx_bdb_head[queue]) 55271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + (__u32)(bdb) - (__u32)(tp->rx_bdb_end[queue])); 55281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 55291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdb->back_ptr->info = BDB_CHAIN_END; 55311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_bdb_curr[queue]->back_ptr->info = BDB_NOT_CHAIN_END; 55321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->rx_bdb_curr[queue] = bdb; 55331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5534807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 55351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 55361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, 55381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 queue) 55391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 55401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 55411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 20) 55431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "smctr_update_tx_chain\n"); 55441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->num_tx_fcbs_used[queue] <= 0) 5546807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return HARDWARE_FAILED; 55471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 55481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 55491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->tx_buff_used[queue] < fcb->memory_alloc) 55501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 55511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_used[queue] = 0; 5552807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return HARDWARE_FAILED; 55531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 55541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_used[queue] -= fcb->memory_alloc; 55561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* if all transmit buffer are cleared 55581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * need to set the tx_buff_curr[] to tx_buff_head[] 55591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * otherwise, tx buffer will be segregate and cannot 55601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * accommodate and buffer greater than (curr - head) and 55611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (end - curr) since we do not allow wrap around allocation. 55621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 55631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->tx_buff_used[queue] == 0) 55641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_buff_curr[queue] = tp->tx_buff_head[queue]; 55651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->num_tx_fcbs_used[queue]--; 55671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcb->frame_status = 0; 55681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->tx_fcb_end[queue] = fcb->next_ptr; 55691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds netif_wake_queue(dev); 5570807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 55711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 55721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 55731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_wait_cmd(struct net_device *dev) 55751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 55761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 55771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int loop_count = 0x20000; 55781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(smctr_debug > 10) 55801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG "%s: smctr_wait_cmd\n", dev->name); 55811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while(loop_count) 55831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 55841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->acb_head->cmd_done_status & ACB_COMMAND_DONE) 55851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 55861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(1); 55871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds loop_count--; 55881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 55891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(loop_count == 0) 5591807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return HARDWARE_FAILED; 55921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->acb_head->cmd_done_status & 0xff) 5594807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return HARDWARE_FAILED; 55951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5596807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 55971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 55981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smctr_wait_while_cbusy(struct net_device *dev) 56001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 56011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_local *tp = netdev_priv(dev); 56021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int timeout = 0x20000; 56031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ioaddr = dev->base_addr; 56041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 r; 56051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(tp->bic_type == BIC_585_CHIP) 56071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 56081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while(timeout) 56091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 56101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = inb(ioaddr + HWR); 56111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((r & HWR_CBUSY) == 0) 56121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 56131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds timeout--; 56141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 56151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 56161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 56171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 56181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while(timeout) 56191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 56201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = inb(ioaddr + CSR); 56211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((r & CSR_CBUSY) == 0) 56221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 56231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds timeout--; 56241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 56251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 56261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(timeout) 5628807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 56291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 5630807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return HARDWARE_FAILED; 56311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 56321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef MODULE 56341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct net_device* dev_smctr[SMCTR_MAX_ADAPTERS]; 56361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int io[SMCTR_MAX_ADAPTERS]; 56371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int irq[SMCTR_MAX_ADAPTERS]; 56381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 56400f805b86c9492c294c710de8539a8be68b521a86David WoodhouseMODULE_FIRMWARE("tr_smctr.bin"); 56411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param_array(io, int, NULL, 0); 56431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param_array(irq, int, NULL, 0); 56441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(ringspeed, int, 0); 56451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5646daca7cd7612639848c39744e02dab537755b31a1Andrew Mortonstatic struct net_device * __init setup_card(int n) 56471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 56481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_device *dev = alloc_trdev(sizeof(struct net_local)); 56491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 56501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev) 56521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ERR_PTR(-ENOMEM); 56531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->irq = irq[n]; 56551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = smctr_probe1(dev, io[n]); 56561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err) 56571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 56581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = register_netdev(dev); 56601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err) 56611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out1; 56621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dev; 56631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out1: 56641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_MCA_LEGACY 56651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { struct net_local *tp = netdev_priv(dev); 56661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tp->slot_num) 56671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mca_mark_as_unused(tp->slot_num); 56681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 56691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 56701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_region(dev->base_addr, SMCTR_IO_EXTENT); 56711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_irq(dev->irq, dev); 56721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 56731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_netdev(dev); 56741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ERR_PTR(err); 56751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 56761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5677daca7cd7612639848c39744e02dab537755b31a1Andrew Mortonint __init init_module(void) 56781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 56791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, found = 0; 56801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_device *dev; 56811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < SMCTR_MAX_ADAPTERS; i++) { 56831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev = io[0]? setup_card(i) : smctr_probe(-1); 56841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!IS_ERR(dev)) { 56851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++found; 56861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_smctr[i] = dev; 56871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 56881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 56891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return found ? 0 : -ENODEV; 56911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 56921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5693afc8eb46c0ea2cab8bc28713b2e0614f015a7516Al Virovoid __exit cleanup_module(void) 56941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 56951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 56961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < SMCTR_MAX_ADAPTERS; i++) { 56981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_device *dev = dev_smctr[i]; 56991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 57001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev) { 57011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 57021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unregister_netdev(dev); 57031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_MCA_LEGACY 57041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { struct net_local *tp = netdev_priv(dev); 57051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tp->slot_num) 57061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mca_mark_as_unused(tp->slot_num); 57071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 57081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 57091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_region(dev->base_addr, SMCTR_IO_EXTENT); 57101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->irq) 57111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_irq(dev->irq, dev); 57121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 57131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_netdev(dev); 57141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 57151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 57161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 57171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* MODULE */ 5718