Commit 921a86e0e306e42452e16894f2cc792659ede16b

Authored by Krzysztof Halasa
Committed by Greg Kroah-Hartman
1 parent b0b5763308

Staging: Add SBE 2T3E3 WAN driver

This is a driver for SBE Inc.'s dual port T3/E3 WAN cards. Based on
their original GPLed driver.

The original driver tarball is now accessible at
http://userweb.kernel.org/~chris/SBE_2T3_Linux_2.0c.tgz

It needs at least a new generic HDLC setup code (not yet written) before
moving to drivers/net/wan.

Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 18 changed files with 4294 additions and 0 deletions Side-by-side Diff

drivers/staging/Kconfig
... ... @@ -155,6 +155,8 @@
155 155  
156 156 source "drivers/staging/westbridge/Kconfig"
157 157  
  158 +source "drivers/staging/sbe-2t3e3/Kconfig"
  159 +
158 160 endif # !STAGING_EXCLUDE_BUILD
159 161 endif # STAGING
drivers/staging/Makefile
... ... @@ -58,4 +58,5 @@
58 58 obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/
59 59 obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/
60 60 obj-$(CONFIG_WESTBRIDGE_ASTORIA) += westbridge/astoria/
  61 +obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3/
drivers/staging/sbe-2t3e3/2t3e3.h
  1 +/*
  2 + * SBE 2T3E3 synchronous serial card driver for Linux
  3 + *
  4 + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of version 2 of the GNU General Public License
  8 + * as published by the Free Software Foundation.
  9 + *
  10 + * This code is based on a driver written by SBE Inc.
  11 + */
  12 +
  13 +#ifndef T3E3_H
  14 +#define T3E3_H
  15 +
  16 +#include <linux/hdlc.h>
  17 +#include <linux/interrupt.h>
  18 +#include <linux/netdevice.h>
  19 +#include <linux/pci.h>
  20 +#include <linux/io.h>
  21 +#include "ctrl.h"
  22 +
  23 +/**************************************************************
  24 + * 21143
  25 + **************************************************************/
  26 +
  27 +/* CSR */
  28 +#define SBE_2T3E3_21143_REG_BUS_MODE 0
  29 +#define SBE_2T3E3_21143_REG_TRANSMIT_POLL_DEMAND 1
  30 +#define SBE_2T3E3_21143_REG_RECEIVE_POLL_DEMAND 2
  31 +#define SBE_2T3E3_21143_REG_RECEIVE_LIST_BASE_ADDRESS 3
  32 +#define SBE_2T3E3_21143_REG_TRANSMIT_LIST_BASE_ADDRESS 4
  33 +#define SBE_2T3E3_21143_REG_STATUS 5
  34 +#define SBE_2T3E3_21143_REG_OPERATION_MODE 6
  35 +#define SBE_2T3E3_21143_REG_INTERRUPT_ENABLE 7
  36 +#define SBE_2T3E3_21143_REG_MISSED_FRAMES_AND_OVERFLOW_COUNTER 8
  37 +#define SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT 9
  38 +#define SBE_2T3E3_21143_REG_BOOT_ROM_PROGRAMMING_ADDRESS 10
  39 +#define SBE_2T3E3_21143_REG_GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL 11
  40 +#define SBE_2T3E3_21143_REG_SIA_STATUS 12
  41 +#define SBE_2T3E3_21143_REG_SIA_CONNECTIVITY 13
  42 +#define SBE_2T3E3_21143_REG_SIA_TRANSMIT_AND_RECEIVE 14
  43 +#define SBE_2T3E3_21143_REG_SIA_AND_GENERAL_PURPOSE_PORT 15
  44 +#define SBE_2T3E3_21143_REG_MAX 16
  45 +
  46 +/* CSR0 - BUS_MODE */
  47 +#define SBE_2T3E3_21143_VAL_WRITE_AND_INVALIDATE_ENABLE 0x01000000
  48 +#define SBE_2T3E3_21143_VAL_READ_LINE_ENABLE 0x00800000
  49 +#define SBE_2T3E3_21143_VAL_READ_MULTIPLE_ENABLE 0x00200000
  50 +#define SBE_2T3E3_21143_VAL_TRANSMIT_AUTOMATIC_POLLING_200us 0x00020000
  51 +#define SBE_2T3E3_21143_VAL_TRANSMIT_AUTOMATIC_POLLING_DISABLED 0x00000000
  52 +#define SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_32 0x0000c000
  53 +#define SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_16 0x00008000
  54 +#define SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_8 0x00004000
  55 +#define SBE_2T3E3_21143_VAL_BUS_ARBITRATION_RR 0x00000002
  56 +#define SBE_2T3E3_21143_VAL_SOFTWARE_RESET 0x00000001
  57 +
  58 +/* CSR5 - STATUS */
  59 +#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_PORT_INTERRUPT 0x04000000
  60 +#define SBE_2T3E3_21143_VAL_ERROR_BITS 0x03800000
  61 +#define SBE_2T3E3_21143_VAL_PARITY_ERROR 0x00000000
  62 +#define SBE_2T3E3_21143_VAL_MASTER_ABORT 0x00800000
  63 +#define SBE_2T3E3_21143_VAL_TARGET_ABORT 0x01000000
  64 +#define SBE_2T3E3_21143_VAL_TRANSMISSION_PROCESS_STATE 0x00700000
  65 +#define SBE_2T3E3_21143_VAL_TX_STOPPED 0x00000000
  66 +#define SBE_2T3E3_21143_VAL_TX_SUSPENDED 0x00600000
  67 +#define SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STATE 0x000e0000
  68 +#define SBE_2T3E3_21143_VAL_RX_STOPPED 0x00000000
  69 +#define SBE_2T3E3_21143_VAL_RX_SUSPENDED 0x000a0000
  70 +#define SBE_2T3E3_21143_VAL_NORMAL_INTERRUPT_SUMMARY 0x00010000
  71 +#define SBE_2T3E3_21143_VAL_ABNORMAL_INTERRUPT_SUMMARY 0x00008000
  72 +#define SBE_2T3E3_21143_VAL_EARLY_RECEIVE_INTERRUPT 0x00004000
  73 +#define SBE_2T3E3_21143_VAL_FATAL_BUS_ERROR 0x00002000
  74 +#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_TIMER_EXPIRED 0x00000800
  75 +#define SBE_2T3E3_21143_VAL_EARLY_TRANSMIT_INTERRUPT 0x00000400
  76 +#define SBE_2T3E3_21143_VAL_RECEIVE_WATCHDOG_TIMEOUT 0x00000200
  77 +#define SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED 0x00000100
  78 +#define SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE 0x00000080
  79 +#define SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT 0x00000040
  80 +#define SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW 0x00000020
  81 +#define SBE_2T3E3_21143_VAL_TRANSMIT_JABBER_TIMEOUT 0x00000008
  82 +#define SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE 0x00000004
  83 +#define SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED 0x00000002
  84 +#define SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT 0x00000001
  85 +
  86 +/* CSR6 - OPERATION_MODE */
  87 +#define SBE_2T3E3_21143_VAL_SPECIAL_CAPTURE_EFFECT_ENABLE 0x80000000
  88 +#define SBE_2T3E3_21143_VAL_RECEIVE_ALL 0x40000000
  89 +#define SBE_2T3E3_21143_VAL_MUST_BE_ONE 0x02000000
  90 +#define SBE_2T3E3_21143_VAL_SCRAMBLER_MODE 0x01000000
  91 +#define SBE_2T3E3_21143_VAL_PCS_FUNCTION 0x00800000
  92 +#define SBE_2T3E3_21143_VAL_TRANSMIT_THRESHOLD_MODE_10Mbs 0x00400000
  93 +#define SBE_2T3E3_21143_VAL_TRANSMIT_THRESHOLD_MODE_100Mbs 0x00000000
  94 +#define SBE_2T3E3_21143_VAL_STORE_AND_FORWARD 0x00200000
  95 +#define SBE_2T3E3_21143_VAL_HEARTBEAT_DISABLE 0x00080000
  96 +#define SBE_2T3E3_21143_VAL_PORT_SELECT 0x00040000
  97 +#define SBE_2T3E3_21143_VAL_CAPTURE_EFFECT_ENABLE 0x00020000
  98 +#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS 0x0000c000
  99 +#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_1 0x00000000
  100 +#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_2 0x00004000
  101 +#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_3 0x00008000
  102 +#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_4 0x0000c000
  103 +#define SBE_2T3E3_21143_VAL_TRANSMISSION_START 0x00002000
  104 +#define SBE_2T3E3_21143_VAL_OPERATING_MODE 0x00000c00
  105 +#define SBE_2T3E3_21143_VAL_LOOPBACK_OFF 0x00000000
  106 +#define SBE_2T3E3_21143_VAL_LOOPBACK_EXTERNAL 0x00000800
  107 +#define SBE_2T3E3_21143_VAL_LOOPBACK_INTERNAL 0x00000400
  108 +#define SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE 0x00000200
  109 +#define SBE_2T3E3_21143_VAL_PASS_ALL_MULTICAST 0x00000080
  110 +#define SBE_2T3E3_21143_VAL_PROMISCUOUS_MODE 0x00000040
  111 +#define SBE_2T3E3_21143_VAL_PASS_BAD_FRAMES 0x00000008
  112 +#define SBE_2T3E3_21143_VAL_RECEIVE_START 0x00000002
  113 +
  114 +/* CSR7 - INTERRUPT_ENABLE */
  115 +#define SBE_2T3E3_21143_VAL_LINK_CHANGED_ENABLE 0x08000000
  116 +#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_PORT_ENABLE 0x04000000
  117 +#define SBE_2T3E3_21143_VAL_NORMAL_INTERRUPT_SUMMARY_ENABLE 0x00010000
  118 +#define SBE_2T3E3_21143_VAL_ABNORMAL_INTERRUPT_SUMMARY_ENABLE 0x00008000
  119 +#define SBE_2T3E3_21143_VAL_EARLY_RECEIVE_INTERRUPT_ENABLE 0x00004000
  120 +#define SBE_2T3E3_21143_VAL_FATAL_BUS_ERROR_ENABLE 0x00002000
  121 +#define SBE_2T3E3_21143_VAL_LINK_FAIL_ENABLE 0x00001000
  122 +#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_TIMER_ENABLE 0x00000800
  123 +#define SBE_2T3E3_21143_VAL_EARLY_TRANSMIT_INTERRUPT_ENABLE 0x00000400
  124 +#define SBE_2T3E3_21143_VAL_RECEIVE_WATCHDOG_TIMEOUT_ENABLE 0x00000200
  125 +#define SBE_2T3E3_21143_VAL_RECEIVE_STOPPED_ENABLE 0x00000100
  126 +#define SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE_ENABLE 0x00000080
  127 +#define SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT_ENABLE 0x00000040
  128 +#define SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW_INTERRUPT_ENABLE 0x00000020
  129 +#define SBE_2T3E3_21143_VAL_TRANSMIT_JABBER_TIMEOUT_ENABLE 0x00000008
  130 +#define SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE_ENABLE 0x00000004
  131 +#define SBE_2T3E3_21143_VAL_TRANSMIT_STOPPED_ENABLE 0x00000002
  132 +#define SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT_ENABLE 0x00000001
  133 +
  134 +/* CSR8 - MISSED_FRAMES_AND_OVERFLOW_COUNTER */
  135 +#define SBE_2T3E3_21143_VAL_OVERFLOW_COUNTER_OVERFLOW 0x10000000
  136 +#define SBE_2T3E3_21143_VAL_OVERFLOW_COUNTER 0x0ffe0000
  137 +#define SBE_2T3E3_21143_VAL_MISSED_FRAME_OVERFLOW 0x00010000
  138 +#define SBE_2T3E3_21143_VAL_MISSED_FRAMES_COUNTER 0x0000ffff
  139 +
  140 +/* CSR9 - BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT */
  141 +#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_DATA_IN 0x00080000
  142 +#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_READ_MODE 0x00040000
  143 +#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_DATA_OUT 0x00020000
  144 +#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_CLOCK 0x00010000
  145 +#define SBE_2T3E3_21143_VAL_READ_OPERATION 0x00004000
  146 +#define SBE_2T3E3_21143_VAL_WRITE_OPERATION 0x00002000
  147 +#define SBE_2T3E3_21143_VAL_BOOT_ROM_SELECT 0x00001000
  148 +#define SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT 0x00000800
  149 +#define SBE_2T3E3_21143_VAL_BOOT_ROM_DATA 0x000000ff
  150 +#define SBE_2T3E3_21143_VAL_SERIAL_ROM_DATA_OUT 0x00000008
  151 +#define SBE_2T3E3_21143_VAL_SERIAL_ROM_DATA_IN 0x00000004
  152 +#define SBE_2T3E3_21143_VAL_SERIAL_ROM_CLOCK 0x00000002
  153 +#define SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT 0x00000001
  154 +
  155 +/* CSR11 - GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL */
  156 +#define SBE_2T3E3_21143_VAL_CYCLE_SIZE 0x80000000
  157 +#define SBE_2T3E3_21143_VAL_TRANSMIT_TIMER 0x78000000
  158 +#define SBE_2T3E3_21143_VAL_NUMBER_OF_TRANSMIT_PACKETS 0x07000000
  159 +#define SBE_2T3E3_21143_VAL_RECEIVE_TIMER 0x00f00000
  160 +#define SBE_2T3E3_21143_VAL_NUMBER_OF_RECEIVE_PACKETS 0x000e0000
  161 +#define SBE_2T3E3_21143_VAL_CONTINUOUS_MODE 0x00010000
  162 +#define SBE_2T3E3_21143_VAL_TIMER_VALUE 0x0000ffff
  163 +
  164 +/* CSR12 - SIA_STATUS */
  165 +#define SBE_2T3E3_21143_VAL_10BASE_T_RECEIVE_PORT_ACTIVITY 0x00000200
  166 +#define SBE_2T3E3_21143_VAL_AUI_RECEIVE_PORT_ACTIVITY 0x00000100
  167 +#define SBE_2T3E3_21143_VAL_10Mbs_LINK_STATUS 0x00000004
  168 +#define SBE_2T3E3_21143_VAL_100Mbs_LINK_STATUS 0x00000002
  169 +#define SBE_2T3E3_21143_VAL_MII_RECEIVE_PORT_ACTIVITY 0x00000001
  170 +
  171 +/* CSR13 - SIA_CONNECTIVITY */
  172 +#define SBE_2T3E3_21143_VAL_10BASE_T_OR_AUI 0x00000008
  173 +#define SBE_2T3E3_21143_VAL_SIA_RESET 0x00000001
  174 +
  175 +/* CSR14 - SIA_TRANSMIT_AND_RECEIVE */
  176 +#define SBE_2T3E3_21143_VAL_100BASE_TX_FULL_DUPLEX 0x00020000
  177 +#define SBE_2T3E3_21143_VAL_COLLISION_DETECT_ENABLE 0x00000400
  178 +#define SBE_2T3E3_21143_VAL_COLLISION_SQUELCH_ENABLE 0x00000200
  179 +#define SBE_2T3E3_21143_VAL_RECEIVE_SQUELCH_ENABLE 0x00000100
  180 +#define SBE_2T3E3_21143_VAL_LINK_PULSE_SEND_ENABLE 0x00000004
  181 +#define SBE_2T3E3_21143_VAL_ENCODER_ENABLE 0x00000001
  182 +
  183 +/* CSR15 - SIA_AND_GENERAL_PURPOSE_PORT */
  184 +#define SBE_2T3E3_21143_VAL_RECEIVE_WATCHDOG_DISABLE 0x00000010
  185 +#define SBE_2T3E3_21143_VAL_AUI_BNC_MODE 0x00000008
  186 +#define SBE_2T3E3_21143_VAL_HOST_UNJAB 0x00000002
  187 +#define SBE_2T3E3_21143_VAL_JABBER_DISABLE 0x00000001
  188 +
  189 +/**************************************************************
  190 + * CPLD
  191 + **************************************************************/
  192 +
  193 +/* reg_map indexes */
  194 +#define SBE_2T3E3_CPLD_REG_PCRA 0
  195 +#define SBE_2T3E3_CPLD_REG_PCRB 1
  196 +#define SBE_2T3E3_CPLD_REG_PLCR 2
  197 +#define SBE_2T3E3_CPLD_REG_PLTR 3
  198 +#define SBE_2T3E3_CPLD_REG_PPFR 4
  199 +#define SBE_2T3E3_CPLD_REG_BOARD_ID 5
  200 +#define SBE_2T3E3_CPLD_REG_FPGA_VERSION 6
  201 +#define SBE_2T3E3_CPLD_REG_FRAMER_BASE_ADDRESS 7
  202 +#define SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT 8
  203 +#define SBE_2T3E3_CPLD_REG_STATIC_RESET 9
  204 +#define SBE_2T3E3_CPLD_REG_PULSE_RESET 10
  205 +#define SBE_2T3E3_CPLD_REG_FPGA_RECONFIGURATION 11
  206 +#define SBE_2T3E3_CPLD_REG_LEDR 12
  207 +#define SBE_2T3E3_CPLD_REG_PICSR 13
  208 +#define SBE_2T3E3_CPLD_REG_PIER 14
  209 +#define SBE_2T3E3_CPLD_REG_PCRC 15
  210 +#define SBE_2T3E3_CPLD_REG_PBWF 16
  211 +#define SBE_2T3E3_CPLD_REG_PBWL 17
  212 +
  213 +#define SBE_2T3E3_CPLD_REG_MAX 18
  214 +
  215 +/**********/
  216 +
  217 +/* val_map indexes */
  218 +#define SBE_2T3E3_CPLD_VAL_LIU_SELECT 0
  219 +#define SBE_2T3E3_CPLD_VAL_DAC_SELECT 1
  220 +#define SBE_2T3E3_CPLD_VAL_LOOP_TIMING_SOURCE 2
  221 +#define SBE_2T3E3_CPLD_VAL_LIU_FRAMER_RESET 3
  222 +
  223 +/* PCRA */
  224 +#define SBE_2T3E3_CPLD_VAL_CRC32 0x40
  225 +#define SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE 0x20
  226 +#define SBE_2T3E3_CPLD_VAL_REAR_PANEL 0x10
  227 +#define SBE_2T3E3_CPLD_VAL_RAW_MODE 0x08
  228 +#define SBE_2T3E3_CPLD_VAL_ALT 0x04
  229 +#define SBE_2T3E3_CPLD_VAL_LOOP_TIMING 0x02
  230 +#define SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3 0x01
  231 +
  232 +/* PCRB */
  233 +#define SBE_2T3E3_CPLD_VAL_PAD_COUNT 0x30
  234 +#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_1 0x00
  235 +#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_2 0x10
  236 +#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_3 0x20
  237 +#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_4 0x30
  238 +#define SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE 0x02
  239 +#define SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE 0x01
  240 +
  241 +/* PCRC */
  242 +#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_NONE 0x00
  243 +#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_0 0x01
  244 +#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_1 0x11
  245 +#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_2 0x21
  246 +
  247 +/* PLTR */
  248 +#define SBE_2T3E3_CPLD_VAL_LCV_COUNTER 0xff
  249 +
  250 +/* SCSR */
  251 +#define SBE_2T3E3_CPLD_VAL_EEPROM_SELECT 0x10
  252 +
  253 +/* PICSR */
  254 +#define SBE_2T3E3_CPLD_VAL_LOSS_OF_SIGNAL_THRESHOLD_LEVEL_1 0x80
  255 +#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_CHANGE 0x40
  256 +#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ASSERTED 0x20
  257 +#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ASSERTED 0x10
  258 +#define SBE_2T3E3_CPLD_VAL_LCV_LIMIT_EXCEEDED 0x08
  259 +#define SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED 0x04
  260 +#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED 0x02
  261 +#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED 0x01
  262 +
  263 +/* PIER */
  264 +#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOS_CHANGE_ENABLE 0x40
  265 +#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ENABLE 0x20
  266 +#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ENABLE 0x10
  267 +#define SBE_2T3E3_CPLD_VAL_LCV_INTERRUPT_ENABLE 0x08
  268 +#define SBE_2T3E3_CPLD_VAL_DMO_ENABLE 0x04
  269 +#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_ENABLE 0x02
  270 +#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_ENABLE 0x01
  271 +
  272 +/**************************************************************
  273 + * Framer
  274 + **************************************************************/
  275 +
  276 +/* reg_map indexes */
  277 +/* common */
  278 +#define SBE_2T3E3_FRAMER_REG_OPERATING_MODE 0
  279 +#define SBE_2T3E3_FRAMER_REG_IO_CONTROL 1
  280 +#define SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE 2
  281 +#define SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS 3
  282 +#define SBE_2T3E3_FRAMER_REG_PMON_LCV_EVENT_COUNT_MSB 28
  283 +#define SBE_2T3E3_FRAMER_REG_PMON_LCV_EVENT_COUNT_LSB 29
  284 +#define SBE_2T3E3_FRAMER_REG_PMON_FRAMING_BIT_ERROR_EVENT_COUNT_MSB 30
  285 +#define SBE_2T3E3_FRAMER_REG_PMON_FRAMING_BIT_ERROR_EVENT_COUNT_LSB 31
  286 +#define SBE_2T3E3_FRAMER_REG_PMON_PARITY_ERROR_EVENT_COUNT_MSB 32
  287 +#define SBE_2T3E3_FRAMER_REG_PMON_PARITY_ERROR_EVENT_COUNT_LSB 33
  288 +#define SBE_2T3E3_FRAMER_REG_PMON_FEBE_EVENT_COUNT_MSB 34
  289 +#define SBE_2T3E3_FRAMER_REG_PMON_FEBE_EVENT_COUNT_LSB 35
  290 +#define SBE_2T3E3_FRAMER_REG_PMON_CP_BIT_ERROR_EVENT_COUNT_MSB 36
  291 +#define SBE_2T3E3_FRAMER_REG_PMON_CP_BIT_ERROR_EVENT_COUNT_LSB 37
  292 +#define SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER 38
  293 +#define SBE_2T3E3_FRAMER_REG_ONE_SECOND_ERROR_STATUS 39
  294 +#define SBE_2T3E3_FRAMER_REG_LCV_ONE_SECOND_ACCUMULATOR_MSB 40
  295 +#define SBE_2T3E3_FRAMER_REG_LCV_ONE_SECOND_ACCUMULATOR_LSB 41
  296 +#define SBE_2T3E3_FRAMER_REG_FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_MSB 42
  297 +#define SBE_2T3E3_FRAMER_REG_FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_LSB 43
  298 +#define SBE_2T3E3_FRAMER_REG_FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_MSB 44
  299 +#define SBE_2T3E3_FRAMER_REG_FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_LSB 45
  300 +#define SBE_2T3E3_FRAMER_REG_LINE_INTERFACE_DRIVE 46
  301 +#define SBE_2T3E3_FRAMER_REG_LINE_INTERFACE_SCAN 47
  302 +
  303 +/* T3 */
  304 +#define SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS 4
  305 +#define SBE_2T3E3_FRAMER_REG_T3_RX_STATUS 5
  306 +#define SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE 6
  307 +#define SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS 7
  308 +#define SBE_2T3E3_FRAMER_REG_T3_RX_SYNC_DETECT_ENABLE 8
  309 +#define SBE_2T3E3_FRAMER_REG_T3_RX_FEAC 10
  310 +#define SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS 11
  311 +#define SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL 12
  312 +#define SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_STATUS 13
  313 +#define SBE_2T3E3_FRAMER_REG_T3_TX_CONFIGURATION 16
  314 +#define SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS 17
  315 +#define SBE_2T3E3_FRAMER_REG_T3_TX_FEAC 18
  316 +#define SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_CONFIGURATION 19
  317 +#define SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS 20
  318 +#define SBE_2T3E3_FRAMER_REG_T3_TX_MBIT_MASK 21
  319 +#define SBE_2T3E3_FRAMER_REG_T3_TX_FBIT_MASK 22
  320 +#define SBE_2T3E3_FRAMER_REG_T3_TX_FBIT_MASK_2 23
  321 +#define SBE_2T3E3_FRAMER_REG_T3_TX_FBIT_MASK_3 24
  322 +
  323 +/* E3 */
  324 +#define SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_1 4
  325 +#define SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2 5
  326 +#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1 6
  327 +#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2 7
  328 +#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1 8
  329 +#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2 9
  330 +#define SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL 12
  331 +#define SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_STATUS 13
  332 +#define SBE_2T3E3_FRAMER_REG_E3_RX_NR_BYTE 14
  333 +#define SBE_2T3E3_FRAMER_REG_E3_RX_SERVICE_BITS 14
  334 +#define SBE_2T3E3_FRAMER_REG_E3_RX_GC_BYTE 15
  335 +#define SBE_2T3E3_FRAMER_REG_E3_TX_CONFIGURATION 16
  336 +#define SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_CONFIGURATION 19
  337 +#define SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS 19
  338 +#define SBE_2T3E3_FRAMER_REG_E3_TX_GC_BYTE 21
  339 +#define SBE_2T3E3_FRAMER_REG_E3_TX_SERVICE_BITS 21
  340 +#define SBE_2T3E3_FRAMER_REG_E3_TX_MA_BYTE 22
  341 +#define SBE_2T3E3_FRAMER_REG_E3_TX_NR_BYTE 23
  342 +#define SBE_2T3E3_FRAMER_REG_E3_TX_FA1_ERROR_MASK 25
  343 +#define SBE_2T3E3_FRAMER_REG_E3_TX_FAS_ERROR_MASK_UPPER 25
  344 +#define SBE_2T3E3_FRAMER_REG_E3_TX_FA2_ERROR_MASK 26
  345 +#define SBE_2T3E3_FRAMER_REG_E3_TX_FAS_ERROR_MASK_LOWER 26
  346 +#define SBE_2T3E3_FRAMER_REG_E3_TX_BIP8_MASK 27
  347 +#define SBE_2T3E3_FRAMER_REG_E3_TX_BIP4_MASK 27
  348 +
  349 +#define SBE_2T3E3_FRAMER_REG_MAX 48
  350 +
  351 +/**********/
  352 +
  353 +/* OPERATING_MODE */
  354 +#define SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE 0x80
  355 +#define SBE_2T3E3_FRAMER_VAL_T3_E3_SELECT 0x40
  356 +#define SBE_2T3E3_FRAMER_VAL_INTERNAL_LOS_ENABLE 0x20
  357 +#define SBE_2T3E3_FRAMER_VAL_RESET 0x10
  358 +#define SBE_2T3E3_FRAMER_VAL_INTERRUPT_ENABLE_RESET 0x08
  359 +#define SBE_2T3E3_FRAMER_VAL_FRAME_FORMAT_SELECT 0x04
  360 +#define SBE_2T3E3_FRAMER_VAL_TIMING_ASYNCH_TXINCLK 0x03
  361 +#define SBE_2T3E3_FRAMER_VAL_E3_G751 0x00
  362 +#define SBE_2T3E3_FRAMER_VAL_E3_G832 0x04
  363 +#define SBE_2T3E3_FRAMER_VAL_T3_CBIT 0x40
  364 +#define SBE_2T3E3_FRAMER_VAL_T3_M13 0x44
  365 +#define SBE_2T3E3_FRAMER_VAL_LOOPBACK_ON 0x80
  366 +#define SBE_2T3E3_FRAMER_VAL_LOOPBACK_OFF 0x00
  367 +
  368 +/* IO_CONTROL */
  369 +#define SBE_2T3E3_FRAMER_VAL_DISABLE_TX_LOSS_OF_CLOCK 0x80
  370 +#define SBE_2T3E3_FRAMER_VAL_LOSS_OF_CLOCK_STATUS 0x40
  371 +#define SBE_2T3E3_FRAMER_VAL_DISABLE_RX_LOSS_OF_CLOCK 0x20
  372 +#define SBE_2T3E3_FRAMER_VAL_AMI_LINE_CODE 0x10
  373 +#define SBE_2T3E3_FRAMER_VAL_UNIPOLAR 0x08
  374 +#define SBE_2T3E3_FRAMER_VAL_TX_LINE_CLOCK_INVERT 0x04
  375 +#define SBE_2T3E3_FRAMER_VAL_RX_LINE_CLOCK_INVERT 0x02
  376 +#define SBE_2T3E3_FRAMER_VAL_REFRAME 0x01
  377 +
  378 +/* BLOCK_INTERRUPT_ENABLE */
  379 +#define SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_ENABLE 0x80
  380 +#define SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_ENABLE 0x02
  381 +#define SBE_2T3E3_FRAMER_VAL_ONE_SECOND_INTERRUPT_ENABLE 0x01
  382 +
  383 +/* BLOCK_INTERRUPT_STATUS */
  384 +#define SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_STATUS 0x80
  385 +#define SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_STATUS 0x02
  386 +#define SBE_2T3E3_FRAMER_VAL_ONE_SECOND_INTERRUPT_STATUS 0x01
  387 +
  388 +/**********/
  389 +
  390 +/* T3_RX_CONFIGURATION_STATUS */
  391 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIS 0x80
  392 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_LOS 0x40
  393 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE 0x20
  394 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_OOF 0x10
  395 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FRAMING_ON_PARITY 0x04
  396 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_F_SYNC_ALGO 0x02
  397 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_M_SYNC_ALGO 0x01
  398 +
  399 +/* T3_RX_STATUS */
  400 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FERF 0x10
  401 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIC 0x04
  402 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEBE 0x07
  403 +
  404 +/* T3_RX_INTERRUPT_ENABLE */
  405 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_CP_BIT_ERROR_INTERRUPT_ENABLE 0x80
  406 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE 0x40
  407 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIS_INTERRUPT_ENABLE 0x20
  408 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE_INTERRUPT_ENABLE 0x10
  409 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FERF_INTERRUPT_ENABLE 0x08
  410 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIC_INTERRUPT_ENABLE 0x04
  411 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE 0x02
  412 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_P_BIT_INTERRUPT_ENABLE 0x01
  413 +
  414 +/* T3_RX_INTERRUPT_STATUS */
  415 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_CP_BIT_ERROR_INTERRUPT_STATUS 0x80
  416 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_STATUS 0x40
  417 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIS_INTERRUPT_STATUS 0x20
  418 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE_INTERRUPT_STATUS 0x10
  419 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FERF_INTERRUPT_STATUS 0x08
  420 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIC_INTERRUPT_STATUS 0x04
  421 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_STATUS 0x02
  422 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_P_BIT_INTERRUPT_STATUS 0x01
  423 +
  424 +/* T3_RX_FEAC_INTERRUPT_ENABLE_STATUS */
  425 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID 0x10
  426 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_REMOVE_INTERRUPT_ENABLE 0x08
  427 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_REMOVE_INTERRUPT_STATUS 0x04
  428 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID_INTERRUPT_ENABLE 0x02
  429 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID_INTERRUPT_STATUS 0x01
  430 +
  431 +/* T3_RX_LAPD_CONTROL */
  432 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_ENABLE 0x04
  433 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_INTERRUPT_ENABLE 0x02
  434 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_INTERRUPT_STATUS 0x01
  435 +
  436 +/* T3_RX_LAPD_STATUS */
  437 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_ABORT 0x40
  438 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_TYPE 0x30
  439 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_CR_TYPE 0x08
  440 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FCS_ERROR 0x04
  441 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_END_OF_MESSAGE 0x02
  442 +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FLAG_PRESENT 0x01
  443 +
  444 +/* T3_TX_CONFIGURATION */
  445 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_YELLOW_ALARM 0x80
  446 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_X_BIT 0x40
  447 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_IDLE 0x20
  448 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_AIS 0x10
  449 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_LOS 0x08
  450 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FERF_ON_LOS 0x04
  451 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FERF_ON_OOF 0x02
  452 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FERF_ON_AIS 0x01
  453 +
  454 +/* T3_TX_FEAC_CONFIGURATION_STATUS */
  455 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_INTERRUPT_ENABLE 0x10
  456 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_INTERRUPT_STATUS 0x08
  457 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_ENABLE 0x04
  458 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_GO 0x02
  459 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_BUSY 0x01
  460 +
  461 +/* T3_TX_LAPD_STATUS */
  462 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_DL_START 0x08
  463 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_DL_BUSY 0x04
  464 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_LAPD_INTERRUPT_ENABLE 0x02
  465 +#define SBE_2T3E3_FRAMER_VAL_T3_TX_LAPD_INTERRUPT_STATUS 0x01
  466 +
  467 +/**********/
  468 +
  469 +/* E3_RX_CONFIGURATION_STATUS_1 */
  470 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_TYPE 0xe0
  471 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_ALGO 0x10
  472 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_T_MARK_ALGO 0x08
  473 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_EXPECTED 0x07
  474 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP4 0x01
  475 +
  476 +/* E3_RX_CONFIGURATION_STATUS_2 */
  477 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_ALGO 0x80
  478 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF 0x40
  479 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_OOF 0x20
  480 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOS 0x10
  481 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_AIS 0x08
  482 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_UNSTABLE 0x04
  483 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_T_MARK 0x02
  484 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF 0x01
  485 +
  486 +/* E3_RX_INTERRUPT_ENABLE_1 */
  487 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_COFA_INTERRUPT_ENABLE 0x10
  488 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE 0x08
  489 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_INTERRUPT_ENABLE 0x04
  490 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE 0x02
  491 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_AIS_INTERRUPT_ENABLE 0x01
  492 +
  493 +/* E3_RX_INTERRUPT_ENABLE_2 */
  494 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_TTB_CHANGE_INTERRUPT_ENABLE 0x40
  495 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FEBE_INTERRUPT_ENABLE 0x10
  496 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_INTERRUPT_ENABLE 0x08
  497 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP8_ERROR_INTERRUPT_ENABLE 0x04
  498 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP4_ERROR_INTERRUPT_ENABLE 0x04
  499 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FRAMING_BYTE_ERROR_INTERRUPT_ENABLE 0x02
  500 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_MISMATCH_INTERRUPT_ENABLE 0x01
  501 +
  502 +/* E3_RX_INTERRUPT_STATUS_1 */
  503 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_COFA_INTERRUPT_STATUS 0x10
  504 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_STATUS 0x08
  505 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_INTERRUPT_STATUS 0x04
  506 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_STATUS 0x02
  507 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_AIS_INTERRUPT_STATUS 0x01
  508 +
  509 +/* E3_RX_INTERRUPT_STATUS_2 */
  510 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_TTB_CHANGE_INTERRUPT_STATUS 0x40
  511 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FEBE_INTERRUPT_STATUS 0x10
  512 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_INTERRUPT_STATUS 0x08
  513 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP8_ERROR_INTERRUPT_STATUS 0x04
  514 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP4_ERROR_INTERRUPT_STATUS 0x04
  515 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FRAMING_BYTE_ERROR_INTERRUPT_STATUS 0x02
  516 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_MISMATCH_INTERRUPT_STATUS 0x01
  517 +
  518 +/* E3_RX_LAPD_CONTROL */
  519 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_DL_FROM_NR 0x08
  520 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_ENABLE 0x04
  521 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_INTERRUPT_ENABLE 0x02
  522 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_INTERRUPT_STATUS 0x01
  523 +
  524 +/* E3_RX_LAPD_STATUS */
  525 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_ABORT 0x40
  526 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_TYPE 0x30
  527 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_CR_TYPE 0x08
  528 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FCS_ERROR 0x04
  529 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_END_OF_MESSAGE 0x02
  530 +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FLAG_PRESENT 0x01
  531 +
  532 +/* E3_TX_CONFIGURATION */
  533 +#define SBE_2T3E3_FRAMER_VAL_E3_TX_BIP4_ENABLE 0x80
  534 +#define SBE_2T3E3_FRAMER_VAL_E3_TX_A_SOURCE_SELECT 0x60
  535 +#define SBE_2T3E3_FRAMER_VAL_E3_TX_DL_IN_NR 0x10
  536 +#define SBE_2T3E3_FRAMER_VAL_E3_TX_N_SOURCE_SELECT 0x18
  537 +#define SBE_2T3E3_FRAMER_VAL_E3_TX_AIS_ENABLE 0x04
  538 +#define SBE_2T3E3_FRAMER_VAL_E3_TX_LOS_ENABLE 0x02
  539 +#define SBE_2T3E3_FRAMER_VAL_E3_TX_MA_RX 0x01
  540 +#define SBE_2T3E3_FRAMER_VAL_E3_TX_FAS_SOURCE_SELECT 0x01
  541 +
  542 +/* E3_TX_LAPD_CONFIGURATION */
  543 +#define SBE_2T3E3_FRAMER_VAL_E3_TX_AUTO_RETRANSMIT 0x08
  544 +#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_MESSAGE_LENGTH 0x02
  545 +#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_ENABLE 0x01
  546 +
  547 +/* E3_TX_LAPD_STATUS_INTERRUPT */
  548 +#define SBE_2T3E3_FRAMER_VAL_E3_TX_DL_START 0x08
  549 +#define SBE_2T3E3_FRAMER_VAL_E3_TX_DL_BUSY 0x04
  550 +#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_INTERRUPT_ENABLE 0x02
  551 +#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_INTERRUPT_STATUS 0x01
  552 +
  553 +
  554 +
  555 +
  556 +
  557 +
  558 +/**************************************************************
  559 + * LIU
  560 + **************************************************************/
  561 +
  562 +/* reg_map indexes */
  563 +#define SBE_2T3E3_LIU_REG_REG0 0
  564 +#define SBE_2T3E3_LIU_REG_REG1 1
  565 +#define SBE_2T3E3_LIU_REG_REG2 2
  566 +#define SBE_2T3E3_LIU_REG_REG3 3
  567 +#define SBE_2T3E3_LIU_REG_REG4 4
  568 +
  569 +#define SBE_2T3E3_LIU_REG_MAX 5
  570 +
  571 +/**********/
  572 +
  573 +/* REG0 */
  574 +#define SBE_2T3E3_LIU_VAL_RECEIVE_LOSS_OF_LOCK_STATUS 0x10
  575 +#define SBE_2T3E3_LIU_VAL_RECEIVE_LOSS_OF_SIGNAL_STATUS 0x08
  576 +#define SBE_2T3E3_LIU_VAL_ANALOG_LOSS_OF_SIGNAL_STATUS 0x04
  577 +#define SBE_2T3E3_LIU_VAL_DIGITAL_LOSS_OF_SIGNAL_STATUS 0x02
  578 +#define SBE_2T3E3_LIU_VAL_DMO_STATUS 0x01
  579 +
  580 +/* REG1 */
  581 +#define SBE_2T3E3_LIU_VAL_TRANSMITTER_OFF 0x10
  582 +#define SBE_2T3E3_LIU_VAL_TRANSMIT_ALL_ONES 0x08
  583 +#define SBE_2T3E3_LIU_VAL_TRANSMIT_CLOCK_INVERT 0x04
  584 +#define SBE_2T3E3_LIU_VAL_TRANSMIT_LEVEL_SELECT 0x02
  585 +#define SBE_2T3E3_LIU_VAL_TRANSMIT_BINARY_DATA 0x01
  586 +
  587 +/* REG2 */
  588 +#define SBE_2T3E3_LIU_VAL_DECODER_DISABLE 0x10
  589 +#define SBE_2T3E3_LIU_VAL_ENCODER_DISABLE 0x08
  590 +#define SBE_2T3E3_LIU_VAL_ANALOG_LOSS_OF_SIGNAL_DISABLE 0x04
  591 +#define SBE_2T3E3_LIU_VAL_DIGITAL_LOSS_OF_SIGNAL_DISABLE 0x02
  592 +#define SBE_2T3E3_LIU_VAL_RECEIVE_EQUALIZATION_DISABLE 0x01
  593 +
  594 +/* REG3 */
  595 +#define SBE_2T3E3_LIU_VAL_RECEIVE_BINARY_DATA 0x10
  596 +#define SBE_2T3E3_LIU_VAL_RECOVERED_DATA_MUTING 0x08
  597 +#define SBE_2T3E3_LIU_VAL_RECEIVE_CLOCK_OUTPUT_2 0x04
  598 +#define SBE_2T3E3_LIU_VAL_INVERT_RECEIVE_CLOCK_2 0x02
  599 +#define SBE_2T3E3_LIU_VAL_INVERT_RECEIVE_CLOCK_1 0x01
  600 +
  601 +/* REG4 */
  602 +#define SBE_2T3E3_LIU_VAL_T3_MODE_SELECT 0x00
  603 +#define SBE_2T3E3_LIU_VAL_E3_MODE_SELECT 0x04
  604 +#define SBE_2T3E3_LIU_VAL_LOCAL_LOOPBACK 0x02
  605 +#define SBE_2T3E3_LIU_VAL_REMOTE_LOOPBACK 0x01
  606 +#define SBE_2T3E3_LIU_VAL_LOOPBACK_OFF 0x00
  607 +#define SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE 0x01
  608 +#define SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG 0x02
  609 +#define SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL 0x03
  610 +
  611 +/**********************************************************************
  612 + *
  613 + * descriptor list and data buffer
  614 + *
  615 + **********************************************************************/
  616 +typedef struct {
  617 + u32 rdes0;
  618 + u32 rdes1;
  619 + u32 rdes2;
  620 + u32 rdes3;
  621 +} t3e3_rx_desc_t;
  622 +
  623 +#define SBE_2T3E3_RX_DESC_RING_SIZE 64
  624 +
  625 +/* RDES0 */
  626 +#define SBE_2T3E3_RX_DESC_21143_OWN 0X80000000
  627 +#define SBE_2T3E3_RX_DESC_FRAME_LENGTH 0x3fff0000
  628 +#define SBE_2T3E3_RX_DESC_FRAME_LENGTH_SHIFT 16
  629 +#define SBE_2T3E3_RX_DESC_ERROR_SUMMARY 0x00008000
  630 +#define SBE_2T3E3_RX_DESC_DESC_ERROR 0x00004000
  631 +#define SBE_2T3E3_RX_DESC_DATA_TYPE 0x00003000
  632 +#define SBE_2T3E3_RX_DESC_RUNT_FRAME 0x00000800
  633 +#define SBE_2T3E3_RX_DESC_FIRST_DESC 0x00000200
  634 +#define SBE_2T3E3_RX_DESC_LAST_DESC 0x00000100
  635 +#define SBE_2T3E3_RX_DESC_FRAME_TOO_LONG 0x00000080
  636 +#define SBE_2T3E3_RX_DESC_COLLISION_SEEN 0x00000040
  637 +#define SBE_2T3E3_RX_DESC_FRAME_TYPE 0x00000020
  638 +#define SBE_2T3E3_RX_DESC_RECEIVE_WATCHDOG 0x00000010
  639 +#define SBE_2T3E3_RX_DESC_MII_ERROR 0x00000008
  640 +#define SBE_2T3E3_RX_DESC_DRIBBLING_BIT 0x00000004
  641 +#define SBE_2T3E3_RX_DESC_CRC_ERROR 0x00000002
  642 +
  643 +/* RDES1 */
  644 +#define SBE_2T3E3_RX_DESC_END_OF_RING 0x02000000
  645 +#define SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED 0x01000000
  646 +#define SBE_2T3E3_RX_DESC_BUFFER_2_SIZE 0x003ff800
  647 +#define SBE_2T3E3_RX_DESC_BUFFER_1_SIZE 0x000007ff
  648 +
  649 +/*********************/
  650 +
  651 +typedef struct {
  652 + u32 tdes0;
  653 + u32 tdes1;
  654 + u32 tdes2;
  655 + u32 tdes3;
  656 +} t3e3_tx_desc_t;
  657 +
  658 +#define SBE_2T3E3_TX_DESC_RING_SIZE 256
  659 +
  660 +/* TDES0 */
  661 +#define SBE_2T3E3_TX_DESC_21143_OWN 0x80000000
  662 +#define SBE_2T3E3_TX_DESC_ERROR_SUMMARY 0x00008000
  663 +#define SBE_2T3E3_TX_DESC_TRANSMIT_JABBER_TIMEOUT 0x00004000
  664 +#define SBE_2T3E3_TX_DESC_LOSS_OF_CARRIER 0x00000800
  665 +#define SBE_2T3E3_TX_DESC_NO_CARRIER 0x00000400
  666 +#define SBE_2T3E3_TX_DESC_LINK_FAIL_REPORT 0x00000004
  667 +#define SBE_2T3E3_TX_DESC_UNDERFLOW_ERROR 0x00000002
  668 +#define SBE_2T3E3_TX_DESC_DEFFERED 0x00000001
  669 +
  670 +/* TDES1 */
  671 +#define SBE_2T3E3_TX_DESC_INTERRUPT_ON_COMPLETION 0x80000000
  672 +#define SBE_2T3E3_TX_DESC_LAST_SEGMENT 0x40000000
  673 +#define SBE_2T3E3_TX_DESC_FIRST_SEGMENT 0x20000000
  674 +#define SBE_2T3E3_TX_DESC_CRC_DISABLE 0x04000000
  675 +#define SBE_2T3E3_TX_DESC_END_OF_RING 0x02000000
  676 +#define SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED 0x01000000
  677 +#define SBE_2T3E3_TX_DESC_DISABLE_PADDING 0x00800000
  678 +#define SBE_2T3E3_TX_DESC_BUFFER_2_SIZE 0x003ff800
  679 +#define SBE_2T3E3_TX_DESC_BUFFER_1_SIZE 0x000007ff
  680 +
  681 +
  682 +#define SBE_2T3E3_MTU 1600
  683 +#define SBE_2T3E3_CRC16_LENGTH 2
  684 +#define SBE_2T3E3_CRC32_LENGTH 4
  685 +
  686 +#define MCLBYTES (SBE_2T3E3_MTU + 128)
  687 +
  688 +struct channel {
  689 + struct pci_dev *pdev;
  690 + struct net_device *dev;
  691 + struct card *card;
  692 + unsigned long addr; /* DECchip */
  693 +
  694 + int leds;
  695 +
  696 + /* pci specific */
  697 + struct {
  698 + u32 slot; /* should be 0 or 1 */
  699 + u32 command;
  700 + u8 cache_size;
  701 + } h;
  702 +
  703 + /* statistics */
  704 + t3e3_stats_t s;
  705 +
  706 + /* running */
  707 + struct {
  708 + u32 flags;
  709 + } r;
  710 +
  711 + /* parameters */
  712 + t3e3_param_t p;
  713 +
  714 + u32 liu_regs[SBE_2T3E3_LIU_REG_MAX]; /* LIU registers */
  715 + u32 framer_regs[SBE_2T3E3_FRAMER_REG_MAX]; /* Framer registers */
  716 +
  717 + /* Ethernet Controller */
  718 + struct {
  719 + u_int16_t card_serial_number[3];
  720 +
  721 + u32 reg[SBE_2T3E3_21143_REG_MAX]; /* registers i.e. CSR */
  722 +
  723 + u32 interrupt_enable_mask;
  724 +
  725 + /* receive chain/ring */
  726 + t3e3_rx_desc_t *rx_ring;
  727 + struct sk_buff *rx_data[SBE_2T3E3_RX_DESC_RING_SIZE];
  728 + u32 rx_ring_current_read;
  729 +
  730 + /* transmit chain/ring */
  731 + t3e3_tx_desc_t *tx_ring;
  732 + struct sk_buff *tx_data[SBE_2T3E3_TX_DESC_RING_SIZE];
  733 + u32 tx_ring_current_read;
  734 + u32 tx_ring_current_write;
  735 + int tx_full;
  736 + int tx_free_cnt;
  737 + spinlock_t tx_lock;
  738 + } ether;
  739 +
  740 + int32_t interrupt_active;
  741 + int32_t rcv_count;
  742 +};
  743 +
  744 +struct card {
  745 + spinlock_t bootrom_lock;
  746 + unsigned long bootrom_addr;
  747 + struct timer_list timer; /* for updating LEDs */
  748 + struct channel channels[0];
  749 +};
  750 +
  751 +#define SBE_2T3E3_FLAG_NETWORK_UP 0x00000001
  752 +#define SBE_2T3E3_FLAG_NO_ERROR_MESSAGES 0x00000002
  753 +
  754 +extern const u32 cpld_reg_map[][2];
  755 +extern const u32 cpld_val_map[][2];
  756 +extern const u32 t3e3_framer_reg_map[];
  757 +extern const u32 t3e3_liu_reg_map[];
  758 +
  759 +void t3e3_init(struct channel *);
  760 +void t3e3_if_up(struct channel *);
  761 +void t3e3_if_down(struct channel *);
  762 +int t3e3_if_start_xmit(struct sk_buff *skb, struct net_device *dev);
  763 +void t3e3_if_config(struct channel *, u32, char *,
  764 + t3e3_resp_t *, int *);
  765 +void t3e3_set_frame_type(struct channel *, u32);
  766 +u32 t3e3_eeprom_read_word(struct channel *, u32);
  767 +void t3e3_read_card_serial_number(struct channel *);
  768 +
  769 +/* interrupt handlers */
  770 +irqreturn_t t3e3_intr(int irq, void *dev_instance);
  771 +void dc_intr(struct channel *);
  772 +void dc_intr_rx(struct channel *);
  773 +void dc_intr_tx(struct channel *);
  774 +void dc_intr_tx_underflow(struct channel *);
  775 +void exar7250_intr(struct channel *);
  776 +void exar7250_E3_intr(struct channel *, u32);
  777 +void exar7250_T3_intr(struct channel *, u32);
  778 +
  779 +/* Ethernet controller */
  780 +u32 bootrom_read(struct channel *, u32);
  781 +void bootrom_write(struct channel *, u32, u32);
  782 +void dc_init(struct channel *);
  783 +void dc_start(struct channel *);
  784 +void dc_stop(struct channel *);
  785 +void dc_start_intr(struct channel *);
  786 +void dc_stop_intr(struct channel *);
  787 +void dc_reset(struct channel *);
  788 +void dc_restart(struct channel *);
  789 +void dc_receiver_onoff(struct channel *, u32);
  790 +void dc_transmitter_onoff(struct channel *, u32);
  791 +void dc_set_loopback(struct channel *, u32);
  792 +u32 dc_init_descriptor_list(struct channel *);
  793 +void dc_clear_descriptor_list(struct channel *);
  794 +void dc_drop_descriptor_list(struct channel *);
  795 +void dc_set_output_port(struct channel *);
  796 +void t3e3_sc_init(struct channel *);
  797 +
  798 +/* CPLD */
  799 +void cpld_init(struct channel *sc);
  800 +u32 cpld_read(struct channel *sc, u32 reg);
  801 +void cpld_set_crc(struct channel *, u32);
  802 +void cpld_start_intr(struct channel *);
  803 +void cpld_stop_intr(struct channel *);
  804 +#if 0
  805 +void cpld_led_onoff(struct channel *, u32, u32, u32, u32);
  806 +#endif
  807 +void cpld_set_clock(struct channel *sc, u32 mode);
  808 +void cpld_set_scrambler(struct channel *, u32);
  809 +void cpld_select_panel(struct channel *, u32);
  810 +void cpld_set_frame_mode(struct channel *, u32);
  811 +void cpld_set_frame_type(struct channel *, u32);
  812 +void cpld_set_pad_count(struct channel *, u32);
  813 +void cpld_set_fractional_mode(struct channel *, u32, u32, u32);
  814 +void cpld_LOS_update(struct channel *);
  815 +
  816 +/* Framer */
  817 +extern u32 exar7250_read(struct channel *, u32);
  818 +extern void exar7250_write(struct channel *, u32, u32);
  819 +void exar7250_init(struct channel *);
  820 +void exar7250_start_intr(struct channel *, u32);
  821 +void exar7250_stop_intr(struct channel *, u32);
  822 +void exar7250_set_frame_type(struct channel *, u32);
  823 +void exar7250_set_loopback(struct channel *, u32);
  824 +void exar7250_unipolar_onoff(struct channel *, u32);
  825 +
  826 +/* LIU */
  827 +u32 exar7300_read(struct channel *, u32);
  828 +void exar7300_write(struct channel *, u32, u32);
  829 +void exar7300_init(struct channel *);
  830 +void exar7300_line_build_out_onoff(struct channel *, u32);
  831 +void exar7300_set_frame_type(struct channel *, u32);
  832 +void exar7300_set_loopback(struct channel *, u32);
  833 +void exar7300_transmit_all_ones_onoff(struct channel *, u32);
  834 +void exar7300_receive_equalization_onoff(struct channel *, u32);
  835 +void exar7300_unipolar_onoff(struct channel *, u32);
  836 +
  837 +void update_led(struct channel *, int);
  838 +int setup_device(struct net_device *dev, struct channel *sc);
  839 +
  840 +static inline int has_two_ports(struct pci_dev *pdev)
  841 +{
  842 + return pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P0;
  843 +}
  844 +
  845 +#define dev_to_priv(dev) (*(struct channel **) ((hdlc_device*)(dev) + 1))
  846 +
  847 +static inline u32 dc_read(unsigned long addr, u32 reg)
  848 +{
  849 + return inl(addr + (reg << 3));
  850 +}
  851 +
  852 +static inline void dc_write(unsigned long addr, u32 reg, u32 val)
  853 +{
  854 + outl(val, addr + (reg << 3));
  855 +}
  856 +
  857 +static inline void dc_set_bits(unsigned long addr, u32 reg, u32 bits)
  858 +{
  859 + dc_write(addr, reg, dc_read(addr, reg) | bits);
  860 +}
  861 +
  862 +static inline void dc_clear_bits(unsigned long addr, u32 reg, u32 bits)
  863 +{
  864 + dc_write(addr, reg, dc_read(addr, reg) & ~bits);
  865 +}
  866 +
  867 +#define CPLD_MAP_REG(reg, sc) (cpld_reg_map[(reg)][(sc)->h.slot])
  868 +
  869 +static inline void cpld_write(struct channel *channel, unsigned reg, u32 val)
  870 +{
  871 + unsigned long flags;
  872 + spin_lock_irqsave(&channel->card->bootrom_lock, flags);
  873 + bootrom_write(channel, CPLD_MAP_REG(reg, channel), val);
  874 + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
  875 +}
  876 +
  877 +#define exar7250_set_bit(sc, reg, bit) \
  878 + exar7250_write((sc), (reg), \
  879 + exar7250_read(sc, reg) | (bit))
  880 +
  881 +#define exar7250_clear_bit(sc, reg, bit) \
  882 + exar7250_write((sc), (reg), \
  883 + exar7250_read(sc, reg) & ~(bit))
  884 +
  885 +#define exar7300_set_bit(sc, reg, bit) \
  886 + exar7300_write((sc), (reg), \
  887 + exar7300_read(sc, reg) | (bit))
  888 +
  889 +#define exar7300_clear_bit(sc, reg, bit) \
  890 + exar7300_write((sc), (reg), \
  891 + exar7300_read(sc, reg) & ~(bit))
  892 +
  893 +
  894 +#endif /* T3E3_H */
drivers/staging/sbe-2t3e3/Kconfig
  1 +config SBE_2T3E3
  2 + tristate "SBE wanPMC-2T3E3 support"
  3 + depends on HDLC && PCI
  4 + help
  5 + Driver for wanPMC-2T3E3 cards by SBE Inc.
  6 +
  7 + If you have such a card, say Y here and see
  8 + <http://www.kernel.org/pub/linux/utils/net/hdlc/>.
  9 +
  10 + To compile this as a module, choose M here: the
  11 + module will be called sbe-2t3e3.
  12 +
  13 + If unsure, say N.
drivers/staging/sbe-2t3e3/Makefile
  1 +obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3.o
  2 +
  3 +sbe-2t3e3-objs := module.o netdev.o maps.o \
  4 + main.o cpld.o intr.o ctrl.o io.o dc.o exar7250.o exar7300.o
drivers/staging/sbe-2t3e3/TODO
  1 +TODO:
  2 + - additional cleaning and tests
  3 + - wait for the new configuration interface in generic HDLC layer and
  4 + when available, convert the driver to it
  5 +
  6 +Please send patches to Krzysztof Halasa <khc@pm.waw.pl>.
drivers/staging/sbe-2t3e3/cpld.c
  1 +/*
  2 + * SBE 2T3E3 synchronous serial card driver for Linux
  3 + *
  4 + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of version 2 of the GNU General Public License
  8 + * as published by the Free Software Foundation.
  9 + *
  10 + * This code is based on a driver written by SBE Inc.
  11 + */
  12 +
  13 +#include <linux/delay.h>
  14 +#include "2t3e3.h"
  15 +#include "ctrl.h"
  16 +
  17 +#define bootrom_set_bit(sc, reg, bit) \
  18 + bootrom_write((sc), (reg), \
  19 + bootrom_read((sc), (reg)) | (bit))
  20 +
  21 +#define bootrom_clear_bit(sc, reg, bit) \
  22 + bootrom_write((sc), (reg), \
  23 + bootrom_read((sc), (reg)) & ~(bit))
  24 +
  25 +static inline void cpld_set_bit(struct channel *channel, unsigned reg, u32 bit)
  26 +{
  27 + unsigned long flags;
  28 + spin_lock_irqsave(&channel->card->bootrom_lock, flags);
  29 + bootrom_set_bit(channel, CPLD_MAP_REG(reg, channel), bit);
  30 + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
  31 +}
  32 +
  33 +static inline void cpld_clear_bit(struct channel *channel, unsigned reg, u32 bit)
  34 +{
  35 + unsigned long flags;
  36 + spin_lock_irqsave(&channel->card->bootrom_lock, flags);
  37 + bootrom_clear_bit(channel, CPLD_MAP_REG(reg, channel), bit);
  38 + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
  39 +}
  40 +
  41 +void cpld_init(struct channel *sc)
  42 +{
  43 + u32 val;
  44 +#if 0
  45 + /* reset LIU and Framer */
  46 + val = cpld_val_map[SBE_2T3E3_CPLD_VAL_LIU_FRAMER_RESET][sc->h.slot];
  47 + cpld_write(sc, SBE_2T3E3_CPLD_REG_STATIC_RESET, val);
  48 + udelay(10000); /* TODO - how long? */
  49 + val = 0;
  50 + cpld_write(sc, SBE_2T3E3_CPLD_REG_STATIC_RESET, val);
  51 +#endif
  52 +
  53 + /* PCRA */
  54 + val = SBE_2T3E3_CPLD_VAL_CRC32 |
  55 + cpld_val_map[SBE_2T3E3_CPLD_VAL_LOOP_TIMING_SOURCE][sc->h.slot];
  56 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRA, val);
  57 +
  58 + /* PCRB */
  59 + val = 0;
  60 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRB, val);
  61 +
  62 + /* PCRC */
  63 + val = 0;
  64 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC, val);
  65 +
  66 + /* PBWF */
  67 + val = 0;
  68 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, val);
  69 +
  70 + /* PBWL */
  71 + val = 0;
  72 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, val);
  73 +
  74 + /* PLTR */
  75 + val = SBE_2T3E3_CPLD_VAL_LCV_COUNTER;
  76 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PLTR, val);
  77 + udelay(1000);
  78 +
  79 + /* PLCR */
  80 + val = 0;
  81 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PLCR, val);
  82 + udelay(1000);
  83 +
  84 + /* PPFR */
  85 + val = 0x55;
  86 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PPFR, val);
  87 + /* TODO: this doesn't work!!! */
  88 +
  89 + /* SERIAL_CHIP_SELECT */
  90 + val = 0;
  91 + cpld_write(sc, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, val);
  92 +
  93 + /* PICSR */
  94 + val = SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED |
  95 + SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED |
  96 + SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED;
  97 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR, val);
  98 +
  99 + cpld_start_intr(sc);
  100 +
  101 + udelay(1000);
  102 +}
  103 +
  104 +void cpld_start_intr(struct channel *sc)
  105 +{
  106 + u32 val;
  107 +
  108 + /* PIER */
  109 + val = SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ENABLE |
  110 + SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ENABLE;
  111 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val);
  112 +#if 0
  113 + /*
  114 + do you want to hang up your computer?
  115 + ENABLE REST OF INTERRUPTS !!!
  116 + you have been warned :).
  117 + */
  118 +#endif
  119 +}
  120 +
  121 +void cpld_stop_intr(struct channel *sc)
  122 +{
  123 + u32 val;
  124 +
  125 + /* PIER */
  126 + val = 0;
  127 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val);
  128 +}
  129 +
  130 +void cpld_set_frame_mode(struct channel *sc, u32 mode)
  131 +{
  132 + if (sc->p.frame_mode == mode)
  133 + return;
  134 +
  135 + switch (mode) {
  136 + case SBE_2T3E3_FRAME_MODE_HDLC:
  137 + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
  138 + SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE |
  139 + SBE_2T3E3_CPLD_VAL_RAW_MODE);
  140 + exar7250_unipolar_onoff(sc, SBE_2T3E3_OFF);
  141 + exar7300_unipolar_onoff(sc, SBE_2T3E3_OFF);
  142 + break;
  143 + case SBE_2T3E3_FRAME_MODE_TRANSPARENT:
  144 + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
  145 + SBE_2T3E3_CPLD_VAL_RAW_MODE);
  146 + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
  147 + SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE);
  148 + exar7250_unipolar_onoff(sc, SBE_2T3E3_OFF);
  149 + exar7300_unipolar_onoff(sc, SBE_2T3E3_OFF);
  150 + break;
  151 + case SBE_2T3E3_FRAME_MODE_RAW:
  152 + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
  153 + SBE_2T3E3_CPLD_VAL_RAW_MODE);
  154 + exar7250_unipolar_onoff(sc, SBE_2T3E3_ON);
  155 + exar7300_unipolar_onoff(sc, SBE_2T3E3_ON);
  156 + break;
  157 + default:
  158 + return;
  159 + }
  160 +
  161 + sc->p.frame_mode = mode;
  162 +}
  163 +
  164 +/* set rate of the local clock */
  165 +void cpld_set_frame_type(struct channel *sc, u32 type)
  166 +{
  167 + switch (type) {
  168 + case SBE_2T3E3_FRAME_TYPE_E3_G751:
  169 + case SBE_2T3E3_FRAME_TYPE_E3_G832:
  170 + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
  171 + SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3);
  172 + break;
  173 + case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
  174 + case SBE_2T3E3_FRAME_TYPE_T3_M13:
  175 + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
  176 + SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3);
  177 + break;
  178 + default:
  179 + return;
  180 + }
  181 +}
  182 +
  183 +void cpld_set_scrambler(struct channel *sc, u32 mode)
  184 +{
  185 + if (sc->p.scrambler == mode)
  186 + return;
  187 +
  188 + switch (mode) {
  189 + case SBE_2T3E3_SCRAMBLER_OFF:
  190 + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
  191 + SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
  192 + break;
  193 + case SBE_2T3E3_SCRAMBLER_LARSCOM:
  194 + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
  195 + SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE);
  196 + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
  197 + SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
  198 + break;
  199 + case SBE_2T3E3_SCRAMBLER_ADC_KENTROX_DIGITAL:
  200 + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
  201 + SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE);
  202 + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
  203 + SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
  204 + break;
  205 + default:
  206 + return;
  207 + }
  208 +
  209 + sc->p.scrambler = mode;
  210 +}
  211 +
  212 +
  213 +void cpld_set_crc(struct channel *sc, u32 crc)
  214 +{
  215 + if (sc->p.crc == crc)
  216 + return;
  217 +
  218 + switch (crc) {
  219 + case SBE_2T3E3_CRC_16:
  220 + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
  221 + SBE_2T3E3_CPLD_VAL_CRC32);
  222 + break;
  223 + case SBE_2T3E3_CRC_32:
  224 + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
  225 + SBE_2T3E3_CPLD_VAL_CRC32);
  226 + break;
  227 + default:
  228 + return;
  229 + }
  230 +
  231 + sc->p.crc = crc;
  232 +}
  233 +
  234 +
  235 +void cpld_select_panel(struct channel *sc, u32 panel)
  236 +{
  237 + if (sc->p.panel == panel)
  238 + return;
  239 + switch (panel) {
  240 + case SBE_2T3E3_PANEL_FRONT:
  241 + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
  242 + SBE_2T3E3_CPLD_VAL_REAR_PANEL);
  243 + break;
  244 + case SBE_2T3E3_PANEL_REAR:
  245 + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
  246 + SBE_2T3E3_CPLD_VAL_REAR_PANEL);
  247 + break;
  248 + default:
  249 + return;
  250 + }
  251 +
  252 + udelay(100);
  253 +
  254 + sc->p.panel = panel;
  255 +}
  256 +
  257 +
  258 +extern void cpld_set_clock(struct channel *sc, u32 mode)
  259 +{
  260 + if (sc->p.clock_source == mode)
  261 + return;
  262 +
  263 + switch (mode) {
  264 + case SBE_2T3E3_TIMING_LOCAL:
  265 + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
  266 + SBE_2T3E3_CPLD_VAL_ALT);
  267 + break;
  268 + case SBE_2T3E3_TIMING_LOOP:
  269 + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
  270 + SBE_2T3E3_CPLD_VAL_ALT);
  271 + break;
  272 + default:
  273 + return;
  274 + }
  275 +
  276 + sc->p.clock_source = mode;
  277 +}
  278 +
  279 +void cpld_set_pad_count(struct channel *sc, u32 count)
  280 +{
  281 + u32 val;
  282 +
  283 + if (sc->p.pad_count == count)
  284 + return;
  285 +
  286 + switch (count) {
  287 + case SBE_2T3E3_PAD_COUNT_1:
  288 + val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_1;
  289 + break;
  290 + case SBE_2T3E3_PAD_COUNT_2:
  291 + val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_2;
  292 + break;
  293 + case SBE_2T3E3_PAD_COUNT_3:
  294 + val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_3;
  295 + break;
  296 + case SBE_2T3E3_PAD_COUNT_4:
  297 + val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_4;
  298 + break;
  299 + default:
  300 + return;
  301 + }
  302 +
  303 + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
  304 + SBE_2T3E3_CPLD_VAL_PAD_COUNT);
  305 + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB, val);
  306 + sc->p.pad_count = count;
  307 +}
  308 +
  309 +void cpld_LOS_update(struct channel *sc)
  310 +{
  311 + u_int8_t los;
  312 +
  313 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR,
  314 + SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED |
  315 + SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED |
  316 + SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED);
  317 + los = cpld_read(sc, SBE_2T3E3_CPLD_REG_PICSR) &
  318 + SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED;
  319 +
  320 + if (los != sc->s.LOS)
  321 + dev_info(&sc->pdev->dev, "SBE 2T3E3: LOS status: %s\n",
  322 + los ? "Loss of signal" : "Signal OK");
  323 + sc->s.LOS = los;
  324 +}
  325 +
  326 +void cpld_set_fractional_mode(struct channel *sc, u32 mode,
  327 + u32 start, u32 stop)
  328 +{
  329 + if (mode == SBE_2T3E3_FRACTIONAL_MODE_NONE) {
  330 + start = 0;
  331 + stop = 0;
  332 + }
  333 +
  334 + if (sc->p.fractional_mode == mode && sc->p.bandwidth_start == start &&
  335 + sc->p.bandwidth_stop == stop)
  336 + return;
  337 +
  338 + switch (mode) {
  339 + case SBE_2T3E3_FRACTIONAL_MODE_NONE:
  340 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
  341 + SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_NONE);
  342 + break;
  343 + case SBE_2T3E3_FRACTIONAL_MODE_0:
  344 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
  345 + SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_0);
  346 + break;
  347 + case SBE_2T3E3_FRACTIONAL_MODE_1:
  348 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
  349 + SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_1);
  350 + break;
  351 + case SBE_2T3E3_FRACTIONAL_MODE_2:
  352 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
  353 + SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_2);
  354 + break;
  355 + default:
  356 + printk(KERN_ERR "wrong mode in set_fractional_mode\n");
  357 + return;
  358 + }
  359 +
  360 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, start);
  361 + cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, stop);
  362 +
  363 + sc->p.fractional_mode = mode;
  364 + sc->p.bandwidth_start = start;
  365 + sc->p.bandwidth_stop = stop;
  366 +}
drivers/staging/sbe-2t3e3/ctrl.c
  1 +/*
  2 + * SBE 2T3E3 synchronous serial card driver for Linux
  3 + *
  4 + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of version 2 of the GNU General Public License
  8 + * as published by the Free Software Foundation.
  9 + *
  10 + * This code is based on a driver written by SBE Inc.
  11 + */
  12 +
  13 +#include <linux/types.h>
  14 +#include "2t3e3.h"
  15 +#include "ctrl.h"
  16 +
  17 +void t3e3_set_frame_type(struct channel *sc, u32 mode)
  18 +{
  19 + if (sc->p.frame_type == mode)
  20 + return;
  21 +
  22 + if (sc->r.flags & SBE_2T3E3_FLAG_NETWORK_UP) {
  23 + dev_err(&sc->pdev->dev, "SBE 2T3E3: changing frame type during active connection\n");
  24 + return;
  25 + }
  26 +
  27 + exar7300_set_frame_type(sc, mode);
  28 + exar7250_set_frame_type(sc, mode);
  29 + cpld_set_frame_type(sc, mode);
  30 +
  31 + sc->p.frame_type = mode;
  32 +}
  33 +
  34 +void t3e3_set_loopback(struct channel *sc, u32 mode)
  35 +{
  36 + u32 tx, rx;
  37 +
  38 + if (sc->p.loopback == mode)
  39 + return;
  40 +
  41 + tx = sc->p.transmitter_on;
  42 + rx = sc->p.receiver_on;
  43 + if (tx == SBE_2T3E3_ON)
  44 + dc_transmitter_onoff(sc, SBE_2T3E3_OFF);
  45 + if (rx == SBE_2T3E3_ON)
  46 + dc_receiver_onoff(sc, SBE_2T3E3_OFF);
  47 +
  48 + /* stop current loopback if any exists */
  49 + switch (sc->p.loopback) {
  50 + case SBE_2T3E3_LOOPBACK_NONE:
  51 + break;
  52 + case SBE_2T3E3_LOOPBACK_ETHERNET:
  53 + dc_set_loopback(sc, SBE_2T3E3_21143_VAL_LOOPBACK_OFF);
  54 + break;
  55 + case SBE_2T3E3_LOOPBACK_FRAMER:
  56 + exar7250_set_loopback(sc, SBE_2T3E3_FRAMER_VAL_LOOPBACK_OFF);
  57 + break;
  58 + case SBE_2T3E3_LOOPBACK_LIU_DIGITAL:
  59 + case SBE_2T3E3_LOOPBACK_LIU_ANALOG:
  60 + case SBE_2T3E3_LOOPBACK_LIU_REMOTE:
  61 + exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_OFF);
  62 + break;
  63 + default:
  64 + return;
  65 + }
  66 +
  67 + switch (mode) {
  68 + case SBE_2T3E3_LOOPBACK_NONE:
  69 + break;
  70 + case SBE_2T3E3_LOOPBACK_ETHERNET:
  71 + dc_set_loopback(sc, SBE_2T3E3_21143_VAL_LOOPBACK_INTERNAL);
  72 + break;
  73 + case SBE_2T3E3_LOOPBACK_FRAMER:
  74 + exar7250_set_loopback(sc, SBE_2T3E3_FRAMER_VAL_LOOPBACK_ON);
  75 + break;
  76 + case SBE_2T3E3_LOOPBACK_LIU_DIGITAL:
  77 + exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL);
  78 + break;
  79 + case SBE_2T3E3_LOOPBACK_LIU_ANALOG:
  80 + exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG);
  81 + break;
  82 + case SBE_2T3E3_LOOPBACK_LIU_REMOTE:
  83 + exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE);
  84 + break;
  85 + default:
  86 + return;
  87 + }
  88 +
  89 + sc->p.loopback = mode;
  90 +
  91 + if (tx == SBE_2T3E3_ON)
  92 + dc_transmitter_onoff(sc, SBE_2T3E3_ON);
  93 + if (rx == SBE_2T3E3_ON)
  94 + dc_receiver_onoff(sc, SBE_2T3E3_ON);
  95 +}
  96 +
  97 +
  98 +void t3e3_reg_read(struct channel *sc, u32 *reg, u32 *val)
  99 +{
  100 + u32 i;
  101 +
  102 + *val = 0;
  103 +
  104 + switch (reg[0]) {
  105 + case SBE_2T3E3_CHIP_21143:
  106 + if (!(reg[1] & 7))
  107 + *val = dc_read(sc->addr, reg[1] / 8);
  108 + break;
  109 + case SBE_2T3E3_CHIP_CPLD:
  110 + for (i = 0; i < SBE_2T3E3_CPLD_REG_MAX; i++)
  111 + if (cpld_reg_map[i][sc->h.slot] == reg[1]) {
  112 + *val = cpld_read(sc, i);
  113 + break;
  114 + }
  115 + break;
  116 + case SBE_2T3E3_CHIP_FRAMER:
  117 + for (i = 0; i < SBE_2T3E3_FRAMER_REG_MAX; i++)
  118 + if (t3e3_framer_reg_map[i] == reg[1]) {
  119 + *val = exar7250_read(sc, i);
  120 + break;
  121 + }
  122 + break;
  123 + case SBE_2T3E3_CHIP_LIU:
  124 + for (i = 0; i < SBE_2T3E3_LIU_REG_MAX; i++)
  125 + if (t3e3_liu_reg_map[i] == reg[1]) {
  126 + *val = exar7300_read(sc, i);
  127 + break;
  128 + }
  129 + break;
  130 + default:
  131 + break;
  132 + }
  133 +}
  134 +
  135 +void t3e3_reg_write(struct channel *sc, u32 *reg)
  136 +{
  137 + u32 i;
  138 +
  139 + switch (reg[0]) {
  140 + case SBE_2T3E3_CHIP_21143:
  141 + dc_write(sc->addr, reg[1], reg[2]);
  142 + break;
  143 + case SBE_2T3E3_CHIP_CPLD:
  144 + for (i = 0; i < SBE_2T3E3_CPLD_REG_MAX; i++)
  145 + if (cpld_reg_map[i][sc->h.slot] == reg[1]) {
  146 + cpld_write(sc, i, reg[2]);
  147 + break;
  148 + }
  149 + break;
  150 + case SBE_2T3E3_CHIP_FRAMER:
  151 + for (i = 0; i < SBE_2T3E3_FRAMER_REG_MAX; i++)
  152 + if (t3e3_framer_reg_map[i] == reg[1]) {
  153 + exar7250_write(sc, i, reg[2]);
  154 + break;
  155 + }
  156 + break;
  157 + case SBE_2T3E3_CHIP_LIU:
  158 + for (i = 0; i < SBE_2T3E3_LIU_REG_MAX; i++)
  159 + if (t3e3_liu_reg_map[i] == reg[1]) {
  160 + exar7300_write(sc, i, reg[2]);
  161 + break;
  162 + }
  163 + break;
  164 + }
  165 +}
  166 +
  167 +void t3e3_port_get(struct channel *sc, t3e3_param_t *param)
  168 +{
  169 + memcpy(param, &(sc->p), sizeof(t3e3_param_t));
  170 +}
  171 +
  172 +void t3e3_port_set(struct channel *sc, t3e3_param_t *param)
  173 +{
  174 + if (param->frame_mode != 0xff)
  175 + cpld_set_frame_mode(sc, param->frame_mode);
  176 +
  177 + if (param->fractional_mode != 0xff)
  178 + cpld_set_fractional_mode(sc, param->fractional_mode,
  179 + param->bandwidth_start,
  180 + param->bandwidth_stop);
  181 +
  182 + if (param->pad_count != 0xff)
  183 + cpld_set_pad_count(sc, param->pad_count);
  184 +
  185 + if (param->crc != 0xff)
  186 + cpld_set_crc(sc, param->crc);
  187 +
  188 + if (param->receiver_on != 0xff)
  189 + dc_receiver_onoff(sc, param->receiver_on);
  190 +
  191 + if (param->transmitter_on != 0xff)
  192 + dc_transmitter_onoff(sc, param->transmitter_on);
  193 +
  194 + if (param->frame_type != 0xff)
  195 + t3e3_set_frame_type(sc, param->frame_type);
  196 +
  197 + if (param->panel != 0xff)
  198 + cpld_select_panel(sc, param->panel);
  199 +
  200 + if (param->line_build_out != 0xff)
  201 + exar7300_line_build_out_onoff(sc, param->line_build_out);
  202 +
  203 + if (param->receive_equalization != 0xff)
  204 + exar7300_receive_equalization_onoff(sc, param->receive_equalization);
  205 +
  206 + if (param->transmit_all_ones != 0xff)
  207 + exar7300_transmit_all_ones_onoff(sc, param->transmit_all_ones);
  208 +
  209 + if (param->loopback != 0xff)
  210 + t3e3_set_loopback(sc, param->loopback);
  211 +
  212 + if (param->clock_source != 0xff)
  213 + cpld_set_clock(sc, param->clock_source);
  214 +
  215 + if (param->scrambler != 0xff)
  216 + cpld_set_scrambler(sc, param->scrambler);
  217 +}
  218 +
  219 +void t3e3_port_get_stats(struct channel *sc,
  220 + t3e3_stats_t *stats)
  221 +{
  222 + u32 result;
  223 +
  224 + sc->s.LOC = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL)
  225 + & SBE_2T3E3_FRAMER_VAL_LOSS_OF_CLOCK_STATUS ? 1 : 0;
  226 +
  227 + switch (sc->p.frame_type) {
  228 + case SBE_2T3E3_FRAME_TYPE_E3_G751:
  229 + case SBE_2T3E3_FRAME_TYPE_E3_G832:
  230 + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);
  231 + sc->s.LOF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_LOF ? 1 : 0;
  232 + sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
  233 +#if 0
  234 + sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_E3_RX_LOS ? 1 : 0;
  235 +#else
  236 + cpld_LOS_update(sc);
  237 +#endif
  238 + sc->s.AIS = result & SBE_2T3E3_FRAMER_VAL_E3_RX_AIS ? 1 : 0;
  239 + sc->s.FERF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_FERF ? 1 : 0;
  240 + break;
  241 +
  242 + case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
  243 + case SBE_2T3E3_FRAME_TYPE_T3_M13:
  244 + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);
  245 + sc->s.AIS = result & SBE_2T3E3_FRAMER_VAL_T3_RX_AIS ? 1 : 0;
  246 +#if 0
  247 + sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_T3_RX_LOS ? 1 : 0;
  248 +#else
  249 + cpld_LOS_update(sc);
  250 +#endif
  251 + sc->s.IDLE = result & SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE ? 1 : 0;
  252 + sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
  253 +
  254 + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_STATUS);
  255 + sc->s.FERF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_FERF ? 1 : 0;
  256 + sc->s.AIC = result & SBE_2T3E3_FRAMER_VAL_T3_RX_AIC ? 1 : 0;
  257 + sc->s.FEBE_code = result & SBE_2T3E3_FRAMER_VAL_T3_RX_FEBE;
  258 +
  259 + sc->s.FEAC = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC);
  260 + break;
  261 +
  262 + default:
  263 + break;
  264 + }
  265 +
  266 + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_LCV_EVENT_COUNT_MSB) << 8;
  267 + result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
  268 + sc->s.LCV += result;
  269 +
  270 + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_FRAMING_BIT_ERROR_EVENT_COUNT_MSB) << 8;
  271 + result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
  272 + sc->s.FRAMING_BIT += result;
  273 +
  274 + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_PARITY_ERROR_EVENT_COUNT_MSB) << 8;
  275 + result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
  276 + sc->s.PARITY_ERROR += result;
  277 +
  278 + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_FEBE_EVENT_COUNT_MSB) << 8;
  279 + result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
  280 + sc->s.FEBE_count += result;
  281 +
  282 + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_CP_BIT_ERROR_EVENT_COUNT_MSB) << 8;
  283 + result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
  284 + sc->s.CP_BIT += result;
  285 +
  286 + memcpy(stats, &(sc->s), sizeof(t3e3_stats_t));
  287 +}
  288 +
  289 +void t3e3_port_del_stats(struct channel *sc)
  290 +{
  291 + memset(&(sc->s), 0, sizeof(t3e3_stats_t));
  292 +}
  293 +
  294 +void t3e3_if_config(struct channel *sc, u32 cmd, char *set,
  295 + t3e3_resp_t *ret, int *rlen)
  296 +{
  297 + t3e3_param_t *param = (t3e3_param_t *)set;
  298 + u32 *data = (u32 *)set;
  299 +
  300 + /* turn off all interrupt */
  301 + /* cpld_stop_intr(sc); */
  302 +
  303 + switch (cmd) {
  304 + case SBE_2T3E3_PORT_GET:
  305 + t3e3_port_get(sc, &(ret->u.param));
  306 + *rlen = sizeof(ret->u.param);
  307 + break;
  308 + case SBE_2T3E3_PORT_SET:
  309 + t3e3_port_set(sc, param);
  310 + *rlen = 0;
  311 + break;
  312 + case SBE_2T3E3_PORT_GET_STATS:
  313 + t3e3_port_get_stats(sc, &(ret->u.stats));
  314 + *rlen = sizeof(ret->u.stats);
  315 + break;
  316 + case SBE_2T3E3_PORT_DEL_STATS:
  317 + t3e3_port_del_stats(sc);
  318 + *rlen = 0;
  319 + break;
  320 + case SBE_2T3E3_PORT_READ_REGS:
  321 + t3e3_reg_read(sc, data, &(ret->u.data));
  322 + *rlen = sizeof(ret->u.data);
  323 + break;
  324 + case SBE_2T3E3_PORT_WRITE_REGS:
  325 +#if 0
  326 + printk(KERN_DEBUG "SBE_2T3E3_PORT_WRITE_REGS, 0x%x, 0x%x, 0x%x\n",
  327 + ((int*)data)[0], ((int*)data)[1], ((int*)data)[2]);
  328 +#endif
  329 + t3e3_reg_write(sc, data);
  330 + *rlen = 0;
  331 + break;
  332 + case SBE_2T3E3_LOG_LEVEL:
  333 + *rlen = 0;
  334 + break;
  335 + default:
  336 + *rlen = 0;
  337 + break;
  338 + }
  339 +
  340 + /* turn on interrupt */
  341 + /* cpld_start_intr(sc); */
  342 +}
  343 +
  344 +void t3e3_sc_init(struct channel *sc)
  345 +{
  346 + memset(sc, 0, sizeof(*sc));
  347 +
  348 + sc->p.frame_mode = SBE_2T3E3_FRAME_MODE_HDLC;
  349 + sc->p.fractional_mode = SBE_2T3E3_FRACTIONAL_MODE_NONE;
  350 + sc->p.crc = SBE_2T3E3_CRC_32;
  351 + sc->p.receiver_on = SBE_2T3E3_OFF;
  352 + sc->p.transmitter_on = SBE_2T3E3_OFF;
  353 + sc->p.frame_type = SBE_2T3E3_FRAME_TYPE_T3_CBIT;
  354 + sc->p.panel = SBE_2T3E3_PANEL_FRONT;
  355 + sc->p.line_build_out = SBE_2T3E3_OFF;
  356 + sc->p.receive_equalization = SBE_2T3E3_OFF;
  357 + sc->p.transmit_all_ones = SBE_2T3E3_OFF;
  358 + sc->p.loopback = SBE_2T3E3_LOOPBACK_NONE;
  359 + sc->p.clock_source = SBE_2T3E3_TIMING_LOCAL;
  360 + sc->p.scrambler = SBE_2T3E3_SCRAMBLER_OFF;
  361 + sc->p.pad_count = SBE_2T3E3_PAD_COUNT_1;
  362 +}
drivers/staging/sbe-2t3e3/ctrl.h
  1 +/*
  2 + * SBE 2T3E3 synchronous serial card driver for Linux
  3 + *
  4 + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of version 2 of the GNU General Public License
  8 + * as published by the Free Software Foundation.
  9 + *
  10 + * This code is based on a driver written by SBE Inc.
  11 + */
  12 +
  13 +#ifndef CTRL_H
  14 +#define CTRL_H
  15 +
  16 +#define SBE_2T3E3_OFF 0
  17 +#define SBE_2T3E3_ON 1
  18 +
  19 +#define SBE_2T3E3_LED_NONE 0
  20 +#define SBE_2T3E3_LED_GREEN 1
  21 +#define SBE_2T3E3_LED_YELLOW 2
  22 +
  23 +#define SBE_2T3E3_CABLE_LENGTH_LESS_THAN_255_FEET 0
  24 +#define SBE_2T3E3_CABLE_LENGTH_GREATER_THAN_255_FEET 1
  25 +
  26 +#define SBE_2T3E3_CRC_16 0
  27 +#define SBE_2T3E3_CRC_32 1
  28 +
  29 +#define SBE_2T3E3_PANEL_FRONT 0
  30 +#define SBE_2T3E3_PANEL_REAR 1
  31 +
  32 +#define SBE_2T3E3_FRAME_MODE_HDLC 0
  33 +#define SBE_2T3E3_FRAME_MODE_TRANSPARENT 1
  34 +#define SBE_2T3E3_FRAME_MODE_RAW 2
  35 +
  36 +#define SBE_2T3E3_FRAME_TYPE_E3_G751 0
  37 +#define SBE_2T3E3_FRAME_TYPE_E3_G832 1
  38 +#define SBE_2T3E3_FRAME_TYPE_T3_CBIT 2
  39 +#define SBE_2T3E3_FRAME_TYPE_T3_M13 3
  40 +
  41 +#define SBE_2T3E3_FRACTIONAL_MODE_NONE 0
  42 +#define SBE_2T3E3_FRACTIONAL_MODE_0 1
  43 +#define SBE_2T3E3_FRACTIONAL_MODE_1 2
  44 +#define SBE_2T3E3_FRACTIONAL_MODE_2 3
  45 +
  46 +#define SBE_2T3E3_SCRAMBLER_OFF 0
  47 +#define SBE_2T3E3_SCRAMBLER_LARSCOM 1
  48 +#define SBE_2T3E3_SCRAMBLER_ADC_KENTROX_DIGITAL 2
  49 +
  50 +#define SBE_2T3E3_TIMING_LOCAL 0
  51 +#define SBE_2T3E3_TIMING_LOOP 1
  52 +
  53 +#define SBE_2T3E3_LOOPBACK_NONE 0
  54 +#define SBE_2T3E3_LOOPBACK_ETHERNET 1
  55 +#define SBE_2T3E3_LOOPBACK_FRAMER 2
  56 +#define SBE_2T3E3_LOOPBACK_LIU_DIGITAL 3
  57 +#define SBE_2T3E3_LOOPBACK_LIU_ANALOG 4
  58 +#define SBE_2T3E3_LOOPBACK_LIU_REMOTE 5
  59 +
  60 +#define SBE_2T3E3_PAD_COUNT_1 1
  61 +#define SBE_2T3E3_PAD_COUNT_2 2
  62 +#define SBE_2T3E3_PAD_COUNT_3 3
  63 +#define SBE_2T3E3_PAD_COUNT_4 4
  64 +
  65 +#define SBE_2T3E3_CHIP_21143 0
  66 +#define SBE_2T3E3_CHIP_CPLD 1
  67 +#define SBE_2T3E3_CHIP_FRAMER 2
  68 +#define SBE_2T3E3_CHIP_LIU 3
  69 +
  70 +#define SBE_2T3E3_LOG_LEVEL_NONE 0
  71 +#define SBE_2T3E3_LOG_LEVEL_ERROR 1
  72 +#define SBE_2T3E3_LOG_LEVEL_WARNING 2
  73 +#define SBE_2T3E3_LOG_LEVEL_INFO 3
  74 +
  75 +/* commands */
  76 +#define SBE_2T3E3_PORT_GET 0
  77 +#define SBE_2T3E3_PORT_SET 1
  78 +#define SBE_2T3E3_PORT_GET_STATS 2
  79 +#define SBE_2T3E3_PORT_DEL_STATS 3
  80 +#define SBE_2T3E3_PORT_READ_REGS 4
  81 +#define SBE_2T3E3_LOG_LEVEL 5
  82 +#define SBE_2T3E3_PORT_WRITE_REGS 6
  83 +
  84 +#define NG_SBE_2T3E3_NODE_TYPE "sbe2T3E3"
  85 +#define NG_SBE_2T3E3_COOKIE 0x03800891
  86 +
  87 +typedef struct t3e3_param {
  88 + u_int8_t frame_mode; /* FRAME_MODE_* */
  89 + u_int8_t crc; /* CRC_* */
  90 + u_int8_t receiver_on; /* ON/OFF */
  91 + u_int8_t transmitter_on; /* ON/OFF */
  92 + u_int8_t frame_type; /* FRAME_TYPE_* */
  93 + u_int8_t panel; /* PANEL_* */
  94 + u_int8_t line_build_out; /* ON/OFF */
  95 + u_int8_t receive_equalization; /* ON/OFF */
  96 + u_int8_t transmit_all_ones; /* ON/OFF */
  97 + u_int8_t loopback; /* LOOPBACK_* */
  98 + u_int8_t clock_source; /* TIMING_* */
  99 + u_int8_t scrambler; /* SCRAMBLER_* */
  100 + u_int8_t pad_count; /* PAD_COUNT_* */
  101 + u_int8_t log_level; /* LOG_LEVEL_* - unused */
  102 + u_int8_t fractional_mode; /* FRACTIONAL_MODE_* */
  103 + u_int8_t bandwidth_start; /* 0-255 */
  104 + u_int8_t bandwidth_stop; /* 0-255 */
  105 +} t3e3_param_t;
  106 +
  107 +typedef struct t3e3_stats {
  108 + u_int64_t in_bytes;
  109 + u32 in_packets, in_dropped;
  110 + u32 in_errors, in_error_desc, in_error_coll, in_error_drib,
  111 + in_error_crc, in_error_mii;
  112 + u_int64_t out_bytes;
  113 + u32 out_packets, out_dropped;
  114 + u32 out_errors, out_error_jab, out_error_lost_carr,
  115 + out_error_no_carr, out_error_link_fail, out_error_underflow,
  116 + out_error_dereferred;
  117 + u_int8_t LOC, LOF, OOF, LOS, AIS, FERF, IDLE, AIC, FEAC;
  118 + u_int16_t FEBE_code;
  119 + u32 LCV, FRAMING_BIT, PARITY_ERROR, FEBE_count, CP_BIT;
  120 +} t3e3_stats_t;
  121 +
  122 +
  123 +typedef struct t3e3_resp {
  124 + union {
  125 + t3e3_param_t param;
  126 + t3e3_stats_t stats;
  127 + u32 data;
  128 + } u;
  129 +} t3e3_resp_t;
  130 +
  131 +#endif /* CTRL_H */
drivers/staging/sbe-2t3e3/dc.c
  1 +/*
  2 + * SBE 2T3E3 synchronous serial card driver for Linux
  3 + *
  4 + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of version 2 of the GNU General Public License
  8 + * as published by the Free Software Foundation.
  9 + *
  10 + * This code is based on a driver written by SBE Inc.
  11 + */
  12 +
  13 +#include <linux/netdevice.h>
  14 +#include <linux/types.h>
  15 +#include <linux/errno.h>
  16 +#include <linux/io.h>
  17 +#include "2t3e3.h"
  18 +#include "ctrl.h"
  19 +
  20 +void dc_init(struct channel *sc)
  21 +{
  22 + u32 val;
  23 +
  24 + dc_stop(sc);
  25 + /*dc_reset(sc);*/ /* do not want to reset here */
  26 +
  27 + /*
  28 + * BUS_MODE (CSR0)
  29 + */
  30 + val = SBE_2T3E3_21143_VAL_READ_LINE_ENABLE |
  31 + SBE_2T3E3_21143_VAL_READ_MULTIPLE_ENABLE |
  32 + SBE_2T3E3_21143_VAL_TRANSMIT_AUTOMATIC_POLLING_200us |
  33 + SBE_2T3E3_21143_VAL_BUS_ARBITRATION_RR;
  34 +
  35 + if (sc->h.command & 16)
  36 + val |= SBE_2T3E3_21143_VAL_WRITE_AND_INVALIDATE_ENABLE;
  37 +
  38 + switch (sc->h.cache_size) {
  39 + case 32:
  40 + val |= SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_32;
  41 + break;
  42 + case 16:
  43 + val |= SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_16;
  44 + break;
  45 + case 8:
  46 + val |= SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_8;
  47 + break;
  48 + default:
  49 + break;
  50 + }
  51 +
  52 + dc_write(sc->addr, SBE_2T3E3_21143_REG_BUS_MODE, val);
  53 +
  54 + /* OPERATION_MODE (CSR6) */
  55 + val = SBE_2T3E3_21143_VAL_RECEIVE_ALL |
  56 + SBE_2T3E3_21143_VAL_MUST_BE_ONE |
  57 + SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_1 |
  58 + SBE_2T3E3_21143_VAL_LOOPBACK_OFF |
  59 + SBE_2T3E3_21143_VAL_PASS_ALL_MULTICAST |
  60 + SBE_2T3E3_21143_VAL_PROMISCUOUS_MODE |
  61 + SBE_2T3E3_21143_VAL_PASS_BAD_FRAMES;
  62 + dc_write(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, val);
  63 + if (sc->p.loopback == SBE_2T3E3_LOOPBACK_ETHERNET)
  64 + sc->p.loopback = SBE_2T3E3_LOOPBACK_NONE;
  65 +
  66 +#if 0 /* No need to clear this register - and it may be in use */
  67 + /*
  68 + * BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT (CSR9)
  69 + */
  70 + val = 0;
  71 + dc_write(sc->addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, val);
  72 +#endif
  73 +
  74 + /*
  75 + * GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL (CSR11)
  76 + */
  77 + val = SBE_2T3E3_21143_VAL_CYCLE_SIZE |
  78 + SBE_2T3E3_21143_VAL_TRANSMIT_TIMER |
  79 + SBE_2T3E3_21143_VAL_NUMBER_OF_TRANSMIT_PACKETS |
  80 + SBE_2T3E3_21143_VAL_RECEIVE_TIMER |
  81 + SBE_2T3E3_21143_VAL_NUMBER_OF_RECEIVE_PACKETS;
  82 + dc_write(sc->addr, SBE_2T3E3_21143_REG_GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL, val);
  83 +
  84 + /* prepare descriptors and data for receive and transmit procecsses */
  85 + if (dc_init_descriptor_list(sc) != 0)
  86 + return;
  87 +
  88 + /* clear ethernet interrupts status */
  89 + dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, 0xFFFFFFFF);
  90 +
  91 + /* SIA mode registers */
  92 + dc_set_output_port(sc);
  93 +}
  94 +
  95 +void dc_start(struct channel *sc)
  96 +{
  97 + u32 val;
  98 +
  99 + if (!(sc->r.flags & SBE_2T3E3_FLAG_NETWORK_UP))
  100 + return;
  101 +
  102 + dc_init(sc);
  103 +
  104 + /* get actual LOS and OOF status */
  105 + switch (sc->p.frame_type) {
  106 + case SBE_2T3E3_FRAME_TYPE_E3_G751:
  107 + case SBE_2T3E3_FRAME_TYPE_E3_G832:
  108 + val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);
  109 + dev_dbg(&sc->pdev->dev, "Start Framer Rx Status = %02X\n", val);
  110 + sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
  111 + break;
  112 + case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
  113 + case SBE_2T3E3_FRAME_TYPE_T3_M13:
  114 + val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);
  115 + dev_dbg(&sc->pdev->dev, "Start Framer Rx Status = %02X\n", val);
  116 + sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
  117 + break;
  118 + default:
  119 + break;
  120 + }
  121 + cpld_LOS_update(sc);
  122 +
  123 + /* start receive and transmit processes */
  124 + dc_transmitter_onoff(sc, SBE_2T3E3_ON);
  125 + dc_receiver_onoff(sc, SBE_2T3E3_ON);
  126 +
  127 + /* start interrupts */
  128 + dc_start_intr(sc);
  129 +}
  130 +
  131 +#define MAX_INT_WAIT_CNT 12000
  132 +void dc_stop(struct channel *sc)
  133 +{
  134 + int wcnt;
  135 +
  136 + /* stop receive and transmit processes */
  137 + dc_receiver_onoff(sc, SBE_2T3E3_OFF);
  138 + dc_transmitter_onoff(sc, SBE_2T3E3_OFF);
  139 +
  140 + /* turn off ethernet interrupts */
  141 + dc_stop_intr(sc);
  142 +
  143 + /* wait to ensure the interrupts have been completed */
  144 + for (wcnt = 0; wcnt < MAX_INT_WAIT_CNT; wcnt++) {
  145 + udelay(5);
  146 + if (!sc->interrupt_active)
  147 + break;
  148 + }
  149 + if (wcnt >= MAX_INT_WAIT_CNT)
  150 + dev_warn(&sc->pdev->dev, "SBE 2T3E3: Interrupt active too long\n");
  151 +
  152 + /* clear all receive/transmit data */
  153 + dc_drop_descriptor_list(sc);
  154 +}
  155 +
  156 +void dc_start_intr(struct channel *sc)
  157 +{
  158 + if (sc->p.loopback == SBE_2T3E3_LOOPBACK_NONE && sc->s.OOF)
  159 + return;
  160 +
  161 + if (sc->p.receiver_on || sc->p.transmitter_on) {
  162 + if (!sc->ether.interrupt_enable_mask)
  163 + dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, 0xFFFFFFFF);
  164 +
  165 + sc->ether.interrupt_enable_mask =
  166 + SBE_2T3E3_21143_VAL_NORMAL_INTERRUPT_SUMMARY_ENABLE |
  167 + SBE_2T3E3_21143_VAL_ABNORMAL_INTERRUPT_SUMMARY_ENABLE |
  168 + SBE_2T3E3_21143_VAL_RECEIVE_STOPPED_ENABLE |
  169 + SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE_ENABLE |
  170 + SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT_ENABLE |
  171 + SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW_INTERRUPT_ENABLE |
  172 + SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE_ENABLE |
  173 + SBE_2T3E3_21143_VAL_TRANSMIT_STOPPED_ENABLE |
  174 + SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT_ENABLE;
  175 +
  176 + dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE,
  177 + sc->ether.interrupt_enable_mask);
  178 + }
  179 +}
  180 +
  181 +void dc_stop_intr(struct channel *sc)
  182 +{
  183 + sc->ether.interrupt_enable_mask = 0;
  184 + dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, 0);
  185 +}
  186 +
  187 +void dc_reset(struct channel *sc)
  188 +{
  189 + /* turn off ethernet interrupts */
  190 + dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, 0);
  191 + dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, 0xFFFFFFFF);
  192 +
  193 + /* software reset */
  194 + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_BUS_MODE,
  195 + SBE_2T3E3_21143_VAL_SOFTWARE_RESET);
  196 + udelay(4); /* 50 PCI cycles < 2us */
  197 +
  198 + /* clear hardware configuration */
  199 + dc_write(sc->addr, SBE_2T3E3_21143_REG_BUS_MODE, 0);
  200 +
  201 + /* clear software configuration */
  202 + dc_write(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, 0);
  203 +
  204 + /* turn off SIA reset */
  205 + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY,
  206 + SBE_2T3E3_21143_VAL_SIA_RESET);
  207 + dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_TRANSMIT_AND_RECEIVE, 0);
  208 + dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_AND_GENERAL_PURPOSE_PORT, 0);
  209 +}
  210 +
  211 +
  212 +void dc_receiver_onoff(struct channel *sc, u32 mode)
  213 +{
  214 + u32 i, state = 0;
  215 +
  216 + if (sc->p.receiver_on == mode)
  217 + return;
  218 +
  219 + switch (mode) {
  220 + case SBE_2T3E3_OFF:
  221 + if (dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE) &
  222 + SBE_2T3E3_21143_VAL_RECEIVE_START) {
  223 + dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
  224 + SBE_2T3E3_21143_VAL_RECEIVE_START);
  225 +
  226 + for (i = 0; i < 16; i++) {
  227 + state = dc_read(sc->addr, SBE_2T3E3_21143_REG_STATUS) &
  228 + SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STATE;
  229 + if (state == SBE_2T3E3_21143_VAL_RX_STOPPED)
  230 + break;
  231 + udelay(5);
  232 + }
  233 + if (state != SBE_2T3E3_21143_VAL_RX_STOPPED)
  234 + dev_warn(&sc->pdev->dev, "SBE 2T3E3: Rx failed to stop\n");
  235 + else
  236 + dev_info(&sc->pdev->dev, "SBE 2T3E3: Rx off\n");
  237 + }
  238 + break;
  239 + case SBE_2T3E3_ON:
  240 + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
  241 + SBE_2T3E3_21143_VAL_RECEIVE_START);
  242 + udelay(100);
  243 + dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_POLL_DEMAND, 0xFFFFFFFF);
  244 + break;
  245 + default:
  246 + return;
  247 + }
  248 +
  249 + sc->p.receiver_on = mode;
  250 +}
  251 +
  252 +void dc_transmitter_onoff(struct channel *sc, u32 mode)
  253 +{
  254 + u32 i, state = 0;
  255 +
  256 + if (sc->p.transmitter_on == mode)
  257 + return;
  258 +
  259 + switch (mode) {
  260 + case SBE_2T3E3_OFF:
  261 + if (dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE) &
  262 + SBE_2T3E3_21143_VAL_TRANSMISSION_START) {
  263 + dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
  264 + SBE_2T3E3_21143_VAL_TRANSMISSION_START);
  265 +
  266 + for (i = 0; i < 16; i++) {
  267 + state = dc_read(sc->addr, SBE_2T3E3_21143_REG_STATUS) &
  268 + SBE_2T3E3_21143_VAL_TRANSMISSION_PROCESS_STATE;
  269 + if (state == SBE_2T3E3_21143_VAL_TX_STOPPED)
  270 + break;
  271 + udelay(5);
  272 + }
  273 + if (state != SBE_2T3E3_21143_VAL_TX_STOPPED)
  274 + dev_warn(&sc->pdev->dev, "SBE 2T3E3: Tx failed to stop\n");
  275 + }
  276 + break;
  277 + case SBE_2T3E3_ON:
  278 + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
  279 + SBE_2T3E3_21143_VAL_TRANSMISSION_START);
  280 + udelay(100);
  281 + dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_POLL_DEMAND, 0xFFFFFFFF);
  282 + break;
  283 + default:
  284 + return;
  285 + }
  286 +
  287 + sc->p.transmitter_on = mode;
  288 +}
  289 +
  290 +
  291 +
  292 +void dc_set_loopback(struct channel *sc, u32 mode)
  293 +{
  294 + u32 val;
  295 +
  296 + switch (mode) {
  297 + case SBE_2T3E3_21143_VAL_LOOPBACK_OFF:
  298 + case SBE_2T3E3_21143_VAL_LOOPBACK_INTERNAL:
  299 + break;
  300 + default:
  301 + return;
  302 + }
  303 +
  304 +#if 0
  305 + /* restart SIA */
  306 + dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY,
  307 + SBE_2T3E3_21143_VAL_SIA_RESET);
  308 + udelay(1000);
  309 + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY,
  310 + SBE_2T3E3_21143_VAL_SIA_RESET);
  311 +#endif
  312 +
  313 + /* select loopback mode */
  314 + val = dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE) &
  315 + ~SBE_2T3E3_21143_VAL_OPERATING_MODE;
  316 + val |= mode;
  317 + dc_write(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, val);
  318 +
  319 + if (mode == SBE_2T3E3_21143_VAL_LOOPBACK_OFF)
  320 + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
  321 + SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE);
  322 + else
  323 + dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
  324 + SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE);
  325 +}
  326 +
  327 +u32 dc_init_descriptor_list(struct channel *sc)
  328 +{
  329 + u32 i, j;
  330 + struct sk_buff *m;
  331 +
  332 + if (sc->ether.rx_ring == NULL)
  333 + sc->ether.rx_ring = kzalloc(SBE_2T3E3_RX_DESC_RING_SIZE *
  334 + sizeof(t3e3_rx_desc_t), GFP_KERNEL);
  335 + if (sc->ether.rx_ring == NULL) {
  336 + dev_err(&sc->pdev->dev, "SBE 2T3E3: no buffer space for RX ring\n");
  337 + return ENOMEM;
  338 + }
  339 +
  340 + if (sc->ether.tx_ring == NULL)
  341 + sc->ether.tx_ring = kzalloc(SBE_2T3E3_TX_DESC_RING_SIZE *
  342 + sizeof(t3e3_tx_desc_t), GFP_KERNEL);
  343 + if (sc->ether.tx_ring == NULL) {
  344 +#ifdef T3E3_USE_CONTIGMALLOC
  345 + t3e3_contigmemory_size = SBE_2T3E3_RX_DESC_RING_SIZE *
  346 + sizeof(t3e3_rx_desc_t);
  347 +#endif
  348 + kfree(sc->ether.rx_ring);
  349 + sc->ether.rx_ring = NULL;
  350 + dev_err(&sc->pdev->dev, "SBE 2T3E3: no buffer space for RX ring\n");
  351 + return ENOMEM;
  352 + }
  353 +
  354 +
  355 + /*
  356 + * Receive ring
  357 + */
  358 + for (i = 0; i < SBE_2T3E3_RX_DESC_RING_SIZE; i++) {
  359 + sc->ether.rx_ring[i].rdes0 = SBE_2T3E3_RX_DESC_21143_OWN;
  360 + sc->ether.rx_ring[i].rdes1 =
  361 + SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED | SBE_2T3E3_MTU;
  362 +
  363 + if (sc->ether.rx_data[i] == NULL) {
  364 + if (!(m = dev_alloc_skb(MCLBYTES))) {
  365 + for (j = 0; j < i; j++) {
  366 + dev_kfree_skb_any(sc->ether.rx_data[j]);
  367 + sc->ether.rx_data[j] = NULL;
  368 + }
  369 +#ifdef T3E3_USE_CONTIGMALLOC
  370 + t3e3_contigmemory_size = SBE_2T3E3_RX_DESC_RING_SIZE *
  371 + sizeof(t3e3_rx_desc_t);
  372 +#endif
  373 + kfree(sc->ether.rx_ring);
  374 + sc->ether.rx_ring = NULL;
  375 +#ifdef T3E3_USE_CONTIGMALLOC
  376 + t3e3_contigmemory_size = SBE_2T3E3_TX_DESC_RING_SIZE *
  377 + sizeof(t3e3_tx_desc_t);
  378 +#endif
  379 + kfree(sc->ether.tx_ring);
  380 + sc->ether.tx_ring = NULL;
  381 + dev_err(&sc->pdev->dev, "SBE 2T3E3: token_alloc err:"
  382 + " no buffer space for RX ring\n");
  383 + return ENOBUFS;
  384 + }
  385 + sc->ether.rx_data[i] = m;
  386 + }
  387 + sc->ether.rx_ring[i].rdes2 = virt_to_phys(sc->ether.rx_data[i]->data);
  388 +
  389 + sc->ether.rx_ring[i].rdes3 = virt_to_phys(
  390 + &sc->ether.rx_ring[(i + 1) % SBE_2T3E3_RX_DESC_RING_SIZE]);
  391 + }
  392 + sc->ether.rx_ring[SBE_2T3E3_RX_DESC_RING_SIZE - 1].rdes1 |=
  393 + SBE_2T3E3_RX_DESC_END_OF_RING;
  394 + sc->ether.rx_ring_current_read = 0;
  395 +
  396 + dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_LIST_BASE_ADDRESS,
  397 + virt_to_phys(&sc->ether.rx_ring[0]));
  398 +
  399 + /*
  400 + * Transmit ring
  401 + */
  402 + for (i = 0; i < SBE_2T3E3_TX_DESC_RING_SIZE; i++) {
  403 + sc->ether.tx_ring[i].tdes0 = 0;
  404 + sc->ether.tx_ring[i].tdes1 = SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED |
  405 + SBE_2T3E3_TX_DESC_DISABLE_PADDING;
  406 +
  407 + sc->ether.tx_ring[i].tdes2 = 0;
  408 + sc->ether.tx_data[i] = NULL;
  409 +
  410 + sc->ether.tx_ring[i].tdes3 = virt_to_phys(
  411 + &sc->ether.tx_ring[(i + 1) % SBE_2T3E3_TX_DESC_RING_SIZE]);
  412 + }
  413 + sc->ether.tx_ring[SBE_2T3E3_TX_DESC_RING_SIZE - 1].tdes1 |=
  414 + SBE_2T3E3_TX_DESC_END_OF_RING;
  415 +
  416 + dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_LIST_BASE_ADDRESS,
  417 + virt_to_phys(&sc->ether.tx_ring[0]));
  418 + sc->ether.tx_ring_current_read = 0;
  419 + sc->ether.tx_ring_current_write = 0;
  420 + sc->ether.tx_free_cnt = SBE_2T3E3_TX_DESC_RING_SIZE;
  421 + spin_lock_init(&sc->ether.tx_lock);
  422 +
  423 + return 0;
  424 +}
  425 +
  426 +void dc_clear_descriptor_list(struct channel *sc)
  427 +{
  428 + u32 i;
  429 +
  430 + /* clear CSR3 and CSR4 */
  431 + dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_LIST_BASE_ADDRESS, 0);
  432 + dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_LIST_BASE_ADDRESS, 0);
  433 +
  434 + /* free all data buffers on TX ring */
  435 + for (i = 0; i < SBE_2T3E3_TX_DESC_RING_SIZE; i++) {
  436 + if (sc->ether.tx_data[i] != NULL) {
  437 + dev_kfree_skb_any(sc->ether.tx_data[i]);
  438 + sc->ether.tx_data[i] = NULL;
  439 + }
  440 + }
  441 +}
  442 +
  443 +void dc_drop_descriptor_list(struct channel *sc)
  444 +{
  445 + u32 i;
  446 +
  447 + dc_clear_descriptor_list(sc);
  448 +
  449 + /* free all data buffers on RX ring */
  450 + for (i = 0; i < SBE_2T3E3_RX_DESC_RING_SIZE; i++) {
  451 + if (sc->ether.rx_data[i] != NULL) {
  452 + dev_kfree_skb_any(sc->ether.rx_data[i]);
  453 + sc->ether.rx_data[i] = NULL;
  454 + }
  455 + }
  456 +
  457 + if (sc->ether.rx_ring != NULL) {
  458 +#ifdef T3E3_USE_CONTIGMALLOC
  459 + t3e3_contigmemory_size = SBE_2T3E3_RX_DESC_RING_SIZE *
  460 + sizeof(t3e3_rx_desc_t);
  461 +#endif
  462 + kfree(sc->ether.rx_ring);
  463 + sc->ether.rx_ring = NULL;
  464 + }
  465 +
  466 + if (sc->ether.tx_ring != NULL) {
  467 +#ifdef T3E3_USE_CONTIGMALLOC
  468 + t3e3_contigmemory_size = SBE_2T3E3_TX_DESC_RING_SIZE *
  469 + sizeof(t3e3_tx_desc_t);
  470 +#endif
  471 + kfree(sc->ether.tx_ring);
  472 + sc->ether.tx_ring = NULL;
  473 + }
  474 +}
  475 +
  476 +
  477 +void dc_set_output_port(struct channel *sc)
  478 +{
  479 + dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
  480 + SBE_2T3E3_21143_VAL_PORT_SELECT);
  481 +
  482 + dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_STATUS, 0x00000301);
  483 + dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY, 0);
  484 + dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_TRANSMIT_AND_RECEIVE, 0);
  485 + dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_AND_GENERAL_PURPOSE_PORT, 0x08000011);
  486 +
  487 + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
  488 + SBE_2T3E3_21143_VAL_TRANSMIT_THRESHOLD_MODE_100Mbs |
  489 + SBE_2T3E3_21143_VAL_HEARTBEAT_DISABLE |
  490 + SBE_2T3E3_21143_VAL_PORT_SELECT |
  491 + SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE);
  492 +}
  493 +
  494 +void dc_restart(struct channel *sc)
  495 +{
  496 + dev_warn(&sc->pdev->dev, "SBE 2T3E3: 21143 restart\n");
  497 +
  498 + dc_stop(sc);
  499 + dc_reset(sc);
  500 + dc_init(sc); /* stop + reset + init */
  501 + dc_start(sc);
  502 +}
drivers/staging/sbe-2t3e3/exar7250.c
  1 +/*
  2 + * SBE 2T3E3 synchronous serial card driver for Linux
  3 + *
  4 + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of version 2 of the GNU General Public License
  8 + * as published by the Free Software Foundation.
  9 + *
  10 + * This code is based on a driver written by SBE Inc.
  11 + */
  12 +
  13 +#include "2t3e3.h"
  14 +#include "ctrl.h"
  15 +
  16 +void exar7250_init(struct channel *sc)
  17 +{
  18 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE,
  19 + SBE_2T3E3_FRAMER_VAL_T3_CBIT |
  20 + SBE_2T3E3_FRAMER_VAL_INTERRUPT_ENABLE_RESET |
  21 + SBE_2T3E3_FRAMER_VAL_TIMING_ASYNCH_TXINCLK);
  22 +
  23 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL,
  24 + SBE_2T3E3_FRAMER_VAL_DISABLE_TX_LOSS_OF_CLOCK |
  25 + SBE_2T3E3_FRAMER_VAL_DISABLE_RX_LOSS_OF_CLOCK |
  26 + SBE_2T3E3_FRAMER_VAL_AMI_LINE_CODE |
  27 + SBE_2T3E3_FRAMER_VAL_RX_LINE_CLOCK_INVERT);
  28 +
  29 + exar7250_set_frame_type(sc, SBE_2T3E3_FRAME_TYPE_T3_CBIT);
  30 +}
  31 +
  32 +void exar7250_set_frame_type(struct channel *sc, u32 type)
  33 +{
  34 + u32 val;
  35 +
  36 + switch (type) {
  37 + case SBE_2T3E3_FRAME_TYPE_E3_G751:
  38 + case SBE_2T3E3_FRAME_TYPE_E3_G832:
  39 + case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
  40 + case SBE_2T3E3_FRAME_TYPE_T3_M13:
  41 + break;
  42 + default:
  43 + return;
  44 + }
  45 +
  46 + exar7250_stop_intr(sc, type);
  47 +
  48 + val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE);
  49 + val &= ~(SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE |
  50 + SBE_2T3E3_FRAMER_VAL_T3_E3_SELECT |
  51 + SBE_2T3E3_FRAMER_VAL_FRAME_FORMAT_SELECT);
  52 + switch (type) {
  53 + case SBE_2T3E3_FRAME_TYPE_E3_G751:
  54 + val |= SBE_2T3E3_FRAMER_VAL_E3_G751;
  55 + break;
  56 + case SBE_2T3E3_FRAME_TYPE_E3_G832:
  57 + val |= SBE_2T3E3_FRAMER_VAL_E3_G832;
  58 + break;
  59 + case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
  60 + val |= SBE_2T3E3_FRAMER_VAL_T3_CBIT;
  61 + break;
  62 + case SBE_2T3E3_FRAME_TYPE_T3_M13:
  63 + val |= SBE_2T3E3_FRAMER_VAL_T3_M13;
  64 + break;
  65 + default:
  66 + return;
  67 + }
  68 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE, val);
  69 + exar7250_start_intr(sc, type);
  70 +}
  71 +
  72 +
  73 +void exar7250_start_intr(struct channel *sc, u32 type)
  74 +{
  75 + u32 val;
  76 +
  77 + switch (type) {
  78 + case SBE_2T3E3_FRAME_TYPE_E3_G751:
  79 + case SBE_2T3E3_FRAME_TYPE_E3_G832:
  80 + val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);
  81 +#if 0
  82 + sc->s.LOS = val & SBE_2T3E3_FRAMER_VAL_E3_RX_LOS ? 1 : 0;
  83 +#else
  84 + cpld_LOS_update(sc);
  85 +#endif
  86 + sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
  87 + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1);
  88 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1,
  89 + SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE |
  90 + SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE);
  91 +#if 0
  92 + /*SBE_2T3E3_FRAMER_VAL_E3_RX_COFA_INTERRUPT_ENABLE |
  93 + SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE |
  94 + SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_INTERRUPT_ENABLE |
  95 + SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE |
  96 + SBE_2T3E3_FRAMER_VAL_E3_RX_AIS_INTERRUPT_ENABLE);*/
  97 +#endif
  98 +
  99 + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2);
  100 +#if 0
  101 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2,
  102 + SBE_2T3E3_FRAMER_VAL_E3_RX_FEBE_INTERRUPT_ENABLE |
  103 + SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_INTERRUPT_ENABLE |
  104 + SBE_2T3E3_FRAMER_VAL_E3_RX_FRAMING_BYTE_ERROR_INTERRUPT_ENABLE);
  105 +#endif
  106 + break;
  107 +
  108 + case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
  109 + case SBE_2T3E3_FRAME_TYPE_T3_M13:
  110 + val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);
  111 +#if 0
  112 + sc->s.LOS = val & SBE_2T3E3_FRAMER_VAL_T3_RX_LOS ? 1 : 0;
  113 +#else
  114 + cpld_LOS_update(sc);
  115 +#endif
  116 + sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
  117 +
  118 + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS);
  119 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE,
  120 + SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE |
  121 + SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE);
  122 +#if 0
  123 + /* SBE_2T3E3_FRAMER_VAL_T3_RX_CP_BIT_ERROR_INTERRUPT_ENABLE |
  124 + SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE |
  125 + SBE_2T3E3_FRAMER_VAL_T3_RX_AIS_INTERRUPT_ENABLE |
  126 + SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE_INTERRUPT_ENABLE |
  127 + SBE_2T3E3_FRAMER_VAL_T3_RX_FERF_INTERRUPT_ENABLE |
  128 + SBE_2T3E3_FRAMER_VAL_T3_RX_AIC_INTERRUPT_ENABLE |
  129 + SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE |
  130 + SBE_2T3E3_FRAMER_VAL_T3_RX_P_BIT_INTERRUPT_ENABLE);*/
  131 +#endif
  132 +
  133 + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS);
  134 +#if 0
  135 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS,
  136 + SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_REMOVE_INTERRUPT_ENABLE |
  137 + SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID_INTERRUPT_ENABLE);
  138 +#endif
  139 +
  140 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL, 0);
  141 + break;
  142 +
  143 + default:
  144 + return;
  145 + }
  146 +
  147 + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS);
  148 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE,
  149 + SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_ENABLE |
  150 + SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_ENABLE);
  151 +}
  152 +
  153 +
  154 +void exar7250_stop_intr(struct channel *sc, u32 type)
  155 +{
  156 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE, 0);
  157 + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS);
  158 +
  159 + switch (type) {
  160 + case SBE_2T3E3_FRAME_TYPE_E3_G751:
  161 + case SBE_2T3E3_FRAME_TYPE_E3_G832:
  162 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1, 0);
  163 + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1);
  164 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2, 0);
  165 + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2);
  166 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL, 0);
  167 + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL);
  168 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS, 0);
  169 + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS);
  170 + break;
  171 +
  172 + case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
  173 + case SBE_2T3E3_FRAME_TYPE_T3_M13:
  174 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE, 0);
  175 + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS);
  176 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS, 0);
  177 + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS);
  178 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL, 0);
  179 + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL);
  180 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS, 0);
  181 + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS);
  182 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS, 0);
  183 + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS);
  184 + break;
  185 + }
  186 +}
  187 +
  188 +
  189 +
  190 +
  191 +void exar7250_unipolar_onoff(struct channel *sc, u32 mode)
  192 +{
  193 + switch (mode) {
  194 + case SBE_2T3E3_OFF:
  195 + exar7300_clear_bit(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL,
  196 + SBE_2T3E3_FRAMER_VAL_UNIPOLAR);
  197 + break;
  198 + case SBE_2T3E3_ON:
  199 + exar7300_set_bit(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL,
  200 + SBE_2T3E3_FRAMER_VAL_UNIPOLAR);
  201 + break;
  202 + }
  203 +}
  204 +
  205 +void exar7250_set_loopback(struct channel *sc, u32 mode)
  206 +{
  207 + switch (mode) {
  208 + case SBE_2T3E3_FRAMER_VAL_LOOPBACK_OFF:
  209 + exar7300_clear_bit(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE,
  210 + SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE);
  211 + break;
  212 + case SBE_2T3E3_FRAMER_VAL_LOOPBACK_ON:
  213 + exar7300_set_bit(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE,
  214 + SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE);
  215 + break;
  216 + }
  217 +}
drivers/staging/sbe-2t3e3/exar7300.c
  1 +/*
  2 + * SBE 2T3E3 synchronous serial card driver for Linux
  3 + *
  4 + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of version 2 of the GNU General Public License
  8 + * as published by the Free Software Foundation.
  9 + *
  10 + * This code is based on a driver written by SBE Inc.
  11 + */
  12 +
  13 +#include "2t3e3.h"
  14 +#include "ctrl.h"
  15 +
  16 +void exar7300_init(struct channel *sc)
  17 +{
  18 + exar7300_write(sc, SBE_2T3E3_LIU_REG_REG1, 0);
  19 +
  20 + /* enable line decodeer and encoder */
  21 + exar7300_write(sc, SBE_2T3E3_LIU_REG_REG2, 0);
  22 + exar7300_write(sc, SBE_2T3E3_LIU_REG_REG3, 0);
  23 + exar7300_write(sc, SBE_2T3E3_LIU_REG_REG4,
  24 + SBE_2T3E3_LIU_VAL_T3_MODE_SELECT |
  25 + SBE_2T3E3_LIU_VAL_LOOPBACK_OFF);
  26 +}
  27 +
  28 +void exar7300_set_loopback(struct channel *sc, u32 mode)
  29 +{
  30 + u32 val;
  31 +
  32 + switch (mode) {
  33 + case SBE_2T3E3_LIU_VAL_LOOPBACK_OFF:
  34 + case SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE:
  35 + case SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG:
  36 + case SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL:
  37 + break;
  38 + default:
  39 + return;
  40 + }
  41 +
  42 + val = exar7300_read(sc, SBE_2T3E3_LIU_REG_REG4);
  43 + val &= ~(SBE_2T3E3_LIU_VAL_LOCAL_LOOPBACK | SBE_2T3E3_LIU_VAL_REMOTE_LOOPBACK);
  44 + val |= mode;
  45 + exar7300_write(sc, SBE_2T3E3_LIU_REG_REG4, val);
  46 +
  47 +#if 0
  48 + /* TODO - is it necessary? idea from 2T3E3_HW_Test_code */
  49 + switch (mode) {
  50 + case SBE_2T3E3_LIU_VAL_LOOPBACK_OFF:
  51 + break;
  52 + case SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE:
  53 + exar7300_receive_equalization_onoff(sc, SBE_2T3E3_ON);
  54 + break;
  55 + case SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG:
  56 + exar7300_receive_equalization_onoff(sc, SBE_2T3E3_OFF);
  57 + break;
  58 + case SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL:
  59 + exar7300_receive_equalization_onoff(sc, SBE_2T3E3_ON);
  60 + break;
  61 + }
  62 +#endif
  63 +}
  64 +
  65 +void exar7300_set_frame_type(struct channel *sc, u32 type)
  66 +{
  67 + u32 val;
  68 +
  69 + switch (type) {
  70 + case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
  71 + case SBE_2T3E3_FRAME_TYPE_T3_M13:
  72 + case SBE_2T3E3_FRAME_TYPE_E3_G751:
  73 + case SBE_2T3E3_FRAME_TYPE_E3_G832:
  74 + break;
  75 + default:
  76 + return;
  77 + }
  78 +
  79 + val = exar7300_read(sc, SBE_2T3E3_LIU_REG_REG4);
  80 + val &= ~(SBE_2T3E3_LIU_VAL_T3_MODE_SELECT |
  81 + SBE_2T3E3_LIU_VAL_E3_MODE_SELECT);
  82 +
  83 + switch (type) {
  84 + case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
  85 + case SBE_2T3E3_FRAME_TYPE_T3_M13:
  86 + val |= SBE_2T3E3_LIU_VAL_T3_MODE_SELECT;
  87 + break;
  88 + case SBE_2T3E3_FRAME_TYPE_E3_G751:
  89 + case SBE_2T3E3_FRAME_TYPE_E3_G832:
  90 + val |= SBE_2T3E3_LIU_VAL_E3_MODE_SELECT;
  91 + break;
  92 + default:
  93 + return;
  94 + }
  95 +
  96 + exar7300_write(sc, SBE_2T3E3_LIU_REG_REG4, val);
  97 +}
  98 +
  99 +
  100 +void exar7300_transmit_all_ones_onoff(struct channel *sc, u32 mode)
  101 +{
  102 + if (sc->p.transmit_all_ones == mode)
  103 + return;
  104 +
  105 + switch (mode) {
  106 + case SBE_2T3E3_ON:
  107 + exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG1,
  108 + SBE_2T3E3_LIU_VAL_TRANSMIT_ALL_ONES);
  109 + break;
  110 + case SBE_2T3E3_OFF:
  111 + exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG1,
  112 + SBE_2T3E3_LIU_VAL_TRANSMIT_ALL_ONES);
  113 + break;
  114 + default:
  115 + return;
  116 + }
  117 +
  118 + sc->p.transmit_all_ones = mode;
  119 +}
  120 +
  121 +void exar7300_receive_equalization_onoff(struct channel *sc, u32 mode)
  122 +{
  123 + if (sc->p.receive_equalization == mode)
  124 + return;
  125 +
  126 + switch (mode) {
  127 + case SBE_2T3E3_OFF:
  128 + exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG2,
  129 + SBE_2T3E3_LIU_VAL_RECEIVE_EQUALIZATION_DISABLE);
  130 + break;
  131 + case SBE_2T3E3_ON:
  132 + exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG2,
  133 + SBE_2T3E3_LIU_VAL_RECEIVE_EQUALIZATION_DISABLE);
  134 + break;
  135 + default:
  136 + return;
  137 + }
  138 +
  139 + sc->p.receive_equalization = mode;
  140 +}
  141 +
  142 +void exar7300_line_build_out_onoff(struct channel *sc, u32 mode)
  143 +{
  144 + if (sc->p.line_build_out == mode)
  145 + return;
  146 +
  147 + switch (mode) {
  148 + case SBE_2T3E3_OFF:
  149 + exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG1,
  150 + SBE_2T3E3_LIU_VAL_TRANSMIT_LEVEL_SELECT);
  151 + exar7300_receive_equalization_onoff(sc, SBE_2T3E3_OFF);
  152 + break;
  153 + case SBE_2T3E3_ON:
  154 + exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG1,
  155 + SBE_2T3E3_LIU_VAL_TRANSMIT_LEVEL_SELECT);
  156 + exar7300_receive_equalization_onoff(sc, SBE_2T3E3_ON);
  157 + break;
  158 + default:
  159 + return;
  160 + }
  161 +
  162 + sc->p.line_build_out = mode;
  163 +}
  164 +
  165 +/* TODO - what about encoder in raw mode??? disable it too? */
  166 +void exar7300_unipolar_onoff(struct channel *sc, u32 mode)
  167 +{
  168 + switch (mode) {
  169 + case SBE_2T3E3_OFF:
  170 + exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG3,
  171 + SBE_2T3E3_LIU_VAL_DECODER_DISABLE);
  172 + exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG1,
  173 + SBE_2T3E3_LIU_VAL_TRANSMIT_BINARY_DATA);
  174 + break;
  175 + case SBE_2T3E3_ON:
  176 + exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG3,
  177 + SBE_2T3E3_LIU_VAL_DECODER_DISABLE);
  178 + exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG1,
  179 + SBE_2T3E3_LIU_VAL_TRANSMIT_BINARY_DATA);
  180 + break;
  181 + }
  182 +}
drivers/staging/sbe-2t3e3/intr.c
  1 +/*
  2 + * SBE 2T3E3 synchronous serial card driver for Linux
  3 + *
  4 + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of version 2 of the GNU General Public License
  8 + * as published by the Free Software Foundation.
  9 + *
  10 + * This code is based on a driver written by SBE Inc.
  11 + */
  12 +
  13 +#include <linux/hdlc.h>
  14 +#include <linux/interrupt.h>
  15 +#include <linux/netdevice.h>
  16 +#include "2t3e3.h"
  17 +
  18 +irqreturn_t t3e3_intr(int irq, void *dev_instance)
  19 +{
  20 + struct channel *sc = dev_to_priv(dev_instance);
  21 + u32 val;
  22 + irqreturn_t ret = IRQ_NONE;
  23 +
  24 + sc->interrupt_active = 1;
  25 +
  26 + val = cpld_read(sc, SBE_2T3E3_CPLD_REG_PICSR);
  27 +
  28 + if (val & SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_CHANGE) {
  29 + dev_dbg(&sc->pdev->dev,
  30 + "Rx LOS Chng Int r=%02x (LOS|OOF=%02x)\n",
  31 + val, (sc->s.LOS << 4) | sc->s.OOF);
  32 + cpld_LOS_update(sc);
  33 + ret = IRQ_HANDLED;
  34 + }
  35 +
  36 + if (val & SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ASSERTED) {
  37 + dc_intr(sc);
  38 + ret = IRQ_HANDLED;
  39 + }
  40 +
  41 + if (val & SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ASSERTED) {
  42 + exar7250_intr(sc);
  43 + ret = IRQ_HANDLED;
  44 + }
  45 +
  46 + /*
  47 + we don't care about other interrupt sources (DMO, LOS, LCV) because
  48 + they are handled by Framer too
  49 + */
  50 +
  51 + sc->interrupt_active = 0;
  52 + return ret;
  53 +}
  54 +
  55 +void dc_intr(struct channel *sc)
  56 +{
  57 + u32 val;
  58 +
  59 + /* disable ethernet interrupts */
  60 + /* grrr this clears interrupt summary bits !!! */
  61 + dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, 0);
  62 +
  63 + while ((val = dc_read(sc->addr, SBE_2T3E3_21143_REG_STATUS)) &
  64 + (SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED |
  65 + SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE |
  66 + SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT |
  67 + SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW |
  68 + SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE |
  69 + SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED |
  70 + SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT)) {
  71 + dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, val);
  72 +
  73 + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Ethernet controller interrupt! (CSR5 = %08X)\n",
  74 + val);
  75 +
  76 + if (val & (SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT |
  77 + SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE |
  78 + SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED)) {
  79 + if (val & SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT)
  80 + dev_dbg(&sc->pdev->dev,
  81 + "Receive interrupt (LOS=%d, OOF=%d)\n",
  82 + sc->s.LOS, sc->s.OOF);
  83 + if (val & SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE)
  84 + dev_dbg(&sc->pdev->dev,
  85 + "Receive buffer unavailable\n");
  86 + if (val & SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED)
  87 + dev_dbg(&sc->pdev->dev,
  88 + "Receive process stopped\n");
  89 + dc_intr_rx(sc);
  90 + }
  91 +
  92 + if (val & SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW) {
  93 + dev_dbg(&sc->pdev->dev, "Transmit underflow\n");
  94 + dc_intr_tx_underflow(sc);
  95 + }
  96 +
  97 + if (val & (SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE |
  98 + SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT |
  99 + SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED)) {
  100 + if (val & SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT)
  101 + dev_dbg(&sc->pdev->dev, "Transmit interrupt\n");
  102 + if (val & SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE)
  103 + dev_dbg(&sc->pdev->dev,
  104 + "Transmit buffer unavailable\n");
  105 + if (val & SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED)
  106 + dev_dbg(&sc->pdev->dev,
  107 + "Transmit process stopped\n");
  108 + dc_intr_tx(sc);
  109 + }
  110 + }
  111 +
  112 + /* enable ethernet interrupts */
  113 + dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE,
  114 + sc->ether.interrupt_enable_mask);
  115 +}
  116 +
  117 +void dc_intr_rx(struct channel *sc)
  118 +{
  119 + u32 current_read;
  120 + u32 error_mask, error;
  121 + t3e3_rx_desc_t *current_desc;
  122 + struct sk_buff *m, *m2;
  123 + unsigned rcv_len;
  124 +
  125 + sc->rcv_count++; /* for the activity LED */
  126 +
  127 + current_read = sc->ether.rx_ring_current_read;
  128 + dev_dbg(&sc->pdev->dev, "intr_rx current_read = %d\n", current_read);
  129 +
  130 + /* when ethernet loopback is set, ignore framer signals */
  131 + if ((sc->p.loopback != SBE_2T3E3_LOOPBACK_ETHERNET) && sc->s.OOF) {
  132 + while (!(sc->ether.rx_ring[current_read].rdes0 &
  133 + SBE_2T3E3_RX_DESC_21143_OWN)) {
  134 + current_desc = &sc->ether.rx_ring[current_read];
  135 + current_desc->rdes1 &= SBE_2T3E3_RX_DESC_END_OF_RING |
  136 + SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED;
  137 + current_desc->rdes1 |= SBE_2T3E3_MTU;
  138 + current_desc->rdes0 = SBE_2T3E3_RX_DESC_21143_OWN;
  139 + current_read = (current_read + 1) % SBE_2T3E3_RX_DESC_RING_SIZE;
  140 + }
  141 + sc->ether.rx_ring_current_read = current_read;
  142 + return;
  143 + }
  144 +
  145 + while (!(sc->ether.rx_ring[current_read].rdes0 &
  146 + SBE_2T3E3_RX_DESC_21143_OWN)) {
  147 + current_desc = &sc->ether.rx_ring[current_read];
  148 +
  149 + dev_dbg(&sc->pdev->dev, "rdes0: %08X rdes1: %08X\n",
  150 + current_desc->rdes0, current_desc->rdes1);
  151 +
  152 + m = sc->ether.rx_data[current_read];
  153 + rcv_len = (current_desc->rdes0 & SBE_2T3E3_RX_DESC_FRAME_LENGTH) >>
  154 + SBE_2T3E3_RX_DESC_FRAME_LENGTH_SHIFT;
  155 +
  156 + dev_dbg(&sc->pdev->dev, "mbuf was received (mbuf len = %d)\n",
  157 + rcv_len);
  158 +
  159 + switch (sc->p.crc) {
  160 + case SBE_2T3E3_CRC_16:
  161 + rcv_len -= SBE_2T3E3_CRC16_LENGTH;
  162 + break;
  163 + case SBE_2T3E3_CRC_32:
  164 + rcv_len -= SBE_2T3E3_CRC32_LENGTH;
  165 + break;
  166 + default:
  167 + break;
  168 + }
  169 +
  170 + if (current_desc->rdes0 & SBE_2T3E3_RX_DESC_LAST_DESC) {
  171 +
  172 + /* TODO: is collision possible? */
  173 + error_mask = SBE_2T3E3_RX_DESC_DESC_ERROR |
  174 + SBE_2T3E3_RX_DESC_COLLISION_SEEN |
  175 + SBE_2T3E3_RX_DESC_DRIBBLING_BIT;
  176 +
  177 + switch (sc->p.frame_mode) {
  178 + case SBE_2T3E3_FRAME_MODE_HDLC:
  179 + error_mask |= SBE_2T3E3_RX_DESC_MII_ERROR;
  180 + if (sc->p.crc == SBE_2T3E3_CRC_32)
  181 + error_mask |= SBE_2T3E3_RX_DESC_CRC_ERROR;
  182 + break;
  183 + case SBE_2T3E3_FRAME_MODE_TRANSPARENT:
  184 + case SBE_2T3E3_FRAME_MODE_RAW:
  185 + break;
  186 + default:
  187 + error_mask = 0;
  188 + }
  189 +
  190 + if (sc->s.LOS) {
  191 + error_mask &= ~(SBE_2T3E3_RX_DESC_DRIBBLING_BIT ||
  192 + SBE_2T3E3_RX_DESC_MII_ERROR);
  193 + }
  194 +
  195 + error = current_desc->rdes0 & error_mask;
  196 + if (error) {
  197 + sc->s.in_errors++;
  198 + dev_dbg(&sc->pdev->dev,
  199 + "error interrupt: NO_ERROR_MESSAGE = %d\n",
  200 + sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES ? 1 : 0);
  201 +
  202 + current_desc->rdes1 &= SBE_2T3E3_RX_DESC_END_OF_RING |
  203 + SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED;
  204 + current_desc->rdes1 |= SBE_2T3E3_MTU;
  205 + current_desc->rdes0 = SBE_2T3E3_RX_DESC_21143_OWN;
  206 +
  207 + if (error & SBE_2T3E3_RX_DESC_DESC_ERROR) {
  208 + if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
  209 + dev_err(&sc->pdev->dev,
  210 + "SBE 2T3E3: descriptor error\n");
  211 + sc->s.in_error_desc++;
  212 + }
  213 +
  214 + if (error & SBE_2T3E3_RX_DESC_COLLISION_SEEN) {
  215 + if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
  216 + dev_err(&sc->pdev->dev,
  217 + "SBE 2T3E3: collision seen\n");
  218 + sc->s.in_error_coll++;
  219 + } else {
  220 + if (error & SBE_2T3E3_RX_DESC_DRIBBLING_BIT) {
  221 + if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
  222 + dev_err(&sc->pdev->dev,
  223 + "SBE 2T3E3: dribbling bits error\n");
  224 + sc->s.in_error_drib++;
  225 + }
  226 +
  227 + if (error & SBE_2T3E3_RX_DESC_CRC_ERROR) {
  228 + if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
  229 + dev_err(&sc->pdev->dev,
  230 + "SBE 2T3E3: crc error\n");
  231 + sc->s.in_error_crc++;
  232 + }
  233 + }
  234 +
  235 + if (error & SBE_2T3E3_RX_DESC_MII_ERROR) {
  236 + if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
  237 + dev_err(&sc->pdev->dev, "SBE 2T3E3: mii error\n");
  238 + sc->s.in_error_mii++;
  239 + }
  240 +
  241 + current_read = (current_read + 1) % SBE_2T3E3_RX_DESC_RING_SIZE;
  242 + sc->r.flags |= SBE_2T3E3_FLAG_NO_ERROR_MESSAGES;
  243 + continue;
  244 + }
  245 + }
  246 +
  247 + current_desc->rdes1 &= SBE_2T3E3_RX_DESC_END_OF_RING |
  248 + SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED;
  249 + current_desc->rdes1 |= SBE_2T3E3_MTU;
  250 +
  251 + if (rcv_len > 1600) {
  252 + sc->s.in_errors++;
  253 + sc->s.in_dropped++;
  254 + if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
  255 + dev_err(&sc->pdev->dev, "SBE 2T3E3: oversized rx: rdes0 = %08X\n",
  256 + current_desc->rdes0);
  257 + } else {
  258 + m2 = dev_alloc_skb(MCLBYTES);
  259 + if (m2 != NULL) {
  260 + current_desc->rdes2 = virt_to_phys(m2->data);
  261 + sc->ether.rx_data[current_read] = m2;
  262 + sc->s.in_packets++;
  263 + sc->s.in_bytes += rcv_len;
  264 + m->dev = sc->dev;
  265 + skb_put(m, rcv_len);
  266 + skb_reset_mac_header(m);
  267 + m->protocol = hdlc_type_trans(m, m->dev);
  268 + netif_rx(m);
  269 +
  270 + /* good packet was received so we will show error messages again... */
  271 + if (sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES) {
  272 + dev_dbg(&sc->pdev->dev,
  273 + "setting ERROR_MESSAGES->0\n");
  274 + sc->r.flags &= ~SBE_2T3E3_FLAG_NO_ERROR_MESSAGES;
  275 + }
  276 +
  277 + } else {
  278 + sc->s.in_errors++;
  279 + sc->s.in_dropped++;
  280 + }
  281 + }
  282 + current_desc->rdes0 = SBE_2T3E3_RX_DESC_21143_OWN;
  283 + current_read = (current_read + 1) % SBE_2T3E3_RX_DESC_RING_SIZE;
  284 + }
  285 +
  286 + sc->ether.rx_ring_current_read = current_read;
  287 +
  288 + dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_POLL_DEMAND, 0xFFFFFFFF);
  289 +}
  290 +
  291 +void dc_intr_tx(struct channel *sc)
  292 +{
  293 + u32 current_read, current_write;
  294 + u32 last_segment, error;
  295 + t3e3_tx_desc_t *current_desc;
  296 +
  297 + spin_lock(&sc->ether.tx_lock);
  298 +
  299 + current_read = sc->ether.tx_ring_current_read;
  300 + current_write = sc->ether.tx_ring_current_write;
  301 +
  302 + while (current_read != current_write) {
  303 + current_desc = &sc->ether.tx_ring[current_read];
  304 +
  305 + if (current_desc->tdes0 & SBE_2T3E3_RX_DESC_21143_OWN)
  306 + break;
  307 +
  308 + dev_dbg(&sc->pdev->dev,
  309 + "txeof: tdes0 = %08X tdes1 = %08X\n",
  310 + current_desc->tdes0, current_desc->tdes1);
  311 +
  312 + error = current_desc->tdes0 & (SBE_2T3E3_TX_DESC_ERROR_SUMMARY |
  313 + SBE_2T3E3_TX_DESC_TRANSMIT_JABBER_TIMEOUT |
  314 + SBE_2T3E3_TX_DESC_LOSS_OF_CARRIER |
  315 + SBE_2T3E3_TX_DESC_NO_CARRIER |
  316 + SBE_2T3E3_TX_DESC_LINK_FAIL_REPORT |
  317 + SBE_2T3E3_TX_DESC_UNDERFLOW_ERROR |
  318 + SBE_2T3E3_TX_DESC_DEFFERED);
  319 +
  320 + last_segment = current_desc->tdes1 & SBE_2T3E3_TX_DESC_LAST_SEGMENT;
  321 +
  322 + current_desc->tdes0 = 0;
  323 + current_desc->tdes1 &= SBE_2T3E3_TX_DESC_END_OF_RING |
  324 + SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED;
  325 + current_desc->tdes2 = 0;
  326 + sc->ether.tx_free_cnt++;
  327 +
  328 + if (last_segment != SBE_2T3E3_TX_DESC_LAST_SEGMENT) {
  329 + current_read = (current_read + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
  330 + continue;
  331 + }
  332 +
  333 +
  334 + if (sc->ether.tx_data[current_read]) {
  335 + sc->s.out_packets++;
  336 + sc->s.out_bytes += sc->ether.tx_data[current_read]->len;
  337 + dev_kfree_skb_any(sc->ether.tx_data[current_read]);
  338 + sc->ether.tx_data[current_read] = NULL;
  339 + }
  340 +
  341 + if (error > 0) {
  342 + sc->s.out_errors++;
  343 +
  344 + if (error & SBE_2T3E3_TX_DESC_TRANSMIT_JABBER_TIMEOUT) {
  345 + dev_err(&sc->pdev->dev, "SBE 2T3E3: transmit jabber timeout\n");
  346 + sc->s.out_error_jab++;
  347 + }
  348 +
  349 + if (sc->p.loopback != SBE_2T3E3_LOOPBACK_ETHERNET) {
  350 + if (error & SBE_2T3E3_TX_DESC_LOSS_OF_CARRIER) {
  351 + dev_err(&sc->pdev->dev, "SBE 2T3E3: loss of carrier\n");
  352 + sc->s.out_error_lost_carr++;
  353 + }
  354 +
  355 + if (error & SBE_2T3E3_TX_DESC_NO_CARRIER) {
  356 + dev_err(&sc->pdev->dev, "SBE 2T3E3: no carrier\n");
  357 + sc->s.out_error_no_carr++;
  358 + }
  359 + }
  360 +
  361 + if (error & SBE_2T3E3_TX_DESC_LINK_FAIL_REPORT) {
  362 + dev_err(&sc->pdev->dev, "SBE 2T3E3: link fail report\n");
  363 + sc->s.out_error_link_fail++;
  364 + }
  365 +
  366 + if (error & SBE_2T3E3_TX_DESC_UNDERFLOW_ERROR) {
  367 + dev_err(&sc->pdev->dev, "SBE 2T3E3:"
  368 + " transmission underflow error\n");
  369 + sc->s.out_error_underflow++;
  370 + spin_unlock(&sc->ether.tx_lock);
  371 +
  372 + dc_restart(sc);
  373 + return;
  374 + }
  375 +
  376 + if (error & SBE_2T3E3_TX_DESC_DEFFERED) {
  377 + dev_err(&sc->pdev->dev, "SBE 2T3E3: transmission deferred\n");
  378 + sc->s.out_error_dereferred++;
  379 + }
  380 + }
  381 +
  382 + current_read = (current_read + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
  383 + }
  384 +
  385 + sc->ether.tx_ring_current_read = current_read;
  386 +
  387 + /* Relieve flow control when the TX queue is drained at least half way */
  388 + if (sc->ether.tx_full &&
  389 + (sc->ether.tx_free_cnt >= (SBE_2T3E3_TX_DESC_RING_SIZE / 2))) {
  390 + sc->ether.tx_full = 0;
  391 + netif_wake_queue(sc->dev);
  392 + }
  393 + spin_unlock(&sc->ether.tx_lock);
  394 +}
  395 +
  396 +
  397 +void dc_intr_tx_underflow(struct channel *sc)
  398 +{
  399 + u32 val;
  400 +
  401 + dc_transmitter_onoff(sc, SBE_2T3E3_OFF);
  402 +
  403 + val = dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE);
  404 + dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
  405 + SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS);
  406 +
  407 + switch (val & SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS) {
  408 + case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_1:
  409 + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
  410 + SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_2);
  411 + break;
  412 + case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_2:
  413 + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
  414 + SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_3);
  415 + break;
  416 + case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_3:
  417 + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
  418 + SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_4);
  419 + break;
  420 + case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_4:
  421 + default:
  422 + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
  423 + SBE_2T3E3_21143_VAL_STORE_AND_FORWARD);
  424 + break;
  425 + }
  426 +
  427 + dc_transmitter_onoff(sc, SBE_2T3E3_ON);
  428 +}
  429 +
  430 +
  431 +
  432 +
  433 +void exar7250_intr(struct channel *sc)
  434 +{
  435 + u32 status, old_OOF;
  436 +
  437 +#if 0
  438 + /* disable interrupts */
  439 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE, 0);
  440 +#endif
  441 +
  442 + old_OOF = sc->s.OOF;
  443 +
  444 + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS);
  445 + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt! (REG[0x05] = %02X)\n", status);
  446 +
  447 + switch (sc->p.frame_type) {
  448 + case SBE_2T3E3_FRAME_TYPE_E3_G751:
  449 + case SBE_2T3E3_FRAME_TYPE_E3_G832:
  450 + exar7250_E3_intr(sc, status);
  451 + break;
  452 +
  453 + case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
  454 + case SBE_2T3E3_FRAME_TYPE_T3_M13:
  455 + exar7250_T3_intr(sc, status);
  456 + break;
  457 +
  458 + default:
  459 + break;
  460 + }
  461 +
  462 + if (sc->s.OOF != old_OOF) {
  463 + if (sc->s.OOF) {
  464 + if (sc->p.loopback == SBE_2T3E3_LOOPBACK_NONE) {
  465 + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Disabling eth interrupts\n");
  466 + /* turn off ethernet interrupts */
  467 + dc_stop_intr(sc);
  468 + }
  469 + } else if (sc->r.flags & SBE_2T3E3_FLAG_NETWORK_UP) {
  470 + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Enabling eth interrupts\n");
  471 + /* start interrupts */
  472 + sc->s.OOF = 1;
  473 + dc_intr_rx(sc);
  474 + sc->s.OOF = 0;
  475 + if (sc->p.receiver_on) {
  476 + dc_receiver_onoff(sc, SBE_2T3E3_OFF);
  477 + dc_receiver_onoff(sc, SBE_2T3E3_ON);
  478 + }
  479 + dc_start_intr(sc);
  480 + }
  481 + }
  482 +#if 0
  483 + /* reenable interrupts */
  484 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE,
  485 + SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_ENABLE |
  486 + SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_ENABLE
  487 + );
  488 +#endif
  489 +}
  490 +
  491 +
  492 +void exar7250_T3_intr(struct channel *sc, u32 block_status)
  493 +{
  494 + u32 status, result;
  495 +
  496 + if (block_status & SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_STATUS) {
  497 + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS);
  498 +
  499 + if (status) {
  500 + dev_dbg(&sc->pdev->dev,
  501 + "Framer interrupt T3 RX (REG[0x13] = %02X)\n",
  502 + status);
  503 +
  504 + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);
  505 +
  506 +#if 0
  507 + if (status & SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_STATUS) {
  508 + dev_dbg(&sc->pdev->dev,
  509 + "Framer interrupt T3: LOS\n");
  510 + sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_T3_RX_LOS ? 1 : 0;
  511 +
  512 + }
  513 +#else
  514 + cpld_LOS_update(sc);
  515 +#endif
  516 + if (status & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_STATUS) {
  517 + sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
  518 + dev_dbg(&sc->pdev->dev,
  519 + "Framer interrupt T3: OOF (%d)\n",
  520 + sc->s.OOF);
  521 + }
  522 +
  523 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE,
  524 + SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE |
  525 + SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE);
  526 +#if 0
  527 + SBE_2T3E3_FRAMER_VAL_T3_RX_CP_BIT_ERROR_INTERRUPT_ENABLE |
  528 + SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE |
  529 + SBE_2T3E3_FRAMER_VAL_T3_RX_AIS_INTERRUPT_ENABLE |
  530 + SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE_INTERRUPT_ENABLE |
  531 + SBE_2T3E3_FRAMER_VAL_T3_RX_FERF_INTERRUPT_ENABLE |
  532 + SBE_2T3E3_FRAMER_VAL_T3_RX_AIC_INTERRUPT_ENABLE |
  533 + SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE |
  534 + SBE_2T3E3_FRAMER_VAL_T3_RX_P_BIT_INTERRUPT_ENABLE
  535 +#endif
  536 + }
  537 +
  538 + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS);
  539 + if (status) {
  540 + dev_dbg(&sc->pdev->dev,
  541 + "Framer interrupt T3 RX (REG[0x17] = %02X)\n",
  542 + status);
  543 +#if 0
  544 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS,
  545 + SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_REMOVE_INTERRUPT_ENABLE |
  546 + SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID_INTERRUPT_ENABLE
  547 + );
  548 +#endif
  549 + }
  550 +
  551 + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL);
  552 + if (status)
  553 + dev_dbg(&sc->pdev->dev,
  554 + "Framer interrupt T3 RX (REG[0x18] = %02X)\n",
  555 + status);
  556 + }
  557 +
  558 +
  559 + if (block_status & SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_STATUS) {
  560 + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS);
  561 + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt T3 TX (REG[0x31] = %02X)\n",
  562 + status);
  563 +
  564 + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS);
  565 + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt T3 TX (REG[0x34] = %02X)\n",
  566 + status);
  567 + }
  568 +}
  569 +
  570 +
  571 +void exar7250_E3_intr(struct channel *sc, u32 block_status)
  572 +{
  573 + u32 status, result;
  574 +
  575 + if (block_status & SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_STATUS) {
  576 + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1);
  577 +
  578 + if (status) {
  579 + dev_dbg(&sc->pdev->dev,
  580 + "Framer interrupt E3 RX (REG[0x14] = %02X)\n",
  581 + status);
  582 +
  583 + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);
  584 +
  585 +#if 0
  586 + if (status & SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_STATUS) {
  587 + dev_dbg(&sc->pdev->dev,
  588 + "Framer interrupt E3: LOS\n");
  589 + sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_E3_RX_LOS ? 1 : 0;
  590 + }
  591 +#else
  592 + cpld_LOS_update(sc);
  593 +#endif
  594 + if (status & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_STATUS) {
  595 + sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
  596 + dev_dbg(&sc->pdev->dev,
  597 + "Framer interrupt E3: OOF (%d)\n",
  598 + sc->s.OOF);
  599 + }
  600 +
  601 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1,
  602 + SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE |
  603 + SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE
  604 + );
  605 +#if 0
  606 + SBE_2T3E3_FRAMER_VAL_E3_RX_COFA_INTERRUPT_ENABLE |
  607 + SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE |
  608 + SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_INTERRUPT_ENABLE |
  609 + SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE |
  610 + SBE_2T3E3_FRAMER_VAL_E3_RX_AIS_INTERRUPT_ENABLE
  611 +#endif
  612 + }
  613 +
  614 + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2);
  615 + if (status) {
  616 + dev_dbg(&sc->pdev->dev,
  617 + "Framer interrupt E3 RX (REG[0x15] = %02X)\n",
  618 + status);
  619 +
  620 +#if 0
  621 + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2,
  622 + SBE_2T3E3_FRAMER_VAL_E3_RX_FEBE_INTERRUPT_ENABLE |
  623 + SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_INTERRUPT_ENABLE |
  624 + SBE_2T3E3_FRAMER_VAL_E3_RX_FRAMING_BYTE_ERROR_INTERRUPT_ENABLE);
  625 +#endif
  626 + }
  627 +
  628 + }
  629 +
  630 + if (block_status & SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_STATUS) {
  631 + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS);
  632 + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt E3 TX (REG[0x34] = %02X)\n",
  633 + status);
  634 + }
  635 +}
drivers/staging/sbe-2t3e3/io.c
  1 +/*
  2 + * SBE 2T3E3 synchronous serial card driver for Linux
  3 + *
  4 + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of version 2 of the GNU General Public License
  8 + * as published by the Free Software Foundation.
  9 + *
  10 + * This code is based on a driver written by SBE Inc.
  11 + */
  12 +
  13 +#include <linux/ip.h>
  14 +#include <asm/system.h>
  15 +#include "2t3e3.h"
  16 +#include "ctrl.h"
  17 +
  18 +/* All access to registers done via the 21143 on port 0 must be
  19 + * protected via the card->bootrom_lock. */
  20 +
  21 +/* priviate define to be used here only - must be protected by card->bootrom_lock */
  22 +#define cpld_write_nolock(channel, reg, val) \
  23 + bootrom_write((channel), CPLD_MAP_REG(reg, channel), val)
  24 +
  25 +u32 cpld_read(struct channel *channel, u32 reg)
  26 +{
  27 + unsigned long flags;
  28 + u32 val;
  29 +
  30 + spin_lock_irqsave(&channel->card->bootrom_lock, flags);
  31 + val = bootrom_read((channel), CPLD_MAP_REG(reg, channel));
  32 + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
  33 + return val;
  34 +}
  35 +
  36 +/****************************************
  37 + * Access via BootROM port
  38 + ****************************************/
  39 +
  40 +u32 bootrom_read(struct channel *channel, u32 reg)
  41 +{
  42 + unsigned long addr = channel->card->bootrom_addr;
  43 + u32 result;
  44 +
  45 + /* select BootROM address */
  46 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_PROGRAMMING_ADDRESS, reg & 0x3FFFF);
  47 +
  48 + /* select reading from BootROM */
  49 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
  50 + SBE_2T3E3_21143_VAL_READ_OPERATION |
  51 + SBE_2T3E3_21143_VAL_BOOT_ROM_SELECT);
  52 +
  53 + udelay(2); /* 20 PCI cycles */
  54 +
  55 + /* read from BootROM */
  56 + result = dc_read(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT) & 0xff;
  57 +
  58 + /* reset CSR9 */
  59 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
  60 +
  61 + return result;
  62 +}
  63 +
  64 +void bootrom_write(struct channel *channel, u32 reg, u32 val)
  65 +{
  66 + unsigned long addr = channel->card->bootrom_addr;
  67 +
  68 + /* select BootROM address */
  69 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_PROGRAMMING_ADDRESS, reg & 0x3FFFF);
  70 +
  71 + /* select writting to BootROM */
  72 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
  73 + SBE_2T3E3_21143_VAL_WRITE_OPERATION |
  74 + SBE_2T3E3_21143_VAL_BOOT_ROM_SELECT |
  75 + (val & 0xff));
  76 +
  77 + udelay(2); /* 20 PCI cycles */
  78 +
  79 + /* reset CSR9 */
  80 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
  81 +}
  82 +
  83 +
  84 +/****************************************
  85 + * Access via Serial I/O port
  86 + ****************************************/
  87 +
  88 +static u32 serialrom_read_bit(struct channel *channel)
  89 +{
  90 + unsigned long addr = channel->card->bootrom_addr;
  91 + u32 bit;
  92 +
  93 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
  94 + SBE_2T3E3_21143_VAL_READ_OPERATION |
  95 + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
  96 + SBE_2T3E3_21143_VAL_SERIAL_ROM_CLOCK |
  97 + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock high */
  98 +
  99 + bit = (dc_read(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT) &
  100 + SBE_2T3E3_21143_VAL_SERIAL_ROM_DATA_OUT) > 0 ? 1 : 0;
  101 +
  102 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
  103 + SBE_2T3E3_21143_VAL_READ_OPERATION |
  104 + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
  105 + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
  106 +
  107 + return bit;
  108 +}
  109 +
  110 +static void serialrom_write_bit(struct channel *channel, u32 bit)
  111 +{
  112 + unsigned long addr = channel->card->bootrom_addr;
  113 + u32 lastbit = -1;
  114 +
  115 + bit &= 1;
  116 +
  117 + if (bit != lastbit) {
  118 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
  119 + SBE_2T3E3_21143_VAL_WRITE_OPERATION |
  120 + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
  121 + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT |
  122 + (bit << 2)); /* clock low */
  123 +
  124 + lastbit = bit;
  125 + }
  126 +
  127 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
  128 + SBE_2T3E3_21143_VAL_WRITE_OPERATION |
  129 + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
  130 + SBE_2T3E3_21143_VAL_SERIAL_ROM_CLOCK |
  131 + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT |
  132 + (bit << 2)); /* clock high */
  133 +
  134 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
  135 + SBE_2T3E3_21143_VAL_WRITE_OPERATION |
  136 + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
  137 + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT |
  138 + (bit << 2)); /* clock low */
  139 +}
  140 +
  141 +/****************************************
  142 + * Access to SerialROM (eeprom)
  143 + ****************************************/
  144 +
  145 +u32 t3e3_eeprom_read_word(struct channel *channel, u32 address)
  146 +{
  147 + unsigned long addr = channel->card->bootrom_addr;
  148 + u32 i, val;
  149 + unsigned long flags;
  150 +
  151 + address &= 0x3f;
  152 +
  153 + spin_lock_irqsave(&channel->card->bootrom_lock, flags);
  154 +
  155 + /* select correct Serial Chip */
  156 + cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT,
  157 + SBE_2T3E3_CPLD_VAL_EEPROM_SELECT);
  158 +
  159 + /* select reading from Serial I/O Bus */
  160 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
  161 + SBE_2T3E3_21143_VAL_READ_OPERATION |
  162 + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
  163 + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
  164 +
  165 + /* select read operation */
  166 + serialrom_write_bit(channel, 0);
  167 + serialrom_write_bit(channel, 1);
  168 + serialrom_write_bit(channel, 1);
  169 + serialrom_write_bit(channel, 0);
  170 +
  171 + for (i = 0x20; i; i >>= 1)
  172 + serialrom_write_bit(channel, address & i ? 1 : 0);
  173 +
  174 + val = 0;
  175 + for (i = 0x8000; i; i >>= 1)
  176 + val |= (serialrom_read_bit(channel) ? i : 0);
  177 +
  178 + /* Reset 21143's CSR9 */
  179 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
  180 + SBE_2T3E3_21143_VAL_READ_OPERATION |
  181 + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
  182 + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
  183 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
  184 +
  185 + /* Unselect Serial Chip */
  186 + cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, 0);
  187 +
  188 + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
  189 +
  190 + return ntohs(val);
  191 +}
  192 +
  193 +
  194 +/****************************************
  195 + * Access to Framer
  196 + ****************************************/
  197 +
  198 +u32 exar7250_read(struct channel *channel, u32 reg)
  199 +{
  200 + u32 result;
  201 + unsigned long flags;
  202 +
  203 +#if 0
  204 + switch (reg) {
  205 + case SBE_2T3E3_FRAMER_REG_OPERATING_MODE:
  206 + return channel->framer_regs[reg];
  207 + break;
  208 + default:
  209 + }
  210 +#endif
  211 +
  212 + spin_lock_irqsave(&channel->card->bootrom_lock, flags);
  213 +
  214 + result = bootrom_read(channel, cpld_reg_map[SBE_2T3E3_CPLD_REG_FRAMER_BASE_ADDRESS]
  215 + [channel->h.slot] + (t3e3_framer_reg_map[reg] << 2));
  216 +
  217 + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
  218 +
  219 + return result;
  220 +}
  221 +
  222 +void exar7250_write(struct channel *channel, u32 reg, u32 val)
  223 +{
  224 + unsigned long flags;
  225 +
  226 + val &= 0xff;
  227 + channel->framer_regs[reg] = val;
  228 +
  229 + spin_lock_irqsave(&channel->card->bootrom_lock, flags);
  230 +
  231 + bootrom_write(channel, cpld_reg_map[SBE_2T3E3_CPLD_REG_FRAMER_BASE_ADDRESS]
  232 + [channel->h.slot] + (t3e3_framer_reg_map[reg] << 2), val);
  233 +
  234 + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
  235 +}
  236 +
  237 +
  238 +/****************************************
  239 + * Access to LIU
  240 + ****************************************/
  241 +
  242 +u32 exar7300_read(struct channel *channel, u32 reg)
  243 +{
  244 + unsigned long addr = channel->card->bootrom_addr, flags;
  245 + u32 i, val;
  246 +
  247 +#if 0
  248 + switch (reg) {
  249 + case SBE_2T3E3_LIU_REG_REG1:
  250 + case SBE_2T3E3_LIU_REG_REG2:
  251 + case SBE_2T3E3_LIU_REG_REG3:
  252 + case SBE_2T3E3_LIU_REG_REG4:
  253 + return channel->liu_regs[reg];
  254 + break;
  255 + default:
  256 + }
  257 +#endif
  258 +
  259 + /* select correct Serial Chip */
  260 +
  261 + spin_lock_irqsave(&channel->card->bootrom_lock, flags);
  262 +
  263 + cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT,
  264 + cpld_val_map[SBE_2T3E3_CPLD_VAL_LIU_SELECT][channel->h.slot]);
  265 +
  266 + /* select reading from Serial I/O Bus */
  267 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
  268 + SBE_2T3E3_21143_VAL_READ_OPERATION |
  269 + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
  270 + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
  271 +
  272 + /* select read operation */
  273 + serialrom_write_bit(channel, 1);
  274 +
  275 + /* Exar7300 register address is 4 bit long */
  276 + reg = t3e3_liu_reg_map[reg];
  277 + for (i = 0; i < 4; i++, reg >>= 1) /* 4 bits of SerialROM address */
  278 + serialrom_write_bit(channel, reg & 1);
  279 + for (i = 0; i < 3; i++) /* remaining 3 bits of SerialROM address */
  280 + serialrom_write_bit(channel, 0);
  281 +
  282 + val = 0; /* Exar7300 register value is 5 bit long */
  283 + for (i = 0; i < 8; i++) /* 8 bits of SerialROM value */
  284 + val += (serialrom_read_bit(channel) << i);
  285 +
  286 + /* Reset 21143's CSR9 */
  287 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
  288 + SBE_2T3E3_21143_VAL_READ_OPERATION |
  289 + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
  290 + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
  291 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
  292 +
  293 + /* Unselect Serial Chip */
  294 + cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, 0);
  295 +
  296 + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
  297 +
  298 + return val;
  299 +}
  300 +
  301 +void exar7300_write(struct channel *channel, u32 reg, u32 val)
  302 +{
  303 + unsigned long addr = channel->card->bootrom_addr, flags;
  304 + u32 i;
  305 +
  306 + channel->liu_regs[reg] = val;
  307 +
  308 + /* select correct Serial Chip */
  309 +
  310 + spin_lock_irqsave(&channel->card->bootrom_lock, flags);
  311 +
  312 + cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT,
  313 + cpld_val_map[SBE_2T3E3_CPLD_VAL_LIU_SELECT][channel->h.slot]);
  314 +
  315 + /* select writting to Serial I/O Bus */
  316 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
  317 + SBE_2T3E3_21143_VAL_WRITE_OPERATION |
  318 + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
  319 + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
  320 +
  321 + /* select write operation */
  322 + serialrom_write_bit(channel, 0);
  323 +
  324 + /* Exar7300 register address is 4 bit long */
  325 + reg = t3e3_liu_reg_map[reg];
  326 + for (i = 0; i < 4; i++) { /* 4 bits */
  327 + serialrom_write_bit(channel, reg & 1);
  328 + reg >>= 1;
  329 + }
  330 + for (i = 0; i < 3; i++) /* remaining 3 bits of SerialROM address */
  331 + serialrom_write_bit(channel, 0);
  332 +
  333 + /* Exar7300 register value is 5 bit long */
  334 + for (i = 0; i < 5; i++) {
  335 + serialrom_write_bit(channel, val & 1);
  336 + val >>= 1;
  337 + }
  338 + for (i = 0; i < 3; i++) /* remaining 3 bits of SerialROM value */
  339 + serialrom_write_bit(channel, 0);
  340 +
  341 + /* Reset 21143_CSR9 */
  342 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
  343 + SBE_2T3E3_21143_VAL_WRITE_OPERATION |
  344 + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
  345 + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
  346 + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
  347 +
  348 + /* Unselect Serial Chip */
  349 + cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, 0);
  350 +
  351 + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
  352 +}
drivers/staging/sbe-2t3e3/main.c
  1 +/*
  2 + * SBE 2T3E3 synchronous serial card driver for Linux
  3 + *
  4 + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of version 2 of the GNU General Public License
  8 + * as published by the Free Software Foundation.
  9 + *
  10 + * This code is based on a driver written by SBE Inc.
  11 + */
  12 +
  13 +#include <linux/interrupt.h>
  14 +#include <linux/netdevice.h>
  15 +#include "2t3e3.h"
  16 +
  17 +void t3e3_init(struct channel *sc)
  18 +{
  19 + cpld_init(sc);
  20 + dc_reset(sc);
  21 + dc_init(sc);
  22 + exar7250_init(sc);
  23 + exar7300_init(sc);
  24 +}
  25 +
  26 +int t3e3_if_start_xmit(struct sk_buff *skb, struct net_device *dev)
  27 +{
  28 + struct channel *sc = dev_to_priv(dev);
  29 + u32 current_write, last_write;
  30 + unsigned long flags;
  31 + struct sk_buff *skb2;
  32 +
  33 + if (skb == NULL) {
  34 + sc->s.out_errors++;
  35 + return 0;
  36 + }
  37 +
  38 + if (sc->p.transmitter_on != SBE_2T3E3_ON) {
  39 + sc->s.out_errors++;
  40 + sc->s.out_dropped++;
  41 + dev_kfree_skb_any(skb);
  42 + return 0;
  43 + }
  44 +
  45 + if (sc->s.OOF && sc->p.loopback == SBE_2T3E3_LOOPBACK_NONE) {
  46 + sc->s.out_dropped++;
  47 + dev_kfree_skb_any(skb);
  48 + return 0;
  49 + }
  50 +
  51 + spin_lock_irqsave(&sc->ether.tx_lock, flags);
  52 +
  53 + current_write = sc->ether.tx_ring_current_write;
  54 + for (skb2 = skb; skb2 != NULL; skb2 = NULL) {
  55 + if (skb2->len) {
  56 + if ((sc->ether.tx_ring[current_write].tdes1 &
  57 + SBE_2T3E3_TX_DESC_BUFFER_1_SIZE) > 0)
  58 + break;
  59 + current_write = (current_write + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
  60 + /*
  61 + * Leave at least 1 tx desc free so that dc_intr_tx() can
  62 + * identify empty list
  63 + */
  64 + if (current_write == sc->ether.tx_ring_current_read)
  65 + break;
  66 + }
  67 + }
  68 + if (skb2 != NULL) {
  69 + netif_stop_queue(sc->dev);
  70 + sc->ether.tx_full = 1;
  71 + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: out of descriptors\n");
  72 + spin_unlock_irqrestore(&sc->ether.tx_lock, flags);
  73 + return NETDEV_TX_BUSY;
  74 + }
  75 +
  76 + current_write = last_write = sc->ether.tx_ring_current_write;
  77 + dev_dbg(&sc->pdev->dev, "sending mbuf (current_write = %d)\n",
  78 + current_write);
  79 +
  80 + for (skb2 = skb; skb2 != NULL; skb2 = NULL) {
  81 + if (skb2->len) {
  82 + dev_dbg(&sc->pdev->dev,
  83 + "sending mbuf (len = %d, next = %p)\n",
  84 + skb2->len, NULL);
  85 +
  86 + sc->ether.tx_free_cnt--;
  87 + sc->ether.tx_ring[current_write].tdes0 = 0;
  88 + sc->ether.tx_ring[current_write].tdes1 &=
  89 + SBE_2T3E3_TX_DESC_END_OF_RING |
  90 + SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED;
  91 +/* DISABLE_PADDING sometimes gets lost somehow, hands off... */
  92 + sc->ether.tx_ring[current_write].tdes1 |=
  93 + SBE_2T3E3_TX_DESC_DISABLE_PADDING | skb2->len;
  94 +
  95 + if (current_write == sc->ether.tx_ring_current_write) {
  96 + sc->ether.tx_ring[current_write].tdes1 |=
  97 + SBE_2T3E3_TX_DESC_FIRST_SEGMENT;
  98 + } else {
  99 + sc->ether.tx_ring[current_write].tdes0 =
  100 + SBE_2T3E3_TX_DESC_21143_OWN;
  101 + }
  102 +
  103 + sc->ether.tx_ring[current_write].tdes2 = virt_to_phys(skb2->data);
  104 + sc->ether.tx_data[current_write] = NULL;
  105 +
  106 + last_write = current_write;
  107 + current_write = (current_write + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
  108 + }
  109 + }
  110 +
  111 + sc->ether.tx_data[last_write] = skb;
  112 + sc->ether.tx_ring[last_write].tdes1 |=
  113 + SBE_2T3E3_TX_DESC_LAST_SEGMENT |
  114 + SBE_2T3E3_TX_DESC_INTERRUPT_ON_COMPLETION;
  115 + sc->ether.tx_ring[sc->ether.tx_ring_current_write].tdes0 |=
  116 + SBE_2T3E3_TX_DESC_21143_OWN;
  117 + sc->ether.tx_ring_current_write = current_write;
  118 +
  119 + dev_dbg(&sc->pdev->dev, "txput: tdes0 = %08X tdes1 = %08X\n",
  120 + sc->ether.tx_ring[last_write].tdes0,
  121 + sc->ether.tx_ring[last_write].tdes1);
  122 +
  123 + dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_POLL_DEMAND,
  124 + 0xffffffff);
  125 +
  126 + spin_unlock_irqrestore(&sc->ether.tx_lock, flags);
  127 + return 0;
  128 +}
  129 +
  130 +
  131 +void t3e3_read_card_serial_number(struct channel *sc)
  132 +{
  133 + u32 i;
  134 +
  135 + for (i = 0; i < 3; i++)
  136 + sc->ether.card_serial_number[i] = t3e3_eeprom_read_word(sc, 10 + i);
  137 +
  138 + printk(KERN_INFO "SBE wanPMC-2T3E3 serial number: %04X%04X%04X\n",
  139 + sc->ether.card_serial_number[0], sc->ether.card_serial_number[1],
  140 + sc->ether.card_serial_number[2]);
  141 +}
  142 +
  143 +/*
  144 + bit 0 led1 (green)
  145 + bit 1 led1 (yellow)
  146 +
  147 + bit 2 led2 (green)
  148 + bit 3 led2 (yellow)
  149 +
  150 + bit 4 led3 (green)
  151 + bit 5 led3 (yellow)
  152 +
  153 + bit 6 led4 (green)
  154 + bit 7 led4 (yellow)
  155 +*/
  156 +
  157 +void update_led(struct channel *sc, int blinker)
  158 +{
  159 + int leds;
  160 + if (sc->s.LOS)
  161 + leds = 0; /* led1 = off */
  162 + else if (sc->s.OOF)
  163 + leds = 2; /* led1 = yellow */
  164 + else if ((blinker & 1) && sc->rcv_count) {
  165 + leds = 0; /* led1 = off */
  166 + sc->rcv_count = 0;
  167 + } else
  168 + leds = 1; /* led1 = green */
  169 + cpld_write(sc, SBE_2T3E3_CPLD_REG_LEDR, leds);
  170 + sc->leds = leds;
  171 +}
drivers/staging/sbe-2t3e3/maps.c
  1 +/*
  2 + * SBE 2T3E3 synchronous serial card driver for Linux
  3 + *
  4 + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of version 2 of the GNU General Public License
  8 + * as published by the Free Software Foundation.
  9 + *
  10 + * This code is based on a driver written by SBE Inc.
  11 + */
  12 +
  13 +#include <linux/kernel.h>
  14 +#include "2t3e3.h"
  15 +
  16 +const u32 cpld_reg_map[][2] =
  17 +{
  18 + { 0x0000, 0x0080 }, /* 0 - Port Control Register A (PCRA) */
  19 + { 0x0004, 0x0084 }, /* 1 - Port Control Register B (PCRB) */
  20 + { 0x0008, 0x0088 }, /* 2 - LCV Count Register (PLCR) */
  21 + { 0x000c, 0x008c }, /* 3 - LCV Threshold register (PLTR) */
  22 + { 0x0010, 0x0090 }, /* 4 - Payload Fill Register (PPFR) */
  23 + { 0x0200, 0x0200 }, /* 5 - Board ID / FPGA Programming Status Register */
  24 + { 0x0204, 0x0204 }, /* 6 - FPGA Version Register */
  25 + { 0x0800, 0x1000 }, /* 7 - Framer Registers Base Address */
  26 + { 0x2000, 0x2000 }, /* 8 - Serial Chip Select Register */
  27 + { 0x2004, 0x2004 }, /* 9 - Static Reset Register */
  28 + { 0x2008, 0x2008 }, /* 10 - Pulse Reset Register */
  29 + { 0x200c, 0x200c }, /* 11 - FPGA Reconfiguration Register */
  30 + { 0x2010, 0x2014 }, /* 12 - LED Register (LEDR) */
  31 + { 0x2018, 0x201c }, /* 13 - LIU Control and Status Register (PISCR) */
  32 + { 0x2020, 0x2024 }, /* 14 - Interrupt Enable Register (PIER) */
  33 + { 0x0068, 0x00e8 }, /* 15 - Port Control Register C (PCRC) */
  34 + { 0x006c, 0x00ec }, /* 16 - Port Bandwidth Start (PBWF) */
  35 + { 0x0070, 0x00f0 }, /* 17 - Port Bandwidth Stop (PBWL) */
  36 +};
  37 +
  38 +const u32 cpld_val_map[][2] =
  39 +{
  40 + { 0x01, 0x02 }, /* LIU1 / LIU2 select for Serial Chip Select */
  41 + { 0x04, 0x08 }, /* DAC1 / DAC2 select for Serial Chip Select */
  42 + { 0x00, 0x04 }, /* LOOP1 / LOOP2 - select of loop timing source */
  43 + { 0x01, 0x02 } /* PORT1 / PORT2 - select LIU and Framer for reset */
  44 +};
  45 +
  46 +const u32 t3e3_framer_reg_map[] = {
  47 + 0x00, /* 0 - OPERATING_MODE */
  48 + 0x01, /* 1 - IO_CONTROL */
  49 + 0x04, /* 2 - BLOCK_INTERRUPT_ENABLE */
  50 + 0x05, /* 3 - BLOCK_INTERRUPT_STATUS */
  51 + 0x10, /* 4 - T3_RX_CONFIGURATION_STATUS, E3_RX_CONFIGURATION_STATUS_1 */
  52 + 0x11, /* 5 - T3_RX_STATUS, E3_RX_CONFIGURATION_STATUS_2 */
  53 + 0x12, /* 6 - T3_RX_INTERRUPT_ENABLE, E3_RX_INTERRUPT_ENABLE_1 */
  54 + 0x13, /* 7 - T3_RX_INTERRUPT_STATUS, E3_RX_INTERRUPT_ENABLE_2 */
  55 + 0x14, /* 8 - T3_RX_SYNC_DETECT_ENABLE, E3_RX_INTERRUPT_STATUS_1 */
  56 + 0x15, /* 9 - E3_RX_INTERRUPT_STATUS_2 */
  57 + 0x16, /* 10 - T3_RX_FEAC */
  58 + 0x17, /* 11 - T3_RX_FEAC_INTERRUPT_ENABLE_STATUS */
  59 + 0x18, /* 12 - T3_RX_LAPD_CONTROL, E3_RX_LAPD_CONTROL */
  60 + 0x19, /* 13 - T3_RX_LAPD_STATUS, E3_RX_LAPD_STATUS */
  61 + 0x1a, /* 14 - E3_RX_NR_BYTE, E3_RX_SERVICE_BITS */
  62 + 0x1b, /* 15 - E3_RX_GC_BYTE */
  63 + 0x30, /* 16 - T3_TX_CONFIGURATION, E3_TX_CONFIGURATION */
  64 + 0x31, /* 17 - T3_TX_FEAC_CONFIGURATION_STATUS */
  65 + 0x32, /* 18 - T3_TX_FEAC */
  66 + 0x33, /* 19 - T3_TX_LAPD_CONFIGURATION, E3_TX_LAPD_CONFIGURATION */
  67 + 0x34, /* 20 - T3_TX_LAPD_STATUS, E3_TX_LAPD_STATUS_INTERRUPT */
  68 + 0x35, /* 21 - T3_TX_MBIT_MASK, E3_TX_GC_BYTE, E3_TX_SERVICE_BITS */
  69 + 0x36, /* 22 - T3_TX_FBIT_MASK, E3_TX_MA_BYTE */
  70 + 0x37, /* 23 - T3_TX_FBIT_MASK_2, E3_TX_NR_BYTE */
  71 + 0x38, /* 24 - T3_TX_FBIT_MASK_3 */
  72 + 0x48, /* 25 - E3_TX_FA1_ERROR_MASK, E3_TX_FAS_ERROR_MASK_UPPER */
  73 + 0x49, /* 26 - E3_TX_FA2_ERROR_MASK, E3_TX_FAS_ERROR_MASK_LOWER */
  74 + 0x4a, /* 27 - E3_TX_BIP8_MASK, E3_TX_BIP4_MASK */
  75 + 0x50, /* 28 - PMON_LCV_EVENT_COUNT_MSB */
  76 + 0x51, /* 29 - PMON_LCV_EVENT_COUNT_LSB */
  77 + 0x52, /* 30 - PMON_FRAMING_BIT_ERROR_EVENT_COUNT_MSB */
  78 + 0x53, /* 31 - PMON_FRAMING_BIT_ERROR_EVENT_COUNT_LSB */
  79 + 0x54, /* 32 - PMON_PARITY_ERROR_EVENT_COUNT_MSB */
  80 + 0x55, /* 33 - PMON_PARITY_ERROR_EVENT_COUNT_LSB */
  81 + 0x56, /* 34 - PMON_FEBE_EVENT_COUNT_MSB */
  82 + 0x57, /* 35 - PMON_FEBE_EVENT_COUNT_LSB */
  83 + 0x58, /* 36 - PMON_CP_BIT_ERROR_EVENT_COUNT_MSB */
  84 + 0x59, /* 37 - PMON_CP_BIT_ERROR_EVENT_COUNT_LSB */
  85 + 0x6c, /* 38 - PMON_HOLDING_REGISTER */
  86 + 0x6d, /* 39 - ONE_SECOND_ERROR_STATUS */
  87 + 0x6e, /* 40 - LCV_ONE_SECOND_ACCUMULATOR_MSB */
  88 + 0x6f, /* 41 - LCV_ONE_SECOND_ACCUMULATOR_LSB */
  89 + 0x70, /* 42 - FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_MSB */
  90 + 0x71, /* 43 - FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_LSB */
  91 + 0x72, /* 44 - FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_MSB */
  92 + 0x73, /* 45 - FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_LSB */
  93 + 0x80, /* 46 - LINE_INTERFACE_DRIVE */
  94 + 0x81 /* 47 - LINE_INTERFACE_SCAN */
  95 +};
  96 +
  97 +const u32 t3e3_liu_reg_map[] =
  98 +{
  99 + 0x00, /* REG0 */
  100 + 0x01, /* REG1 */
  101 + 0x02, /* REG2 */
  102 + 0x03, /* REG3 */
  103 + 0x04 /* REG4 */
  104 +};
drivers/staging/sbe-2t3e3/module.c
  1 +/*
  2 + * SBE 2T3E3 synchronous serial card driver for Linux
  3 + *
  4 + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of version 2 of the GNU General Public License
  8 + * as published by the Free Software Foundation.
  9 + *
  10 + * This code is based on a driver written by SBE Inc.
  11 + */
  12 +
  13 +#include <linux/module.h>
  14 +#include <linux/slab.h>
  15 +#include <linux/delay.h>
  16 +#include <linux/netdevice.h>
  17 +#include <linux/pci.h>
  18 +#include <linux/hdlc.h>
  19 +#include <linux/if_arp.h>
  20 +#include <linux/interrupt.h>
  21 +#include "2t3e3.h"
  22 +
  23 +static void check_leds(unsigned long arg)
  24 +{
  25 + struct card *card = (struct card *)arg;
  26 + struct channel *channel0 = &card->channels[0];
  27 + static int blinker;
  28 +
  29 + update_led(channel0, ++blinker);
  30 + if (has_two_ports(channel0->pdev))
  31 + update_led(&card->channels[1], blinker);
  32 +
  33 + card->timer.expires = jiffies + HZ / 10;
  34 + add_timer(&card->timer);
  35 +}
  36 +
  37 +static void t3e3_remove_channel(struct channel *channel)
  38 +{
  39 + struct pci_dev *pdev = channel->pdev;
  40 + struct net_device *dev = channel->dev;
  41 +
  42 + /* system hangs if board asserts irq while module is unloaded */
  43 + cpld_stop_intr(channel);
  44 + free_irq(dev->irq, dev);
  45 + dc_drop_descriptor_list(channel);
  46 + unregister_hdlc_device(dev);
  47 + free_netdev(dev);
  48 + pci_release_regions(pdev);
  49 + pci_disable_device(pdev);
  50 + pci_set_drvdata(pdev, NULL);
  51 +}
  52 +
  53 +static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev *pdev, struct card *card)
  54 +{
  55 + struct net_device *dev;
  56 + unsigned int val;
  57 + int err;
  58 +
  59 + err = pci_enable_device(pdev);
  60 + if (err)
  61 + return err;
  62 +
  63 + err = pci_request_regions(pdev, "SBE 2T3E3");
  64 + if (err)
  65 + goto disable;
  66 +
  67 + dev = alloc_hdlcdev(channel);
  68 + if (!dev) {
  69 + printk(KERN_ERR "SBE 2T3E3" ": Out of memory\n");
  70 + goto free_regions;
  71 + }
  72 +
  73 + t3e3_sc_init(channel);
  74 + dev_to_priv(dev) = channel;
  75 +
  76 + channel->pdev = pdev;
  77 + channel->dev = dev;
  78 + channel->card = card;
  79 + channel->addr = pci_resource_start(pdev, 0);
  80 + if (pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P1)
  81 + channel->h.slot = 1;
  82 + else
  83 + channel->h.slot = 0;
  84 +
  85 + if (setup_device(dev, channel))
  86 + goto free_regions;
  87 +
  88 + pci_read_config_dword(channel->pdev, 0x40, &val); /* mask sleep mode */
  89 + pci_write_config_dword(channel->pdev, 0x40, val & 0x3FFFFFFF);
  90 +
  91 + pci_read_config_byte(channel->pdev, PCI_CACHE_LINE_SIZE, &channel->h.cache_size);
  92 + pci_read_config_dword(channel->pdev, PCI_COMMAND, &channel->h.command);
  93 + t3e3_init(channel);
  94 +
  95 + if (request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev)) {
  96 + printk(KERN_WARNING "%s: could not get irq: %d\n", dev->name, dev->irq);
  97 + goto free_regions;
  98 + }
  99 +
  100 + pci_set_drvdata(pdev, channel);
  101 + return 0;
  102 +
  103 +free_regions:
  104 + pci_release_regions(pdev);
  105 +disable:
  106 + pci_disable_device(pdev);
  107 + return err;
  108 +}
  109 +
  110 +static void __devexit t3e3_remove_card(struct pci_dev *pdev)
  111 +{
  112 + struct channel *channel0 = pci_get_drvdata(pdev);
  113 + struct card *card = channel0->card;
  114 +
  115 + del_timer(&card->timer);
  116 + if (has_two_ports(channel0->pdev)) {
  117 + t3e3_remove_channel(&card->channels[1]);
  118 + pci_dev_put(card->channels[1].pdev);
  119 + }
  120 + t3e3_remove_channel(channel0);
  121 + kfree(card);
  122 +}
  123 +
  124 +static int __devinit t3e3_init_card(struct pci_dev *pdev, const struct pci_device_id *ent)
  125 +{
  126 + /* pdev points to channel #0 */
  127 + struct pci_dev *pdev1 = NULL;
  128 + struct card *card;
  129 + int channels = 1, err;
  130 +
  131 + if (has_two_ports(pdev)) {
  132 + while ((pdev1 = pci_get_subsys(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
  133 + PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_2T3E3_P1,
  134 + pdev1)))
  135 + if (pdev1->bus == pdev->bus &&
  136 + pdev1->devfn == pdev->devfn + 8 /* next device on the same bus */)
  137 + break; /* found the second channel */
  138 +
  139 + if (!pdev1) {
  140 + printk(KERN_ERR "SBE 2T3E3" ": Can't find the second channel\n");
  141 + return -EFAULT;
  142 + }
  143 + channels = 2;
  144 + /* holds the reference for pdev1 */
  145 + }
  146 +
  147 + card = kzalloc(sizeof(struct card) + channels * sizeof(struct channel), GFP_KERNEL);
  148 + if (!card) {
  149 + printk(KERN_ERR "SBE 2T3E3" ": Out of memory\n");
  150 + return -ENOBUFS;
  151 + }
  152 +
  153 + spin_lock_init(&card->bootrom_lock);
  154 + card->bootrom_addr = pci_resource_start(pdev, 0);
  155 +
  156 + err = t3e3_init_channel(&card->channels[0], pdev, card);
  157 + if (err)
  158 + goto free_card;
  159 +
  160 + if (channels == 2) {
  161 + err = t3e3_init_channel(&card->channels[1], pdev1, card);
  162 + if (err) {
  163 + t3e3_remove_channel(&card->channels[0]);
  164 + goto free_card;
  165 + }
  166 + }
  167 +
  168 + /* start LED timer */
  169 + init_timer(&card->timer);
  170 + card->timer.function = check_leds;
  171 + card->timer.expires = jiffies + HZ / 10;
  172 + card->timer.data = (unsigned long)card;
  173 + add_timer(&card->timer);
  174 + return 0;
  175 +
  176 +free_card:
  177 + kfree(card);
  178 + return err;
  179 +}
  180 +
  181 +static struct pci_device_id t3e3_pci_tbl[] __devinitdata = {
  182 + { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
  183 + PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_T3E3, 0, 0, 0 },
  184 + { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
  185 + PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_2T3E3_P0, 0, 0, 0 },
  186 + /* channel 1 will be initialized after channel 0 */
  187 + { 0, }
  188 +};
  189 +
  190 +static struct pci_driver t3e3_pci_driver = {
  191 + .name = "SBE T3E3",
  192 + .id_table = t3e3_pci_tbl,
  193 + .probe = t3e3_init_card,
  194 + .remove = t3e3_remove_card,
  195 +};
  196 +
  197 +static int __init t3e3_init_module(void)
  198 +{
  199 + return pci_register_driver(&t3e3_pci_driver);
  200 +}
  201 +
  202 +static void __exit t3e3_cleanup_module(void)
  203 +{
  204 + pci_unregister_driver(&t3e3_pci_driver);
  205 +}
  206 +
  207 +module_init(t3e3_init_module);
  208 +module_exit(t3e3_cleanup_module);
  209 +MODULE_LICENSE("GPL");
  210 +MODULE_DEVICE_TABLE(pci, t3e3_pci_tbl);
drivers/staging/sbe-2t3e3/netdev.c
  1 +/*
  2 + * SBE 2T3E3 synchronous serial card driver for Linux
  3 + *
  4 + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of version 2 of the GNU General Public License
  8 + * as published by the Free Software Foundation.
  9 + *
  10 + * This code is based on a driver written by SBE Inc.
  11 + */
  12 +
  13 +#include <linux/capability.h>
  14 +#include <linux/module.h>
  15 +#include <linux/slab.h>
  16 +#include <linux/delay.h>
  17 +#include <linux/netdevice.h>
  18 +#include <linux/pci.h>
  19 +#include <linux/hdlc.h>
  20 +#include <linux/if_arp.h>
  21 +#include <linux/interrupt.h>
  22 +#include "2t3e3.h"
  23 +
  24 +int t3e3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  25 +{
  26 + struct channel *sc = dev_to_priv(dev);
  27 + int cmd_2t3e3, len, rlen;
  28 + t3e3_param_t param;
  29 + t3e3_resp_t resp;
  30 + void *data = ifr->ifr_data + sizeof(cmd_2t3e3) + sizeof(len);
  31 +
  32 + if (cmd == SIOCWANDEV)
  33 + return hdlc_ioctl(dev, ifr, cmd);
  34 + if (!capable(CAP_SYS_ADMIN))
  35 + return -EPERM;
  36 + if (cmd != SIOCDEVPRIVATE + 15)
  37 + return -EINVAL;
  38 +
  39 + if (copy_from_user(&cmd_2t3e3, ifr->ifr_data, sizeof(cmd_2t3e3)))
  40 + return -EFAULT;
  41 + if (copy_from_user(&len, ifr->ifr_data + sizeof(cmd_2t3e3), sizeof(len)))
  42 + return -EFAULT;
  43 +
  44 + if (len > sizeof(param))
  45 + return -EFAULT;
  46 +
  47 + if (len)
  48 + if (copy_from_user(&param, data, len))
  49 + return -EFAULT;
  50 +
  51 + t3e3_if_config(sc, cmd_2t3e3, (char *)&param, &resp, &rlen);
  52 +
  53 + if (rlen)
  54 + if (copy_to_user(data, &resp, rlen))
  55 + return -EFAULT;
  56 +
  57 + return 0;
  58 +}
  59 +
  60 +static struct net_device_stats* t3e3_get_stats(struct net_device *dev)
  61 +{
  62 + struct net_device_stats *nstats = &dev->stats;
  63 + struct channel *sc = dev_to_priv(dev);
  64 + t3e3_stats_t *stats = &sc->s;
  65 +
  66 + memset(nstats, 0, sizeof(struct net_device_stats));
  67 + nstats->rx_packets = stats->in_packets;
  68 + nstats->tx_packets = stats->out_packets;
  69 + nstats->rx_bytes = stats->in_bytes;
  70 + nstats->tx_bytes = stats->out_bytes;
  71 +
  72 + nstats->rx_errors = stats->in_errors;
  73 + nstats->tx_errors = stats->out_errors;
  74 + nstats->rx_crc_errors = stats->in_error_crc;
  75 +
  76 +
  77 + nstats->rx_dropped = stats->in_dropped;
  78 + nstats->tx_dropped = stats->out_dropped;
  79 + nstats->tx_carrier_errors = stats->out_error_lost_carr +
  80 + stats->out_error_no_carr;
  81 +
  82 + return nstats;
  83 +}
  84 +
  85 +int t3e3_open(struct net_device *dev)
  86 +{
  87 + struct channel *sc = dev_to_priv(dev);
  88 + int ret = hdlc_open(dev);
  89 +
  90 + if (ret)
  91 + return ret;
  92 +
  93 + sc->r.flags |= SBE_2T3E3_FLAG_NETWORK_UP;
  94 + dc_start(dev_to_priv(dev));
  95 + netif_start_queue(dev);
  96 + try_module_get(THIS_MODULE);
  97 + return 0;
  98 +}
  99 +
  100 +int t3e3_close(struct net_device *dev)
  101 +{
  102 + struct channel *sc = dev_to_priv(dev);
  103 + hdlc_close(dev);
  104 + netif_stop_queue(dev);
  105 + dc_stop(sc);
  106 + sc->r.flags &= ~SBE_2T3E3_FLAG_NETWORK_UP;
  107 + module_put(THIS_MODULE);
  108 + return 0;
  109 +}
  110 +
  111 +static int t3e3_attach(struct net_device *dev, unsigned short foo1,
  112 + unsigned short foo2)
  113 +{
  114 + return 0;
  115 +}
  116 +
  117 +static const struct net_device_ops t3e3_ops = {
  118 + .ndo_open = t3e3_open,
  119 + .ndo_stop = t3e3_close,
  120 + .ndo_change_mtu = hdlc_change_mtu,
  121 + .ndo_start_xmit = hdlc_start_xmit,
  122 + .ndo_do_ioctl = t3e3_ioctl,
  123 + .ndo_get_stats = t3e3_get_stats,
  124 +};
  125 +
  126 +int setup_device(struct net_device *dev, struct channel *sc)
  127 +{
  128 + hdlc_device *hdlc = dev_to_hdlc(dev);
  129 + int retval;
  130 +
  131 + dev->base_addr = pci_resource_start(sc->pdev, 0);
  132 + dev->irq = sc->pdev->irq;
  133 + dev->netdev_ops = &t3e3_ops;
  134 + dev->tx_queue_len = 100;
  135 + hdlc->xmit = t3e3_if_start_xmit;
  136 + hdlc->attach = t3e3_attach;
  137 + if ((retval = register_hdlc_device(dev))) {
  138 + dev_err(&sc->pdev->dev, "error registering HDLC device\n");
  139 + return retval;
  140 + }
  141 + return 0;
  142 +}