📄 smctr.c
字号:
/* * smctr.c: A network driver for the SMC Token Ring Adapters. * * Written by Jay Schulist <jschlst@samba.org> * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * * This device driver works with the following SMC adapters: * - SMC TokenCard Elite (8115T, chips 825/584) * - SMC TokenCard Elite/A MCA (8115T/A, chips 825/594) * * Source(s): * - SMC TokenCard SDK. * * Maintainer(s): * JS Jay Schulist <jschlst@samba.org> * * Changes: * 07102000 JS Fixed a timing problem in smctr_wait_cmd(); * Also added a bit more discriptive error msgs. * 07122000 JS Fixed problem with detecting a card with * module io/irq/mem specified. * * To do: * 1. Multicast support. * * Initial 2.5 cleanup Alan Cox <alan@redhat.com> 2002/10/28 */#include <linux/module.h>#include <linux/config.h>#include <linux/kernel.h>#include <linux/types.h>#include <linux/fcntl.h>#include <linux/interrupt.h>#include <linux/ptrace.h>#include <linux/ioport.h>#include <linux/in.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/time.h>#include <linux/errno.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/mca-legacy.h>#include <linux/delay.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/trdevice.h>#include <linux/bitops.h>#include <asm/system.h>#include <asm/io.h>#include <asm/dma.h>#include <asm/irq.h>#if BITS_PER_LONG == 64#error FIXME: driver does not support 64-bit platforms#endif#include "smctr.h" /* Our Stuff */#include "smctr_firmware.h" /* SMC adapter firmware */static char version[] __initdata = KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n";static const char cardname[] = "smctr";#define SMCTR_IO_EXTENT 20#ifdef CONFIG_MCA_LEGACYstatic unsigned int smctr_posid = 0x6ec6;#endifstatic int ringspeed;/* SMC Name of the Adapter. */static char smctr_name[] = "SMC TokenCard";static char *smctr_model = "Unknown";/* Use 0 for production, 1 for verification, 2 for debug, and * 3 for very verbose debug. */#ifndef SMCTR_DEBUG#define SMCTR_DEBUG 1#endifstatic unsigned int smctr_debug = SMCTR_DEBUG;/* smctr.c prototypes and functions are arranged alphabeticly * for clearity, maintainability and pure old fashion fun. *//* A */static int smctr_alloc_shared_memory(struct net_device *dev);/* B */static int smctr_bypass_state(struct net_device *dev);/* C */static int smctr_checksum_firmware(struct net_device *dev);static int __init smctr_chk_isa(struct net_device *dev);static int smctr_chg_rx_mask(struct net_device *dev);static int smctr_clear_int(struct net_device *dev);static int smctr_clear_trc_reset(int ioaddr);static int smctr_close(struct net_device *dev);/* D */static int smctr_decode_firmware(struct net_device *dev);static int smctr_disable_16bit(struct net_device *dev);static int smctr_disable_adapter_ctrl_store(struct net_device *dev);static int smctr_disable_bic_int(struct net_device *dev);/* E */static int smctr_enable_16bit(struct net_device *dev);static int smctr_enable_adapter_ctrl_store(struct net_device *dev);static int smctr_enable_adapter_ram(struct net_device *dev);static int smctr_enable_bic_int(struct net_device *dev);/* G */static int __init smctr_get_boardid(struct net_device *dev, int mca);static int smctr_get_group_address(struct net_device *dev);static int smctr_get_functional_address(struct net_device *dev);static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev);static int smctr_get_physical_drop_number(struct net_device *dev);static __u8 *smctr_get_rx_pointer(struct net_device *dev, short queue);static int smctr_get_station_id(struct net_device *dev);static struct net_device_stats *smctr_get_stats(struct net_device *dev);static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, __u16 bytes_count);static int smctr_get_upstream_neighbor_addr(struct net_device *dev);/* H */static int smctr_hardware_send_packet(struct net_device *dev, struct net_local *tp);/* I */static int smctr_init_acbs(struct net_device *dev);static int smctr_init_adapter(struct net_device *dev);static int smctr_init_card_real(struct net_device *dev);static int smctr_init_rx_bdbs(struct net_device *dev);static int smctr_init_rx_fcbs(struct net_device *dev);static int smctr_init_shared_memory(struct net_device *dev);static int smctr_init_tx_bdbs(struct net_device *dev);static int smctr_init_tx_fcbs(struct net_device *dev);static int smctr_internal_self_test(struct net_device *dev);static irqreturn_t smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs);static int smctr_issue_enable_int_cmd(struct net_device *dev, __u16 interrupt_enable_mask);static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ibits);static int smctr_issue_init_timers_cmd(struct net_device *dev);static int smctr_issue_init_txrx_cmd(struct net_device *dev);static int smctr_issue_insert_cmd(struct net_device *dev);static int smctr_issue_read_ring_status_cmd(struct net_device *dev);static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt);static int smctr_issue_remove_cmd(struct net_device *dev);static int smctr_issue_resume_acb_cmd(struct net_device *dev);static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue);static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue);static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue);static int smctr_issue_test_internal_rom_cmd(struct net_device *dev);static int smctr_issue_test_hic_cmd(struct net_device *dev);static int smctr_issue_test_mac_reg_cmd(struct net_device *dev);static int smctr_issue_trc_loopback_cmd(struct net_device *dev);static int smctr_issue_tri_loopback_cmd(struct net_device *dev);static int smctr_issue_write_byte_cmd(struct net_device *dev, short aword_cnt, void *byte);static int smctr_issue_write_word_cmd(struct net_device *dev, short aword_cnt, void *word);/* J */static int smctr_join_complete_state(struct net_device *dev);/* L */static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev);static int smctr_load_firmware(struct net_device *dev);static int smctr_load_node_addr(struct net_device *dev);static int smctr_lobe_media_test(struct net_device *dev);static int smctr_lobe_media_test_cmd(struct net_device *dev);static int smctr_lobe_media_test_state(struct net_device *dev);/* M */static int smctr_make_8025_hdr(struct net_device *dev, MAC_HEADER *rmf, MAC_HEADER *tmf, __u16 ac_fc);static int smctr_make_access_pri(struct net_device *dev, MAC_SUB_VECTOR *tsv);static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv);static int smctr_make_auth_funct_class(struct net_device *dev, MAC_SUB_VECTOR *tsv);static int smctr_make_corr(struct net_device *dev, MAC_SUB_VECTOR *tsv, __u16 correlator);static int smctr_make_funct_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv);static int smctr_make_group_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv);static int smctr_make_phy_drop_num(struct net_device *dev, MAC_SUB_VECTOR *tsv);static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv);static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv);static int smctr_make_ring_station_status(struct net_device *dev, MAC_SUB_VECTOR *tsv);static int smctr_make_ring_station_version(struct net_device *dev, MAC_SUB_VECTOR *tsv);static int smctr_make_tx_status_code(struct net_device *dev, MAC_SUB_VECTOR *tsv, __u16 tx_fstatus);static int smctr_make_upstream_neighbor_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv);static int smctr_make_wrap_data(struct net_device *dev, MAC_SUB_VECTOR *tsv);/* O */static int smctr_open(struct net_device *dev);static int smctr_open_tr(struct net_device *dev);/* P */struct net_device *smctr_probe(int unit);static int __init smctr_probe1(struct net_device *dev, int ioaddr);static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, struct net_device *dev, __u16 rx_status);/* R */static int smctr_ram_memory_test(struct net_device *dev);static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf, __u16 *correlator);static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf, __u16 *correlator);static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf);static int smctr_rcv_rq_addr_state_attch(struct net_device *dev, MAC_HEADER *rmf, __u16 *correlator);static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf, __u16 *correlator);static int smctr_reset_adapter(struct net_device *dev);static int smctr_restart_tx_chain(struct net_device *dev, short queue);static int smctr_ring_status_chg(struct net_device *dev);static int smctr_rx_frame(struct net_device *dev);/* S */static int smctr_send_dat(struct net_device *dev);static int smctr_send_packet(struct sk_buff *skb, struct net_device *dev);static int smctr_send_lobe_media_test(struct net_device *dev);static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf, __u16 correlator);static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf, __u16 correlator);static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf, __u16 correlator);static int smctr_send_rpt_tx_forward(struct net_device *dev, MAC_HEADER *rmf, __u16 tx_fstatus);static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf, __u16 rcode, __u16 correlator);static int smctr_send_rq_init(struct net_device *dev);static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, __u16 *tx_fstatus);static int smctr_set_auth_access_pri(struct net_device *dev, MAC_SUB_VECTOR *rsv);static int smctr_set_auth_funct_class(struct net_device *dev, MAC_SUB_VECTOR *rsv);static int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv, __u16 *correlator);static int smctr_set_error_timer_value(struct net_device *dev, MAC_SUB_VECTOR *rsv);static int smctr_set_frame_forward(struct net_device *dev, MAC_SUB_VECTOR *rsv, __u8 dc_sc);static int smctr_set_local_ring_num(struct net_device *dev, MAC_SUB_VECTOR *rsv);static unsigned short smctr_set_ctrl_attention(struct net_device *dev);static void smctr_set_multicast_list(struct net_device *dev);static int smctr_set_page(struct net_device *dev, __u8 *buf);static int smctr_set_phy_drop(struct net_device *dev, MAC_SUB_VECTOR *rsv);static int smctr_set_ring_speed(struct net_device *dev);static int smctr_set_rx_look_ahead(struct net_device *dev);static int smctr_set_trc_reset(int ioaddr);static int smctr_setup_single_cmd(struct net_device *dev, __u16 command, __u16 subcommand);static int smctr_setup_single_cmd_w_data(struct net_device *dev, __u16 command, __u16 subcommand);static char *smctr_malloc(struct net_device *dev, __u16 size);static int smctr_status_chg(struct net_device *dev);/* T */static void smctr_timeout(struct net_device *dev);static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb, __u16 queue);static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue);static unsigned short smctr_tx_move_frame(struct net_device *dev, struct sk_buff *skb, __u8 *pbuff, unsigned int bytes);/* U */static int smctr_update_err_stats(struct net_device *dev);static int smctr_update_rx_chain(struct net_device *dev, __u16 queue);static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, __u16 queue);/* W */static int smctr_wait_cmd(struct net_device *dev);static int smctr_wait_while_cbusy(struct net_device *dev);#define TO_256_BYTE_BOUNDRY(X) (((X + 0xff) & 0xff00) - X)#define TO_PARAGRAPH_BOUNDRY(X) (((X + 0x0f) & 0xfff0) - X)#define PARAGRAPH_BOUNDRY(X) smctr_malloc(dev, TO_PARAGRAPH_BOUNDRY(X))/* Allocate Adapter Shared Memory. * IMPORTANT NOTE: Any changes to this function MUST be mirrored in the * function "get_num_rx_bdbs" below!!! * * Order of memory allocation: * * 0. Initial System Configuration Block Pointer * 1. System Configuration Block * 2. System Control Block * 3. Action Command Block * 4. Interrupt Status Block * * 5. MAC TX FCB'S * 6. NON-MAC TX FCB'S * 7. MAC TX BDB'S * 8. NON-MAC TX BDB'S * 9. MAC RX FCB'S * 10. NON-MAC RX FCB'S * 11. MAC RX BDB'S * 12. NON-MAC RX BDB'S * 13. MAC TX Data Buffer( 1, 256 byte buffer) * 14. MAC RX Data Buffer( 1, 256 byte buffer) * * 15. NON-MAC TX Data Buffer * 16. NON-MAC RX Data Buffer */static int smctr_alloc_shared_memory(struct net_device *dev){ struct net_local *tp = netdev_priv(dev); if(smctr_debug > 10) printk(KERN_DEBUG "%s: smctr_alloc_shared_memory\n", dev->name); /* Allocate initial System Control Block pointer. * This pointer is located in the last page, last offset - 4. */ tp->iscpb_ptr = (ISCPBlock *)(tp->ram_access + ((__u32)64 * 0x400) - (long)ISCP_BLOCK_SIZE); /* Allocate System Control Blocks. */ tp->scgb_ptr = (SCGBlock *)smctr_malloc(dev, sizeof(SCGBlock)); PARAGRAPH_BOUNDRY(tp->sh_mem_used); tp->sclb_ptr = (SCLBlock *)smctr_malloc(dev, sizeof(SCLBlock)); PARAGRAPH_BOUNDRY(tp->sh_mem_used); tp->acb_head = (ACBlock *)smctr_malloc(dev, sizeof(ACBlock)*tp->num_acbs); PARAGRAPH_BOUNDRY(tp->sh_mem_used); tp->isb_ptr = (ISBlock *)smctr_malloc(dev, sizeof(ISBlock)); PARAGRAPH_BOUNDRY(tp->sh_mem_used); tp->misc_command_data = (__u16 *)smctr_malloc(dev, MISC_DATA_SIZE); PARAGRAPH_BOUNDRY(tp->sh_mem_used); /* Allocate transmit FCBs. */ tp->tx_fcb_head[MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, sizeof(FCBlock) * tp->num_tx_fcbs[MAC_QUEUE]); tp->tx_fcb_head[NON_MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, sizeof(FCBlock) * tp->num_tx_fcbs[NON_MAC_QUEUE]); tp->tx_fcb_head[BUG_QUEUE] = (FCBlock *)smctr_malloc(dev, sizeof(FCBlock) * tp->num_tx_fcbs[BUG_QUEUE]); /* Allocate transmit BDBs. */ tp->tx_bdb_head[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, sizeof(BDBlock) * tp->num_tx_bdbs[MAC_QUEUE]); tp->tx_bdb_head[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, sizeof(BDBlock) * tp->num_tx_bdbs[NON_MAC_QUEUE]); tp->tx_bdb_head[BUG_QUEUE] = (BDBlock *)smctr_malloc(dev, sizeof(BDBlock) * tp->num_tx_bdbs[BUG_QUEUE]); /* Allocate receive FCBs. */ tp->rx_fcb_head[MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, sizeof(FCBlock) * tp->num_rx_fcbs[MAC_QUEUE]); tp->rx_fcb_head[NON_MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, sizeof(FCBlock) * tp->num_rx_fcbs[NON_MAC_QUEUE]); /* Allocate receive BDBs. */ tp->rx_bdb_head[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, sizeof(BDBlock) * tp->num_rx_bdbs[MAC_QUEUE]); tp->rx_bdb_end[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 0); tp->rx_bdb_head[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, sizeof(BDBlock) * tp->num_rx_bdbs[NON_MAC_QUEUE]); tp->rx_bdb_end[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 0); /* Allocate MAC transmit buffers. * MAC Tx Buffers doen't have to be on an ODD Boundry. */ tp->tx_buff_head[MAC_QUEUE] = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[MAC_QUEUE]); tp->tx_buff_curr[MAC_QUEUE] = tp->tx_buff_head[MAC_QUEUE]; tp->tx_buff_end [MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); /* Allocate BUG transmit buffers. */ tp->tx_buff_head[BUG_QUEUE]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -