Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net v2 3/8] xsk: fix use-after-free of xs->skb in xsk_build_skb() free_err path
From: Jason Xing @ 2026-04-21  0:01 UTC (permalink / raw)
  To: Stanislav Fomichev; +Cc: bpf, netdev, Jason Xing
In-Reply-To: <eef5d62d475b0aeb93f6f84585f36972.sdf.kernel@gmail.com>

On Tue, Apr 21, 2026 at 3:34 AM Stanislav Fomichev <sdf.kernel@gmail.com> wrote:
>
> > From: Jason Xing <kernelxing@tencent.com>
> >
> > When xsk_build_skb() processes multi-buffer packets in copy mode, the
> > first descriptor stores data into the skb linear area without adding
> > any frags, so nr_frags stays at 0. The caller then sets xs->skb = skb
> > to accumulate subsequent descriptors.
> >
> > If a continuation descriptor fails (e.g. alloc_page returns NULL with
> > -EAGAIN), we jump to free_err where the condition:
> >
> >   if (skb && !skb_shinfo(skb)->nr_frags)
> >       kfree_skb(skb);
> >
> > evaluates to true because nr_frags is still 0 (the first descriptor
> > used the linear area, not frags). This frees the skb while xs->skb
> > still points to it, creating a dangling pointer. On the next transmit
> > attempt or socket close, xs->skb is dereferenced, causing a
> > use-after-free or double-free.
> >
> > Fix by adding a !xs->skb check to the condition, ensuring we only free
> > skbs that were freshly allocated in this call (xs->skb is NULL) and
> > never free an in-progress multi-buffer skb that the caller still
> > references.
> >
> > Closes: https://lore.kernel.org/all/20260415082654.21026-4-kerneljasonxing@gmail.com/
> > Fixes: 6b9c129c2f93 ("xsk: remove @first_frag from xsk_build_skb()")
> > Signed-off-by: Jason Xing <kernelxing@tencent.com>
> > ---
> >  net/xdp/xsk.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
> > index 6521604f8d42..4fdd1a45a9bd 100644
> > --- a/net/xdp/xsk.c
> > +++ b/net/xdp/xsk.c
> > @@ -889,7 +889,7 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
> >       return skb;
> >
> >  free_err:
> > -     if (skb && !skb_shinfo(skb)->nr_frags)
> > +     if (skb && !xs->skb && !skb_shinfo(skb)->nr_frags)
> >               kfree_skb(skb);
> >
> >       if (err == -EOVERFLOW) {
> > --
> > 2.41.3
>
> Now "!skb_shinfo(skb)->nr_frags" feels redundant? It's either
> "skb && !xs->skb" and we own the kfree. or "xs->skb != NULL" and we
> want xsk_drop_skb? Or am I missing something?

Your feeling about being redundant is right. I'm removing it now:)

At this stage, the job of this if statement is to find out the first
skb, so !xs->skb is a clear indicator as you said.

Thanks,
Jason

^ permalink raw reply

* Re: [PATCH net v2 8/8] xsk: fix u64 descriptor address truncation on 32-bit architectures
From: Jason Xing @ 2026-04-21  0:49 UTC (permalink / raw)
  To: Stanislav Fomichev
  Cc: davem, edumazet, kuba, pabeni, bjorn, magnus.karlsson,
	maciej.fijalkowski, jonathan.lemon, sdf, ast, daniel, hawk,
	john.fastabend, bpf, netdev, Jason Xing
In-Reply-To: <aeaCzchKwsp_LWyA@devvm17672.vll0.facebook.com>

On Tue, Apr 21, 2026 at 3:49 AM Stanislav Fomichev <sdf.kernel@gmail.com> wrote:
>
> On 04/20, Jason Xing wrote:
> > From: Jason Xing <kernelxing@tencent.com>
> >
> > In copy mode TX, xsk_skb_destructor_set_addr() stores the 64-bit
> > descriptor address into skb_shinfo(skb)->destructor_arg (void *) via a
> > uintptr_t cast:
> >
> >     skb_shinfo(skb)->destructor_arg = (void *)((uintptr_t)addr | 0x1UL);
> >
> > On 32-bit architectures uintptr_t is 32 bits, so the upper 32 bits of
> > the descriptor address are silently dropped. In XDP_ZEROCOPY unaligned
> > mode the chunk offset is encoded in bits 48-63 of the descriptor
> > address (XSK_UNALIGNED_BUF_OFFSET_SHIFT = 48), meaning the offset is
> > lost entirely. The completion queue then returns a truncated address to
> > userspace, making buffer recycling impossible.
> >
> > Fix this by handling the 32-bit case directly in
> > xsk_skb_destructor_set_addr(): when !CONFIG_64BIT, allocate an xsk_addrs
> > struct (the same path already used for multi-descriptor SKBs) to store
> > the full u64 address.
>
> Is it easier to make XSK `depends on 64BIT` to avoid dealing with that? Does

Of course, it would be super easy. Actually the initial version looks
like this. One line of coder is simply enough.

> anybody seriously run af_xdp on 32 bit systems?

But my worry as you guess is if there exists a 32 bit system? I doubt
it. That's why I put some effort into adding the compatibility code to
cover the case. Good news is that it doesn't add any side effects of
the 64 bit system since they are protected under IS_ENABLED condition.

Thanks,
Jason

^ permalink raw reply

* [PATCH net 1/4] ice: fix timestamp interrupt configuration for E825C
From: Jacob Keller @ 2026-04-21  0:51 UTC (permalink / raw)
  To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni
  Cc: netdev, Jacob Keller, Grzegorz Nitka, Aleksandr Loktionov,
	Petr Oros, Sunitha Mekala
In-Reply-To: <20260420-jk-iwl-net-2026-04-20-ptp-e825c-phy-interrupt-fixes-v1-0-bc2240f42251@intel.com>

From: Grzegorz Nitka <grzegorz.nitka@intel.com>

The E825C ice_phy_cfg_intr_eth56g() function is responsible for programming
the PHY interrupt for a given port. This function writes to the
PHY_REG_TS_INT_CONFIG register of the port. The register is responsible for
configuring whether the port interrupt logic is enabled, as well as
programming the threshold of waiting timestamps that will trigger an
interrupt from this port.

This threshold value must not be programmed to zero while the interrupt is
enabled. Doing so puts the port in a misconfigured state where the PHY
timestamp interrupt for the quad of connected ports will become stuck.

This occurs, because a threshold of zero results in the timestamp interrupt
status for the port becoming stuck high. The four ports in the connected
quad have their timestamp status indicators muxed together. A new interrupt
cannot be generated until the timestamp status indicators return low for
all four ports.

Normally, the timestamp status for a port will clear once there are fewer
timestamps in that ports timestamp memory bank than the threshold. A
threshold of zero makes this impossible, so the timestamp status for the
port does not clear.

The ice driver never intentionally programs the threshold to zero, indeed
the driver always programs it to a value of 1, intending to get an
interrupt immediately as soon as even a single packet is waiting for a
timestamp.

However, there is a subtle flaw in the programming logic in the
ice_phy_cfg_intr_eth56g() function. Due to the way that the hardware
handles enabling the PHY interrupt. If the threshold value is modified at
the same time as the interrupt is enabled, the HW PHY state machine might
enable the interrupt before the new threshold value is actually updated.
This leaves a potential race condition caused by the hardware logic where
a PHY timestamp interrupt might be triggered before the non-zero threshold
is written, resulting in the PHY timestamp logic becoming stuck.

Once the PHY timestamp status is stuck high, it will remain stuck even
after attempting to reprogram the PHY block by changing its threshold or
disabling the interrupt. Even a typical PF or CORE reset will not reset the
particular block of the PHY that becomes stuck. Even a warm power cycle is
not guaranteed to cause the PHY block to reset, and a cold power cycle is
required.

Prevent this by always writing the PHY_REG_TS_INT_CONFIG in two stages.
First write the threshold value with the interrupt disabled, and only write
the enable bit after the threshold has been programmed. When disabling the
interrupt, leave the threshold unchanged. Additionally, re-read the
register after writing it to guarantee that the write to the PHY has been
flushed upon exit of the function.

While we're modifying this function implementation, explicitly reject
programming a threshold of 0 when enabling the interrupt. No caller does
this today, but the consequences of doing so are significant. An explicit
rejection in the code makes this clear.

Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products")
Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Petr Oros <poros@redhat.com>
Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
 drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 36 +++++++++++++++++++++++++----
 1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
index 5a5c511ccbb6..7f2f7440e705 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
@@ -1847,6 +1847,8 @@ static int ice_phy_cfg_mac_eth56g(struct ice_hw *hw, u8 port)
  * @ena: enable or disable interrupt
  * @threshold: interrupt threshold
  *
+ * The threshold cannot be 0 while the interrupt is enabled.
+ *
  * Configure TX timestamp interrupt for the specified port
  *
  * Return:
@@ -1858,19 +1860,45 @@ int ice_phy_cfg_intr_eth56g(struct ice_hw *hw, u8 port, bool ena, u8 threshold)
 	int err;
 	u32 val;
 
+	if (ena && !threshold)
+		return -EINVAL;
+
 	err = ice_read_ptp_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG, &val);
 	if (err)
 		return err;
 
+	val &= ~PHY_TS_INT_CONFIG_ENA_M;
 	if (ena) {
-		val |= PHY_TS_INT_CONFIG_ENA_M;
 		val &= ~PHY_TS_INT_CONFIG_THRESHOLD_M;
 		val |= FIELD_PREP(PHY_TS_INT_CONFIG_THRESHOLD_M, threshold);
-	} else {
-		val &= ~PHY_TS_INT_CONFIG_ENA_M;
+		err = ice_write_ptp_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG,
+					       val);
+		if (err) {
+			ice_debug(hw, ICE_DBG_PTP,
+				  "Failed to update 'threshold' PHY_REG_TS_INT_CONFIG port=%u ena=%u threshold=%u\n",
+				  port, !!ena, threshold);
+			return err;
+		}
+		val |= PHY_TS_INT_CONFIG_ENA_M;
 	}
 
-	return ice_write_ptp_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG, val);
+	err = ice_write_ptp_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG, val);
+	if (err) {
+		ice_debug(hw, ICE_DBG_PTP,
+			  "Failed to update 'ena' PHY_REG_TS_INT_CONFIG port=%u ena=%u threshold=%u\n",
+			  port, !!ena, threshold);
+		return err;
+	}
+
+	err = ice_read_ptp_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG, &val);
+	if (err) {
+		ice_debug(hw, ICE_DBG_PTP,
+			  "Failed to read PHY_REG_TS_INT_CONFIG port=%u ena=%u threshold=%u\n",
+			  port, !!ena, threshold);
+		return err;
+	}
+
+	return 0;
 }
 
 /**

-- 
2.54.0.rc2.531.gaf818d63126a


^ permalink raw reply related

* [PATCH net 2/4] ice: perform PHY soft reset for E825C ports at initialization
From: Jacob Keller @ 2026-04-21  0:51 UTC (permalink / raw)
  To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni
  Cc: netdev, Jacob Keller, Grzegorz Nitka, Timothy Miskell,
	Aleksandr Loktionov, Petr Oros, Sunitha Mekala
In-Reply-To: <20260420-jk-iwl-net-2026-04-20-ptp-e825c-phy-interrupt-fixes-v1-0-bc2240f42251@intel.com>

From: Grzegorz Nitka <grzegorz.nitka@intel.com>

In some cases the PHY timestamp block of the E825C can become stuck. This
is known to occur if the software writes 0 to the Tx timestamp threshold,
and with older versions of the ice driver the threshold configuration is
buggy and can race in such that hardware briefly operates with a zero
threshold enabled. There are no other known ways to trigger this behavior,
but once it occurs, the hardware is not recovered by normal reset, a driver
reload, or even a warm power cycle of the system. A cold power cycle is
sufficient to recover hardware, but this is extremely invasive and can
result in significant downtime on customer deployments.

The PHY for each port has a timestamping block which has its own reset
functionality accessible by programming the PHY_REG_GLOBAL register.
Writing to the PHY_REG_GLOBAL_SOFT_RESET_BIT triggers the hardware to
perform a complete reset of the timestamping block of the PHY. This
includes clearing the timestamp status for the port, clearing all
outstanding timestamps in the memory bank, and resetting the PHY timer.

The new ice_ptp_phy_soft_reset_eth56g() function toggles the
PHY_REG_GLOBAL soft reset bit with the required delays, ensuring the
PHY is properly reinitialized without requiring a full device reset.
The sequence clears the reset bit, asserts it, then clears it again,
with short waits between transitions to allow hardware stabilization.

Call this function in the new ice_ptp_init_phc_e825c(), implementing the
E825C device specific variant of the ice_ptp_init_phc(). Note that if
ice_ptp_init_phc() fails, PTP functionality may be disabled, but the driver
will still load to allow basic functionality to continue.

This causes the clock owning PF driver to perform a PHY soft reset for
every port during initialization. This ensures the driver begins life in a
known functional state regardless of how it was previously programmed.

This ensures that we properly reconfigure the hardware after a device reset
or when loading the driver, even if it was previously misconfigured with an
out-of-date or modified driver.

Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products")
Signed-off-by: Timothy Miskell <timothy.miskell@intel.com>
Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Petr Oros <poros@redhat.com>
Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
 drivers/net/ethernet/intel/ice/ice_ptp_hw.h |  4 ++
 drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 90 ++++++++++++++++++++++++++++-
 2 files changed, 93 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
index 9bfd3e79c580..ac4611291052 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
@@ -374,6 +374,7 @@ int ice_stop_phy_timer_eth56g(struct ice_hw *hw, u8 port, bool soft_reset);
 int ice_start_phy_timer_eth56g(struct ice_hw *hw, u8 port);
 int ice_phy_cfg_intr_eth56g(struct ice_hw *hw, u8 port, bool ena, u8 threshold);
 int ice_phy_cfg_ptp_1step_eth56g(struct ice_hw *hw, u8 port);
+int ice_ptp_phy_soft_reset_eth56g(struct ice_hw *hw, u8 port);
 
 #define ICE_ETH56G_NOMINAL_INCVAL	0x140000000ULL
 #define ICE_ETH56G_NOMINAL_PCS_REF_TUS	0x100000000ULL
@@ -676,6 +677,9 @@ static inline u64 ice_get_base_incval(struct ice_hw *hw)
 #define ICE_P0_GNSS_PRSNT_N	BIT(4)
 
 /* ETH56G PHY register addresses */
+#define PHY_REG_GLOBAL			0x0
+#define PHY_REG_GLOBAL_SOFT_RESET_M	BIT(11)
+
 /* Timestamp PHY incval registers */
 #define PHY_REG_TIMETUS_L		0x8
 #define PHY_REG_TIMETUS_U		0xC
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
index 7f2f7440e705..d4c2bb084255 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
@@ -377,6 +377,31 @@ static void ice_ptp_cfg_sync_delay(const struct ice_hw *hw, u32 delay)
  * The following functions operate on devices with the ETH 56G PHY.
  */
 
+/**
+ * ice_ptp_init_phc_e825c - Perform E825C specific PHC initialization
+ * @hw: pointer to HW struct
+ *
+ * Perform E825C-specific PTP hardware clock initialization steps.
+ *
+ * Return: 0 on success, or a negative error value on failure.
+ */
+static int ice_ptp_init_phc_e825c(struct ice_hw *hw)
+{
+	int err;
+
+	/* Soft reset all ports, to ensure everything is at a clean state */
+	for (int port = 0; port < hw->ptp.num_lports; port++) {
+		err = ice_ptp_phy_soft_reset_eth56g(hw, port);
+		if (err) {
+			ice_debug(hw, ICE_DBG_PTP, "Failed to soft reset port %d, err %d\n",
+				  port, err);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
 /**
  * ice_ptp_get_dest_dev_e825 - get destination PHY for given port number
  * @hw: pointer to the HW struct
@@ -2179,6 +2204,69 @@ int ice_ptp_read_tx_hwtstamp_status_eth56g(struct ice_hw *hw, u32 *ts_status)
 	return 0;
 }
 
+/**
+ * ice_ptp_phy_soft_reset_eth56g - Perform a PHY soft reset on ETH56G
+ * @hw: pointer to the HW structure
+ * @port: PHY port number
+ *
+ * Trigger a soft reset of the ETH56G PHY by toggling the soft reset
+ * bit in the PHY global register. The reset sequence consists of:
+ *   1. Clearing the soft reset bit
+ *   2. Asserting the soft reset bit
+ *   3. Clearing the soft reset bit again
+ *
+ * Short delays are inserted between each step to allow the hardware
+ * to settle. This provides a controlled way to reinitialize the PHY
+ * without requiring a full device reset.
+ *
+ * Return: 0 on success, or a negative error code on failure when
+ *         reading or writing the PHY register.
+ */
+int ice_ptp_phy_soft_reset_eth56g(struct ice_hw *hw, u8 port)
+{
+	u32 global_val;
+	int err;
+
+	err = ice_read_ptp_reg_eth56g(hw, port, PHY_REG_GLOBAL, &global_val);
+	if (err) {
+		ice_debug(hw, ICE_DBG_PTP, "Failed to read PHY_REG_GLOBAL for port %d, err %d\n",
+			  port, err);
+		return err;
+	}
+
+	global_val &= ~PHY_REG_GLOBAL_SOFT_RESET_M;
+	ice_debug(hw, ICE_DBG_PTP, "Clearing soft reset bit for port %d, val: 0x%x\n",
+		  port, global_val);
+	err = ice_write_ptp_reg_eth56g(hw, port, PHY_REG_GLOBAL, global_val);
+	if (err) {
+		ice_debug(hw, ICE_DBG_PTP, "Failed to write PHY_REG_GLOBAL for port %d, err %d\n",
+			  port, err);
+		return err;
+	}
+
+	usleep_range(5000, 6000);
+
+	global_val |= PHY_REG_GLOBAL_SOFT_RESET_M;
+	ice_debug(hw, ICE_DBG_PTP, "Set soft reset bit for port %d, val: 0x%x\n",
+		  port, global_val);
+	err = ice_write_ptp_reg_eth56g(hw, port, PHY_REG_GLOBAL, global_val);
+	if (err) {
+		ice_debug(hw, ICE_DBG_PTP, "Failed to write PHY_REG_GLOBAL for port %d, err %d\n",
+			  port, err);
+		return err;
+	}
+	usleep_range(5000, 6000);
+
+	global_val &= ~PHY_REG_GLOBAL_SOFT_RESET_M;
+	ice_debug(hw, ICE_DBG_PTP, "Clear soft reset bit for port %d, val: 0x%x\n",
+		  port, global_val);
+	err = ice_write_ptp_reg_eth56g(hw, port, PHY_REG_GLOBAL, global_val);
+	if (err)
+		ice_debug(hw, ICE_DBG_PTP, "Failed to write PHY_REG_GLOBAL for port %d, err %d\n",
+			  port, err);
+	return err;
+}
+
 /**
  * ice_get_phy_tx_tstamp_ready_eth56g - Read the Tx memory status register
  * @hw: pointer to the HW struct
@@ -5592,7 +5680,7 @@ int ice_ptp_init_phc(struct ice_hw *hw)
 	case ICE_MAC_GENERIC:
 		return ice_ptp_init_phc_e82x(hw);
 	case ICE_MAC_GENERIC_3K_E825:
-		return 0;
+		return ice_ptp_init_phc_e825c(hw);
 	default:
 		return -EOPNOTSUPP;
 	}

-- 
2.54.0.rc2.531.gaf818d63126a


^ permalink raw reply related

* [PATCH net 3/4] ice: fix ready bitmap check for non-E822 devices
From: Jacob Keller @ 2026-04-21  0:51 UTC (permalink / raw)
  To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni
  Cc: netdev, Jacob Keller, Aleksandr Loktionov, Petr Oros,
	Sunitha Mekala
In-Reply-To: <20260420-jk-iwl-net-2026-04-20-ptp-e825c-phy-interrupt-fixes-v1-0-bc2240f42251@intel.com>

The E800 hardware (apart from E810) has a ready bitmap for the PHY
indicating which timestamp slots currently have an outstanding timestamp
waiting to be read by software.

This bitmap is checked in multiple places using the
ice_get_phy_tx_tstamp_ready():

 * ice_ptp_process_tx_tstamp() calls it to determine which timestamps to
   attempt reading from the PHY
 * ice_ptp_tx_tstamps_pending() calls it in a loop at the end of the
   miscellaneous IRQ to check if new timestamps came in while the interrupt
   handler was executing.
 * ice_ptp_maybe_trigger_tx_interrupt() calls it in the auxiliary work task
   to trigger a software interrupt in the event that the hardware logic
   gets stuck.

For E82X devices, multiple PHYs share the same block, and the parameter
passed to the ready bitmap is a block number associated with the given
port. For E825-C devices, the PHYs have their own independent blocks and do
not share, so the parameter passed needs to be the port number. For E810
devices, the ice_get_phy_tx_tstamp_ready() always returns all 1s regardless
of what port, since this hardware does not have a ready bitmap. Finally,
for E830 devices, each PF has its own ready bitmap accessible via register,
and the block parameter is unused.

The first call correctly uses the Tx timestamp tracker block parameter to
check the appropriate timestamp block. This works because the tracker is
setup correctly for each timestamp device type.

The second two callers behave incorrectly for all device types other than
the older E822 devices. They both iterate in a loop using
ICE_GET_QUAD_NUM() which is a macro only used by E822 devices. This logic
is incorrect for devices other than the E822 devices.

For E810 the calls would always return true, causing E810 devices to always
attempt to trigger a software interrupt even when they have no reason to.
For E830, this results in duplicate work as the ready bitmap is checked
once per number of quads. Finally, for E825-C, this results in the pending
checks failing to detect timestamps on ports other than the first two.

Fix this by introducing a new hardware API function to ice_ptp_hw.c,
ice_check_phy_tx_tstamp_ready(). This function will check if any timestamps
are available and returns a positive value if any timestamps are pending.
For E810, the function always returns false, so that the re-trigger checks
never happen. For E830, check the ready bitmap just once. For E82x
hardware, check each quad. Finally, for E825-C, check every port.

The interface function returns an integer to enable reporting of error code
if the driver is unable read the ready bitmap. This enables callers to
handle this case properly. The previous implementation assumed that
timestamps are available if they failed to read the bitmap. This is
problematic as it could lead to continuous software IRQ triggering if the
PHY timestamp registers somehow become inaccessible.

This change is especially important for E825-C devices, as the missing
checks could leave a window open where a new timestamp could arrive while
the existing timestamps aren't completed. As a result, the hardware
threshold logic would not trigger a new interrupt. Without the check, the
timestamp is left unhandled, and new timestamps will not cause an interrupt
again until the timestamp is handled. Since both the interrupt check and
the backup check in the auxiliary task do not function properly, the device
may have Tx timestamps permanently stuck failing on a given port.

The faulty checks originate from commit d938a8cca88a ("ice: Auxbus devices
& driver for E822 TS") and commit 712e876371f8 ("ice: periodically kick Tx
timestamp interrupt"), however at the time of the original coding, both
functions only operated on E822 hardware. This is no longer the case, and
hasn't been since the introduction of the ETH56G PHY model in commit
7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products")

Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products")
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Petr Oros <poros@redhat.com>
Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
 drivers/net/ethernet/intel/ice/ice_ptp_hw.h |   1 +
 drivers/net/ethernet/intel/ice/ice_ptp.c    |  44 +++++------
 drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 117 ++++++++++++++++++++++++++++
 3 files changed, 136 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
index ac4611291052..1c9e77dbc770 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
@@ -300,6 +300,7 @@ void ice_ptp_reset_ts_memory(struct ice_hw *hw);
 int ice_ptp_init_phc(struct ice_hw *hw);
 void ice_ptp_init_hw(struct ice_hw *hw);
 int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready);
+int ice_check_phy_tx_tstamp_ready(struct ice_hw *hw);
 int ice_ptp_one_port_cmd(struct ice_hw *hw, u8 configured_port,
 			 enum ice_ptp_tmr_cmd configured_cmd);
 
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
index 6cb0cf7a9891..36df742c326c 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
@@ -2710,7 +2710,7 @@ static bool ice_any_port_has_timestamps(struct ice_pf *pf)
 bool ice_ptp_tx_tstamps_pending(struct ice_pf *pf)
 {
 	struct ice_hw *hw = &pf->hw;
-	unsigned int i;
+	int ret;
 
 	/* Check software indicator */
 	switch (pf->ptp.tx_interrupt_mode) {
@@ -2731,16 +2731,19 @@ bool ice_ptp_tx_tstamps_pending(struct ice_pf *pf)
 	}
 
 	/* Check hardware indicator */
-	for (i = 0; i < ICE_GET_QUAD_NUM(hw->ptp.num_lports); i++) {
-		u64 tstamp_ready = 0;
-		int err;
-
-		err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready);
-		if (err || tstamp_ready)
-			return true;
+	ret = ice_check_phy_tx_tstamp_ready(hw);
+	if (ret < 0) {
+		dev_dbg(ice_pf_to_dev(pf), "Unable to read PHY Tx timestamp ready bitmap, err %d\n",
+			ret);
+		/* Stop triggering IRQs if we're unable to read PHY */
+		return false;
 	}
 
-	return false;
+	/* ice_check_phy_tx_tstamp_ready() returns 1 if there are timestamps
+	 * available, 0 if there are no waiting timestamps, and a negative
+	 * value if there was an error (which we checked for above).
+	 */
+	return ret > 0;
 }
 
 /**
@@ -2824,8 +2827,7 @@ static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf)
 {
 	struct device *dev = ice_pf_to_dev(pf);
 	struct ice_hw *hw = &pf->hw;
-	bool trigger_oicr = false;
-	unsigned int i;
+	int ret;
 
 	if (!pf->ptp.port.tx.has_ready_bitmap)
 		return;
@@ -2833,21 +2835,11 @@ static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf)
 	if (!ice_pf_src_tmr_owned(pf))
 		return;
 
-	for (i = 0; i < ICE_GET_QUAD_NUM(hw->ptp.num_lports); i++) {
-		u64 tstamp_ready;
-		int err;
-
-		err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready);
-		if (!err && tstamp_ready) {
-			trigger_oicr = true;
-			break;
-		}
-	}
-
-	if (trigger_oicr) {
-		/* Trigger a software interrupt, to ensure this data
-		 * gets processed.
-		 */
+	ret = ice_check_phy_tx_tstamp_ready(hw);
+	if (ret < 0) {
+		dev_dbg(dev, "PTP periodic task unable to read PHY timestamp ready bitmap, err %d\n",
+			ret);
+	} else if (ret) {
 		dev_dbg(dev, "PTP periodic task detected waiting timestamps. Triggering Tx timestamp interrupt now.\n");
 
 		wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
index d4c2bb084255..4795af06b983 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
@@ -2168,6 +2168,35 @@ int ice_start_phy_timer_eth56g(struct ice_hw *hw, u8 port)
 	return 0;
 }
 
+/**
+ * ice_check_phy_tx_tstamp_ready_eth56g - Check Tx memory status for all ports
+ * @hw: pointer to the HW struct
+ *
+ * Check the PHY_REG_TX_MEMORY_STATUS for all ports. A set bit indicates
+ * a waiting timestamp.
+ *
+ * Return: 1 if any port has at least one timestamp ready bit set,
+ * 0 otherwise, and a negative error code if unable to read the bitmap.
+ */
+static int ice_check_phy_tx_tstamp_ready_eth56g(struct ice_hw *hw)
+{
+	int port;
+
+	for (port = 0; port < hw->ptp.num_lports; port++) {
+		u64 tstamp_ready;
+		int err;
+
+		err = ice_get_phy_tx_tstamp_ready(hw, port, &tstamp_ready);
+		if (err)
+			return err;
+
+		if (tstamp_ready)
+			return 1;
+	}
+
+	return 0;
+}
+
 /**
  * ice_ptp_read_tx_hwtstamp_status_eth56g - Get TX timestamp status
  * @hw: pointer to the HW struct
@@ -4318,6 +4347,35 @@ ice_get_phy_tx_tstamp_ready_e82x(struct ice_hw *hw, u8 quad, u64 *tstamp_ready)
 	return 0;
 }
 
+/**
+ * ice_check_phy_tx_tstamp_ready_e82x - Check Tx memory status for all quads
+ * @hw: pointer to the HW struct
+ *
+ * Check the Q_REG_TX_MEMORY_STATUS for all quads. A set bit indicates
+ * a waiting timestamp.
+ *
+ * Return: 1 if any quad has at least one timestamp ready bit set,
+ * 0 otherwise, and a negative error value if unable to read the bitmap.
+ */
+static int ice_check_phy_tx_tstamp_ready_e82x(struct ice_hw *hw)
+{
+	int quad;
+
+	for (quad = 0; quad < ICE_GET_QUAD_NUM(hw->ptp.num_lports); quad++) {
+		u64 tstamp_ready;
+		int err;
+
+		err = ice_get_phy_tx_tstamp_ready(hw, quad, &tstamp_ready);
+		if (err)
+			return err;
+
+		if (tstamp_ready)
+			return 1;
+	}
+
+	return 0;
+}
+
 /**
  * ice_phy_cfg_intr_e82x - Configure TX timestamp interrupt
  * @hw: pointer to the HW struct
@@ -4871,6 +4929,23 @@ ice_get_phy_tx_tstamp_ready_e810(struct ice_hw *hw, u8 port, u64 *tstamp_ready)
 	return 0;
 }
 
+/**
+ * ice_check_phy_tx_tstamp_ready_e810 - Check Tx memory status register
+ * @hw: pointer to the HW struct
+ *
+ * The E810 devices do not have a Tx memory status register. Note this is
+ * intentionally different behavior from ice_get_phy_tx_tstamp_ready_e810
+ * which always says that all bits are ready. This function is called in cases
+ * where code will trigger interrupts if timestamps are waiting, and should
+ * not be called for E810 hardware.
+ *
+ * Return: 0.
+ */
+static int ice_check_phy_tx_tstamp_ready_e810(struct ice_hw *hw)
+{
+	return 0;
+}
+
 /* E810 SMA functions
  *
  * The following functions operate specifically on E810 hardware and are used
@@ -5125,6 +5200,21 @@ static void ice_get_phy_tx_tstamp_ready_e830(const struct ice_hw *hw, u8 port,
 	*tstamp_ready |= rd32(hw, E830_PRTMAC_TS_TX_MEM_VALID_L);
 }
 
+/**
+ * ice_check_phy_tx_tstamp_ready_e830 - Check Tx memory status register
+ * @hw: pointer to the HW struct
+ *
+ * Return: 1 if the device has waiting timestamps, 0 otherwise.
+ */
+static int ice_check_phy_tx_tstamp_ready_e830(struct ice_hw *hw)
+{
+	u64 tstamp_ready;
+
+	ice_get_phy_tx_tstamp_ready_e830(hw, 0, &tstamp_ready);
+
+	return !!tstamp_ready;
+}
+
 /**
  * ice_ptp_init_phy_e830 - initialize PHY parameters
  * @ptp: pointer to the PTP HW struct
@@ -5717,6 +5807,33 @@ int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready)
 	}
 }
 
+/**
+ * ice_check_phy_tx_tstamp_ready - Check PHY Tx timestamp memory status
+ * @hw: pointer to the HW struct
+ *
+ * Check the PHY for Tx timestamp memory status on all ports. If you need to
+ * see individual timestamp status for each index, use
+ * ice_get_phy_tx_tstamp_ready() instead.
+ *
+ * Return: 1 if any port has timestamps available, 0 if there are no timestamps
+ * available, and a negative error code on failure.
+ */
+int ice_check_phy_tx_tstamp_ready(struct ice_hw *hw)
+{
+	switch (hw->mac_type) {
+	case ICE_MAC_E810:
+		return ice_check_phy_tx_tstamp_ready_e810(hw);
+	case ICE_MAC_E830:
+		return ice_check_phy_tx_tstamp_ready_e830(hw);
+	case ICE_MAC_GENERIC:
+		return ice_check_phy_tx_tstamp_ready_e82x(hw);
+	case ICE_MAC_GENERIC_3K_E825:
+		return ice_check_phy_tx_tstamp_ready_eth56g(hw);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
 /**
  * ice_cgu_get_pin_desc_e823 - get pin description array
  * @hw: pointer to the hw struct

-- 
2.54.0.rc2.531.gaf818d63126a


^ permalink raw reply related

* [PATCH net 4/4] ice: fix ice_ptp_read_tx_hwtstamp_status_eth56g
From: Jacob Keller @ 2026-04-21  0:51 UTC (permalink / raw)
  To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni
  Cc: netdev, Jacob Keller, Aleksandr Loktionov, Petr Oros,
	Sunitha Mekala
In-Reply-To: <20260420-jk-iwl-net-2026-04-20-ptp-e825c-phy-interrupt-fixes-v1-0-bc2240f42251@intel.com>

The ice_ptp_read_tx_hwtstamp_status_eth56g function calls
ice_read_phy_eth56g with a PHY index. However the function actually expects
a port index. This causes the function to read the wrong PHY_PTP_INT_STATUS
registers, and effectively makes the status wrong for the second set of
ports from 4 to 7.

The ice_read_phy_eth56g function uses the provided port index to determine
which PHY device to read. We could refactor the entire chain to take a PHY
index, but this would impact many code sites. Instead, multiply the PHY
index by the number of ports, so that we read from the first port of each
PHY.

Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products")
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Petr Oros <poros@redhat.com>
Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
 drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
index 4795af06b983..24fb7a3e14d6 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
@@ -2219,13 +2219,19 @@ int ice_ptp_read_tx_hwtstamp_status_eth56g(struct ice_hw *hw, u32 *ts_status)
 	*ts_status = 0;
 
 	for (phy = 0; phy < params->num_phys; phy++) {
+		u8 port;
 		int err;
 
-		err = ice_read_phy_eth56g(hw, phy, PHY_PTP_INT_STATUS, &status);
+		/* ice_read_phy_eth56g expects a port index, so use the first
+		 * port of the PHY
+		 */
+		port = phy * hw->ptp.ports_per_phy;
+
+		err = ice_read_phy_eth56g(hw, port, PHY_PTP_INT_STATUS, &status);
 		if (err)
 			return err;
 
-		*ts_status |= (status & mask) << (phy * hw->ptp.ports_per_phy);
+		*ts_status |= (status & mask) << port;
 	}
 
 	ice_debug(hw, ICE_DBG_PTP, "PHY interrupt err: %x\n", *ts_status);

-- 
2.54.0.rc2.531.gaf818d63126a


^ permalink raw reply related

* [PATCH net 0/4] Intel Wired LAN Driver Updates 2026-04-20 (ice)
From: Jacob Keller @ 2026-04-21  0:51 UTC (permalink / raw)
  To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni
  Cc: netdev, Jacob Keller, Grzegorz Nitka, Aleksandr Loktionov,
	Petr Oros, Sunitha Mekala, Timothy Miskell

Since this is a set of related fixes for just the ice driver, Jake provides
the following description for the series:

We recently ran into a nasty corner case issue with a customer operating
E825C cards seeing some strange behavior with missing Tx timestamps. During
the course of debugging. This series contains a few fixes found during this
debugging process.

The primary issue discovered in the investigation is a misconfiguration of
the E825C PHY timestamp interrupt register, PHY_REG_TS_INT_CONFIG. This
register is responsible for programming the Tx timestamp behavior of a PHY
port. The driver programs two values here: a threshold for when to
interrupt and whether the interrupt is enabled.

The threshold value is used by hardware to determine when to trigger a Tx
timestamp interrupt. The interrupt cause for the port is raised when the
number of outstanding timestamps in the PHY port timestamp memory meets the
threshold. The interrupt cause is not cleared until the number of
outstanding timestamps drops *below* the threshold.

It is considered a misconfiguration if the threshold is programmed to 0. If
the interrupt is enabled while the threshold is zero, hardware will raise
the interrupt cause at the next time it checks. Once raised, the interrupt
cause for the port will never lower, since you cannot have fewer than zero
outstanding timestamps.

Worse, the timestamp status for the port will remain high even if the
PHY_REG_TS_INT_CONFIG is reprogrammed with a new threshold. The PHY is a
separate hardware block from the MAC, and thus the interrupt status for the
port will remain high even if you reset the device MAC with a PF reset,
CORE reset, or GLOBAL reset.

PHY ports are connected together into quads. Each quad muxes the PHY
interrupt status for the 4 ports on the quad together before connecting
that to the MACs miscellaneous interrupt vector. As a result, if a single
PHY port in the quad is stuck, no timestamp interrupts will be generated
for any timestamp on any port on that quad.

The ice driver never directly writes a value of 0 for the threshold.
Indeed, the desired behavior is to set the threshold to 1, so that
interrupts are generated as soon as a single timestamp is captured.
Unfortunately, it turns out that for the E825C PHY, programming the
threshold and enable bit in the same write may cause a race in the PHY
timestamp block. The PHY may "see" the interrupt as enabled first before it
sees the threshold value. If the previous threshold value is zero (such as
when the register is initialized to zero at a cold power on), the hardware
may race with programming the threshold and set the PHY interrupt status to
high as described above.

The first patch in this series corrects that programming order, ensuring
that the threshold is always written first in a separate transaction from
enabling the interrupt bit. Additionally, an explicit check against writing
a 0 is added to make it clear to future readers that writing 0 to the
threshold while enabling the interrupt is not safe.

The PHY timestamp block does not reset with the MAC, and seems to only
reset during cold power on. This makes recovery from the faulty
configuration difficult. To address this, perform an explicit reset of the
PHY PTP block during initialization. This is achieved by writing the
PHY_REG_GLOBAL register. This performs a PHY soft reset, which completely
resets the timestamp block. This includes clearing the timestamp memory,
the PHY timestamp interrupt status, and the PHY PTP counter. A soft reset
of all ports on the device is done as part of ice_ptp_init_phc() during
early initialization of the PTP functionality by the PTP clock owner, prior
to programming each PHY. The ice_ptp_init_phc() function is called at
driver init and during reinitialization after all forms of device reset.
This ensures that the driver begins operation at a clean slate, rather than
carrying over the stale and potentially buggy configuration of a previous
driver.

While attempting to root cause the issue with the PHY timestamp interrupt,
we also discovered that the driver incorrectly assumes that it is operating
on E822 hardware when reading the PHY timestamp memory status registers in
a few places. This includes the check at the end of the interrupt handler,
as well as the check done inside the PTP auxiliary function. This prevented
the driver from detecting waiting timestamps on ports other than the first
two.

Finally, the ice_ptp_read_tx_hwstamp_status_eth56g() function was
discovered to only read the timestamp interrupt status value from the first
quad due to mistaking the port index for a PHY quad index. This resulted in
reporting the timestamp status for the second quad as identical to the
first quad instead of properly reporting its value. This is a minor fix
since the function currently is only used for diagnostic purposes and does
not impact driver decision logic.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
Grzegorz Nitka (2):
      ice: fix timestamp interrupt configuration for E825C
      ice: perform PHY soft reset for E825C ports at initialization

Jacob Keller (2):
      ice: fix ready bitmap check for non-E822 devices
      ice: fix ice_ptp_read_tx_hwtstamp_status_eth56g

 drivers/net/ethernet/intel/ice/ice_ptp_hw.h |   5 +
 drivers/net/ethernet/intel/ice/ice_ptp.c    |  44 ++---
 drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 253 +++++++++++++++++++++++++++-
 3 files changed, 269 insertions(+), 33 deletions(-)
---
base-commit: a663bac71a2f0b3ac6c373168ca57b2a6e6381aa
change-id: 20260420-jk-iwl-net-2026-04-20-ptp-e825c-phy-interrupt-fixes-97ac6cb90fd7

Best regards,
--  
Jacob Keller <jacob.e.keller@intel.com>


^ permalink raw reply

* Re: [PATCH net v2 4/8] xsk: prevent CQ desync when freeing half-built skbs in xsk_build_skb()
From: Jason Xing @ 2026-04-21  0:51 UTC (permalink / raw)
  To: Stanislav Fomichev; +Cc: bpf, netdev, Jason Xing
In-Reply-To: <7f15844902d6dcee6ba070b0f3002b20.sdf.kernel@gmail.com>

On Tue, Apr 21, 2026 at 3:34 AM Stanislav Fomichev <sdf.kernel@gmail.com> wrote:
>
> > From: Jason Xing <kernelxing@tencent.com>
> >
> > Once xsk_skb_init_misc() has been called on an skb, its destructor is
> > set to xsk_destruct_skb(), which submits the descriptor address(es) to
> > the completion queue and advances the CQ producer. If such an skb is
> > subsequently freed via kfree_skb() along an error path - before the
> > skb has ever been handed to the driver - the destructor still runs and
> > submits a bogus, half-initialized address to the CQ.
> >
> > Introduce a new common helper to fix the issue. That function will be
> > used by the subsequent patches soon.
> >
> > Closes: https://lore.kernel.org/all/20260419045822.843BFC2BCAF@smtp.kernel.org/
> > Fixes: c30d084960cf ("xsk: avoid overwriting skb fields for multi-buffer traffic")
> > Signed-off-by: Jason Xing <kernelxing@tencent.com>
> > ---
> >  net/xdp/xsk.c | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> >
> > diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
> > index 4fdd1a45a9bd..614e7bd1252b 100644
> > --- a/net/xdp/xsk.c
> > +++ b/net/xdp/xsk.c
> > @@ -717,6 +717,12 @@ static int xsk_skb_metadata(struct sk_buff *skb, void *buffer,
> >       return 0;
> >  }
> >
> > +static void xsk_drop_untrans_skb(struct sk_buff *skb)
> > +{
> > +     skb->destructor = sock_wfree;
> > +     kfree_skb(skb);
> > +}
> > +
> >  static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
> >                                             struct xdp_desc *desc)
> >  {
> > @@ -890,7 +896,7 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
> >
> >  free_err:
> >       if (skb && !xs->skb && !skb_shinfo(skb)->nr_frags)
> > -             kfree_skb(skb);
> > +             xsk_drop_untrans_skb(skb);
> >
> >       if (err == -EOVERFLOW) {
> >               if (xs->skb) {
> > --
> > 2.41.3
> >
>
> Have you considered the alternative where we postpone `skb->destructor =
> xsk_destruct_skb` to a later point? Will this be less messy than
> undoing that descriptor in a few curated places?

Thanks. It does make sense. Adding the following code seems fine:
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 887abed25466..02e723ca3080 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -820,7 +820,6 @@ static struct sk_buff
*xsk_build_skb_zerocopy(struct xdp_sock *xs,

                skb_reserve(skb, hr);

-               xsk_skb_init_misc(skb, xs, desc->addr);
                if (desc->options & XDP_TX_METADATA) {
                        err = xsk_skb_metadata(skb, buffer, desc, pool, hr);
                        if (unlikely(err))
@@ -914,7 +913,6 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
                        if (unlikely(err))
                                goto free_err;

-                       xsk_skb_init_misc(skb, xs, desc->addr);
                        if (desc->options & XDP_TX_METADATA) {
                                err = xsk_skb_metadata(skb, buffer, desc,
                                                       xs->pool, hr);
@@ -964,6 +962,8 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
                }
        }

+       if (!xs->skb)
+               xsk_skb_init_misc(skb, xs, desc->addr);
        xsk_inc_num_desc(skb);

        return skb;

Thanks,
Jason

^ permalink raw reply related

* Re: [PATCH net 1/4] xsk: avoid skb leak in XDP_TX_METADATA case
From: Jason Xing @ 2026-04-21  0:55 UTC (permalink / raw)
  To: Stanislav Fomichev
  Cc: davem, edumazet, kuba, pabeni, bjorn, magnus.karlsson,
	maciej.fijalkowski, jonathan.lemon, sdf, ast, daniel, hawk,
	john.fastabend, horms, andrew+netdev, bpf, netdev, Jason Xing
In-Reply-To: <aeZTxgvr0mdIG-lK@devvm17672.vll0.facebook.com>

On Tue, Apr 21, 2026 at 12:27 AM Stanislav Fomichev
<sdf.kernel@gmail.com> wrote:
>
> On 04/20, Stanislav Fomichev wrote:
> > On 04/20, Stanislav Fomichev wrote:
> > > On 04/18, Jason Xing wrote:
> > > > From: Jason Xing <kernelxing@tencent.com>
> > > >
> > > > Fix it by explicitly adding kfree_skb() before returning back to its
> > > > caller.
> > > >
> > > > How to reproduce it in virtio_net:
> > > > 1. the current skb is the first one (which means no frag and xs->skb is
> > > >    NULL) and users enable metadata feature.
> > > > 2. xsk_skb_metadata() returns a error code.
> > > > 3. the caller xsk_build_skb() clears skb by using 'skb = NULL;'.
> > > > 4. there is no chance to free this skb anymore.
> > > >
> > > > Closes: https://lore.kernel.org/all/20260415085204.3F87AC19424@smtp.kernel.org/
> > > > Fixes: 30c3055f9c0d ("xsk: wrap generic metadata handling onto separate function")
> > > > Signed-off-by: Jason Xing <kernelxing@tencent.com>
> > >
> > > Acked-by: Stanislav Fomichev <sdf@fomichev.me>
> >
> > Actually, I take that back.. While looking at patch 2 (which always
> > confuses me with that -EOVERFLOW handling), looks like we set
> > skb->destructor in xsk_skb_init_misc? So this kfree will do
> > xsk_cq_submit_addr_locked? Not sure that's what we want? Should we
> > move xsk_skb_init_misc to happen after xsk_skb_metadata?
>
> Ooops, looks like you already addressed these in v2? Let me look into
> that..

Thanks for the detailed check. To be frank, my mind sometimes went
blank while checking those complex paths...

Yep, let's discuss that there instead :)

Thanks,
Jason

^ permalink raw reply

* [PATCH net v2 0/2] tcp: symmetric challenge ACK for SEG.ACK > SND.NXT
From: Jiayuan Chen @ 2026-04-21  1:40 UTC (permalink / raw)
  To: netdev
  Cc: Jiayuan Chen, Eric Dumazet, Neal Cardwell, Kuniyuki Iwashima,
	David S. Miller, David Ahern, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Shuah Khan, linux-kernel, linux-kselftest

Commit 354e4aa391ed ("tcp: RFC 5961 5.2 Blind Data Injection Attack
Mitigation") quotes RFC 5961 Section 5.2 in full, which requires
that any incoming segment whose ACK value falls outside
[SND.UNA - MAX.SND.WND, SND.NXT] MUST be discarded and an ACK sent
back.  Linux currently sends that challenge ACK only on the lower
edge (SEG.ACK < SND.UNA - MAX.SND.WND); on the symmetric upper edge
(SEG.ACK > SND.NXT) the segment is silently dropped with
SKB_DROP_REASON_TCP_ACK_UNSENT_DATA.

Patch 1 completes the mitigation by emitting a rate-limited challenge
ACK on that branch, reusing tcp_send_challenge_ack() and honouring
FLAG_NO_CHALLENGE_ACK for consistency with the lower-edge case.  It
also updates the existing tcp_ts_recent_invalid_ack.pkt selftest,
which drives this exact path, to consume the new challenge ACK so
bisect stays clean.

Patch 2 adds a new packetdrill selftest that exercises RFC 5961
Section 5.2 on both edges of the acceptable window, filling a gap in
the selftests tree (neither edge had dedicated coverage before).

---

Changelog
=========

v1 -> v2:
  - Add Reviewed-by tag.
  - Fold the tcp_ts_recent_invalid_ack.pkt update into patch 1 so
    that bisect stays clean and the fix is self-contained for
    backport.
  - Extend the new selftest to cover both edges of RFC 5961
    Section 5.2 (SEG.ACK > SND.NXT and SEG.ACK < SND.UNA -
    MAX.SND.WND) in a single connection, and rename it to
    tcp_rfc5961_ack-out-of-window.pkt.  Neither edge had explicit
    packetdrill coverage before.

v1: https://lore.kernel.org/netdev/20260420025428.101192-1-jiayuan.chen@linux.dev/

Jiayuan Chen (2):
  tcp: send a challenge ACK on SEG.ACK > SND.NXT
  selftests/net: packetdrill: cover RFC 5961 5.2 challenge ACK on both
    edges

 net/ipv4/tcp_input.c                          | 10 ++--
 .../tcp_rfc5961_ack-out-of-window.pkt         | 46 +++++++++++++++++++
 .../packetdrill/tcp_ts_recent_invalid_ack.pkt |  4 +-
 3 files changed, 56 insertions(+), 4 deletions(-)
 create mode 100644 tools/testing/selftests/net/packetdrill/tcp_rfc5961_ack-out-of-window.pkt

-- 
2.43.0


^ permalink raw reply

* [PATCH net v2 1/2] tcp: send a challenge ACK on SEG.ACK > SND.NXT
From: Jiayuan Chen @ 2026-04-21  1:41 UTC (permalink / raw)
  To: netdev
  Cc: Jiayuan Chen, Eric Dumazet, Neal Cardwell, Kuniyuki Iwashima,
	David S. Miller, David Ahern, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Shuah Khan, linux-kernel, linux-kselftest
In-Reply-To: <20260421014128.289362-1-jiayuan.chen@linux.dev>

RFC 5961 Section 5.2 validates an incoming segment's ACK value
against the range [SND.UNA - MAX.SND.WND, SND.NXT] and states:

  "All incoming segments whose ACK value doesn't satisfy the above
   condition MUST be discarded and an ACK sent back."

Commit 354e4aa391ed ("tcp: RFC 5961 5.2 Blind Data Injection Attack
Mitigation") opted Linux into this mitigation and implements the
challenge ACK on the lower side (SEG.ACK < SND.UNA - MAX.SND.WND),
but the symmetric upper side (SEG.ACK > SND.NXT) still takes the
pre-RFC-5961 path and silently returns
SKB_DROP_REASON_TCP_ACK_UNSENT_DATA, even though RFC 793 Section 3.9
(now RFC 9293 Section 3.10.7.4) has always required:

  "If the ACK acknowledges something not yet sent (SEG.ACK > SND.NXT)
   then send an ACK, drop the segment, and return."

Complete the mitigation by sending a challenge ACK on that branch,
reusing the existing tcp_send_challenge_ack() path which already
enforces the per-socket RFC 5961 Section 7 rate limit via
__tcp_oow_rate_limited().  FLAG_NO_CHALLENGE_ACK is honoured for
symmetry with the lower-edge case.

Update the existing tcp_ts_recent_invalid_ack.pkt selftest, which
drives this exact path, to consume the new challenge ACK.

Fixes: 354e4aa391ed ("tcp: RFC 5961 5.2 Blind Data Injection Attack Mitigation")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Eric Dumazet <edumazet@google.com>
---
 net/ipv4/tcp_input.c                                   | 10 +++++++---
 .../net/packetdrill/tcp_ts_recent_invalid_ack.pkt      |  4 +++-
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 021f745747c5..c2b6f05acdfa 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4284,11 +4284,15 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
 		goto old_ack;
 	}
 
-	/* If the ack includes data we haven't sent yet, discard
-	 * this segment (RFC793 Section 3.9).
+	/* If the ack includes data we haven't sent yet, drop the
+	 * segment.  RFC 793 Section 3.9 and RFC 5961 Section 5.2
+	 * require us to send an ACK back in that case.
 	 */
-	if (after(ack, tp->snd_nxt))
+	if (after(ack, tp->snd_nxt)) {
+		if (!(flag & FLAG_NO_CHALLENGE_ACK))
+			tcp_send_challenge_ack(sk, false);
 		return -SKB_DROP_REASON_TCP_ACK_UNSENT_DATA;
+	}
 
 	if (after(ack, prior_snd_una)) {
 		flag |= FLAG_SND_UNA_ADVANCED;
diff --git a/tools/testing/selftests/net/packetdrill/tcp_ts_recent_invalid_ack.pkt b/tools/testing/selftests/net/packetdrill/tcp_ts_recent_invalid_ack.pkt
index 174ce9a1bfc0..ee6baf7c36cf 100644
--- a/tools/testing/selftests/net/packetdrill/tcp_ts_recent_invalid_ack.pkt
+++ b/tools/testing/selftests/net/packetdrill/tcp_ts_recent_invalid_ack.pkt
@@ -19,7 +19,9 @@
 
 // bad packet with high tsval (its ACK sequence is above our sndnxt)
    +0 < F. 1:1(0) ack 9999 win 20000 <nop,nop,TS val 200000 ecr 100>
-
+// Challenge ACK for SEG.ACK > SND.NXT (RFC 5961 5.2 / RFC 793 3.9).
+// ecr=200 (not 200000) proves ts_recent was not updated from the bad packet.
+   +0 > . 1:1(0) ack 1 <nop,nop,TS val 200 ecr 200>
 
    +0 < . 1:1001(1000) ack 1 win 20000 <nop,nop,TS val 201 ecr 100>
    +0 > . 1:1(0) ack 1001 <nop,nop,TS val 200 ecr 201>
-- 
2.43.0


^ permalink raw reply related

* [PATCH net v2 2/2] selftests/net: packetdrill: cover RFC 5961 5.2 challenge ACK on both edges
From: Jiayuan Chen @ 2026-04-21  1:41 UTC (permalink / raw)
  To: netdev
  Cc: Jiayuan Chen, Eric Dumazet, Neal Cardwell, Kuniyuki Iwashima,
	David S. Miller, David Ahern, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Shuah Khan, linux-kernel, linux-kselftest
In-Reply-To: <20260421014128.289362-1-jiayuan.chen@linux.dev>

RFC 5961 Section 5.2 / RFC 793 Section 3.9 require a challenge ACK
whenever an incoming SEG.ACK falls outside
[SND.UNA - MAX.SND.WND, SND.NXT].  There is currently no packetdrill
coverage for either edge.

Add tcp_rfc5961_ack-out-of-window.pkt, which in a single passive-open
connection exercises:

  - Upper edge (SEG.ACK > SND.NXT): peer ACKs data that was never
    sent before the server has transmitted anything.
  - Lower edge (SEG.ACK < SND.UNA - MAX.SND.WND): after the server
    has sent 2000 bytes (the peer-advertised rwnd forces two 1000-byte
    segments, both acknowledged), peer sends an ACK that is older
    than the acceptable window.

Both cases must elicit a challenge ACK
<SEQ = SND.NXT, ACK = RCV.NXT, CTL = ACK>.  The per-socket RFC 5961
Section 7 rate limit is disabled for the duration of the test so that
both challenge ACKs can fire back-to-back.

Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Eric Dumazet <edumazet@google.com>
---
 .../tcp_rfc5961_ack-out-of-window.pkt         | 46 +++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 tools/testing/selftests/net/packetdrill/tcp_rfc5961_ack-out-of-window.pkt

diff --git a/tools/testing/selftests/net/packetdrill/tcp_rfc5961_ack-out-of-window.pkt b/tools/testing/selftests/net/packetdrill/tcp_rfc5961_ack-out-of-window.pkt
new file mode 100644
index 000000000000..44d54c812820
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_rfc5961_ack-out-of-window.pkt
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// RFC 5961 Section 5.2 / RFC 793 Section 3.9: an incoming segment's
+// ACK value must lie in [SND.UNA - MAX.SND.WND, SND.NXT]; otherwise
+// the receiver MUST discard the segment and send a challenge ACK
+// back.  Exercise both edges of that window in a single connection.
+
+`./defaults.sh
+sysctl -q net.ipv4.tcp_invalid_ratelimit=0
+`
+
+   0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+  +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+  +0 bind(3, ..., ...) = 0
+  +0 listen(3, 1) = 0
+
+// Three-way handshake.  Peer advertises rwnd = 1000 (no wscale), so
+// MAX.SND.WND is tracked as 1000.
+  +0 < S 0:0(0) win 1000 <mss 1000,sackOK,nop,nop,nop,wscale 0>
+  +0 > S. 0:0(0) ack 1 <...>
++.1 < . 1:1(0) ack 1 win 1000
+  +0 accept(3, ..., ...) = 4
+
+// ---- Upper edge: SEG.ACK > SND.NXT --------------------------------
+// Server has sent nothing yet, so SND.UNA = SND.NXT = 1.
+// Peer sends a pure ACK with SEG.ACK = 2, beyond SND.NXT.
+  +0 < . 1:1(0) ack 2 win 1000
+// Expect a challenge ACK: <SEQ = SND.NXT = 1, ACK = RCV.NXT = 1>.
+  +0 > . 1:1(0) ack 1
+
+// Advance SND.UNA past MAX.SND.WND so that the lower edge becomes
+// reachable.  Write 2000 bytes; the peer's rwnd of 1000 forces two
+// 1000-byte segments, each acknowledged in turn.
+  +0 write(4, ..., 2000) = 2000
+  +0 > P. 1:1001(1000) ack 1
++.01 < . 1:1(0) ack 1001 win 1000
+  +0 > P. 1001:2001(1000) ack 1
++.01 < . 1:1(0) ack 2001 win 1000
+// Now SND.UNA = SND.NXT = 2001, MAX.SND.WND = 1000, bytes_acked = 2000.
+
+// ---- Lower edge: SEG.ACK < SND.UNA - MAX.SND.WND ------------------
+// SND.UNA - MAX.SND.WND = 2001 - 1000 = 1001, so SEG.ACK = 1000 falls
+// below the acceptable range.
+  +0 < . 1:1(0) ack 1000 win 1000
+// Expect a challenge ACK: <SEQ = SND.NXT = 2001, ACK = RCV.NXT = 1>.
+  +0 > . 2001:2001(0) ack 1
-- 
2.43.0


^ permalink raw reply related

* [PATCH net-deletions] net: remove ax25 and amateur radio (hamradio) subsystem
From: Jakub Kicinski @ 2026-04-21  2:18 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, Jakub Kicinski,
	corbet, skhan, federico.vaga, carlos.bilbao, avadhut.naik, alexs,
	si.yanteng, dzm91, 2023002089, tsbogend, dsahern, jani.nikula,
	mchehab+huawei, gregkh, jirislaby, tytso, herbert, ebiggers,
	johannes.berg, geert, pablo, tglx, mashiro.chen, mingo, dqfext,
	jreuter, sdf, pkshih, enelsonmoore, mkl, toke, kees, crossd,
	jlayton, wangliang74, aha310510, takamitz, kuniyu, linux-doc,
	linux-mips

Remove the amateur radio (AX.25, NET/ROM, ROSE) protocol implementation
and all associated hamradio device drivers from the kernel tree.
This set of protocols has long been a huge bug/syzbot magnet,
and since nobody stepped up to help us deal with the influx
of the AI-generated bug reports we need to move it out of tree
to protect our sanity.

The code is moved to an out-of-tree repo:
https://github.com/linux-netdev/mod-orphan
if it's cleaned up and reworked there we can accept it back.

Minimal stub headers are kept for include/net/ax25.h (AX25_P_IP,
AX25_ADDR_LEN, ax25_address) and include/net/rose.h (ROSE_ADDR_LEN)
so that the conditional integration code in arp.c and tun.c continues
to compile and work when the out-of-tree modules are loaded.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
CC: corbet@lwn.net
CC: skhan@linuxfoundation.org
CC: federico.vaga@vaga.pv.it
CC: carlos.bilbao@kernel.org
CC: avadhut.naik@amd.com
CC: alexs@kernel.org
CC: si.yanteng@linux.dev
CC: dzm91@hust.edu.cn
CC: 2023002089@link.tyut.edu.cn
CC: tsbogend@alpha.franken.de
CC: dsahern@kernel.org
CC: jani.nikula@intel.com
CC: mchehab+huawei@kernel.org
CC: gregkh@linuxfoundation.org
CC: jirislaby@kernel.org
CC: tytso@mit.edu
CC: herbert@gondor.apana.org.au
CC: ebiggers@kernel.org
CC: johannes.berg@intel.com
CC: geert@linux-m68k.org
CC: pablo@netfilter.org
CC: tglx@kernel.org
CC: mashiro.chen@mailbox.org
CC: mingo@kernel.org
CC: dqfext@gmail.com
CC: jreuter@yaina.de
CC: sdf@fomichev.me
CC: pkshih@realtek.com
CC: enelsonmoore@gmail.com
CC: mkl@pengutronix.de
CC: toke@toke.dk
CC: kees@kernel.org
CC: crossd@gmail.com
CC: jlayton@kernel.org
CC: wangliang74@huawei.com
CC: aha310510@gmail.com
CC: takamitz@amazon.co.jp
CC: kuniyu@google.com
CC: linux-doc@vger.kernel.org
CC: linux-mips@vger.kernel.org
---
 MAINTAINERS                                   |   73 -
 Documentation/.renames.txt                    |    2 -
 .../admin-guide/kernel-parameters.txt         |   18 -
 Documentation/networking/6pack.rst            |  191 --
 Documentation/networking/ax25.rst             |   17 -
 .../device_drivers/hamradio/baycom.rst        |  174 --
 .../device_drivers/hamradio/index.rst         |   12 -
 .../device_drivers/hamradio/z8530drv.rst      |  686 ------
 .../networking/device_drivers/index.rst       |    1 -
 Documentation/networking/index.rst            |    2 -
 Documentation/staging/magic-number.rst        |    3 -
 .../it_IT/staging/magic-number.rst            |    3 -
 .../sp_SP/process/magic-number.rst            |    3 -
 .../zh_CN/process/magic-number.rst            |    3 -
 .../zh_TW/process/magic-number.rst            |    3 -
 drivers/net/hamradio/Kconfig                  |  162 --
 net/Kconfig                                   |    1 -
 net/ax25/Kconfig                              |  108 -
 drivers/net/Makefile                          |    1 -
 drivers/net/hamradio/Makefile                 |   22 -
 net/Makefile                                  |    3 -
 net/ax25/Makefile                             |   12 -
 net/netrom/Makefile                           |   10 -
 net/rose/Makefile                             |   10 -
 drivers/net/hamradio/z8530.h                  |  246 --
 include/linux/hdlcdrv.h                       |  276 ---
 include/linux/netdevice.h                     |    5 +-
 include/linux/scc.h                           |   86 -
 include/linux/yam.h                           |   67 -
 include/net/ax25.h                            |  476 +---
 include/net/netrom.h                          |  273 ---
 include/net/rose.h                            |  263 +-
 include/uapi/linux/baycom.h                   |   40 -
 include/uapi/linux/hdlcdrv.h                  |  111 -
 include/uapi/linux/netrom.h                   |   37 -
 include/uapi/linux/rose.h                     |   91 -
 include/uapi/linux/scc.h                      |  174 --
 drivers/net/hamradio/6pack.c                  |  912 -------
 drivers/net/hamradio/baycom_epp.c             | 1316 ----------
 drivers/net/hamradio/baycom_par.c             |  598 -----
 drivers/net/hamradio/baycom_ser_fdx.c         |  678 -----
 drivers/net/hamradio/baycom_ser_hdx.c         |  727 ------
 drivers/net/hamradio/bpqether.c               |  593 -----
 drivers/net/hamradio/hdlcdrv.c                |  747 ------
 drivers/net/hamradio/mkiss.c                  |  980 --------
 drivers/net/hamradio/scc.c                    | 2179 -----------------
 drivers/net/hamradio/yam.c                    | 1191 ---------
 net/ax25/af_ax25.c                            | 2089 ----------------
 net/ax25/ax25_addr.c                          |  303 ---
 net/ax25/ax25_dev.c                           |  200 --
 net/ax25/ax25_ds_in.c                         |  298 ---
 net/ax25/ax25_ds_subr.c                       |  204 --
 net/ax25/ax25_ds_timer.c                      |  235 --
 net/ax25/ax25_iface.c                         |  214 --
 net/ax25/ax25_in.c                            |  455 ----
 net/ax25/ax25_ip.c                            |  247 --
 net/ax25/ax25_out.c                           |  398 ---
 net/ax25/ax25_route.c                         |  416 ----
 net/ax25/ax25_std_in.c                        |  443 ----
 net/ax25/ax25_std_subr.c                      |   83 -
 net/ax25/ax25_std_timer.c                     |  175 --
 net/ax25/ax25_subr.c                          |  296 ---
 net/ax25/ax25_timer.c                         |  224 --
 net/ax25/ax25_uid.c                           |  204 --
 net/ax25/sysctl_net_ax25.c                    |  181 --
 net/ipv4/arp.c                                |    1 -
 net/netrom/af_netrom.c                        | 1536 ------------
 net/netrom/nr_dev.c                           |  178 --
 net/netrom/nr_in.c                            |  301 ---
 net/netrom/nr_loopback.c                      |   73 -
 net/netrom/nr_out.c                           |  272 --
 net/netrom/nr_route.c                         |  989 --------
 net/netrom/nr_subr.c                          |  280 ---
 net/netrom/nr_timer.c                         |  249 --
 net/netrom/sysctl_net_netrom.c                |  156 --
 net/rose/af_rose.c                            | 1687 -------------
 net/rose/rose_dev.c                           |  141 --
 net/rose/rose_in.c                            |  301 ---
 net/rose/rose_link.c                          |  289 ---
 net/rose/rose_loopback.c                      |  133 -
 net/rose/rose_out.c                           |  122 -
 net/rose/rose_route.c                         | 1333 ----------
 net/rose/rose_subr.c                          |  556 -----
 net/rose/rose_timer.c                         |  227 --
 net/rose/sysctl_net_rose.c                    |  125 -
 arch/mips/configs/bcm47xx_defconfig           |    1 -
 arch/mips/configs/bigsur_defconfig            |   10 -
 arch/mips/configs/gpr_defconfig               |   11 -
 arch/mips/configs/mtx1_defconfig              |   11 -
 arch/mips/configs/rb532_defconfig             |    1 -
 arch/mips/configs/rm200_defconfig             |    7 -
 arch/mips/configs/rt305x_defconfig            |    1 -
 arch/mips/configs/xway_defconfig              |    1 -
 93 files changed, 6 insertions(+), 29237 deletions(-)
 delete mode 100644 Documentation/networking/6pack.rst
 delete mode 100644 Documentation/networking/ax25.rst
 delete mode 100644 Documentation/networking/device_drivers/hamradio/baycom.rst
 delete mode 100644 Documentation/networking/device_drivers/hamradio/index.rst
 delete mode 100644 Documentation/networking/device_drivers/hamradio/z8530drv.rst
 delete mode 100644 drivers/net/hamradio/Kconfig
 delete mode 100644 net/ax25/Kconfig
 delete mode 100644 drivers/net/hamradio/Makefile
 delete mode 100644 net/ax25/Makefile
 delete mode 100644 net/netrom/Makefile
 delete mode 100644 net/rose/Makefile
 delete mode 100644 drivers/net/hamradio/z8530.h
 delete mode 100644 include/linux/hdlcdrv.h
 delete mode 100644 include/linux/scc.h
 delete mode 100644 include/linux/yam.h
 delete mode 100644 include/net/netrom.h
 delete mode 100644 include/uapi/linux/baycom.h
 delete mode 100644 include/uapi/linux/hdlcdrv.h
 delete mode 100644 include/uapi/linux/netrom.h
 delete mode 100644 include/uapi/linux/rose.h
 delete mode 100644 include/uapi/linux/scc.h
 delete mode 100644 drivers/net/hamradio/6pack.c
 delete mode 100644 drivers/net/hamradio/baycom_epp.c
 delete mode 100644 drivers/net/hamradio/baycom_par.c
 delete mode 100644 drivers/net/hamradio/baycom_ser_fdx.c
 delete mode 100644 drivers/net/hamradio/baycom_ser_hdx.c
 delete mode 100644 drivers/net/hamradio/bpqether.c
 delete mode 100644 drivers/net/hamradio/hdlcdrv.c
 delete mode 100644 drivers/net/hamradio/mkiss.c
 delete mode 100644 drivers/net/hamradio/scc.c
 delete mode 100644 drivers/net/hamradio/yam.c
 delete mode 100644 net/ax25/af_ax25.c
 delete mode 100644 net/ax25/ax25_addr.c
 delete mode 100644 net/ax25/ax25_dev.c
 delete mode 100644 net/ax25/ax25_ds_in.c
 delete mode 100644 net/ax25/ax25_ds_subr.c
 delete mode 100644 net/ax25/ax25_ds_timer.c
 delete mode 100644 net/ax25/ax25_iface.c
 delete mode 100644 net/ax25/ax25_in.c
 delete mode 100644 net/ax25/ax25_ip.c
 delete mode 100644 net/ax25/ax25_out.c
 delete mode 100644 net/ax25/ax25_route.c
 delete mode 100644 net/ax25/ax25_std_in.c
 delete mode 100644 net/ax25/ax25_std_subr.c
 delete mode 100644 net/ax25/ax25_std_timer.c
 delete mode 100644 net/ax25/ax25_subr.c
 delete mode 100644 net/ax25/ax25_timer.c
 delete mode 100644 net/ax25/ax25_uid.c
 delete mode 100644 net/ax25/sysctl_net_ax25.c
 delete mode 100644 net/netrom/af_netrom.c
 delete mode 100644 net/netrom/nr_dev.c
 delete mode 100644 net/netrom/nr_in.c
 delete mode 100644 net/netrom/nr_loopback.c
 delete mode 100644 net/netrom/nr_out.c
 delete mode 100644 net/netrom/nr_route.c
 delete mode 100644 net/netrom/nr_subr.c
 delete mode 100644 net/netrom/nr_timer.c
 delete mode 100644 net/netrom/sysctl_net_netrom.c
 delete mode 100644 net/rose/af_rose.c
 delete mode 100644 net/rose/rose_dev.c
 delete mode 100644 net/rose/rose_in.c
 delete mode 100644 net/rose/rose_link.c
 delete mode 100644 net/rose/rose_loopback.c
 delete mode 100644 net/rose/rose_out.c
 delete mode 100644 net/rose/rose_route.c
 delete mode 100644 net/rose/rose_subr.c
 delete mode 100644 net/rose/rose_timer.c
 delete mode 100644 net/rose/sysctl_net_rose.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 66f29cde4985..cfcf422dd40a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -102,12 +102,6 @@ F:	Documentation/networking/6lowpan.rst
 F:	include/net/6lowpan.h
 F:	net/6lowpan/
 
-6PACK NETWORK DRIVER FOR AX.25
-M:	Andreas Koensgen <ajk@comnets.uni-bremen.de>
-L:	linux-hams@vger.kernel.org
-S:	Maintained
-F:	drivers/net/hamradio/6pack.c
-
 802.11 (including CFG80211/NL80211)
 M:	Johannes Berg <johannes@sipsolutions.net>
 L:	linux-wireless@vger.kernel.org
@@ -4281,14 +4275,6 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/leds/backlight/awinic,aw99706.yaml
 F:	drivers/video/backlight/aw99706.c
 
-AX.25 NETWORK LAYER
-L:	linux-hams@vger.kernel.org
-S:	Orphan
-W:	https://linux-ax25.in-berlin.de
-F:	include/net/ax25.h
-F:	include/uapi/linux/ax25.h
-F:	net/ax25/
-
 AXENTIA ARM DEVICES
 M:	Peter Rosin <peda@axentia.se>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -4430,13 +4416,6 @@ F:	include/uapi/linux/batadv_packet.h
 F:	include/uapi/linux/batman_adv.h
 F:	net/batman-adv/
 
-BAYCOM/HDLCDRV DRIVERS FOR AX.25
-M:	Thomas Sailer <t.sailer@alumni.ethz.ch>
-L:	linux-hams@vger.kernel.org
-S:	Maintained
-W:	http://www.baycom.org/~tom/ham/ham.html
-F:	drivers/net/hamradio/baycom*
-
 BCACHE (BLOCK LAYER CACHE)
 M:	Coly Li <colyli@fnnas.com>
 M:	Kent Overstreet <kent.overstreet@linux.dev>
@@ -7020,20 +6999,6 @@ S:	Maintained
 F:	drivers/rtc/rtc-ds1685.c
 F:	include/linux/rtc/ds1685.h
 
-DAMA SLAVE for AX.25
-M:	Joerg Reuter <jreuter@yaina.de>
-L:	linux-hams@vger.kernel.org
-S:	Maintained
-W:	http://yaina.de/jreuter/
-W:	http://www.qsl.net/dl1bke/
-F:	net/ax25/af_ax25.c
-F:	net/ax25/ax25_dev.c
-F:	net/ax25/ax25_ds_*
-F:	net/ax25/ax25_in.c
-F:	net/ax25/ax25_out.c
-F:	net/ax25/ax25_timer.c
-F:	net/ax25/sysctl_net_ax25.c
-
 DASHARO ACPI PLATFORM DRIVER
 M:	Michał Kopeć <michal.kopec@3mdeb.com>
 S:	Maintained
@@ -11444,11 +11409,6 @@ T:	git https://github.com/Rust-for-Linux/linux.git timekeeping-next
 F:	rust/kernel/time.rs
 F:	rust/kernel/time/
 
-HIGH-SPEED SCC DRIVER FOR AX.25
-L:	linux-hams@vger.kernel.org
-S:	Orphan
-F:	drivers/net/hamradio/scc.c
-
 HIGHPOINT ROCKETRAID 3xxx RAID DRIVER
 M:	HighPoint Linux Team <linux@highpoint-tech.com>
 S:	Supported
@@ -18272,14 +18232,6 @@ F:	net/bridge/br_netfilter*.c
 F:	net/netfilter/
 F:	tools/testing/selftests/net/netfilter/
 
-NETROM NETWORK LAYER
-L:	linux-hams@vger.kernel.org
-S:	Orphan
-W:	https://linux-ax25.in-berlin.de
-F:	include/net/netrom.h
-F:	include/uapi/linux/netrom.h
-F:	net/netrom/
-
 NETRONIX EMBEDDED CONTROLLER
 M:	Jonathan Neuschäfer <j.neuschaefer@gmx.net>
 S:	Maintained
@@ -23072,14 +23024,6 @@ F:	include/linux/mfd/rohm-bd96802.h
 F:	include/linux/mfd/rohm-generic.h
 F:	include/linux/mfd/rohm-shared.h
 
-ROSE NETWORK LAYER
-L:	linux-hams@vger.kernel.org
-S:	Orphan
-W:	https://linux-ax25.in-berlin.de
-F:	include/net/rose.h
-F:	include/uapi/linux/rose.h
-F:	net/rose/
-
 ROTATION DRIVER FOR ALLWINNER A83T
 M:	Jernej Skrabec <jernej.skrabec@gmail.com>
 L:	linux-media@vger.kernel.org
@@ -29105,13 +29049,6 @@ F:	lib/decompress_unxz.c
 F:	lib/xz/
 F:	scripts/xz_wrap.sh
 
-YAM DRIVER FOR AX.25
-M:	Jean-Paul Roubelat <jpr@f6fbb.org>
-L:	linux-hams@vger.kernel.org
-S:	Maintained
-F:	drivers/net/hamradio/yam*
-F:	include/linux/yam.h
-
 YAMA SECURITY MODULE
 M:	Kees Cook <kees@kernel.org>
 S:	Supported
@@ -29133,16 +29070,6 @@ S:	Maintained
 F:	Documentation/input/devices/yealink.rst
 F:	drivers/input/misc/yealink.*
 
-Z8530 DRIVER FOR AX.25
-M:	Joerg Reuter <jreuter@yaina.de>
-L:	linux-hams@vger.kernel.org
-S:	Maintained
-W:	http://yaina.de/jreuter/
-W:	http://www.qsl.net/dl1bke/
-F:	Documentation/networking/device_drivers/hamradio/z8530drv.rst
-F:	drivers/net/hamradio/*scc.c
-F:	drivers/net/hamradio/z8530.h
-
 ZD1211RW WIRELESS DRIVER
 L:	linux-wireless@vger.kernel.org
 S:	Orphan
diff --git a/Documentation/.renames.txt b/Documentation/.renames.txt
index c4de5200abdb..df4db1121995 100644
--- a/Documentation/.renames.txt
+++ b/Documentation/.renames.txt
@@ -783,7 +783,6 @@ namespaces/compatibility-list admin-guide/namespaces/compatibility-list
 namespaces/index admin-guide/namespaces/index
 namespaces/resource-control admin-guide/namespaces/resource-control
 networking/altera_tse networking/device_drivers/ethernet/altera/altera_tse
-networking/baycom networking/device_drivers/hamradio/baycom
 networking/bpf_flow_dissector bpf/prog_flow_dissector
 networking/cxacru networking/device_drivers/atm/cxacru
 networking/defza networking/device_drivers/fddi/defza
@@ -846,7 +845,6 @@ networking/ixgbe networking/device_drivers/ethernet/intel/ixgbe
 networking/ixgbevf networking/device_drivers/ethernet/intel/ixgbevf
 networking/netdev-FAQ process/maintainer-netdev
 networking/skfp networking/device_drivers/fddi/skfp
-networking/z8530drv networking/device_drivers/hamradio/z8530drv
 nfc/index driver-api/nfc/index
 nfc/nfc-hci driver-api/nfc/nfc-hci
 nfc/nfc-pn544 driver-api/nfc/nfc-pn544
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index f2ce1f4975c1..09354ff7cff2 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -6,7 +6,6 @@
 	APPARMOR AppArmor support is enabled.
 	ARM	ARM architecture is enabled.
 	ARM64	ARM64 architecture is enabled.
-	AX25	Appropriate AX.25 support is enabled.
 	CLK	Common clock infrastructure is enabled.
 	CMA	Contiguous Memory Area support is enabled.
 	DRM	Direct Rendering Management support is enabled.
@@ -633,23 +632,6 @@ Kernel parameters
 			1 - Enable the BAU.
 			unset - Disable the BAU.
 
-	baycom_epp=	[HW,AX25]
-			Format: <io>,<mode>
-
-	baycom_par=	[HW,AX25] BayCom Parallel Port AX.25 Modem
-			Format: <io>,<mode>
-			See header of drivers/net/hamradio/baycom_par.c.
-
-	baycom_ser_fdx=	[HW,AX25]
-			BayCom Serial Port AX.25 Modem (Full Duplex Mode)
-			Format: <io>,<irq>,<mode>[,<baud>]
-			See header of drivers/net/hamradio/baycom_ser_fdx.c.
-
-	baycom_ser_hdx=	[HW,AX25]
-			BayCom Serial Port AX.25 Modem (Half Duplex Mode)
-			Format: <io>,<irq>,<mode>
-			See header of drivers/net/hamradio/baycom_ser_hdx.c.
-
 	bdev_allow_write_mounted=
 			Format: <bool>
 			Control the ability to open a mounted block device
diff --git a/Documentation/networking/6pack.rst b/Documentation/networking/6pack.rst
deleted file mode 100644
index 66d5fd4fc821..000000000000
--- a/Documentation/networking/6pack.rst
+++ /dev/null
@@ -1,191 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==============
-6pack Protocol
-==============
-
-This is the 6pack-mini-HOWTO, written by
-
-Andreas Könsgen DG3KQ
-
-:Internet: ajk@comnets.uni-bremen.de
-:AMPR-net: dg3kq@db0pra.ampr.org
-:AX.25:    dg3kq@db0ach.#nrw.deu.eu
-
-Last update: April 7, 1998
-
-1. What is 6pack, and what are the advantages to KISS?
-======================================================
-
-6pack is a transmission protocol for data exchange between the PC and
-the TNC over a serial line. It can be used as an alternative to KISS.
-
-6pack has two major advantages:
-
-- The PC is given full control over the radio
-  channel. Special control data is exchanged between the PC and the TNC so
-  that the PC knows at any time if the TNC is receiving data, if a TNC
-  buffer underrun or overrun has occurred, if the PTT is
-  set and so on. This control data is processed at a higher priority than
-  normal data, so a data stream can be interrupted at any time to issue an
-  important event. This helps to improve the channel access and timing
-  algorithms as everything is computed in the PC. It would even be possible
-  to experiment with something completely different from the known CSMA and
-  DAMA channel access methods.
-  This kind of real-time control is especially important to supply several
-  TNCs that are connected between each other and the PC by a daisy chain
-  (however, this feature is not supported yet by the Linux 6pack driver).
-
-- Each packet transferred over the serial line is supplied with a checksum,
-  so it is easy to detect errors due to problems on the serial line.
-  Received packets that are corrupt are not passed on to the AX.25 layer.
-  Damaged packets that the TNC has received from the PC are not transmitted.
-
-More details about 6pack are described in the file 6pack.ps that is located
-in the doc directory of the AX.25 utilities package.
-
-2. Who has developed the 6pack protocol?
-========================================
-
-The 6pack protocol has been developed by Ekki Plicht DF4OR, Henning Rech
-DF9IC and Gunter Jost DK7WJ. A driver for 6pack, written by Gunter Jost and
-Matthias Welwarsky DG2FEF, comes along with the PC version of FlexNet.
-They have also written a firmware for TNCs to perform the 6pack
-protocol (see section 4 below).
-
-3. Where can I get the latest version of 6pack for LinuX?
-=========================================================
-
-At the moment, the 6pack stuff can obtained via anonymous ftp from
-db0bm.automation.fh-aachen.de. In the directory /incoming/dg3kq,
-there is a file named 6pack.tgz.
-
-4. Preparing the TNC for 6pack operation
-========================================
-
-To be able to use 6pack, a special firmware for the TNC is needed. The EPROM
-of a newly bought TNC does not contain 6pack, so you will have to
-program an EPROM yourself. The image file for 6pack EPROMs should be
-available on any packet radio box where PC/FlexNet can be found. The name of
-the file is 6pack.bin. This file is copyrighted and maintained by the FlexNet
-team. It can be used under the terms of the license that comes along
-with PC/FlexNet. Please do not ask me about the internals of this file as I
-don't know anything about it. I used a textual description of the 6pack
-protocol to program the Linux driver.
-
-TNCs contain a 64kByte EPROM, the lower half of which is used for
-the firmware/KISS. The upper half is either empty or is sometimes
-programmed with software called TAPR. In the latter case, the TNC
-is supplied with a DIP switch so you can easily change between the
-two systems. When programming a new EPROM, one of the systems is replaced
-by 6pack. It is useful to replace TAPR, as this software is rarely used
-nowadays. If your TNC is not equipped with the switch mentioned above, you
-can build in one yourself that switches over the highest address pin
-of the EPROM between HIGH and LOW level. After having inserted the new EPROM
-and switched to 6pack, apply power to the TNC for a first test. The connect
-and the status LED are lit for about a second if the firmware initialises
-the TNC correctly.
-
-5. Building and installing the 6pack driver
-===========================================
-
-The driver has been tested with kernel version 2.1.90. Use with older
-kernels may lead to a compilation error because the interface to a kernel
-function has been changed in the 2.1.8x kernels.
-
-How to turn on 6pack support:
------------------------------
-
-- In the linux kernel configuration program, select the code maturity level
-  options menu and turn on the prompting for development drivers.
-
-- Select the amateur radio support menu and turn on the serial port 6pack
-  driver.
-
-- Compile and install the kernel and the modules.
-
-To use the driver, the kissattach program delivered with the AX.25 utilities
-has to be modified.
-
-- Do a cd to the directory that holds the kissattach sources. Edit the
-  kissattach.c file. At the top, insert the following lines::
-
-    #ifndef N_6PACK
-    #define N_6PACK (N_AX25+1)
-    #endif
-
-  Then find the line:
-
-    int disc = N_AX25;
-
-  and replace N_AX25 by N_6PACK.
-
-- Recompile kissattach. Rename it to spattach to avoid confusions.
-
-Installing the driver:
-----------------------
-
-- Do an insmod 6pack. Look at your /var/log/messages file to check if the
-  module has printed its initialization message.
-
-- Do a spattach as you would launch kissattach when starting a KISS port.
-  Check if the kernel prints the message '6pack: TNC found'.
-
-- From here, everything should work as if you were setting up a KISS port.
-  The only difference is that the network device that represents
-  the 6pack port is called sp instead of sl or ax. So, sp0 would be the
-  first 6pack port.
-
-Although the driver has been tested on various platforms, I still declare it
-ALPHA. BE CAREFUL! Sync your disks before insmoding the 6pack module
-and spattaching. Watch out if your computer behaves strangely. Read section
-6 of this file about known problems.
-
-Note that the connect and status LEDs of the TNC are controlled in a
-different way than they are when the TNC is used with PC/FlexNet. When using
-FlexNet, the connect LED is on if there is a connection; the status LED is
-on if there is data in the buffer of the PC's AX.25 engine that has to be
-transmitted. Under Linux, the 6pack layer is beyond the AX.25 layer,
-so the 6pack driver doesn't know anything about connects or data that
-has not yet been transmitted. Therefore the LEDs are controlled
-as they are in KISS mode: The connect LED is turned on if data is transferred
-from the PC to the TNC over the serial line, the status LED if data is
-sent to the PC.
-
-6. Known problems
-=================
-
-When testing the driver with 2.0.3x kernels and
-operating with data rates on the radio channel of 9600 Baud or higher,
-the driver may, on certain systems, sometimes print the message '6pack:
-bad checksum', which is due to data loss if the other station sends two
-or more subsequent packets. I have been told that this is due to a problem
-with the serial driver of 2.0.3x kernels. I don't know yet if the problem
-still exists with 2.1.x kernels, as I have heard that the serial driver
-code has been changed with 2.1.x.
-
-When shutting down the sp interface with ifconfig, the kernel crashes if
-there is still an AX.25 connection left over which an IP connection was
-running, even if that IP connection is already closed. The problem does not
-occur when there is a bare AX.25 connection still running. I don't know if
-this is a problem of the 6pack driver or something else in the kernel.
-
-The driver has been tested as a module, not yet as a kernel-builtin driver.
-
-The 6pack protocol supports daisy-chaining of TNCs in a token ring, which is
-connected to one serial port of the PC. This feature is not implemented
-and at least at the moment I won't be able to do it because I do not have
-the opportunity to build a TNC daisy-chain and test it.
-
-Some of the comments in the source code are inaccurate. They are left from
-the SLIP/KISS driver, from which the 6pack driver has been derived.
-I haven't modified or removed them yet -- sorry! The code itself needs
-some cleaning and optimizing. This will be done in a later release.
-
-If you encounter a bug or if you have a question or suggestion concerning the
-driver, feel free to mail me, using the addresses given at the beginning of
-this file.
-
-Have fun!
-
-Andreas
diff --git a/Documentation/networking/ax25.rst b/Documentation/networking/ax25.rst
deleted file mode 100644
index 89c79dd6c6f9..000000000000
--- a/Documentation/networking/ax25.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=====
-AX.25
-=====
-
-To use the amateur radio protocols within Linux you will need to get a
-suitable copy of the AX.25 Utilities. More detailed information about
-AX.25, NET/ROM and ROSE, associated programs and utilities can be
-found on https://linux-ax25.in-berlin.de.
-
-There is a mailing list for discussing Linux amateur radio matters
-called linux-hams@vger.kernel.org. To subscribe to it, send a message to
-linux-hams+subscribe@vger.kernel.org or use the web interface at
-https://vger.kernel.org. The subject and body of the message are
-ignored.  You don't need to be subscribed to post but of course that
-means you might miss an answer.
diff --git a/Documentation/networking/device_drivers/hamradio/baycom.rst b/Documentation/networking/device_drivers/hamradio/baycom.rst
deleted file mode 100644
index fe2d010f0e86..000000000000
--- a/Documentation/networking/device_drivers/hamradio/baycom.rst
+++ /dev/null
@@ -1,174 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-===============================
-Linux Drivers for Baycom Modems
-===============================
-
-Thomas M. Sailer, HB9JNX/AE4WA, <sailer@ife.ee.ethz.ch>
-
-The drivers for the baycom modems have been split into
-separate drivers as they did not share any code, and the driver
-and device names have changed.
-
-This document describes the Linux Kernel Drivers for simple Baycom style
-amateur radio modems.
-
-The following drivers are available:
-====================================
-
-baycom_ser_fdx:
-  This driver supports the SER12 modems either full or half duplex.
-  Its baud rate may be changed via the ``baud`` module parameter,
-  therefore it supports just about every bit bang modem on a
-  serial port. Its devices are called bcsf0 through bcsf3.
-  This is the recommended driver for SER12 type modems,
-  however if you have a broken UART clone that does not have working
-  delta status bits, you may try baycom_ser_hdx.
-
-baycom_ser_hdx:
-  This is an alternative driver for SER12 type modems.
-  It only supports half duplex, and only 1200 baud. Its devices
-  are called bcsh0 through bcsh3. Use this driver only if baycom_ser_fdx
-  does not work with your UART.
-
-baycom_par:
-  This driver supports the par96 and picpar modems.
-  Its devices are called bcp0 through bcp3.
-
-baycom_epp:
-  This driver supports the EPP modem.
-  Its devices are called bce0 through bce3.
-  This driver is work-in-progress.
-
-The following modems are supported:
-
-======= ========================================================================
-ser12   This is a very simple 1200 baud AFSK modem. The modem consists only
-	of a modulator/demodulator chip, usually a TI TCM3105. The computer
-	is responsible for regenerating the receiver bit clock, as well as
-	for handling the HDLC protocol. The modem connects to a serial port,
-	hence the name. Since the serial port is not used as an async serial
-	port, the kernel driver for serial ports cannot be used, and this
-	driver only supports standard serial hardware (8250, 16450, 16550)
-
-par96   This is a modem for 9600 baud FSK compatible to the G3RUH standard.
-	The modem does all the filtering and regenerates the receiver clock.
-	Data is transferred from and to the PC via a shift register.
-	The shift register is filled with 16 bits and an interrupt is signalled.
-	The PC then empties the shift register in a burst. This modem connects
-	to the parallel port, hence the name. The modem leaves the
-	implementation of the HDLC protocol and the scrambler polynomial to
-	the PC.
-
-picpar  This is a redesign of the par96 modem by Henning Rech, DF9IC. The modem
-	is protocol compatible to par96, but uses only three low power ICs
-	and can therefore be fed from the parallel port and does not require
-	an additional power supply. Furthermore, it incorporates a carrier
-	detect circuitry.
-
-EPP     This is a high-speed modem adaptor that connects to an enhanced parallel
-	port.
-
-	Its target audience is users working over a high speed hub (76.8kbit/s).
-
-eppfpga This is a redesign of the EPP adaptor.
-======= ========================================================================
-
-All of the above modems only support half duplex communications. However,
-the driver supports the KISS (see below) fullduplex command. It then simply
-starts to send as soon as there's a packet to transmit and does not care
-about DCD, i.e. it starts to send even if there's someone else on the channel.
-This command is required by some implementations of the DAMA channel
-access protocol.
-
-
-The Interface of the drivers
-============================
-
-Unlike previous drivers, these drivers are no longer character devices,
-but they are now true kernel network interfaces. Installation is therefore
-simple. Once installed, four interfaces named bc{sf,sh,p,e}[0-3] are available.
-sethdlc from the ax25 utilities may be used to set driver states etc.
-Users of userland AX.25 stacks may use the net2kiss utility (also available
-in the ax25 utilities package) to convert packets of a network interface
-to a KISS stream on a pseudo tty. There's also a patch available from
-me for WAMPES which allows attaching a kernel network interface directly.
-
-
-Configuring the driver
-======================
-
-Every time a driver is inserted into the kernel, it has to know which
-modems it should access at which ports. This can be done with the setbaycom
-utility. If you are only using one modem, you can also configure the
-driver from the insmod command line (or by means of an option line in
-``/etc/modprobe.d/*.conf``).
-
-Examples::
-
-  modprobe baycom_ser_fdx mode="ser12*" iobase=0x3f8 irq=4
-  sethdlc -i bcsf0 -p mode "ser12*" io 0x3f8 irq 4
-
-Both lines configure the first port to drive a ser12 modem at the first
-serial port (COM1 under DOS). The * in the mode parameter instructs the driver
-to use the software DCD algorithm (see below)::
-
-  insmod baycom_par mode="picpar" iobase=0x378
-  sethdlc -i bcp0 -p mode "picpar" io 0x378
-
-Both lines configure the first port to drive a picpar modem at the
-first parallel port (LPT1 under DOS). (Note: picpar implies
-hardware DCD, par96 implies software DCD).
-
-The channel access parameters can be set with sethdlc -a or kissparms.
-Note that both utilities interpret the values slightly differently.
-
-
-Hardware DCD versus Software DCD
-================================
-
-To avoid collisions on the air, the driver must know when the channel is
-busy. This is the task of the DCD circuitry/software. The driver may either
-utilise a software DCD algorithm (options=1) or use a DCD signal from
-the hardware (options=0).
-
-======= =================================================================
-ser12   if software DCD is utilised, the radio's squelch should always be
-	open. It is highly recommended to use the software DCD algorithm,
-	as it is much faster than most hardware squelch circuitry. The
-	disadvantage is a slightly higher load on the system.
-
-par96   the software DCD algorithm for this type of modem is rather poor.
-	The modem simply does not provide enough information to implement
-	a reasonable DCD algorithm in software. Therefore, if your radio
-	feeds the DCD input of the PAR96 modem, the use of the hardware
-	DCD circuitry is recommended.
-
-picpar  the picpar modem features a builtin DCD hardware, which is highly
-	recommended.
-======= =================================================================
-
-
-
-Compatibility with the rest of the Linux kernel
-===============================================
-
-The serial driver and the baycom serial drivers compete
-for the same hardware resources. Of course only one driver can access a given
-interface at a time. The serial driver grabs all interfaces it can find at
-startup time. Therefore the baycom drivers subsequently won't be able to
-access a serial port. You might therefore find it necessary to release
-a port owned by the serial driver with 'setserial /dev/ttyS# uart none', where
-# is the number of the interface. The baycom drivers do not reserve any
-ports at startup, unless one is specified on the 'insmod' command line. Another
-method to solve the problem is to compile all drivers as modules and
-leave it to kmod to load the correct driver depending on the application.
-
-The parallel port drivers (baycom_par, baycom_epp) now use the parport subsystem
-to arbitrate the ports between different client drivers.
-
-vy 73s de
-
-Tom Sailer, sailer@ife.ee.ethz.ch
-
-hb9jnx @ hb9w.ampr.org
diff --git a/Documentation/networking/device_drivers/hamradio/index.rst b/Documentation/networking/device_drivers/hamradio/index.rst
deleted file mode 100644
index 6af481c5b020..000000000000
--- a/Documentation/networking/device_drivers/hamradio/index.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-
-Amateur Radio Device Drivers
-============================
-
-Contents:
-
-.. toctree::
-   :maxdepth: 2
-
-   baycom
-   z8530drv
diff --git a/Documentation/networking/device_drivers/hamradio/z8530drv.rst b/Documentation/networking/device_drivers/hamradio/z8530drv.rst
deleted file mode 100644
index d2942760f167..000000000000
--- a/Documentation/networking/device_drivers/hamradio/z8530drv.rst
+++ /dev/null
@@ -1,686 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-.. include:: <isonum.txt>
-
-=========================================================
-SCC.C - Linux driver for Z8530 based HDLC cards for AX.25
-=========================================================
-
-
-This is a subset of the documentation. To use this driver you MUST have the
-full package from:
-
-Internet:
-
-    1. ftp://ftp.ccac.rwth-aachen.de/pub/jr/z8530drv-utils_3.0-3.tar.gz
-
-    2. ftp://ftp.pspt.fi/pub/ham/linux/ax25/z8530drv-utils_3.0-3.tar.gz
-
-Please note that the information in this document may be hopelessly outdated.
-A new version of the documentation, along with links to other important
-Linux Kernel AX.25 documentation and programs, is available on
-http://yaina.de/jreuter
-
-Copyright |copy| 1993,2000 by Joerg Reuter DL1BKE <jreuter@yaina.de>
-
-portions Copyright |copy| 1993 Guido ten Dolle PE1NNZ
-
-for the complete copyright notice see >> Copying.Z8530DRV <<
-
-1. Initialization of the driver
-===============================
-
-To use the driver, 3 steps must be performed:
-
-     1. if compiled as module: loading the module
-     2. Setup of hardware, MODEM and KISS parameters with sccinit
-     3. Attach each channel to the Linux kernel AX.25 with "ifconfig"
-
-Unlike the versions below 2.4 this driver is a real network device
-driver. If you want to run xNOS instead of our fine kernel AX.25
-use a 2.x version (available from above sites) or read the
-AX.25-HOWTO on how to emulate a KISS TNC on network device drivers.
-
-
-1.1 Loading the module
-======================
-
-(If you're going to compile the driver as a part of the kernel image,
- skip this chapter and continue with 1.2)
-
-Before you can use a module, you'll have to load it with::
-
-	insmod scc.o
-
-please read 'man insmod' that comes with module-init-tools.
-
-You should include the insmod in one of the /etc/rc.d/rc.* files,
-and don't forget to insert a call of sccinit after that. It
-will read your /etc/z8530drv.conf.
-
-1.2. /etc/z8530drv.conf
-=======================
-
-To setup all parameters you must run /sbin/sccinit from one
-of your rc.*-files. This has to be done BEFORE you can
-"ifconfig" an interface. Sccinit reads the file /etc/z8530drv.conf
-and sets the hardware, MODEM and KISS parameters. A sample file is
-delivered with this package. Change it to your needs.
-
-The file itself consists of two main sections.
-
-1.2.1 configuration of hardware parameters
-==========================================
-
-The hardware setup section defines the following parameters for each
-Z8530::
-
-    chip    1
-    data_a  0x300                   # data port A
-    ctrl_a  0x304                   # control port A
-    data_b  0x301                   # data port B
-    ctrl_b  0x305                   # control port B
-    irq     5                       # IRQ No. 5
-    pclock  4915200                 # clock
-    board   BAYCOM                  # hardware type
-    escc    no                      # enhanced SCC chip? (8580/85180/85280)
-    vector  0                       # latch for interrupt vector
-    special no                      # address of special function register
-    option  0                       # option to set via sfr
-
-
-chip
-	- this is just a delimiter to make sccinit a bit simpler to
-	  program. A parameter has no effect.
-
-data_a
-	- the address of the data port A of this Z8530 (needed)
-ctrl_a
-	- the address of the control port A (needed)
-data_b
-	- the address of the data port B (needed)
-ctrl_b
-	- the address of the control port B (needed)
-
-irq
-	- the used IRQ for this chip. Different chips can use different
-	  IRQs or the same. If they share an interrupt, it needs to be
-	  specified within one chip-definition only.
-
-pclock  - the clock at the PCLK pin of the Z8530 (option, 4915200 is
-	  default), measured in Hertz
-
-board
-	- the "type" of the board:
-
-	   =======================  ========
-	   SCC type                 value
-	   =======================  ========
-	   PA0HZP SCC card          PA0HZP
-	   EAGLE card               EAGLE
-	   PC100 card               PC100
-	   PRIMUS-PC (DG9BL) card   PRIMUS
-	   BayCom (U)SCC card       BAYCOM
-	   =======================  ========
-
-escc
-	- if you want support for ESCC chips (8580, 85180, 85280), set
-	  this to "yes" (option, defaults to "no")
-
-vector
-	- address of the vector latch (aka "intack port") for PA0HZP
-	  cards. There can be only one vector latch for all chips!
-	  (option, defaults to 0)
-
-special
-	- address of the special function register on several cards.
-	  (option, defaults to 0)
-
-option  - The value you write into that register (option, default is 0)
-
-You can specify up to four chips (8 channels). If this is not enough,
-just change::
-
-	#define MAXSCC 4
-
-to a higher value.
-
-Example for the BAYCOM USCC:
-----------------------------
-
-::
-
-	chip    1
-	data_a  0x300                   # data port A
-	ctrl_a  0x304                   # control port A
-	data_b  0x301                   # data port B
-	ctrl_b  0x305                   # control port B
-	irq     5                       # IRQ No. 5 (#)
-	board   BAYCOM                  # hardware type (*)
-	#
-	# SCC chip 2
-	#
-	chip    2
-	data_a  0x302
-	ctrl_a  0x306
-	data_b  0x303
-	ctrl_b  0x307
-	board   BAYCOM
-
-An example for a PA0HZP card:
------------------------------
-
-::
-
-	chip 1
-	data_a 0x153
-	data_b 0x151
-	ctrl_a 0x152
-	ctrl_b 0x150
-	irq 9
-	pclock 4915200
-	board PA0HZP
-	vector 0x168
-	escc no
-	#
-	#
-	#
-	chip 2
-	data_a 0x157
-	data_b 0x155
-	ctrl_a 0x156
-	ctrl_b 0x154
-	irq 9
-	pclock 4915200
-	board PA0HZP
-	vector 0x168
-	escc no
-
-A DRSI would should probably work with this:
---------------------------------------------
-(actually: two DRSI cards...)
-
-::
-
-	chip 1
-	data_a 0x303
-	data_b 0x301
-	ctrl_a 0x302
-	ctrl_b 0x300
-	irq 7
-	pclock 4915200
-	board DRSI
-	escc no
-	#
-	#
-	#
-	chip 2
-	data_a 0x313
-	data_b 0x311
-	ctrl_a 0x312
-	ctrl_b 0x310
-	irq 7
-	pclock 4915200
-	board DRSI
-	escc no
-
-Note that you cannot use the on-board baudrate generator off DRSI
-cards. Use "mode dpll" for clock source (see below).
-
-This is based on information provided by Mike Bilow (and verified
-by Paul Helay)
-
-The utility "gencfg"
---------------------
-
-If you only know the parameters for the PE1CHL driver for DOS,
-run gencfg. It will generate the correct port addresses (I hope).
-Its parameters are exactly the same as the ones you use with
-the "attach scc" command in net, except that the string "init" must
-not appear. Example::
-
-	gencfg 2 0x150 4 2 0 1 0x168 9 4915200
-
-will print a skeleton z8530drv.conf for the OptoSCC to stdout.
-
-::
-
-	gencfg 2 0x300 2 4 5 -4 0 7 4915200 0x10
-
-does the same for the BAYCOM USCC card. In my opinion it is much easier
-to edit scc_config.h...
-
-
-1.2.2 channel configuration
-===========================
-
-The channel definition is divided into three sub sections for each
-channel:
-
-An example for scc0::
-
-	# DEVICE
-
-	device scc0	# the device for the following params
-
-	# MODEM / BUFFERS
-
-	speed 1200		# the default baudrate
-	clock dpll		# clock source:
-				# 	dpll     = normal half duplex operation
-				# 	external = MODEM provides own Rx/Tx clock
-				#	divider  = use full duplex divider if
-				#		   installed (1)
-	mode nrzi		# HDLC encoding mode
-				#	nrzi = 1k2 MODEM, G3RUH 9k6 MODEM
-				#	nrz  = DF9IC 9k6 MODEM
-				#
-	bufsize	384		# size of buffers. Note that this must include
-				# the AX.25 header, not only the data field!
-				# (optional, defaults to 384)
-
-	# KISS (Layer 1)
-
-	txdelay 36              # (see chapter 1.4)
-	persist 64
-	slot    8
-	tail    8
-	fulldup 0
-	wait    12
-	min     3
-	maxkey  7
-	idle    3
-	maxdef  120
-	group   0
-	txoff   off
-	softdcd on
-	slip    off
-
-The order WITHIN these sections is unimportant. The order OF these
-sections IS important. The MODEM parameters are set with the first
-recognized KISS parameter...
-
-Please note that you can initialize the board only once after boot
-(or insmod). You can change all parameters but "mode" and "clock"
-later with the Sccparam program or through KISS. Just to avoid
-security holes...
-
-(1) this divider is usually mounted on the SCC-PBC (PA0HZP) or not
-    present at all (BayCom). It feeds back the output of the DPLL
-    (digital pll) as transmit clock. Using this mode without a divider
-    installed will normally result in keying the transceiver until
-    maxkey expires --- of course without sending anything (useful).
-
-2. Attachment of a channel by your AX.25 software
-=================================================
-
-2.1 Kernel AX.25
-================
-
-To set up an AX.25 device you can simply type::
-
-	ifconfig scc0 44.128.1.1 hw ax25 dl0tha-7
-
-This will create a network interface with the IP number 44.128.20.107
-and the callsign "dl0tha". If you do not have any IP number (yet) you
-can use any of the 44.128.0.0 network. Note that you do not need
-axattach. The purpose of axattach (like slattach) is to create a KISS
-network device linked to a TTY. Please read the documentation of the
-ax25-utils and the AX.25-HOWTO to learn how to set the parameters of
-the kernel AX.25.
-
-2.2 NOS, NET and TFKISS
-=======================
-
-Since the TTY driver (aka KISS TNC emulation) is gone you need
-to emulate the old behaviour. The cost of using these programs is
-that you probably need to compile the kernel AX.25, regardless of whether
-you actually use it or not. First setup your /etc/ax25/axports,
-for example::
-
-	9k6	dl0tha-9  9600  255 4 9600 baud port (scc3)
-	axlink	dl0tha-15 38400 255 4 Link to NOS
-
-Now "ifconfig" the scc device::
-
-	ifconfig scc3 44.128.1.1 hw ax25 dl0tha-9
-
-You can now axattach a pseudo-TTY::
-
-	axattach /dev/ptys0 axlink
-
-and start your NOS and attach /dev/ptys0 there. The problem is that
-NOS is reachable only via digipeating through the kernel AX.25
-(disastrous on a DAMA controlled channel). To solve this problem,
-configure "rxecho" to echo the incoming frames from "9k6" to "axlink"
-and outgoing frames from "axlink" to "9k6" and start::
-
-	rxecho
-
-Or simply use "kissbridge" coming with z8530drv-utils::
-
-	ifconfig scc3 hw ax25 dl0tha-9
-	kissbridge scc3 /dev/ptys0
-
-
-3. Adjustment and Display of parameters
-=======================================
-
-3.1 Displaying SCC Parameters:
-==============================
-
-Once a SCC channel has been attached, the parameter settings and
-some statistic information can be shown using the param program::
-
-	dl1bke-u:~$ sccstat scc0
-
-	Parameters:
-
-	speed       : 1200 baud
-	txdelay     : 36
-	persist     : 255
-	slottime    : 0
-	txtail      : 8
-	fulldup     : 1
-	waittime    : 12
-	mintime     : 3 sec
-	maxkeyup    : 7 sec
-	idletime    : 3 sec
-	maxdefer    : 120 sec
-	group       : 0x00
-	txoff       : off
-	softdcd     : on
-	SLIP        : off
-
-	Status:
-
-	HDLC                  Z8530           Interrupts         Buffers
-	-----------------------------------------------------------------------
-	Sent       :     273  RxOver :     0  RxInts :   125074  Size    :  384
-	Received   :    1095  TxUnder:     0  TxInts :     4684  NoSpace :    0
-	RxErrors   :    1591                  ExInts :    11776
-	TxErrors   :       0                  SpInts :     1503
-	Tx State   :    idle
-
-
-The status info shown is:
-
-==============	==============================================================
-Sent		number of frames transmitted
-Received	number of frames received
-RxErrors	number of receive errors (CRC, ABORT)
-TxErrors	number of discarded Tx frames (due to various reasons)
-Tx State	status of the Tx interrupt handler: idle/busy/active/tail (2)
-RxOver		number of receiver overruns
-TxUnder		number of transmitter underruns
-RxInts		number of receiver interrupts
-TxInts		number of transmitter interrupts
-EpInts		number of receiver special condition interrupts
-SpInts		number of external/status interrupts
-Size		maximum size of an AX.25 frame (*with* AX.25 headers!)
-NoSpace		number of times a buffer could not get allocated
-==============	==============================================================
-
-An overrun is abnormal. If lots of these occur, the product of
-baudrate and number of interfaces is too high for the processing
-power of your computer. NoSpace errors are unlikely to be caused by the
-driver or the kernel AX.25.
-
-
-3.2 Setting Parameters
-======================
-
-
-The setting of parameters of the emulated KISS TNC is done in the
-same way in the SCC driver. You can change parameters by using
-the kissparms program from the ax25-utils package or use the program
-"sccparam"::
-
-     sccparam <device> <paramname> <decimal-|hexadecimal value>
-
-You can change the following parameters:
-
-===========   =====
-param	      value
-===========   =====
-speed         1200
-txdelay       36
-persist       255
-slottime      0
-txtail        8
-fulldup       1
-waittime      12
-mintime       3
-maxkeyup      7
-idletime      3
-maxdefer      120
-group         0x00
-txoff         off
-softdcd       on
-SLIP          off
-===========   =====
-
-
-The parameters have the following meaning:
-
-speed:
-     The baudrate on this channel in bits/sec
-
-     Example: sccparam /dev/scc3 speed 9600
-
-txdelay:
-     The delay (in units of 10 ms) after keying of the
-     transmitter, until the first byte is sent. This is usually
-     called "TXDELAY" in a TNC.  When 0 is specified, the driver
-     will just wait until the CTS signal is asserted. This
-     assumes the presence of a timer or other circuitry in the
-     MODEM and/or transmitter, that asserts CTS when the
-     transmitter is ready for data.
-     A normal value of this parameter is 30-36.
-
-     Example: sccparam /dev/scc0 txd 20
-
-persist:
-     This is the probability that the transmitter will be keyed
-     when the channel is found to be free.  It is a value from 0
-     to 255, and the probability is (value+1)/256.  The value
-     should be somewhere near 50-60, and should be lowered when
-     the channel is used more heavily.
-
-     Example: sccparam /dev/scc2 persist 20
-
-slottime:
-     This is the time between samples of the channel. It is
-     expressed in units of 10 ms.  About 200-300 ms (value 20-30)
-     seems to be a good value.
-
-     Example: sccparam /dev/scc0 slot 20
-
-tail:
-     The time the transmitter will remain keyed after the last
-     byte of a packet has been transferred to the SCC. This is
-     necessary because the CRC and a flag still have to leave the
-     SCC before the transmitter is keyed down. The value depends
-     on the baudrate selected.  A few character times should be
-     sufficient, e.g. 40ms at 1200 baud. (value 4)
-     The value of this parameter is in 10 ms units.
-
-     Example: sccparam /dev/scc2 4
-
-full:
-     The full-duplex mode switch. This can be one of the following
-     values:
-
-     0:   The interface will operate in CSMA mode (the normal
-	  half-duplex packet radio operation)
-     1:   Fullduplex mode, i.e. the transmitter will be keyed at
-	  any time, without checking the received carrier.  It
-	  will be unkeyed when there are no packets to be sent.
-     2:   Like 1, but the transmitter will remain keyed, also
-	  when there are no packets to be sent.  Flags will be
-	  sent in that case, until a timeout (parameter 10)
-	  occurs.
-
-     Example: sccparam /dev/scc0 fulldup off
-
-wait:
-     The initial waittime before any transmit attempt, after the
-     frame has been queue for transmit.  This is the length of
-     the first slot in CSMA mode.  In full duplex modes it is
-     set to 0 for maximum performance.
-     The value of this parameter is in 10 ms units.
-
-     Example: sccparam /dev/scc1 wait 4
-
-maxkey:
-     The maximal time the transmitter will be keyed to send
-     packets, in seconds.  This can be useful on busy CSMA
-     channels, to avoid "getting a bad reputation" when you are
-     generating a lot of traffic.  After the specified time has
-     elapsed, no new frame will be started. Instead, the trans-
-     mitter will be switched off for a specified time (parameter
-     min), and then the selected algorithm for keyup will be
-     started again.
-     The value 0 as well as "off" will disable this feature,
-     and allow infinite transmission time.
-
-     Example: sccparam /dev/scc0 maxk 20
-
-min:
-     This is the time the transmitter will be switched off when
-     the maximum transmission time is exceeded.
-
-     Example: sccparam /dev/scc3 min 10
-
-idle:
-     This parameter specifies the maximum idle time in full duplex
-     2 mode, in seconds.  When no frames have been sent for this
-     time, the transmitter will be keyed down.  A value of 0 is
-     has same result as the fullduplex mode 1. This parameter
-     can be disabled.
-
-     Example: sccparam /dev/scc2 idle off	# transmit forever
-
-maxdefer
-     This is the maximum time (in seconds) to wait for a free channel
-     to send. When this timer expires the transmitter will be keyed
-     IMMEDIATELY. If you love to get trouble with other users you
-     should set this to a very low value ;-)
-
-     Example: sccparam /dev/scc0 maxdefer 240	# 2 minutes
-
-
-txoff:
-     When this parameter has the value 0, the transmission of packets
-     is enable. Otherwise it is disabled.
-
-     Example: sccparam /dev/scc2 txoff on
-
-group:
-     It is possible to build special radio equipment to use more than
-     one frequency on the same band, e.g. using several receivers and
-     only one transmitter that can be switched between frequencies.
-     Also, you can connect several radios that are active on the same
-     band.  In these cases, it is not possible, or not a good idea, to
-     transmit on more than one frequency.  The SCC driver provides a
-     method to lock transmitters on different interfaces, using the
-     "param <interface> group <x>" command.  This will only work when
-     you are using CSMA mode (parameter full = 0).
-
-     The number <x> must be 0 if you want no group restrictions, and
-     can be computed as follows to create restricted groups:
-     <x> is the sum of some OCTAL numbers:
-
-
-     ===  =======================================================
-     200  This transmitter will only be keyed when all other
-	  transmitters in the group are off.
-     100  This transmitter will only be keyed when the carrier
-	  detect of all other interfaces in the group is off.
-     0xx  A byte that can be used to define different groups.
-	  Interfaces are in the same group, when the logical AND
-	  between their xx values is nonzero.
-     ===  =======================================================
-
-     Examples:
-
-     When 2 interfaces use group 201, their transmitters will never be
-     keyed at the same time.
-
-     When 2 interfaces use group 101, the transmitters will only key
-     when both channels are clear at the same time.  When group 301,
-     the transmitters will not be keyed at the same time.
-
-     Don't forget to convert the octal numbers into decimal before
-     you set the parameter.
-
-     Example: (to be written)
-
-softdcd:
-     use a software dcd instead of the real one... Useful for a very
-     slow squelch.
-
-     Example: sccparam /dev/scc0 soft on
-
-
-4. Problems
-===========
-
-If you have tx-problems with your BayCom USCC card please check
-the manufacturer of the 8530. SGS chips have a slightly
-different timing. Try Zilog...  A solution is to write to register 8
-instead to the data port, but this won't work with the ESCC chips.
-*SIGH!*
-
-A very common problem is that the PTT locks until the maxkeyup timer
-expires, although interrupts and clock source are correct. In most
-cases compiling the driver with CONFIG_SCC_DELAY (set with
-make config) solves the problems. For more hints read the (pseudo) FAQ
-and the documentation coming with z8530drv-utils.
-
-I got reports that the driver has problems on some 386-based systems.
-(i.e. Amstrad) Those systems have a bogus AT bus timing which will
-lead to delayed answers on interrupts. You can recognize these
-problems by looking at the output of Sccstat for the suspected
-port. If it shows under- and overruns you own such a system.
-
-Delayed processing of received data: This depends on
-
-- the kernel version
-
-- kernel profiling compiled or not
-
-- a high interrupt load
-
-- a high load of the machine --- running X, Xmorph, XV and Povray,
-  while compiling the kernel... hmm ... even with 32 MB RAM ...  ;-)
-  Or running a named for the whole .ampr.org domain on an 8 MB
-  box...
-
-- using information from rxecho or kissbridge.
-
-Kernel panics: please read /linux/README and find out if it
-really occurred within the scc driver.
-
-If you cannot solve a problem, send me
-
-- a description of the problem,
-- information on your hardware (computer system, scc board, modem)
-- your kernel version
-- the output of cat /proc/net/z8530
-
-4. Thor RLC100
-==============
-
-Mysteriously this board seems not to work with the driver. Anyone
-got it up-and-running?
-
-
-Many thanks to Linus Torvalds and Alan Cox for including the driver
-in the Linux standard distribution and their support.
-
-::
-
-	Joerg Reuter	ampr-net: dl1bke@db0pra.ampr.org
-			AX-25   : DL1BKE @ DB0ABH.#BAY.DEU.EU
-			Internet: jreuter@yaina.de
-			WWW     : http://yaina.de/jreuter
diff --git a/Documentation/networking/device_drivers/index.rst b/Documentation/networking/device_drivers/index.rst
index 1df51c9f7827..1f54f01d24be 100644
--- a/Documentation/networking/device_drivers/index.rst
+++ b/Documentation/networking/device_drivers/index.rst
@@ -13,6 +13,5 @@ Hardware Device Drivers
    cellular/index
    ethernet/index
    fddi/index
-   hamradio/index
    wifi/index
    wwan/index
diff --git a/Documentation/networking/index.rst b/Documentation/networking/index.rst
index 2e946924ad3f..44a422ad3b05 100644
--- a/Documentation/networking/index.rst
+++ b/Documentation/networking/index.rst
@@ -40,11 +40,9 @@ Refer to :ref:`netdev-FAQ` for a guide on netdev development process specifics.
    tls-handshake
    nfc
    6lowpan
-   6pack
    arcnet-hardware
    arcnet
    atm
-   ax25
    bonding
    cdc_mbim
    dctcp
diff --git a/Documentation/staging/magic-number.rst b/Documentation/staging/magic-number.rst
index 79afddf0e692..670d3189a976 100644
--- a/Documentation/staging/magic-number.rst
+++ b/Documentation/staging/magic-number.rst
@@ -72,11 +72,8 @@ PG_MAGIC              'P'              pg_{read,write}_hdr      ``include/uapi/l
 APM_BIOS_MAGIC        0x4101           apm_user                 ``arch/x86/kernel/apm_32.c``
 FASYNC_MAGIC          0x4601           fasync_struct            ``include/linux/fs.h``
 SLIP_MAGIC            0x5302           slip                     ``drivers/net/slip/slip.h``
-BAYCOM_MAGIC          19730510         baycom_state             ``drivers/net/hamradio/baycom_epp.c``
-HDLCDRV_MAGIC         0x5ac6e778       hdlcdrv_state            ``include/linux/hdlcdrv.h``
 KV_MAGIC              0x5f4b565f       kernel_vars_s            ``arch/mips/include/asm/sn/klkernvars.h``
 CODA_MAGIC            0xC0DAC0DA       coda_file_info           ``fs/coda/coda_fs_i.h``
-YAM_MAGIC             0xF10A7654       yam_port                 ``drivers/net/hamradio/yam.c``
 CCB_MAGIC             0xf2691ad2       ccb                      ``drivers/scsi/ncr53c8xx.c``
 QUEUE_MAGIC_FREE      0xf7e1c9a3       queue_entry              ``drivers/scsi/arm/queue.c``
 QUEUE_MAGIC_USED      0xf7e1cc33       queue_entry              ``drivers/scsi/arm/queue.c``
diff --git a/Documentation/translations/it_IT/staging/magic-number.rst b/Documentation/translations/it_IT/staging/magic-number.rst
index cd8f23571835..43dd6398300b 100644
--- a/Documentation/translations/it_IT/staging/magic-number.rst
+++ b/Documentation/translations/it_IT/staging/magic-number.rst
@@ -78,11 +78,8 @@ PG_MAGIC              'P'              pg_{read,write}_hdr      ``include/linux/
 APM_BIOS_MAGIC        0x4101           apm_user                 ``arch/x86/kernel/apm_32.c``
 FASYNC_MAGIC          0x4601           fasync_struct            ``include/linux/fs.h``
 SLIP_MAGIC            0x5302           slip                     ``drivers/net/slip.h``
-BAYCOM_MAGIC          0x19730510       baycom_state             ``drivers/net/baycom_epp.c``
-HDLCDRV_MAGIC         0x5ac6e778       hdlcdrv_state            ``include/linux/hdlcdrv.h``
 KV_MAGIC              0x5f4b565f       kernel_vars_s            ``arch/mips/include/asm/sn/klkernvars.h``
 CODA_MAGIC            0xC0DAC0DA       coda_file_info           ``fs/coda/coda_fs_i.h``
-YAM_MAGIC             0xF10A7654       yam_port                 ``drivers/net/hamradio/yam.c``
 CCB_MAGIC             0xf2691ad2       ccb                      ``drivers/scsi/ncr53c8xx.c``
 QUEUE_MAGIC_FREE      0xf7e1c9a3       queue_entry              ``drivers/scsi/arm/queue.c``
 QUEUE_MAGIC_USED      0xf7e1cc33       queue_entry              ``drivers/scsi/arm/queue.c``
diff --git a/Documentation/translations/sp_SP/process/magic-number.rst b/Documentation/translations/sp_SP/process/magic-number.rst
index beb4b4c1de11..f5b4c3f2849f 100644
--- a/Documentation/translations/sp_SP/process/magic-number.rst
+++ b/Documentation/translations/sp_SP/process/magic-number.rst
@@ -77,11 +77,8 @@ PG_MAGIC              'P'              pg_{read,write}_hdr      ``include/linux/
 APM_BIOS_MAGIC        0x4101           apm_user                 ``arch/x86/kernel/apm_32.c``
 FASYNC_MAGIC          0x4601           fasync_struct            ``include/linux/fs.h``
 SLIP_MAGIC            0x5302           slip                     ``drivers/net/slip.h``
-BAYCOM_MAGIC          0x19730510       baycom_state             ``drivers/net/baycom_epp.c``
-HDLCDRV_MAGIC         0x5ac6e778       hdlcdrv_state            ``include/linux/hdlcdrv.h``
 KV_MAGIC              0x5f4b565f       kernel_vars_s            ``arch/mips/include/asm/sn/klkernvars.h``
 CODA_MAGIC            0xC0DAC0DA       coda_file_info           ``fs/coda/coda_fs_i.h``
-YAM_MAGIC             0xF10A7654       yam_port                 ``drivers/net/hamradio/yam.c``
 CCB_MAGIC             0xf2691ad2       ccb                      ``drivers/scsi/ncr53c8xx.c``
 QUEUE_MAGIC_FREE      0xf7e1c9a3       queue_entry              ``drivers/scsi/arm/queue.c``
 QUEUE_MAGIC_USED      0xf7e1cc33       queue_entry              ``drivers/scsi/arm/queue.c``
diff --git a/Documentation/translations/zh_CN/process/magic-number.rst b/Documentation/translations/zh_CN/process/magic-number.rst
index 4ebc84cc0c54..05ee75cf4346 100644
--- a/Documentation/translations/zh_CN/process/magic-number.rst
+++ b/Documentation/translations/zh_CN/process/magic-number.rst
@@ -70,11 +70,8 @@ PG_MAGIC              'P'              pg_{read,write}_hdr      ``include/linux/
 APM_BIOS_MAGIC        0x4101           apm_user                 ``arch/x86/kernel/apm_32.c``
 FASYNC_MAGIC          0x4601           fasync_struct            ``include/linux/fs.h``
 SLIP_MAGIC            0x5302           slip                     ``drivers/net/slip.h``
-BAYCOM_MAGIC          0x19730510       baycom_state             ``drivers/net/baycom_epp.c``
-HDLCDRV_MAGIC         0x5ac6e778       hdlcdrv_state            ``include/linux/hdlcdrv.h``
 KV_MAGIC              0x5f4b565f       kernel_vars_s            ``arch/mips/include/asm/sn/klkernvars.h``
 CODA_MAGIC            0xC0DAC0DA       coda_file_info           ``fs/coda/coda_fs_i.h``
-YAM_MAGIC             0xF10A7654       yam_port                 ``drivers/net/hamradio/yam.c``
 CCB_MAGIC             0xf2691ad2       ccb                      ``drivers/scsi/ncr53c8xx.c``
 QUEUE_MAGIC_FREE      0xf7e1c9a3       queue_entry              ``drivers/scsi/arm/queue.c``
 QUEUE_MAGIC_USED      0xf7e1cc33       queue_entry              ``drivers/scsi/arm/queue.c``
diff --git a/Documentation/translations/zh_TW/process/magic-number.rst b/Documentation/translations/zh_TW/process/magic-number.rst
index 5582df6d7ca7..bc7eb025dd1e 100644
--- a/Documentation/translations/zh_TW/process/magic-number.rst
+++ b/Documentation/translations/zh_TW/process/magic-number.rst
@@ -64,11 +64,8 @@ PG_MAGIC              'P'              pg_{read,write}_hdr      ``include/linux/
 APM_BIOS_MAGIC        0x4101           apm_user                 ``arch/x86/kernel/apm_32.c``
 FASYNC_MAGIC          0x4601           fasync_struct            ``include/linux/fs.h``
 SLIP_MAGIC            0x5302           slip                     ``drivers/net/slip.h``
-BAYCOM_MAGIC          0x19730510       baycom_state             ``drivers/net/baycom_epp.c``
-HDLCDRV_MAGIC         0x5ac6e778       hdlcdrv_state            ``include/linux/hdlcdrv.h``
 KV_MAGIC              0x5f4b565f       kernel_vars_s            ``arch/mips/include/asm/sn/klkernvars.h``
 CODA_MAGIC            0xC0DAC0DA       coda_file_info           ``fs/coda/coda_fs_i.h``
-YAM_MAGIC             0xF10A7654       yam_port                 ``drivers/net/hamradio/yam.c``
 CCB_MAGIC             0xf2691ad2       ccb                      ``drivers/scsi/ncr53c8xx.c``
 QUEUE_MAGIC_FREE      0xf7e1c9a3       queue_entry              ``drivers/scsi/arm/queue.c``
 QUEUE_MAGIC_USED      0xf7e1cc33       queue_entry              ``drivers/scsi/arm/queue.c``
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
deleted file mode 100644
index 36a9aade9f33..000000000000
--- a/drivers/net/hamradio/Kconfig
+++ /dev/null
@@ -1,162 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-config MKISS
-	tristate "Serial port KISS driver"
-	depends on AX25 && TTY
-	select CRC16
-	help
-	  KISS is a protocol used for the exchange of data between a computer
-	  and a Terminal Node Controller (a small embedded system commonly
-	  used for networking over AX.25 amateur radio connections; it
-	  connects the computer's serial port with the radio's microphone
-	  input and speaker output).
-
-	  Although KISS is less advanced than the 6pack protocol, it has
-	  the advantage that it is already supported by most modern TNCs
-	  without the need for a firmware upgrade.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called mkiss.
-
-config 6PACK
-	tristate "Serial port 6PACK driver"
-	depends on AX25 && TTY
-	help
-	  6pack is a transmission protocol for the data exchange between your
-	  PC and your TNC (the Terminal Node Controller acts as a kind of
-	  modem connecting your computer's serial port to your radio's
-	  microphone input and speaker output). This protocol can be used as
-	  an alternative to KISS for networking over AX.25 amateur radio
-	  connections, but it has some extended functionality.
-
-	  Note that this driver is still experimental and might cause
-	  problems. For details about the features and the usage of the
-	  driver, read <file:Documentation/networking/6pack.rst>.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called 6pack.
-
-config BPQETHER
-	tristate "BPQ Ethernet driver"
-	depends on AX25
-	help
-	  AX.25 is the protocol used for computer communication over amateur
-	  radio. If you say Y here, you will be able to send and receive AX.25
-	  traffic over Ethernet (also called "BPQ AX.25"), which could be
-	  useful if some other computer on your local network has a direct
-	  amateur radio connection.
-
-config SCC
-	tristate "Z8530 SCC driver"
-	depends on ISA && AX25
-	help
-	  These cards are used to connect your Linux box to an amateur radio
-	  in order to communicate with other computers. If you want to use
-	  this, read
-	  <file:Documentation/networking/device_drivers/hamradio/z8530drv.rst>
-	  and the AX25-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>. Also make sure to say Y
-	  to "Amateur Radio AX.25 Level 2" support.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called scc.
-
-config SCC_DELAY
-	bool "additional delay for PA0HZP OptoSCC compatible boards"
-	depends on SCC
-	help
-	  Say Y here if you experience problems with the SCC driver not
-	  working properly; please read
-	  <file:Documentation/networking/device_drivers/hamradio/z8530drv.rst>
-	  for details.
-
-	  If unsure, say N.
-
-config SCC_TRXECHO
-	bool "support for TRX that feedback the tx signal to rx"
-	depends on SCC
-	help
-	  Some transmitters feed the transmitted signal back to the receive
-	  line.  Say Y here to foil this by explicitly disabling the receiver
-	  during data transmission.
-
-	  If in doubt, say Y.
-
-config BAYCOM_SER_FDX
-	tristate "BAYCOM ser12 fullduplex driver for AX.25"
-	depends on AX25 && HAS_IOPORT
-	select CRC_CCITT
-	help
-	  This is one of two drivers for Baycom style simple amateur radio
-	  modems that connect to a serial interface. The driver supports the
-	  ser12 design in full-duplex mode. In addition, it allows the
-	  baudrate to be set between 300 and 4800 baud (however not all modems
-	  support all baudrates). This is the preferred driver. The next
-	  driver, "BAYCOM ser12 half-duplex driver for AX.25" is the old
-	  driver and still provided in case this driver does not work with
-	  your serial interface chip. To configure the driver, use the sethdlc
-	  utility available in the standard ax25 utilities package.
-	  For more information on the modems, see
-	  <file:Documentation/networking/device_drivers/hamradio/baycom.rst>.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called baycom_ser_fdx.  This is recommended.
-
-config BAYCOM_SER_HDX
-	tristate "BAYCOM ser12 halfduplex driver for AX.25"
-	depends on AX25 && HAS_IOPORT
-	select CRC_CCITT
-	help
-	  This is one of two drivers for Baycom style simple amateur radio
-	  modems that connect to a serial interface. The driver supports the
-	  ser12 design in half-duplex mode. This is the old driver.  It is
-	  still provided in case your serial interface chip does not work with
-	  the full-duplex driver. This driver is deprecated.  To configure
-	  the driver, use the sethdlc utility available in the standard ax25
-	  utilities package. For more information on the modems, see
-	  <file:Documentation/networking/device_drivers/hamradio/baycom.rst>.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called baycom_ser_hdx.  This is recommended.
-
-config BAYCOM_PAR
-	tristate "BAYCOM picpar and par96 driver for AX.25"
-	depends on PARPORT && AX25
-	select CRC_CCITT
-	help
-	  This is a driver for Baycom style simple amateur radio modems that
-	  connect to a parallel interface. The driver supports the picpar and
-	  par96 designs. To configure the driver, use the sethdlc utility
-	  available in the standard ax25 utilities package.
-	  For more information on the modems, see
-	  <file:Documentation/networking/device_drivers/hamradio/baycom.rst>.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called baycom_par.  This is recommended.
-
-config BAYCOM_EPP
-	tristate "BAYCOM epp driver for AX.25"
-	depends on PARPORT && AX25 && !64BIT
-	select CRC_CCITT
-	help
-	  This is a driver for Baycom style simple amateur radio modems that
-	  connect to a parallel interface. The driver supports the EPP
-	  designs. To configure the driver, use the sethdlc utility available
-	  in the standard ax25 utilities package.
-	  For more information on the modems, see
-	  <file:Documentation/networking/device_drivers/hamradio/baycom.rst>.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called baycom_epp.  This is recommended.
-
-config YAM
-	tristate "YAM driver for AX.25"
-	depends on AX25 && HAS_IOPORT
-	help
-	  The YAM is a modem for packet radio which connects to the serial
-	  port and includes some of the functions of a Terminal Node
-	  Controller. If you have one of those, say Y here.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called yam.
-
- 
diff --git a/net/Kconfig b/net/Kconfig
index 5c588dbcbdbd..bdea8aef7983 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -414,7 +414,6 @@ endmenu # Network testing
 
 endmenu # Networking options
 
-source "net/ax25/Kconfig"
 source "net/can/Kconfig"
 source "net/bluetooth/Kconfig"
 source "net/rxrpc/Kconfig"
diff --git a/net/ax25/Kconfig b/net/ax25/Kconfig
deleted file mode 100644
index 310169ce1488..000000000000
--- a/net/ax25/Kconfig
+++ /dev/null
@@ -1,108 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Amateur Radio protocols and AX.25 device configuration
-#
-
-menuconfig HAMRADIO
-	depends on NET
-	bool "Amateur Radio support"
-	help
-	  If you want to connect your Linux box to an amateur radio, answer Y
-	  here. You want to read <https://www.tapr.org/>
-	  and more specifically about AX.25 on Linux
-	  <https://linux-ax25.in-berlin.de>.
-
-	  Note that the answer to this question won't directly affect the
-	  kernel: saying N will just cause the configurator to skip all
-	  the questions about amateur radio.
-
-comment "Packet Radio protocols"
-	depends on HAMRADIO
-
-config AX25
-	tristate "Amateur Radio AX.25 Level 2 protocol"
-	depends on HAMRADIO
-	help
-	  This is the protocol used for computer communication over amateur
-	  radio. It is either used by itself for point-to-point links, or to
-	  carry other protocols such as tcp/ip. To use it, you need a device
-	  that connects your Linux box to your amateur radio. You can either
-	  use a low speed TNC (a Terminal Node Controller acts as a kind of
-	  modem connecting your computer's serial port to your radio's
-	  microphone input and speaker output) supporting the KISS protocol or
-	  one of the various SCC cards that are supported by the generic Z8530
-	  or the DMA SCC driver. Another option are the Baycom modem serial
-	  and parallel port hacks or the sound card modem (supported by their
-	  own drivers). If you say Y here, you also have to say Y to one of
-	  those drivers.
-
-	  Information about where to get supporting software for Linux amateur
-	  radio as well as information about how to configure an AX.25 port is
-	  contained in the AX25-HOWTO, available from
-	  <https://www.tldp.org/docs.html#howto>. You might also want to
-	  check out the file <file:Documentation/networking/ax25.rst> in the
-	  kernel source. More information about digital amateur radio in
-	  general is on the WWW at
-	  <https://www.tapr.org/>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called ax25.
-
-config AX25_DAMA_SLAVE
-	bool "AX.25 DAMA Slave support"
-	default y
-	depends on AX25
-	help
-	  DAMA is a mechanism to prevent collisions when doing AX.25
-	  networking. A DAMA server (called "master") accepts incoming traffic
-	  from clients (called "slaves") and redistributes it to other slaves.
-	  If you say Y here, your Linux box will act as a DAMA slave; this is
-	  transparent in that you don't have to do any special DAMA
-	  configuration. Linux cannot yet act as a DAMA server.  This option
-	  only compiles DAMA slave support into the kernel.  It still needs to
-	  be enabled at runtime.  For more about DAMA see
-	  <https://linux-ax25.in-berlin.de>.  If unsure, say Y.
-
-config NETROM
-	tristate "Amateur Radio NET/ROM protocol"
-	depends on AX25
-	help
-	  NET/ROM is a network layer protocol on top of AX.25 useful for
-	  routing.
-
-	  A comprehensive listing of all the software for Linux amateur radio
-	  users as well as information about how to configure an AX.25 port is
-	  contained in the Linux Ham Wiki, available from
-	  <https://linux-ax25.in-berlin.de>. You also might want to check out
-	  the file <file:Documentation/networking/ax25.rst>. More information
-	  about digital amateur radio in general is on the WWW at
-	  <https://www.tapr.org/>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called netrom.
-
-config ROSE
-	tristate "Amateur Radio X.25 PLP (Rose)"
-	depends on AX25
-	help
-	  The Packet Layer Protocol (PLP) is a way to route packets over X.25
-	  connections in general and amateur radio AX.25 connections in
-	  particular, essentially an alternative to NET/ROM.
-
-	  A comprehensive listing of all the software for Linux amateur radio
-	  users as well as information about how to configure an AX.25 port is
-	  contained in the Linux Ham Wiki, available from
-	  <https://linux-ax25.in-berlin.de>.  You also might want to check out
-	  the file <file:Documentation/networking/ax25.rst>. More information
-	  about digital amateur radio in general is on the WWW at
-	  <https://www.tapr.org/>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called rose.
-
-menu "AX.25 network device drivers"
-	depends on HAMRADIO && AX25
-
-source "drivers/net/hamradio/Kconfig"
-
-endmenu
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 3b2d28127634..b87a741fc952 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -54,7 +54,6 @@ obj-y += dsa/
 endif
 obj-$(CONFIG_ETHERNET) += ethernet/
 obj-$(CONFIG_FDDI) += fddi/
-obj-$(CONFIG_HAMRADIO) += hamradio/
 obj-$(CONFIG_QCOM_IPA) += ipa/
 obj-$(CONFIG_PLIP) += plip/
 obj-$(CONFIG_PPP) += ppp/
diff --git a/drivers/net/hamradio/Makefile b/drivers/net/hamradio/Makefile
deleted file mode 100644
index 25fc400369ba..000000000000
--- a/drivers/net/hamradio/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the Linux AX.25 and HFMODEM device drivers.
-#
-#
-# 19971130 	Moved the amateur radio related network drivers from 
-#		drivers/net/ to drivers/hamradio for easier maintenance.
-#               Joerg Reuter DL1BKE <jreuter@yaina.de>
-#
-# 20000806	Rewritten to use lists instead of if-statements.
-#		Christoph Hellwig <hch@infradead.org>
-#
-
-obj-$(CONFIG_SCC)		+= scc.o
-obj-$(CONFIG_MKISS)		+= mkiss.o
-obj-$(CONFIG_6PACK)		+= 6pack.o
-obj-$(CONFIG_YAM)		+= yam.o
-obj-$(CONFIG_BPQETHER)		+= bpqether.o
-obj-$(CONFIG_BAYCOM_SER_FDX)	+= baycom_ser_fdx.o	hdlcdrv.o
-obj-$(CONFIG_BAYCOM_SER_HDX)	+= baycom_ser_hdx.o	hdlcdrv.o
-obj-$(CONFIG_BAYCOM_PAR)	+= baycom_par.o		hdlcdrv.o
-obj-$(CONFIG_BAYCOM_EPP)	+= baycom_epp.o		hdlcdrv.o
diff --git a/net/Makefile b/net/Makefile
index 98e182829eff..d2175fce0406 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -28,9 +28,6 @@ obj-y				+= dsa/
 obj-$(CONFIG_ATALK)		+= appletalk/
 obj-$(CONFIG_X25)		+= x25/
 obj-$(CONFIG_LAPB)		+= lapb/
-obj-$(CONFIG_NETROM)		+= netrom/
-obj-$(CONFIG_ROSE)		+= rose/
-obj-$(CONFIG_AX25)		+= ax25/
 obj-$(CONFIG_CAN)		+= can/
 obj-$(CONFIG_BT)		+= bluetooth/
 obj-$(CONFIG_SUNRPC)		+= sunrpc/
diff --git a/net/ax25/Makefile b/net/ax25/Makefile
deleted file mode 100644
index 2e53affc8568..000000000000
--- a/net/ax25/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the Linux AX.25 layer.
-#
-
-obj-$(CONFIG_AX25) += ax25.o
-
-ax25-y	 := ax25_addr.o ax25_dev.o ax25_iface.o ax25_in.o ax25_ip.o ax25_out.o \
-	    ax25_route.o ax25_std_in.o ax25_std_subr.o ax25_std_timer.o \
-	    ax25_subr.o ax25_timer.o ax25_uid.o af_ax25.o
-ax25-$(CONFIG_AX25_DAMA_SLAVE) += ax25_ds_in.o ax25_ds_subr.o ax25_ds_timer.o
-ax25-$(CONFIG_SYSCTL) += sysctl_net_ax25.o
diff --git a/net/netrom/Makefile b/net/netrom/Makefile
deleted file mode 100644
index 603e36c9af2e..000000000000
--- a/net/netrom/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for the Linux NET/ROM layer.
-#
-
-obj-$(CONFIG_NETROM) += netrom.o
-
-netrom-y		:= af_netrom.o nr_dev.o nr_in.o nr_loopback.o \
-			   nr_out.o nr_route.o nr_subr.o nr_timer.o
-netrom-$(CONFIG_SYSCTL)	+= sysctl_net_netrom.o
diff --git a/net/rose/Makefile b/net/rose/Makefile
deleted file mode 100644
index 3e6638f5ba57..000000000000
--- a/net/rose/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for the Linux Rose (X.25 PLP) layer.
-#
-
-obj-$(CONFIG_ROSE) += rose.o
-
-rose-y	  := af_rose.o rose_dev.o rose_in.o rose_link.o rose_loopback.o \
-	     rose_out.o rose_route.o rose_subr.o rose_timer.o
-rose-$(CONFIG_SYSCTL) += sysctl_net_rose.o
diff --git a/drivers/net/hamradio/z8530.h b/drivers/net/hamradio/z8530.h
deleted file mode 100644
index 1655901d713b..000000000000
--- a/drivers/net/hamradio/z8530.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/* 8530 Serial Communications Controller Register definitions */
-#define	FLAG	0x7e
-
-/* Write Register 0 */
-#define	R0	0		/* Register selects */
-#define	R1	1
-#define	R2	2
-#define	R3	3
-#define	R4	4
-#define	R5	5
-#define	R6	6
-#define	R7	7
-#define	R8	8
-#define	R9	9
-#define	R10	10
-#define	R11	11
-#define	R12	12
-#define	R13	13
-#define	R14	14
-#define	R15	15
-
-#define	NULLCODE	0	/* Null Code */
-#define	POINT_HIGH	0x8	/* Select upper half of registers */
-#define	RES_EXT_INT	0x10	/* Reset Ext. Status Interrupts */
-#define	SEND_ABORT	0x18	/* HDLC Abort */
-#define	RES_RxINT_FC	0x20	/* Reset RxINT on First Character */
-#define	RES_Tx_P	0x28	/* Reset TxINT Pending */
-#define	ERR_RES		0x30	/* Error Reset */
-#define	RES_H_IUS	0x38	/* Reset highest IUS */
-
-#define	RES_Rx_CRC	0x40	/* Reset Rx CRC Checker */
-#define	RES_Tx_CRC	0x80	/* Reset Tx CRC Checker */
-#define	RES_EOM_L	0xC0	/* Reset EOM latch */
-
-/* Write Register 1 */
-
-#define	EXT_INT_ENAB	0x1	/* Ext Int Enable */
-#define	TxINT_ENAB	0x2	/* Tx Int Enable */
-#define	PAR_SPEC	0x4	/* Parity is special condition */
-
-#define	RxINT_DISAB	0	/* Rx Int Disable */
-#define	RxINT_FCERR	0x8	/* Rx Int on First Character Only or Error */
-#define	INT_ALL_Rx	0x10	/* Int on all Rx Characters or error */
-#define	INT_ERR_Rx	0x18	/* Int on error only */
-
-#define	WT_RDY_RT	0x20	/* Wait/Ready on R/T */
-#define	WT_FN_RDYFN	0x40	/* Wait/FN/Ready FN */
-#define	WT_RDY_ENAB	0x80	/* Wait/Ready Enable */
-
-/* Write Register #2 (Interrupt Vector) */
-
-/* Write Register 3 */
-
-#define	RxENABLE	0x1	/* Rx Enable */
-#define	SYNC_L_INH	0x2	/* Sync Character Load Inhibit */
-#define	ADD_SM		0x4	/* Address Search Mode (SDLC) */
-#define	RxCRC_ENAB	0x8	/* Rx CRC Enable */
-#define	ENT_HM		0x10	/* Enter Hunt Mode */
-#define	AUTO_ENAB	0x20	/* Auto Enables */
-#define	Rx5		0x0	/* Rx 5 Bits/Character */
-#define	Rx7		0x40	/* Rx 7 Bits/Character */
-#define	Rx6		0x80	/* Rx 6 Bits/Character */
-#define	Rx8		0xc0	/* Rx 8 Bits/Character */
-
-/* Write Register 4 */
-
-#define	PAR_ENA		0x1	/* Parity Enable */
-#define	PAR_EVEN	0x2	/* Parity Even/Odd* */
-
-#define	SYNC_ENAB	0	/* Sync Modes Enable */
-#define	SB1		0x4	/* 1 stop bit/char */
-#define	SB15		0x8	/* 1.5 stop bits/char */
-#define	SB2		0xc	/* 2 stop bits/char */
-
-#define	MONSYNC		0	/* 8 Bit Sync character */
-#define	BISYNC		0x10	/* 16 bit sync character */
-#define	SDLC		0x20	/* SDLC Mode (01111110 Sync Flag) */
-#define	EXTSYNC		0x30	/* External Sync Mode */
-
-#define	X1CLK		0x0	/* x1 clock mode */
-#define	X16CLK		0x40	/* x16 clock mode */
-#define	X32CLK		0x80	/* x32 clock mode */
-#define	X64CLK		0xC0	/* x64 clock mode */
-
-/* Write Register 5 */
-
-#define	TxCRC_ENAB	0x1	/* Tx CRC Enable */
-#define	RTS		0x2	/* RTS */
-#define	SDLC_CRC	0x4	/* SDLC/CRC-16 */
-#define	TxENAB		0x8	/* Tx Enable */
-#define	SND_BRK		0x10	/* Send Break */
-#define	Tx5		0x0	/* Tx 5 bits (or less)/character */
-#define	Tx7		0x20	/* Tx 7 bits/character */
-#define	Tx6		0x40	/* Tx 6 bits/character */
-#define	Tx8		0x60	/* Tx 8 bits/character */
-#define	DTR		0x80	/* DTR */
-
-/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */
-
-/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */
-
-/* Write Register 8 (transmit buffer) */
-
-/* Write Register 9 (Master interrupt control) */
-#define	VIS	1	/* Vector Includes Status */
-#define	NV	2	/* No Vector */
-#define	DLC	4	/* Disable Lower Chain */
-#define	MIE	8	/* Master Interrupt Enable */
-#define	STATHI	0x10	/* Status high */
-#define	NORESET	0	/* No reset on write to R9 */
-#define	CHRB	0x40	/* Reset channel B */
-#define	CHRA	0x80	/* Reset channel A */
-#define	FHWRES	0xc0	/* Force hardware reset */
-
-/* Write Register 10 (misc control bits) */
-#define	BIT6	1	/* 6 bit/8bit sync */
-#define	LOOPMODE 2	/* SDLC Loop mode */
-#define	ABUNDER	4	/* Abort/flag on SDLC xmit underrun */
-#define	MARKIDLE 8	/* Mark/flag on idle */
-#define	GAOP	0x10	/* Go active on poll */
-#define	NRZ	0	/* NRZ mode */
-#define	NRZI	0x20	/* NRZI mode */
-#define	FM1	0x40	/* FM1 (transition = 1) */
-#define	FM0	0x60	/* FM0 (transition = 0) */
-#define	CRCPS	0x80	/* CRC Preset I/O */
-
-/* Write Register 11 (Clock Mode control) */
-#define	TRxCXT	0	/* TRxC = Xtal output */
-#define	TRxCTC	1	/* TRxC = Transmit clock */
-#define	TRxCBR	2	/* TRxC = BR Generator Output */
-#define	TRxCDP	3	/* TRxC = DPLL output */
-#define	TRxCOI	4	/* TRxC O/I */
-#define	TCRTxCP	0	/* Transmit clock = RTxC pin */
-#define	TCTRxCP	8	/* Transmit clock = TRxC pin */
-#define	TCBR	0x10	/* Transmit clock = BR Generator output */
-#define	TCDPLL	0x18	/* Transmit clock = DPLL output */
-#define	RCRTxCP	0	/* Receive clock = RTxC pin */
-#define	RCTRxCP	0x20	/* Receive clock = TRxC pin */
-#define	RCBR	0x40	/* Receive clock = BR Generator output */
-#define	RCDPLL	0x60	/* Receive clock = DPLL output */
-#define	RTxCX	0x80	/* RTxC Xtal/No Xtal */
-
-/* Write Register 12 (lower byte of baud rate generator time constant) */
-
-/* Write Register 13 (upper byte of baud rate generator time constant) */
-
-/* Write Register 14 (Misc control bits) */
-#define	BRENABL	1	/* Baud rate generator enable */
-#define	BRSRC	2	/* Baud rate generator source */
-#define	DTRREQ	4	/* DTR/Request function */
-#define	AUTOECHO 8	/* Auto Echo */
-#define	LOOPBAK	0x10	/* Local loopback */
-#define	SEARCH	0x20	/* Enter search mode */
-#define	RMC	0x40	/* Reset missing clock */
-#define	DISDPLL	0x60	/* Disable DPLL */
-#define	SSBR	0x80	/* Set DPLL source = BR generator */
-#define	SSRTxC	0xa0	/* Set DPLL source = RTxC */
-#define	SFMM	0xc0	/* Set FM mode */
-#define	SNRZI	0xe0	/* Set NRZI mode */
-
-/* Write Register 15 (external/status interrupt control) */
-#define	ZCIE	2	/* Zero count IE */
-#define	DCDIE	8	/* DCD IE */
-#define	SYNCIE	0x10	/* Sync/hunt IE */
-#define	CTSIE	0x20	/* CTS IE */
-#define	TxUIE	0x40	/* Tx Underrun/EOM IE */
-#define	BRKIE	0x80	/* Break/Abort IE */
-
-
-/* Read Register 0 */
-#define	Rx_CH_AV	0x1	/* Rx Character Available */
-#define	ZCOUNT		0x2	/* Zero count */
-#define	Tx_BUF_EMP	0x4	/* Tx Buffer empty */
-#define	DCD		0x8	/* DCD */
-#define	SYNC_HUNT	0x10	/* Sync/hunt */
-#define	CTS		0x20	/* CTS */
-#define	TxEOM		0x40	/* Tx underrun */
-#define	BRK_ABRT	0x80	/* Break/Abort */
-
-/* Read Register 1 */
-#define	ALL_SNT		0x1	/* All sent */
-/* Residue Data for 8 Rx bits/char programmed */
-#define	RES3		0x8	/* 0/3 */
-#define	RES4		0x4	/* 0/4 */
-#define	RES5		0xc	/* 0/5 */
-#define	RES6		0x2	/* 0/6 */
-#define	RES7		0xa	/* 0/7 */
-#define	RES8		0x6	/* 0/8 */
-#define	RES18		0xe	/* 1/8 */
-#define	RES28		0x0	/* 2/8 */
-/* Special Rx Condition Interrupts */
-#define	PAR_ERR		0x10	/* Parity error */
-#define	Rx_OVR		0x20	/* Rx Overrun Error */
-#define	CRC_ERR		0x40	/* CRC/Framing Error */
-#define	END_FR		0x80	/* End of Frame (SDLC) */
-
-/* Read Register 2 (channel b only) - Interrupt vector */
-
-/* Read Register 3 (interrupt pending register) ch a only */
-#define	CHBEXT	0x1		/* Channel B Ext/Stat IP */
-#define	CHBTxIP	0x2		/* Channel B Tx IP */
-#define	CHBRxIP	0x4		/* Channel B Rx IP */
-#define	CHAEXT	0x8		/* Channel A Ext/Stat IP */
-#define	CHATxIP	0x10		/* Channel A Tx IP */
-#define	CHARxIP	0x20		/* Channel A Rx IP */
-
-/* Read Register 8 (receive data register) */
-
-/* Read Register 10  (misc status bits) */
-#define	ONLOOP	2		/* On loop */
-#define	LOOPSEND 0x10		/* Loop sending */
-#define	CLK2MIS	0x40		/* Two clocks missing */
-#define	CLK1MIS	0x80		/* One clock missing */
-
-/* Read Register 12 (lower byte of baud rate generator constant) */
-
-/* Read Register 13 (upper byte of baud rate generator constant) */
-
-/* Read Register 15 (value of WR 15) */
-
-/* Z85C30/Z85230 Enhanced SCC register definitions */
-
-/* Write Register 7' (SDLC/HDLC Programmable Enhancements) */
-#define AUTOTXF	0x01		/* Auto Tx Flag */
-#define AUTOEOM 0x02		/* Auto EOM Latch Reset */
-#define AUTORTS	0x04		/* Auto RTS */
-#define TXDNRZI 0x08		/* TxD Pulled High in SDLC NRZI mode */
-#define RXFIFOH 0x08		/* Z85230: Int on RX FIFO half full */
-#define FASTDTR 0x10		/* Fast DTR/REQ Mode */
-#define CRCCBCR	0x20		/* CRC Check Bytes Completely Received */
-#define TXFIFOE 0x20		/* Z85230: Int on TX FIFO completely empty */
-#define EXTRDEN	0x40		/* Extended Read Enabled */
-
-/* Write Register 15 (external/status interrupt control) */
-#define SHDLCE	1		/* SDLC/HDLC Enhancements Enable */
-#define FIFOE	4		/* FIFO Enable */
-
-/* Read Register 6 (frame status FIFO) */
-#define BCLSB	0xff		/* LSB of 14 bits count */
-
-/* Read Register 7 (frame status FIFO) */
-#define BCMSB	0x3f		/* MSB of 14 bits count */
-#define FDA	0x40		/* FIFO Data Available Status */
-#define FOS	0x80		/* FIFO Overflow Status */
diff --git a/include/linux/hdlcdrv.h b/include/linux/hdlcdrv.h
deleted file mode 100644
index 5d70c3f98f5b..000000000000
--- a/include/linux/hdlcdrv.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * hdlcdrv.h  -- HDLC packet radio network driver.
- * The Linux soundcard driver for 1200 baud and 9600 baud packet radio
- * (C) 1996-1998 by Thomas Sailer, HB9JNX/AE4WA
- */
-#ifndef _HDLCDRV_H
-#define _HDLCDRV_H
-
-
-#include <linux/netdevice.h>
-#include <linux/if.h>
-#include <linux/spinlock.h>
-#include <uapi/linux/hdlcdrv.h>
-
-#define HDLCDRV_MAGIC      0x5ac6e778
-#define HDLCDRV_HDLCBUFFER  32 /* should be a power of 2 for speed reasons */
-#define HDLCDRV_BITBUFFER  256 /* should be a power of 2 for speed reasons */
-#undef HDLCDRV_LOOPBACK  /* define for HDLC debugging purposes */
-#define HDLCDRV_DEBUG
-
-/* maximum packet length, excluding CRC */
-#define HDLCDRV_MAXFLEN             400	
-
-
-struct hdlcdrv_hdlcbuffer {
-	spinlock_t lock;
-	unsigned rd, wr;
-	unsigned short buf[HDLCDRV_HDLCBUFFER];
-};
-
-#ifdef HDLCDRV_DEBUG
-struct hdlcdrv_bitbuffer {
-	unsigned int rd;
-	unsigned int wr;
-	unsigned int shreg;
-	unsigned char buffer[HDLCDRV_BITBUFFER];
-};
-
-static inline void hdlcdrv_add_bitbuffer(struct hdlcdrv_bitbuffer *buf, 
-					 unsigned int bit)
-{
-	unsigned char new;
-
-	new = buf->shreg & 1;
-	buf->shreg >>= 1;
-	buf->shreg |= (!!bit) << 7;
-	if (new) {
-		buf->buffer[buf->wr] = buf->shreg;
-		buf->wr = (buf->wr+1) % sizeof(buf->buffer);
-		buf->shreg = 0x80;
-	}
-}
-
-static inline void hdlcdrv_add_bitbuffer_word(struct hdlcdrv_bitbuffer *buf, 
-					      unsigned int bits)
-{
-	buf->buffer[buf->wr] = bits & 0xff;
-	buf->wr = (buf->wr+1) % sizeof(buf->buffer);
-	buf->buffer[buf->wr] = (bits >> 8) & 0xff;
-	buf->wr = (buf->wr+1) % sizeof(buf->buffer);
-
-}
-#endif /* HDLCDRV_DEBUG */
-
-/* -------------------------------------------------------------------- */
-/*
- * Information that need to be kept for each driver. 
- */
-
-struct hdlcdrv_ops {
-	/*
-	 * first some informations needed by the hdlcdrv routines
-	 */
-	const char *drvname;
-	const char *drvinfo;
-	/*
-	 * the routines called by the hdlcdrv routines
-	 */
-	int (*open)(struct net_device *);
-	int (*close)(struct net_device *);
-	int (*ioctl)(struct net_device *, void __user *,
-		     struct hdlcdrv_ioctl *, int);
-};
-
-struct hdlcdrv_state {
-	int magic;
-	int opened;
-
-	const struct hdlcdrv_ops *ops;
-
-	struct {
-		int bitrate;
-	} par;
-
-	struct hdlcdrv_pttoutput {
-		int dma2;
-		int seriobase;
-		int pariobase;
-		int midiiobase;
-		unsigned int flags;
-	} ptt_out;
-
-	struct hdlcdrv_channel_params ch_params;
-
-	struct hdlcdrv_hdlcrx {
-		struct hdlcdrv_hdlcbuffer hbuf;
-		unsigned long in_hdlc_rx;
-		/* 0 = sync hunt, != 0 receiving */
-		int rx_state;	
-		unsigned int bitstream;
-		unsigned int bitbuf;
-		int numbits;
-		unsigned char dcd;
-		
-		int len;
-		unsigned char *bp;
-		unsigned char buffer[HDLCDRV_MAXFLEN+2];
-	} hdlcrx;
-
-	struct hdlcdrv_hdlctx {
-		struct hdlcdrv_hdlcbuffer hbuf;
-		unsigned long in_hdlc_tx;
-		/*
-		 * 0 = send flags
-		 * 1 = send txtail (flags)
-		 * 2 = send packet
-		 */
-		int tx_state;	
-		int numflags;
-		unsigned int bitstream;
-		unsigned char ptt;
-		int calibrate;
-		int slotcnt;
-
-		unsigned int bitbuf;
-		int numbits;
-		
-		int len;
-		unsigned char *bp;
-		unsigned char buffer[HDLCDRV_MAXFLEN+2];
-	} hdlctx;
-
-#ifdef HDLCDRV_DEBUG
-	struct hdlcdrv_bitbuffer bitbuf_channel;
-	struct hdlcdrv_bitbuffer bitbuf_hdlc;
-#endif /* HDLCDRV_DEBUG */
-
-	int ptt_keyed;
-
-	/* queued skb for transmission */
-	struct sk_buff *skb;
-};
-
-
-/* -------------------------------------------------------------------- */
-
-static inline int hdlcdrv_hbuf_full(struct hdlcdrv_hdlcbuffer *hb) 
-{
-	unsigned long flags;
-	int ret;
-	
-	spin_lock_irqsave(&hb->lock, flags);
-	ret = !((HDLCDRV_HDLCBUFFER - 1 + hb->rd - hb->wr) % HDLCDRV_HDLCBUFFER);
-	spin_unlock_irqrestore(&hb->lock, flags);
-	return ret;
-}
-
-/* -------------------------------------------------------------------- */
-
-static inline int hdlcdrv_hbuf_empty(struct hdlcdrv_hdlcbuffer *hb)
-{
-	unsigned long flags;
-	int ret;
-	
-	spin_lock_irqsave(&hb->lock, flags);
-	ret = (hb->rd == hb->wr);
-	spin_unlock_irqrestore(&hb->lock, flags);
-	return ret;
-}
-
-/* -------------------------------------------------------------------- */
-
-static inline unsigned short hdlcdrv_hbuf_get(struct hdlcdrv_hdlcbuffer *hb)
-{
-	unsigned long flags;
-	unsigned short val;
-	unsigned newr;
-
-	spin_lock_irqsave(&hb->lock, flags);
-	if (hb->rd == hb->wr)
-		val = 0;
-	else {
-		newr = (hb->rd+1) % HDLCDRV_HDLCBUFFER;
-		val = hb->buf[hb->rd];
-		hb->rd = newr;
-	}
-	spin_unlock_irqrestore(&hb->lock, flags);
-	return val;
-}
-
-/* -------------------------------------------------------------------- */
-
-static inline void hdlcdrv_hbuf_put(struct hdlcdrv_hdlcbuffer *hb, 
-				    unsigned short val)
-{
-	unsigned newp;
-	unsigned long flags;
-	
-	spin_lock_irqsave(&hb->lock, flags);
-	newp = (hb->wr+1) % HDLCDRV_HDLCBUFFER;
-	if (newp != hb->rd) { 
-		hb->buf[hb->wr] = val & 0xffff;
-		hb->wr = newp;
-	}
-	spin_unlock_irqrestore(&hb->lock, flags);
-}
-
-/* -------------------------------------------------------------------- */
-
-static inline void hdlcdrv_putbits(struct hdlcdrv_state *s, unsigned int bits)
-{
-	hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, bits);
-}
-
-static inline unsigned int hdlcdrv_getbits(struct hdlcdrv_state *s)
-{
-	unsigned int ret;
-
-	if (hdlcdrv_hbuf_empty(&s->hdlctx.hbuf)) {
-		if (s->hdlctx.calibrate > 0)
-			s->hdlctx.calibrate--;
-		else
-			s->hdlctx.ptt = 0;
-		ret = 0;
-	} else 
-		ret = hdlcdrv_hbuf_get(&s->hdlctx.hbuf);
-#ifdef HDLCDRV_LOOPBACK
-	hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, ret);
-#endif /* HDLCDRV_LOOPBACK */
-	return ret;
-}
-
-static inline void hdlcdrv_channelbit(struct hdlcdrv_state *s, unsigned int bit)
-{
-#ifdef HDLCDRV_DEBUG
-	hdlcdrv_add_bitbuffer(&s->bitbuf_channel, bit);
-#endif /* HDLCDRV_DEBUG */
-}
-
-static inline void hdlcdrv_setdcd(struct hdlcdrv_state *s, int dcd)
-{
-	s->hdlcrx.dcd = !!dcd;
-}
-
-static inline int hdlcdrv_ptt(struct hdlcdrv_state *s)
-{
-	return s->hdlctx.ptt || (s->hdlctx.calibrate > 0);
-}
-
-/* -------------------------------------------------------------------- */
-
-void hdlcdrv_receiver(struct net_device *, struct hdlcdrv_state *);
-void hdlcdrv_transmitter(struct net_device *, struct hdlcdrv_state *);
-void hdlcdrv_arbitrate(struct net_device *, struct hdlcdrv_state *);
-struct net_device *hdlcdrv_register(const struct hdlcdrv_ops *ops,
-				    unsigned int privsize, const char *ifname,
-				    unsigned int baseaddr, unsigned int irq, 
-				    unsigned int dma);
-void hdlcdrv_unregister(struct net_device *dev);
-
-/* -------------------------------------------------------------------- */
-
-
-
-#endif /* _HDLCDRV_H */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7969fcdd5ac4..e9e2ec8d4c19 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -162,7 +162,7 @@ static inline bool dev_xmit_complete(int rc)
 
 #if defined(CONFIG_HYPERV_NET)
 # define LL_MAX_HEADER 128
-#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25)
+#elif defined(CONFIG_WLAN)
 # if defined(CONFIG_MAC80211_MESH)
 #  define LL_MAX_HEADER 128
 # else
@@ -2316,9 +2316,6 @@ struct net_device {
 #if IS_ENABLED(CONFIG_ATALK)
 	void 			*atalk_ptr;
 #endif
-#if IS_ENABLED(CONFIG_AX25)
-	struct ax25_dev	__rcu	*ax25_ptr;
-#endif
 #if IS_ENABLED(CONFIG_CFG80211)
 	struct wireless_dev	*ieee80211_ptr;
 #endif
diff --git a/include/linux/scc.h b/include/linux/scc.h
deleted file mode 100644
index 745eabd17c10..000000000000
--- a/include/linux/scc.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* $Id: scc.h,v 1.29 1997/04/02 14:56:45 jreuter Exp jreuter $ */
-#ifndef	_SCC_H
-#define	_SCC_H
-
-#include <uapi/linux/scc.h>
-
-
-enum {TX_OFF, TX_ON};	/* command for scc_key_trx() */
-
-/* Vector masks in RR2B */
-
-#define VECTOR_MASK	0x06
-#define TXINT		0x00
-#define EXINT		0x02
-#define RXINT		0x04
-#define SPINT		0x06
-
-#ifdef CONFIG_SCC_DELAY
-#define Inb(port)	inb_p(port)
-#define Outb(port, val)	outb_p(val, port)
-#else
-#define Inb(port)	inb(port)
-#define Outb(port, val)	outb(val, port)
-#endif
-
-/* SCC channel control structure for KISS */
-
-struct scc_kiss {
-	unsigned char txdelay;		/* Transmit Delay 10 ms/cnt */
-	unsigned char persist;		/* Persistence (0-255) as a % */
-	unsigned char slottime;		/* Delay to wait on persistence hit */
-	unsigned char tailtime;		/* Delay after last byte written */
-	unsigned char fulldup;		/* Full Duplex mode 0=CSMA 1=DUP 2=ALWAYS KEYED */
-	unsigned char waittime;		/* Waittime before any transmit attempt */
-	unsigned int  maxkeyup;		/* Maximum time to transmit (seconds) */
-	unsigned int  mintime;		/* Minimal offtime after MAXKEYUP timeout (seconds) */
-	unsigned int  idletime;		/* Maximum idle time in ALWAYS KEYED mode (seconds) */
-	unsigned int  maxdefer;		/* Timer for CSMA channel busy limit */
-	unsigned char tx_inhibit;	/* Transmit is not allowed when set */	
-	unsigned char group;		/* Group ID for AX.25 TX interlocking */
-	unsigned char mode;		/* 'normal' or 'hwctrl' mode (unused) */
-	unsigned char softdcd;		/* Use DPLL instead of DCD pin for carrier detect */
-};
-
-
-/* SCC channel structure */
-
-struct scc_channel {
-	int init;			/* channel exists? */
-
-	struct net_device *dev;		/* link to device control structure */
-	struct net_device_stats dev_stat;/* device statistics */
-
-	char brand;			/* manufacturer of the board */
-	long clock;			/* used clock */
-
-	io_port ctrl;			/* I/O address of CONTROL register */
-	io_port	data;			/* I/O address of DATA register */
-	io_port special;		/* I/O address of special function port */
-	int irq;			/* Number of Interrupt */
-
-	char option;
-	char enhanced;			/* Enhanced SCC support */
-
-	unsigned char wreg[16]; 	/* Copy of last written value in WRx */
-	unsigned char status;		/* Copy of R0 at last external interrupt */
-	unsigned char dcd;		/* DCD status */
-
-        struct scc_kiss kiss;		/* control structure for KISS params */
-        struct scc_stat stat;		/* statistical information */
-        struct scc_modem modem; 	/* modem information */
-
-        struct sk_buff_head tx_queue;	/* next tx buffer */
-        struct sk_buff *rx_buff;	/* pointer to frame currently received */
-        struct sk_buff *tx_buff;	/* pointer to frame currently transmitted */
-
-	/* Timer */
-	struct timer_list tx_t;		/* tx timer for this channel */
-	struct timer_list tx_wdog;	/* tx watchdogs */
-	
-	/* Channel lock */
-	spinlock_t	lock;		/* Channel guard lock */
-};
-
-#endif /* defined(_SCC_H) */
diff --git a/include/linux/yam.h b/include/linux/yam.h
deleted file mode 100644
index a29b04fa1e66..000000000000
--- a/include/linux/yam.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*****************************************************************************/
-
-/*
- *	yam.h  -- YAM radio modem driver.
- *
- *	Copyright (C) 1998 Frederic Rible F1OAT (frible@teaser.fr)
- *	Adapted from baycom.c driver written by Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *  Please note that the GPL allows you to use the driver, NOT the radio.
- *  In order to use the radio, you need a license from the communications
- *  authority of your country.
- */
-
-/*****************************************************************************/
-
-#define SIOCYAMRESERVED	(0)
-#define SIOCYAMSCFG 	(1)	/* Set configuration */
-#define SIOCYAMGCFG 	(2)	/* Get configuration */
-#define SIOCYAMSMCS 	(3)	/* Set mcs data */
-
-#define YAM_IOBASE   (1 << 0)
-#define YAM_IRQ      (1 << 1)
-#define YAM_BITRATE  (1 << 2) /* Bit rate of radio port ->57600 */
-#define YAM_MODE     (1 << 3) /* 0=simplex 1=duplex 2=duplex+tempo */
-#define YAM_HOLDDLY  (1 << 4) /* duplex tempo (sec) */
-#define YAM_TXDELAY  (1 << 5) /* Tx Delay (ms) */
-#define YAM_TXTAIL   (1 << 6) /* Tx Tail  (ms) */
-#define YAM_PERSIST  (1 << 7) /* Persist  (ms) */
-#define YAM_SLOTTIME (1 << 8) /* Slottime (ms) */
-#define YAM_BAUDRATE (1 << 9) /* Baud rate of rs232 port ->115200 */
-
-#define YAM_MAXBITRATE  57600
-#define YAM_MAXBAUDRATE 115200
-#define YAM_MAXMODE     2
-#define YAM_MAXHOLDDLY  99
-#define YAM_MAXTXDELAY  999
-#define YAM_MAXTXTAIL   999
-#define YAM_MAXPERSIST  255
-#define YAM_MAXSLOTTIME 999
-
-#define YAM_FPGA_SIZE	5302
-
-struct yamcfg {
-	unsigned int mask;		/* Mask of commands */
-	unsigned int iobase;	/* IO Base of COM port */
-	unsigned int irq;		/* IRQ of COM port */
-	unsigned int bitrate;	/* Bit rate of radio port */
-	unsigned int baudrate;	/* Baud rate of the RS232 port */
-	unsigned int txdelay;	/* TxDelay */
-	unsigned int txtail;	/* TxTail */
-	unsigned int persist;	/* Persistence */
-	unsigned int slottime;	/* Slottime */
-	unsigned int mode;		/* mode 0 (simp), 1(Dupl), 2(Dupl+delay) */
-	unsigned int holddly;	/* PTT delay in FullDuplex 2 mode */
-};
-
-struct yamdrv_ioctl_cfg {
-	int cmd;
-	struct yamcfg cfg;
-};
-
-struct yamdrv_ioctl_mcs {
-	int cmd;
-	unsigned int bitrate;
-	unsigned char bits[YAM_FPGA_SIZE];
-};
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 9fc6a6657266..6b2f518facdb 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -1,480 +1,10 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-/*
- *	Declarations of AX.25 type objects.
- *
- *	Alan Cox (GW4PTS) 	10/11/93
- */
 #ifndef _AX25_H
-#define _AX25_H 
+#define _AX25_H
 
 #include <linux/ax25.h>
-#include <linux/spinlock.h>
-#include <linux/timer.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/refcount.h>
-#include <net/neighbour.h>
-#include <net/sock.h>
-#include <linux/seq_file.h>
 
-#define	AX25_T1CLAMPLO  		1
-#define	AX25_T1CLAMPHI 			(30 * HZ)
-
-#define	AX25_BPQ_HEADER_LEN		16
-#define	AX25_KISS_HEADER_LEN		1
-
-#define	AX25_HEADER_LEN			17
-#define	AX25_ADDR_LEN			7
-#define	AX25_DIGI_HEADER_LEN		(AX25_MAX_DIGIS * AX25_ADDR_LEN)
-#define	AX25_MAX_HEADER_LEN		(AX25_HEADER_LEN + AX25_DIGI_HEADER_LEN)
-
-/* AX.25 Protocol IDs */
-#define AX25_P_ROSE			0x01
-#define AX25_P_VJCOMP			0x06	/* Compressed TCP/IP packet   */
-						/* Van Jacobsen (RFC 1144)    */
-#define AX25_P_VJUNCOMP			0x07	/* Uncompressed TCP/IP packet */
-						/* Van Jacobsen (RFC 1144)    */
-#define	AX25_P_SEGMENT			0x08	/* Segmentation fragment      */
-#define AX25_P_TEXNET			0xc3	/* TEXTNET datagram protocol  */
-#define AX25_P_LQ			0xc4	/* Link Quality Protocol      */
-#define AX25_P_ATALK			0xca	/* Appletalk                  */
-#define AX25_P_ATALK_ARP		0xcb	/* Appletalk ARP              */
-#define AX25_P_IP			0xcc	/* ARPA Internet Protocol     */
-#define AX25_P_ARP			0xcd	/* ARPA Address Resolution    */
-#define AX25_P_FLEXNET			0xce	/* FlexNet                    */
-#define AX25_P_NETROM 			0xcf	/* NET/ROM                    */
-#define AX25_P_TEXT 			0xF0	/* No layer 3 protocol impl.  */
-
-/* AX.25 Segment control values */
-#define	AX25_SEG_REM			0x7F
-#define	AX25_SEG_FIRST			0x80
-
-#define AX25_CBIT			0x80	/* Command/Response bit */
-#define AX25_EBIT			0x01	/* HDLC Address Extension bit */
-#define AX25_HBIT			0x80	/* Has been repeated bit */
-
-#define AX25_SSSID_SPARE		0x60	/* Unused bits in SSID for standard AX.25 */
-#define AX25_ESSID_SPARE		0x20	/* Unused bits in SSID for extended AX.25 */
-#define AX25_DAMA_FLAG			0x20	/* Well, it is *NOT* unused! (dl1bke 951121 */
-
-#define	AX25_COND_ACK_PENDING		0x01
-#define	AX25_COND_REJECT		0x02
-#define	AX25_COND_PEER_RX_BUSY		0x04
-#define	AX25_COND_OWN_RX_BUSY		0x08
-#define	AX25_COND_DAMA_MODE		0x10
-
-#ifndef _LINUX_NETDEVICE_H
-#include <linux/netdevice.h>
-#endif
-
-/* Upper sub-layer (LAPB) definitions */
-
-/* Control field templates */
-#define	AX25_I			0x00	/* Information frames */
-#define	AX25_S			0x01	/* Supervisory frames */
-#define	AX25_RR			0x01	/* Receiver ready */
-#define	AX25_RNR		0x05	/* Receiver not ready */
-#define	AX25_REJ		0x09	/* Reject */
-#define	AX25_U			0x03	/* Unnumbered frames */
-#define	AX25_SABM		0x2f	/* Set Asynchronous Balanced Mode */
-#define	AX25_SABME		0x6f	/* Set Asynchronous Balanced Mode Extended */
-#define	AX25_DISC		0x43	/* Disconnect */
-#define	AX25_DM			0x0f	/* Disconnected mode */
-#define	AX25_UA			0x63	/* Unnumbered acknowledge */
-#define	AX25_FRMR		0x87	/* Frame reject */
-#define	AX25_UI			0x03	/* Unnumbered information */
-#define	AX25_XID		0xaf	/* Exchange information */
-#define	AX25_TEST		0xe3	/* Test */
-
-#define	AX25_PF			0x10	/* Poll/final bit for standard AX.25 */
-#define	AX25_EPF		0x01	/* Poll/final bit for extended AX.25 */
-
-#define AX25_ILLEGAL		0x100	/* Impossible to be a real frame type */
-
-#define	AX25_POLLOFF		0
-#define	AX25_POLLON		1
-
-/* AX25 L2 C-bit */
-#define AX25_COMMAND		1
-#define AX25_RESPONSE		2
-
-/* Define Link State constants. */
-
-enum { 
-	AX25_STATE_0,			/* Listening */
-	AX25_STATE_1,			/* SABM sent */
-	AX25_STATE_2,			/* DISC sent */
-	AX25_STATE_3,			/* Established */
-	AX25_STATE_4			/* Recovery */
-};
-
-#define AX25_MODULUS 		8	/*  Standard AX.25 modulus */
-#define	AX25_EMODULUS		128	/*  Extended AX.25 modulus */
-
-enum {
-	AX25_PROTO_STD_SIMPLEX,
-	AX25_PROTO_STD_DUPLEX,
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	AX25_PROTO_DAMA_SLAVE,
-#endif
-	__AX25_PROTO_MAX,
-	AX25_PROTO_MAX = __AX25_PROTO_MAX -1
-};
-
-enum {
-	AX25_VALUES_IPDEFMODE,	/* 0=DG 1=VC */
-	AX25_VALUES_AXDEFMODE,	/* 0=Normal 1=Extended Seq Nos */
-	AX25_VALUES_BACKOFF,	/* 0=None 1=Linear 2=Exponential */
-	AX25_VALUES_CONMODE,	/* Allow connected modes - 0=No 1=no "PID text" 2=all PIDs */
-	AX25_VALUES_WINDOW,	/* Default window size for standard AX.25 */
-	AX25_VALUES_EWINDOW,	/* Default window size for extended AX.25 */
-	AX25_VALUES_T1,		/* Default T1 timeout value */
-	AX25_VALUES_T2,		/* Default T2 timeout value */
-	AX25_VALUES_T3,		/* Default T3 timeout value */
-	AX25_VALUES_IDLE,	/* Connected mode idle timer */
-	AX25_VALUES_N2,		/* Default N2 value */
-	AX25_VALUES_PACLEN,	/* AX.25 MTU */
-	AX25_VALUES_PROTOCOL,	/* Std AX.25, DAMA Slave */
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	AX25_VALUES_DS_TIMEOUT,	/* DAMA Slave timeout */
-#endif
-	AX25_MAX_VALUES		/* THIS MUST REMAIN THE LAST ENTRY OF THIS LIST */
-};
-
-#define	AX25_DEF_IPDEFMODE	0			/* Datagram */
-#define	AX25_DEF_AXDEFMODE	0			/* Normal */
-#define	AX25_DEF_BACKOFF	1			/* Linear backoff */
-#define	AX25_DEF_CONMODE	2			/* Connected mode allowed */
-#define	AX25_DEF_WINDOW		2			/* Window=2 */
-#define	AX25_DEF_EWINDOW	32			/* Module-128 Window=32 */
-#define	AX25_DEF_T1		10000			/* T1=10s */
-#define	AX25_DEF_T2		3000			/* T2=3s  */
-#define	AX25_DEF_T3		300000			/* T3=300s */
-#define	AX25_DEF_N2		10			/* N2=10 */
-#define AX25_DEF_IDLE		0			/* Idle=None */
-#define AX25_DEF_PACLEN		256			/* Paclen=256 */
-#define	AX25_DEF_PROTOCOL	AX25_PROTO_STD_SIMPLEX	/* Standard AX.25 */
-#define AX25_DEF_DS_TIMEOUT	180000			/* DAMA timeout 3 minutes */
-
-typedef struct ax25_uid_assoc {
-	struct hlist_node	uid_node;
-	refcount_t		refcount;
-	kuid_t			uid;
-	ax25_address		call;
-} ax25_uid_assoc;
-
-#define ax25_uid_for_each(__ax25, list) \
-	hlist_for_each_entry(__ax25, list, uid_node)
-
-#define ax25_uid_hold(ax25) \
-	refcount_inc(&((ax25)->refcount))
-
-static inline void ax25_uid_put(ax25_uid_assoc *assoc)
-{
-	if (refcount_dec_and_test(&assoc->refcount)) {
-		kfree(assoc);
-	}
-}
-
-typedef struct {
-	ax25_address		calls[AX25_MAX_DIGIS];
-	unsigned char		repeated[AX25_MAX_DIGIS];
-	unsigned char		ndigi;
-	signed char		lastrepeat;
-} ax25_digi;
-
-typedef struct ax25_route {
-	struct ax25_route	*next;
-	ax25_address		callsign;
-	struct net_device	*dev;
-	ax25_digi		*digipeat;
-	char			ip_mode;
-} ax25_route;
-
-void __ax25_put_route(ax25_route *ax25_rt);
-
-extern rwlock_t ax25_route_lock;
-
-static inline void ax25_route_lock_use(void)
-{
-	read_lock(&ax25_route_lock);
-}
-
-static inline void ax25_route_lock_unuse(void)
-{
-	read_unlock(&ax25_route_lock);
-}
-
-typedef struct {
-	char			slave;			/* slave_mode?   */
-	struct timer_list	slave_timer;		/* timeout timer */
-	unsigned short		slave_timeout;		/* when? */
-} ax25_dama_info;
-
-typedef struct ax25_dev {
-	struct list_head	list;
-
-	struct net_device	*dev;
-	netdevice_tracker	dev_tracker;
-
-	struct net_device	*forward;
-	struct ctl_table_header *sysheader;
-	int			values[AX25_MAX_VALUES];
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	ax25_dama_info		dama;
-#endif
-	refcount_t		refcount;
-	bool device_up;
-	struct rcu_head		rcu;
-} ax25_dev;
-
-typedef struct ax25_cb {
-	struct hlist_node	ax25_node;
-	ax25_address		source_addr, dest_addr;
-	ax25_digi		*digipeat;
-	ax25_dev		*ax25_dev;
-	netdevice_tracker	dev_tracker;
-	unsigned char		iamdigi;
-	unsigned char		state, modulus, pidincl;
-	unsigned short		vs, vr, va;
-	unsigned char		condition, backoff;
-	unsigned char		n2, n2count;
-	struct timer_list	t1timer, t2timer, t3timer, idletimer;
-	unsigned long		t1, t2, t3, idle, rtt;
-	unsigned short		paclen, fragno, fraglen;
-	struct sk_buff_head	write_queue;
-	struct sk_buff_head	reseq_queue;
-	struct sk_buff_head	ack_queue;
-	struct sk_buff_head	frag_queue;
-	unsigned char		window;
-	struct timer_list	timer, dtimer;
-	struct sock		*sk;		/* Backlink to socket */
-	refcount_t		refcount;
-} ax25_cb;
-
-struct ax25_sock {
-	struct sock		sk;
-	struct ax25_cb		*cb;
-};
-
-#define ax25_sk(ptr) container_of_const(ptr, struct ax25_sock, sk)
-
-static inline struct ax25_cb *sk_to_ax25(const struct sock *sk)
-{
-	return ax25_sk(sk)->cb;
-}
-
-#define ax25_for_each(__ax25, list) \
-	hlist_for_each_entry(__ax25, list, ax25_node)
-
-#define ax25_cb_hold(__ax25) \
-	refcount_inc(&((__ax25)->refcount))
-
-static __inline__ void ax25_cb_put(ax25_cb *ax25)
-{
-	if (refcount_dec_and_test(&ax25->refcount)) {
-		kfree(ax25->digipeat);
-		kfree(ax25);
-	}
-}
-
-static inline void ax25_dev_hold(ax25_dev *ax25_dev)
-{
-	refcount_inc(&ax25_dev->refcount);
-}
-
-static inline void ax25_dev_put(ax25_dev *ax25_dev)
-{
-	if (refcount_dec_and_test(&ax25_dev->refcount))
-		kfree_rcu(ax25_dev, rcu);
-}
-static inline __be16 ax25_type_trans(struct sk_buff *skb, struct net_device *dev)
-{
-	skb->dev      = dev;
-	skb_reset_mac_header(skb);
-	skb->pkt_type = PACKET_HOST;
-	return htons(ETH_P_AX25);
-}
-
-/* af_ax25.c */
-extern struct hlist_head ax25_list;
-extern spinlock_t ax25_list_lock;
-void ax25_cb_add(ax25_cb *);
-struct sock *ax25_find_listener(ax25_address *, int, struct net_device *, int);
-struct sock *ax25_get_socket(ax25_address *, ax25_address *, int);
-ax25_cb *ax25_find_cb(const ax25_address *, ax25_address *, ax25_digi *,
-		      struct net_device *);
-void ax25_send_to_raw(ax25_address *, struct sk_buff *, int);
-void ax25_destroy_socket(ax25_cb *);
-ax25_cb * __must_check ax25_create_cb(void);
-void ax25_fillin_cb(ax25_cb *, ax25_dev *);
-struct sock *ax25_make_new(struct sock *, struct ax25_dev *);
-
-/* ax25_addr.c */
-extern const ax25_address ax25_bcast;
-extern const ax25_address ax25_defaddr;
-extern const ax25_address null_ax25_address;
-char *ax2asc(char *buf, const ax25_address *);
-void asc2ax(ax25_address *addr, const char *callsign);
-int ax25cmp(const ax25_address *, const ax25_address *);
-int ax25digicmp(const ax25_digi *, const ax25_digi *);
-const unsigned char *ax25_addr_parse(const unsigned char *, int,
-	ax25_address *, ax25_address *, ax25_digi *, int *, int *);
-int ax25_addr_build(unsigned char *, const ax25_address *,
-		    const ax25_address *, const ax25_digi *, int, int);
-int ax25_addr_size(const ax25_digi *);
-void ax25_digi_invert(const ax25_digi *, ax25_digi *);
-
-/* ax25_dev.c */
-extern spinlock_t ax25_dev_lock;
-
-#if IS_ENABLED(CONFIG_AX25)
-static inline ax25_dev *ax25_dev_ax25dev(const struct net_device *dev)
-{
-	return rcu_dereference_rtnl(dev->ax25_ptr);
-}
-#endif
-
-ax25_dev *ax25_addr_ax25dev(ax25_address *);
-void ax25_dev_device_up(struct net_device *);
-void ax25_dev_device_down(struct net_device *);
-int ax25_fwd_ioctl(unsigned int, struct ax25_fwd_struct *);
-struct net_device *ax25_fwd_dev(struct net_device *);
-void ax25_dev_free(void);
-
-/* ax25_ds_in.c */
-int ax25_ds_frame_in(ax25_cb *, struct sk_buff *, int);
-
-/* ax25_ds_subr.c */
-void ax25_ds_nr_error_recovery(ax25_cb *);
-void ax25_ds_enquiry_response(ax25_cb *);
-void ax25_ds_establish_data_link(ax25_cb *);
-void ax25_dev_dama_off(ax25_dev *);
-void ax25_dama_on(ax25_cb *);
-void ax25_dama_off(ax25_cb *);
-
-/* ax25_ds_timer.c */
-void ax25_ds_setup_timer(ax25_dev *);
-void ax25_ds_set_timer(ax25_dev *);
-void ax25_ds_del_timer(ax25_dev *);
-void ax25_ds_timer(ax25_cb *);
-void ax25_ds_t1_timeout(ax25_cb *);
-void ax25_ds_heartbeat_expiry(ax25_cb *);
-void ax25_ds_t3timer_expiry(ax25_cb *);
-void ax25_ds_idletimer_expiry(ax25_cb *);
-
-/* ax25_iface.c */
-
-struct ax25_protocol {
-	struct ax25_protocol *next;
-	unsigned int pid;
-	int (*func)(struct sk_buff *, ax25_cb *);
-};
-
-void ax25_register_pid(struct ax25_protocol *ap);
-void ax25_protocol_release(unsigned int);
-
-struct ax25_linkfail {
-	struct hlist_node lf_node;
-	void (*func)(ax25_cb *, int);
-};
-
-void ax25_linkfail_register(struct ax25_linkfail *lf);
-void ax25_linkfail_release(struct ax25_linkfail *lf);
-int __must_check ax25_listen_register(const ax25_address *,
-				      struct net_device *);
-void ax25_listen_release(const ax25_address *, struct net_device *);
-int(*ax25_protocol_function(unsigned int))(struct sk_buff *, ax25_cb *);
-int ax25_listen_mine(const ax25_address *, struct net_device *);
-void ax25_link_failed(ax25_cb *, int);
-int ax25_protocol_is_registered(unsigned int);
-
-/* ax25_in.c */
-int ax25_rx_iframe(ax25_cb *, struct sk_buff *);
-int ax25_kiss_rcv(struct sk_buff *, struct net_device *, struct packet_type *,
-		  struct net_device *);
-
-/* ax25_ip.c */
-netdev_tx_t ax25_ip_xmit(struct sk_buff *skb);
-extern const struct header_ops ax25_header_ops;
-
-/* ax25_out.c */
-ax25_cb *ax25_send_frame(struct sk_buff *, int, const ax25_address *,
-			 ax25_address *, ax25_digi *, struct net_device *);
-void ax25_output(ax25_cb *, int, struct sk_buff *);
-void ax25_kick(ax25_cb *);
-void ax25_transmit_buffer(ax25_cb *, struct sk_buff *, int);
-void ax25_queue_xmit(struct sk_buff *skb, struct net_device *dev);
-int ax25_check_iframes_acked(ax25_cb *, unsigned short);
-
-/* ax25_route.c */
-void ax25_rt_device_down(struct net_device *);
-int ax25_rt_ioctl(unsigned int, void __user *);
-extern const struct seq_operations ax25_rt_seqops;
-ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev);
-struct sk_buff *ax25_rt_build_path(struct sk_buff *, ax25_address *,
-				   ax25_address *, ax25_digi *);
-void ax25_rt_free(void);
-
-/* ax25_std_in.c */
-int ax25_std_frame_in(ax25_cb *, struct sk_buff *, int);
-
-/* ax25_std_subr.c */
-void ax25_std_nr_error_recovery(ax25_cb *);
-void ax25_std_establish_data_link(ax25_cb *);
-void ax25_std_transmit_enquiry(ax25_cb *);
-void ax25_std_enquiry_response(ax25_cb *);
-void ax25_std_timeout_response(ax25_cb *);
-
-/* ax25_std_timer.c */
-void ax25_std_heartbeat_expiry(ax25_cb *);
-void ax25_std_t1timer_expiry(ax25_cb *);
-void ax25_std_t2timer_expiry(ax25_cb *);
-void ax25_std_t3timer_expiry(ax25_cb *);
-void ax25_std_idletimer_expiry(ax25_cb *);
-
-/* ax25_subr.c */
-void ax25_clear_queues(ax25_cb *);
-void ax25_frames_acked(ax25_cb *, unsigned short);
-void ax25_requeue_frames(ax25_cb *);
-int ax25_validate_nr(ax25_cb *, unsigned short);
-int ax25_decode(ax25_cb *, struct sk_buff *, int *, int *, int *);
-void ax25_send_control(ax25_cb *, int, int, int);
-void ax25_return_dm(struct net_device *, ax25_address *, ax25_address *,
-		    ax25_digi *);
-void ax25_calculate_t1(ax25_cb *);
-void ax25_calculate_rtt(ax25_cb *);
-void ax25_disconnect(ax25_cb *, int);
-
-/* ax25_timer.c */
-void ax25_setup_timers(ax25_cb *);
-void ax25_start_heartbeat(ax25_cb *);
-void ax25_start_t1timer(ax25_cb *);
-void ax25_start_t2timer(ax25_cb *);
-void ax25_start_t3timer(ax25_cb *);
-void ax25_start_idletimer(ax25_cb *);
-void ax25_stop_heartbeat(ax25_cb *);
-void ax25_stop_t1timer(ax25_cb *);
-void ax25_stop_t2timer(ax25_cb *);
-void ax25_stop_t3timer(ax25_cb *);
-void ax25_stop_idletimer(ax25_cb *);
-int ax25_t1timer_running(ax25_cb *);
-unsigned long ax25_display_timer(struct timer_list *);
-
-/* ax25_uid.c */
-extern int  ax25_uid_policy;
-ax25_uid_assoc *ax25_findbyuid(kuid_t);
-int __must_check ax25_uid_ioctl(int, struct sockaddr_ax25 *);
-extern const struct seq_operations ax25_uid_seqops;
-void ax25_uid_free(void);
-
-/* sysctl_net_ax25.c */
-#ifdef CONFIG_SYSCTL
-int ax25_register_dev_sysctl(ax25_dev *ax25_dev);
-void ax25_unregister_dev_sysctl(ax25_dev *ax25_dev);
-#else
-static inline int ax25_register_dev_sysctl(ax25_dev *ax25_dev) { return 0; }
-static inline void ax25_unregister_dev_sysctl(ax25_dev *ax25_dev) {}
-#endif /* CONFIG_SYSCTL */
+#define	AX25_ADDR_LEN	7
+#define	AX25_P_IP	0xCC
 
 #endif
diff --git a/include/net/netrom.h b/include/net/netrom.h
deleted file mode 100644
index f0565a5987d1..000000000000
--- a/include/net/netrom.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- *	Declarations of NET/ROM type objects.
- *
- *	Jonathan Naylor G4KLX	9/4/95
- */
-
-#ifndef _NETROM_H
-#define _NETROM_H 
-
-#include <linux/netrom.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <net/sock.h>
-#include <linux/refcount.h>
-#include <linux/seq_file.h>
-#include <net/ax25.h>
-
-#define	NR_NETWORK_LEN			15
-#define	NR_TRANSPORT_LEN		5
-
-#define	NR_PROTO_IP			0x0C
-
-#define	NR_PROTOEXT			0x00
-#define	NR_CONNREQ			0x01
-#define	NR_CONNACK			0x02
-#define	NR_DISCREQ			0x03
-#define	NR_DISCACK			0x04
-#define	NR_INFO				0x05
-#define	NR_INFOACK			0x06
-#define	NR_RESET			0x07
-
-#define	NR_CHOKE_FLAG			0x80
-#define	NR_NAK_FLAG			0x40
-#define	NR_MORE_FLAG			0x20
-
-/* Define Link State constants. */
-enum {
-	NR_STATE_0,
-	NR_STATE_1,
-	NR_STATE_2,
-	NR_STATE_3
-};
-
-#define	NR_COND_ACK_PENDING		0x01
-#define	NR_COND_REJECT			0x02
-#define	NR_COND_PEER_RX_BUSY		0x04
-#define	NR_COND_OWN_RX_BUSY		0x08
-
-#define NR_DEFAULT_T1			120000		/* Outstanding frames - 120 seconds */
-#define NR_DEFAULT_T2			5000		/* Response delay     - 5 seconds */
-#define NR_DEFAULT_N2			3		/* Number of Retries - 3 */
-#define	NR_DEFAULT_T4			180000		/* Busy Delay - 180 seconds */
-#define	NR_DEFAULT_IDLE			0		/* No Activity Timeout - none */
-#define	NR_DEFAULT_WINDOW		4		/* Default Window Size - 4 */
-#define	NR_DEFAULT_OBS			6		/* Default Obsolescence Count - 6 */
-#define	NR_DEFAULT_QUAL			10		/* Default Neighbour Quality - 10 */
-#define	NR_DEFAULT_TTL			16		/* Default Time To Live - 16 */
-#define	NR_DEFAULT_ROUTING		1		/* Is routing enabled ? */
-#define	NR_DEFAULT_FAILS		2		/* Link fails until route fails */
-#define	NR_DEFAULT_RESET		0		/* Sent / accept reset cmds? */
-
-#define NR_MODULUS 			256
-#define NR_MAX_WINDOW_SIZE		127			/* Maximum Window Allowable - 127 */
-#define	NR_MAX_PACKET_SIZE		236			/* Maximum Packet Length - 236 */
-
-struct nr_sock {
-	struct sock		sock;
-	ax25_address		user_addr, source_addr, dest_addr;
-	struct net_device		*device;
-	unsigned char		my_index,   my_id;
-	unsigned char		your_index, your_id;
-	unsigned char		state, condition, bpqext, window;
-	unsigned short		vs, vr, va, vl;
-	unsigned char		n2, n2count;
-	unsigned long		t1, t2, t4, idle;
-	unsigned short		fraglen;
-	struct timer_list	t1timer;
-	struct timer_list	t2timer;
-	struct timer_list	t4timer;
-	struct timer_list	idletimer;
-	struct sk_buff_head	ack_queue;
-	struct sk_buff_head	reseq_queue;
-	struct sk_buff_head	frag_queue;
-};
-
-#define nr_sk(sk) ((struct nr_sock *)(sk))
-
-struct nr_neigh {
-	struct hlist_node	neigh_node;
-	ax25_address		callsign;
-	ax25_digi		*digipeat;
-	ax25_cb			*ax25;
-	struct net_device	*dev;
-	unsigned char		quality;
-	unsigned char		locked;
-	unsigned short		count;
-	unsigned int		number;
-	unsigned char		failed;
-	refcount_t		refcount;
-};
-
-struct nr_route {
-	unsigned char   quality;
-	unsigned char   obs_count;
-	struct nr_neigh *neighbour;
-};
-
-struct nr_node {
-	struct hlist_node	node_node;
-	ax25_address		callsign;
-	char			mnemonic[7];
-	unsigned char		which;
-	unsigned char		count;
-	struct nr_route		routes[3];
-	refcount_t		refcount;
-	spinlock_t		node_lock;
-};
-
-/*********************************************************************
- *	nr_node & nr_neigh lists, refcounting and locking
- *********************************************************************/
-
-#define nr_node_hold(__nr_node) \
-	refcount_inc(&((__nr_node)->refcount))
-
-static __inline__ void nr_node_put(struct nr_node *nr_node)
-{
-	if (refcount_dec_and_test(&nr_node->refcount)) {
-		kfree(nr_node);
-	}
-}
-
-#define nr_neigh_hold(__nr_neigh) \
-	refcount_inc(&((__nr_neigh)->refcount))
-
-static __inline__ void nr_neigh_put(struct nr_neigh *nr_neigh)
-{
-	if (refcount_dec_and_test(&nr_neigh->refcount)) {
-		if (nr_neigh->ax25)
-			ax25_cb_put(nr_neigh->ax25);
-		kfree(nr_neigh->digipeat);
-		kfree(nr_neigh);
-	}
-}
-
-/* nr_node_lock and nr_node_unlock also hold/put the node's refcounter.
- */
-static __inline__ void nr_node_lock(struct nr_node *nr_node)
-{
-	nr_node_hold(nr_node);
-	spin_lock_bh(&nr_node->node_lock);
-}
-
-static __inline__ void nr_node_unlock(struct nr_node *nr_node)
-{
-	spin_unlock_bh(&nr_node->node_lock);
-	nr_node_put(nr_node);
-}
-
-#define nr_neigh_for_each(__nr_neigh, list) \
-	hlist_for_each_entry(__nr_neigh, list, neigh_node)
-
-#define nr_neigh_for_each_safe(__nr_neigh, node2, list) \
-	hlist_for_each_entry_safe(__nr_neigh, node2, list, neigh_node)
-
-#define nr_node_for_each(__nr_node, list) \
-	hlist_for_each_entry(__nr_node, list, node_node)
-
-#define nr_node_for_each_safe(__nr_node, node2, list) \
-	hlist_for_each_entry_safe(__nr_node, node2, list, node_node)
-
-
-/*********************************************************************/
-
-/* af_netrom.c */
-extern int  sysctl_netrom_default_path_quality;
-extern int  sysctl_netrom_obsolescence_count_initialiser;
-extern int  sysctl_netrom_network_ttl_initialiser;
-extern int  sysctl_netrom_transport_timeout;
-extern int  sysctl_netrom_transport_maximum_tries;
-extern int  sysctl_netrom_transport_acknowledge_delay;
-extern int  sysctl_netrom_transport_busy_delay;
-extern int  sysctl_netrom_transport_requested_window_size;
-extern int  sysctl_netrom_transport_no_activity_timeout;
-extern int  sysctl_netrom_routing_control;
-extern int  sysctl_netrom_link_fails_count;
-extern int  sysctl_netrom_reset_circuit;
-
-int nr_rx_frame(struct sk_buff *, struct net_device *);
-void nr_destroy_socket(struct sock *);
-
-/* nr_dev.c */
-int nr_rx_ip(struct sk_buff *, struct net_device *);
-void nr_setup(struct net_device *);
-
-/* nr_in.c */
-int nr_process_rx_frame(struct sock *, struct sk_buff *);
-
-/* nr_loopback.c */
-void nr_loopback_init(void);
-void nr_loopback_clear(void);
-int nr_loopback_queue(struct sk_buff *);
-
-/* nr_out.c */
-void nr_output(struct sock *, struct sk_buff *);
-void nr_send_nak_frame(struct sock *);
-void nr_kick(struct sock *);
-void nr_transmit_buffer(struct sock *, struct sk_buff *);
-void nr_establish_data_link(struct sock *);
-void nr_enquiry_response(struct sock *);
-void nr_check_iframes_acked(struct sock *, unsigned short);
-
-/* nr_route.c */
-void nr_rt_device_down(struct net_device *);
-struct net_device *nr_dev_first(void);
-struct net_device *nr_dev_get(ax25_address *);
-int nr_rt_ioctl(unsigned int, void __user *);
-void nr_link_failed(ax25_cb *, int);
-int nr_route_frame(struct sk_buff *, ax25_cb *);
-extern const struct seq_operations nr_node_seqops;
-extern const struct seq_operations nr_neigh_seqops;
-void nr_rt_free(void);
-
-/* nr_subr.c */
-void nr_clear_queues(struct sock *);
-void nr_frames_acked(struct sock *, unsigned short);
-void nr_requeue_frames(struct sock *);
-int nr_validate_nr(struct sock *, unsigned short);
-int nr_in_rx_window(struct sock *, unsigned short);
-void nr_write_internal(struct sock *, int);
-
-void __nr_transmit_reply(struct sk_buff *skb, int mine, unsigned char cmdflags);
-
-/*
- * This routine is called when a Connect Acknowledge with the Choke Flag
- * set is needed to refuse a connection.
- */
-#define nr_transmit_refusal(skb, mine)					\
-do {									\
-	__nr_transmit_reply((skb), (mine), NR_CONNACK | NR_CHOKE_FLAG);	\
-} while (0)
-
-/*
- * This routine is called when we don't have a circuit matching an incoming
- * NET/ROM packet.  This is an G8PZT Xrouter extension.
- */
-#define nr_transmit_reset(skb, mine)					\
-do {									\
-	__nr_transmit_reply((skb), (mine), NR_RESET);			\
-} while (0)
-
-void nr_disconnect(struct sock *, int);
-
-/* nr_timer.c */
-void nr_init_timers(struct sock *sk);
-void nr_start_heartbeat(struct sock *);
-void nr_start_t1timer(struct sock *);
-void nr_start_t2timer(struct sock *);
-void nr_start_t4timer(struct sock *);
-void nr_start_idletimer(struct sock *);
-void nr_stop_heartbeat(struct sock *);
-void nr_stop_t1timer(struct sock *);
-void nr_stop_t2timer(struct sock *);
-void nr_stop_t4timer(struct sock *);
-void nr_stop_idletimer(struct sock *);
-int nr_t1timer_running(struct sock *);
-
-/* sysctl_net_netrom.c */
-int nr_register_sysctl(void);
-void nr_unregister_sysctl(void);
-
-#endif
diff --git a/include/net/rose.h b/include/net/rose.h
index 2b5491bbf39a..41bfcb224f0b 100644
--- a/include/net/rose.h
+++ b/include/net/rose.h
@@ -1,266 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-/*
- *	Declarations of Rose type objects.
- *
- *	Jonathan Naylor G4KLX	25/8/96
- */
-
 #ifndef _ROSE_H
-#define _ROSE_H 
+#define _ROSE_H
 
-#include <linux/refcount.h>
-#include <linux/rose.h>
-#include <net/ax25.h>
-#include <net/sock.h>
-
-#define	ROSE_ADDR_LEN			5
-
-#define	ROSE_MIN_LEN			3
-
-#define	ROSE_CALL_REQ_ADDR_LEN_OFF	3
-#define	ROSE_CALL_REQ_ADDR_LEN_VAL	0xAA	/* each address is 10 digits */
-#define	ROSE_CALL_REQ_DEST_ADDR_OFF	4
-#define	ROSE_CALL_REQ_SRC_ADDR_OFF	9
-#define	ROSE_CALL_REQ_FACILITIES_OFF	14
-
-#define	ROSE_GFI			0x10
-#define	ROSE_Q_BIT			0x80
-#define	ROSE_D_BIT			0x40
-#define	ROSE_M_BIT			0x10
-
-#define	ROSE_CALL_REQUEST		0x0B
-#define	ROSE_CALL_ACCEPTED		0x0F
-#define	ROSE_CLEAR_REQUEST		0x13
-#define	ROSE_CLEAR_CONFIRMATION		0x17
-#define	ROSE_DATA			0x00
-#define	ROSE_INTERRUPT			0x23
-#define	ROSE_INTERRUPT_CONFIRMATION	0x27
-#define	ROSE_RR				0x01
-#define	ROSE_RNR			0x05
-#define	ROSE_REJ			0x09
-#define	ROSE_RESET_REQUEST		0x1B
-#define	ROSE_RESET_CONFIRMATION		0x1F
-#define	ROSE_REGISTRATION_REQUEST	0xF3
-#define	ROSE_REGISTRATION_CONFIRMATION	0xF7
-#define	ROSE_RESTART_REQUEST		0xFB
-#define	ROSE_RESTART_CONFIRMATION	0xFF
-#define	ROSE_DIAGNOSTIC			0xF1
-#define	ROSE_ILLEGAL			0xFD
-
-/* Define Link State constants. */
-
-enum {
-	ROSE_STATE_0,			/* Ready */
-	ROSE_STATE_1,			/* Awaiting Call Accepted */
-	ROSE_STATE_2,			/* Awaiting Clear Confirmation */
-	ROSE_STATE_3,			/* Data Transfer */
-	ROSE_STATE_4,			/* Awaiting Reset Confirmation */
-	ROSE_STATE_5			/* Deferred Call Acceptance */
-};
-
-#define ROSE_DEFAULT_T0			180000		/* Default T10 T20 value */
-#define ROSE_DEFAULT_T1			200000		/* Default T11 T21 value */
-#define ROSE_DEFAULT_T2			180000		/* Default T12 T22 value */
-#define	ROSE_DEFAULT_T3			180000		/* Default T13 T23 value */
-#define	ROSE_DEFAULT_HB			5000		/* Default Holdback value */
-#define	ROSE_DEFAULT_IDLE		0		/* No Activity Timeout - none */
-#define	ROSE_DEFAULT_ROUTING		1		/* Default routing flag */
-#define	ROSE_DEFAULT_FAIL_TIMEOUT	120000		/* Time until link considered usable */
-#define	ROSE_DEFAULT_MAXVC		50		/* Maximum number of VCs per neighbour */
-#define	ROSE_DEFAULT_WINDOW_SIZE	7		/* Default window size */
-
-#define ROSE_MODULUS 			8
-#define	ROSE_MAX_PACKET_SIZE		251		/* Maximum packet size */
-
-#define	ROSE_COND_ACK_PENDING		0x01
-#define	ROSE_COND_PEER_RX_BUSY		0x02
-#define	ROSE_COND_OWN_RX_BUSY		0x04
-
-#define	FAC_NATIONAL			0x00
-#define	FAC_CCITT			0x0F
-
-#define	FAC_NATIONAL_RAND		0x7F
-#define	FAC_NATIONAL_FLAGS		0x3F
-#define	FAC_NATIONAL_DEST_DIGI		0xE9
-#define	FAC_NATIONAL_SRC_DIGI		0xEB
-#define	FAC_NATIONAL_FAIL_CALL		0xED
-#define	FAC_NATIONAL_FAIL_ADD		0xEE
-#define	FAC_NATIONAL_DIGIS			0xEF
-
-#define	FAC_CCITT_DEST_NSAP		0xC9
-#define	FAC_CCITT_SRC_NSAP		0xCB
-
-struct rose_neigh {
-	struct rose_neigh	*next;
-	ax25_address		callsign;
-	ax25_digi		*digipeat;
-	ax25_cb			*ax25;
-	struct net_device		*dev;
-	unsigned short		count;
-	refcount_t		use;
-	unsigned int		number;
-	char			restarted;
-	char			dce_mode;
-	char			loopback;
-	struct sk_buff_head	queue;
-	struct timer_list	t0timer;
-	struct timer_list	ftimer;
-};
-
-struct rose_node {
-	struct rose_node	*next;
-	rose_address		address;
-	unsigned short		mask;
-	unsigned char		count;
-	char			loopback;
-	struct rose_neigh	*neighbour[3];
-};
-
-struct rose_route {
-	struct rose_route	*next;
-	unsigned int		lci1, lci2;
-	rose_address		src_addr, dest_addr;
-	ax25_address		src_call, dest_call;
-	struct rose_neigh 	*neigh1, *neigh2;
-	unsigned int		rand;
-};
-
-struct rose_sock {
-	struct sock		sock;
-	rose_address		source_addr,   dest_addr;
-	ax25_address		source_call,   dest_call;
-	unsigned char		source_ndigis, dest_ndigis;
-	ax25_address		source_digis[ROSE_MAX_DIGIS];
-	ax25_address		dest_digis[ROSE_MAX_DIGIS];
-	struct rose_neigh	*neighbour;
-	struct net_device	*device;
-	netdevice_tracker	dev_tracker;
-	unsigned int		lci, rand;
-	unsigned char		state, condition, qbitincl, defer;
-	unsigned char		cause, diagnostic;
-	unsigned short		vs, vr, va, vl;
-	unsigned long		t1, t2, t3, hb, idle;
-#ifdef M_BIT
-	unsigned short		fraglen;
-	struct sk_buff_head	frag_queue;
-#endif
-	struct sk_buff_head	ack_queue;
-	struct rose_facilities_struct facilities;
-	struct timer_list	timer;
-	struct timer_list	idletimer;
-};
-
-#define rose_sk(sk) ((struct rose_sock *)(sk))
-
-static inline void rose_neigh_hold(struct rose_neigh *rose_neigh)
-{
-	refcount_inc(&rose_neigh->use);
-}
-
-static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
-{
-	if (refcount_dec_and_test(&rose_neigh->use)) {
-		if (rose_neigh->ax25)
-			ax25_cb_put(rose_neigh->ax25);
-		kfree(rose_neigh->digipeat);
-		kfree(rose_neigh);
-	}
-}
-
-/* af_rose.c */
-extern ax25_address rose_callsign;
-extern int  sysctl_rose_restart_request_timeout;
-extern int  sysctl_rose_call_request_timeout;
-extern int  sysctl_rose_reset_request_timeout;
-extern int  sysctl_rose_clear_request_timeout;
-extern int  sysctl_rose_no_activity_timeout;
-extern int  sysctl_rose_ack_hold_back_timeout;
-extern int  sysctl_rose_routing_control;
-extern int  sysctl_rose_link_fail_timeout;
-extern int  sysctl_rose_maximum_vcs;
-extern int  sysctl_rose_window_size;
-
-int rosecmp(const rose_address *, const rose_address *);
-int rosecmpm(const rose_address *, const rose_address *, unsigned short);
-char *rose2asc(char *buf, const rose_address *);
-struct sock *rose_find_socket(unsigned int, struct rose_neigh *);
-void rose_kill_by_neigh(struct rose_neigh *);
-unsigned int rose_new_lci(struct rose_neigh *);
-int rose_rx_call_request(struct sk_buff *, struct net_device *,
-			 struct rose_neigh *, unsigned int);
-void rose_destroy_socket(struct sock *);
-
-/* rose_dev.c */
-void rose_setup(struct net_device *);
-
-/* rose_in.c */
-int rose_process_rx_frame(struct sock *, struct sk_buff *);
-
-/* rose_link.c */
-void rose_start_ftimer(struct rose_neigh *);
-void rose_stop_ftimer(struct rose_neigh *);
-void rose_stop_t0timer(struct rose_neigh *);
-int rose_ftimer_running(struct rose_neigh *);
-void rose_link_rx_restart(struct sk_buff *, struct rose_neigh *,
-			  unsigned short);
-void rose_transmit_clear_request(struct rose_neigh *, unsigned int,
-				 unsigned char, unsigned char);
-void rose_transmit_link(struct sk_buff *, struct rose_neigh *);
-
-/* rose_loopback.c */
-void rose_loopback_init(void);
-void rose_loopback_clear(void);
-int rose_loopback_queue(struct sk_buff *, struct rose_neigh *);
-
-/* rose_out.c */
-void rose_kick(struct sock *);
-void rose_enquiry_response(struct sock *);
-
-/* rose_route.c */
-extern struct rose_neigh *rose_loopback_neigh;
-extern const struct seq_operations rose_neigh_seqops;
-extern const struct seq_operations rose_node_seqops;
-extern struct seq_operations rose_route_seqops;
-
-void rose_add_loopback_neigh(void);
-int __must_check rose_add_loopback_node(const rose_address *);
-void rose_del_loopback_node(const rose_address *);
-void rose_rt_device_down(struct net_device *);
-void rose_link_device_down(struct net_device *);
-struct net_device *rose_dev_first(void);
-struct net_device *rose_dev_get(rose_address *);
-struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh *);
-struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *,
-				  unsigned char *, int);
-int rose_rt_ioctl(unsigned int, void __user *);
-void rose_link_failed(ax25_cb *, int);
-int rose_route_frame(struct sk_buff *, ax25_cb *);
-void rose_rt_free(void);
-
-/* rose_subr.c */
-void rose_clear_queues(struct sock *);
-void rose_frames_acked(struct sock *, unsigned short);
-void rose_requeue_frames(struct sock *);
-int rose_validate_nr(struct sock *, unsigned short);
-void rose_write_internal(struct sock *, int);
-int rose_decode(struct sk_buff *, int *, int *, int *, int *, int *);
-int rose_parse_facilities(unsigned char *, unsigned int,
-			  struct rose_facilities_struct *);
-void rose_disconnect(struct sock *, int, int, int);
-
-/* rose_timer.c */
-void rose_start_heartbeat(struct sock *);
-void rose_start_t1timer(struct sock *);
-void rose_start_t2timer(struct sock *);
-void rose_start_t3timer(struct sock *);
-void rose_start_hbtimer(struct sock *);
-void rose_start_idletimer(struct sock *);
-void rose_stop_heartbeat(struct sock *);
-void rose_stop_timer(struct sock *);
-void rose_stop_idletimer(struct sock *);
-
-/* sysctl_net_rose.c */
-void rose_register_sysctl(void);
-void rose_unregister_sysctl(void);
+#define	ROSE_ADDR_LEN	5
 
 #endif
diff --git a/include/uapi/linux/baycom.h b/include/uapi/linux/baycom.h
deleted file mode 100644
index 478cb565ae52..000000000000
--- a/include/uapi/linux/baycom.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * The Linux BAYCOM driver for the Baycom serial 1200 baud modem
- * and the parallel 9600 baud modem
- * (C) 1997-1998 by Thomas Sailer, HB9JNX/AE4WA
- */
-
-#ifndef _BAYCOM_H
-#define _BAYCOM_H
-
-/* -------------------------------------------------------------------- */
-/*
- * structs for the IOCTL commands
- */
-
-struct baycom_debug_data {
-	unsigned long debug1;
-	unsigned long debug2;
-	long debug3;
-};
-
-struct baycom_ioctl {
-	int cmd;
-	union {
-		struct baycom_debug_data dbg;
-	} data;
-};
-
-/* -------------------------------------------------------------------- */
-
-/*
- * ioctl values change for baycom
- */
-#define BAYCOMCTL_GETDEBUG       0x92
-
-/* -------------------------------------------------------------------- */
-
-#endif /* _BAYCOM_H */
-
-/* --------------------------------------------------------------------- */
diff --git a/include/uapi/linux/hdlcdrv.h b/include/uapi/linux/hdlcdrv.h
deleted file mode 100644
index 9fe9499403a6..000000000000
--- a/include/uapi/linux/hdlcdrv.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * hdlcdrv.h  -- HDLC packet radio network driver.
- * The Linux soundcard driver for 1200 baud and 9600 baud packet radio
- * (C) 1996-1998 by Thomas Sailer, HB9JNX/AE4WA
- */
-
-#ifndef _UAPI_HDLCDRV_H
-#define _UAPI_HDLCDRV_H
-
-/* -------------------------------------------------------------------- */
-/*
- * structs for the IOCTL commands
- */
-
-struct hdlcdrv_params {
-	int iobase;
-	int irq;
-	int dma;
-	int dma2;
-	int seriobase;
-	int pariobase;
-	int midiiobase;
-};	
-
-struct hdlcdrv_channel_params {
-	int tx_delay;  /* the transmitter keyup delay in 10ms units */
-	int tx_tail;   /* the transmitter keyoff delay in 10ms units */
-	int slottime;  /* the slottime in 10ms; usually 10 = 100ms */
-	int ppersist;  /* the p-persistence 0..255 */
-	int fulldup;   /* some driver do not support full duplex, setting */
-	               /* this just makes them send even if DCD is on */
-};	
-
-struct hdlcdrv_old_channel_state {
-  	int ptt;
-  	int dcd;
-  	int ptt_keyed;
-};
-
-struct hdlcdrv_channel_state {
- 	int ptt;
- 	int dcd;
- 	int ptt_keyed;
- 	unsigned long tx_packets;
- 	unsigned long tx_errors;
- 	unsigned long rx_packets;
- 	unsigned long rx_errors;
-};
-
-struct hdlcdrv_ioctl {
-	int cmd;
-	union {
-		struct hdlcdrv_params mp;
-		struct hdlcdrv_channel_params cp;
-		struct hdlcdrv_channel_state cs;
-		struct hdlcdrv_old_channel_state ocs;
-		unsigned int calibrate;
-		unsigned char bits;
-		char modename[128];
-		char drivername[32];
-	} data;
-};
-
-/* -------------------------------------------------------------------- */
-
-/*
- * ioctl values
- */
-#define HDLCDRVCTL_GETMODEMPAR       0
-#define HDLCDRVCTL_SETMODEMPAR       1
-#define HDLCDRVCTL_MODEMPARMASK      2  /* not handled by hdlcdrv */
-#define HDLCDRVCTL_GETCHANNELPAR    10
-#define HDLCDRVCTL_SETCHANNELPAR    11
-#define HDLCDRVCTL_OLDGETSTAT       20
-#define HDLCDRVCTL_CALIBRATE        21
-#define HDLCDRVCTL_GETSTAT          22
-
-/*
- * these are mainly for debugging purposes
- */
-#define HDLCDRVCTL_GETSAMPLES       30
-#define HDLCDRVCTL_GETBITS          31
-
-/*
- * not handled by hdlcdrv, but by its depending drivers
- */
-#define HDLCDRVCTL_GETMODE          40
-#define HDLCDRVCTL_SETMODE          41
-#define HDLCDRVCTL_MODELIST         42
-#define HDLCDRVCTL_DRIVERNAME       43
-
-/*
- * mask of needed modem parameters, returned by HDLCDRVCTL_MODEMPARMASK
- */
-#define HDLCDRV_PARMASK_IOBASE      (1<<0)
-#define HDLCDRV_PARMASK_IRQ         (1<<1)
-#define HDLCDRV_PARMASK_DMA         (1<<2)
-#define HDLCDRV_PARMASK_DMA2        (1<<3)
-#define HDLCDRV_PARMASK_SERIOBASE   (1<<4)
-#define HDLCDRV_PARMASK_PARIOBASE   (1<<5)
-#define HDLCDRV_PARMASK_MIDIIOBASE  (1<<6)
-
-/* -------------------------------------------------------------------- */
-
-
-/* -------------------------------------------------------------------- */
-
-#endif /* _UAPI_HDLCDRV_H */
-
-/* -------------------------------------------------------------------- */
diff --git a/include/uapi/linux/netrom.h b/include/uapi/linux/netrom.h
deleted file mode 100644
index 7498ea3c3940..000000000000
--- a/include/uapi/linux/netrom.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * These are the public elements of the Linux kernel NET/ROM implementation.
- * For kernel AX.25 see the file ax25.h. This file requires ax25.h for the
- * definition of the ax25_address structure.
- */
-
-#ifndef	NETROM_KERNEL_H
-#define	NETROM_KERNEL_H
-
-#include <linux/ax25.h>
-
-#define NETROM_MTU	236
-
-#define NETROM_T1	1
-#define NETROM_T2	2
-#define NETROM_N2	3
-#define	NETROM_T4	6
-#define	NETROM_IDLE	7
-
-#define	SIOCNRDECOBS		(SIOCPROTOPRIVATE+2)
-
-struct nr_route_struct {
-#define	NETROM_NEIGH	0
-#define	NETROM_NODE	1
-	int		type;
-	ax25_address	callsign;
-	char		device[16];
-	unsigned int	quality;
-	char		mnemonic[7];
-	ax25_address	neighbour;
-	unsigned int	obs_count;
-	unsigned int	ndigis;
-	ax25_address	digipeaters[AX25_MAX_DIGIS];
-};
-
-#endif
diff --git a/include/uapi/linux/rose.h b/include/uapi/linux/rose.h
deleted file mode 100644
index 19aa4693c8fc..000000000000
--- a/include/uapi/linux/rose.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * These are the public elements of the Linux kernel Rose implementation.
- * For kernel AX.25 see the file ax25.h. This file requires ax25.h for the
- * definition of the ax25_address structure.
- */
-
-#ifndef	ROSE_KERNEL_H
-#define	ROSE_KERNEL_H
-
-#include <linux/socket.h>
-#include <linux/ax25.h>
-
-#define ROSE_MTU	251
-
-#define ROSE_MAX_DIGIS 6
-
-#define	ROSE_DEFER	1
-#define ROSE_T1		2
-#define	ROSE_T2		3
-#define	ROSE_T3		4
-#define	ROSE_IDLE	5
-#define	ROSE_QBITINCL	6
-#define	ROSE_HOLDBACK	7
-
-#define	SIOCRSGCAUSE		(SIOCPROTOPRIVATE+0)
-#define	SIOCRSSCAUSE		(SIOCPROTOPRIVATE+1)
-#define	SIOCRSL2CALL		(SIOCPROTOPRIVATE+2)
-#define	SIOCRSSL2CALL		(SIOCPROTOPRIVATE+2)
-#define	SIOCRSACCEPT		(SIOCPROTOPRIVATE+3)
-#define	SIOCRSCLRRT		(SIOCPROTOPRIVATE+4)
-#define	SIOCRSGL2CALL		(SIOCPROTOPRIVATE+5)
-#define	SIOCRSGFACILITIES	(SIOCPROTOPRIVATE+6)
-
-#define	ROSE_DTE_ORIGINATED	0x00
-#define	ROSE_NUMBER_BUSY	0x01
-#define	ROSE_INVALID_FACILITY	0x03
-#define	ROSE_NETWORK_CONGESTION	0x05
-#define	ROSE_OUT_OF_ORDER	0x09
-#define	ROSE_ACCESS_BARRED	0x0B
-#define	ROSE_NOT_OBTAINABLE	0x0D
-#define	ROSE_REMOTE_PROCEDURE	0x11
-#define	ROSE_LOCAL_PROCEDURE	0x13
-#define	ROSE_SHIP_ABSENT	0x39
-
-typedef struct {
-	char		rose_addr[5];
-} rose_address;
-
-struct sockaddr_rose {
-	__kernel_sa_family_t srose_family;
-	rose_address	srose_addr;
-	ax25_address	srose_call;
-	int		srose_ndigis;
-	ax25_address	srose_digi;
-};
-
-struct full_sockaddr_rose {
-	__kernel_sa_family_t srose_family;
-	rose_address	srose_addr;
-	ax25_address	srose_call;
-	unsigned int	srose_ndigis;
-	ax25_address	srose_digis[ROSE_MAX_DIGIS];
-};
-
-struct rose_route_struct {
-	rose_address	address;
-	unsigned short	mask;
-	ax25_address	neighbour;
-	char		device[16];
-	unsigned char	ndigis;
-	ax25_address	digipeaters[AX25_MAX_DIGIS];
-};
-
-struct rose_cause_struct {
-	unsigned char	cause;
-	unsigned char	diagnostic;
-};
-
-struct rose_facilities_struct {
-	rose_address	source_addr,   dest_addr;
-	ax25_address	source_call,   dest_call;
-	unsigned char	source_ndigis, dest_ndigis;
-	ax25_address	source_digis[ROSE_MAX_DIGIS];
-	ax25_address	dest_digis[ROSE_MAX_DIGIS];
-	unsigned int	rand;
-	rose_address	fail_addr;
-	ax25_address	fail_call;
-};
-
-#endif
diff --git a/include/uapi/linux/scc.h b/include/uapi/linux/scc.h
deleted file mode 100644
index 947edb17ce9d..000000000000
--- a/include/uapi/linux/scc.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/* $Id: scc.h,v 1.29 1997/04/02 14:56:45 jreuter Exp jreuter $ */
-
-#ifndef _UAPI_SCC_H
-#define _UAPI_SCC_H
-
-#include <linux/sockios.h>
-
-/* selection of hardware types */
-
-#define PA0HZP		0x00	/* hardware type for PA0HZP SCC card and compatible */
-#define EAGLE		0x01    /* hardware type for EAGLE card */
-#define PC100		0x02	/* hardware type for PC100 card */
-#define PRIMUS		0x04	/* hardware type for PRIMUS-PC (DG9BL) card */
-#define DRSI		0x08	/* hardware type for DRSI PC*Packet card */
-#define BAYCOM		0x10	/* hardware type for BayCom (U)SCC */
-
-/* DEV ioctl() commands */
-
-enum SCC_ioctl_cmds {
-	SIOCSCCRESERVED = SIOCDEVPRIVATE,
-	SIOCSCCCFG,
-	SIOCSCCINI,
-	SIOCSCCCHANINI,
-	SIOCSCCSMEM,
-	SIOCSCCGKISS,
-	SIOCSCCSKISS,
-	SIOCSCCGSTAT,
-	SIOCSCCCAL
-};
-
-/* Device parameter control (from WAMPES) */
-
-enum L1_params {
-	PARAM_DATA,
-	PARAM_TXDELAY,
-	PARAM_PERSIST,
-	PARAM_SLOTTIME,
-	PARAM_TXTAIL,
-	PARAM_FULLDUP,
-	PARAM_SOFTDCD,		/* was: PARAM_HW */
-	PARAM_MUTE,		/* ??? */
-	PARAM_DTR,
-	PARAM_RTS,
-	PARAM_SPEED,
-	PARAM_ENDDELAY,		/* ??? */
-	PARAM_GROUP,
-	PARAM_IDLE,
-	PARAM_MIN,
-	PARAM_MAXKEY,
-	PARAM_WAIT,
-	PARAM_MAXDEFER,
-	PARAM_TX,
-	PARAM_HWEVENT = 31,
-	PARAM_RETURN = 255	/* reset kiss mode */
-};
-
-/* fulldup parameter */
-
-enum FULLDUP_modes {
-	KISS_DUPLEX_HALF,	/* normal CSMA operation */
-	KISS_DUPLEX_FULL,	/* fullduplex, key down trx after transmission */
-	KISS_DUPLEX_LINK,	/* fullduplex, key down trx after 'idletime' sec */
-	KISS_DUPLEX_OPTIMA	/* fullduplex, let the protocol layer control the hw */
-};
-
-/* misc. parameters */
-
-#define TIMER_OFF	65535U	/* to switch off timers */
-#define NO_SUCH_PARAM	65534U	/* param not implemented */
-
-/* HWEVENT parameter */
-
-enum HWEVENT_opts {
-	HWEV_DCD_ON,
-	HWEV_DCD_OFF,
-	HWEV_ALL_SENT
-};
-
-/* channel grouping */
-
-#define RXGROUP		0100	/* if set, only tx when all channels clear */
-#define TXGROUP		0200	/* if set, don't transmit simultaneously */
-
-/* Tx/Rx clock sources */
-
-enum CLOCK_sources {
-	CLK_DPLL,	/* normal halfduplex operation */
-	CLK_EXTERNAL,	/* external clocking (G3RUH/DF9IC modems) */
-	CLK_DIVIDER,	/* Rx = DPLL, Tx = divider (fullduplex with */
-			/* modems without clock regeneration */
-	CLK_BRG		/* experimental fullduplex mode with DPLL/BRG for */
-			/* MODEMs without clock recovery */
-};
-
-/* Tx state */
-
-enum TX_state {
-	TXS_IDLE,	/* Transmitter off, no data pending */
-	TXS_BUSY,	/* waiting for permission to send / tailtime */
-	TXS_ACTIVE,	/* Transmitter on, sending data */
-	TXS_NEWFRAME,	/* reset CRC and send (next) frame */
-	TXS_IDLE2,	/* Transmitter on, no data pending */
-	TXS_WAIT,	/* Waiting for Mintime to expire */
-	TXS_TIMEOUT	/* We had a transmission timeout */
-};
-
-typedef unsigned long io_port;	/* type definition for an 'io port address' */
-
-/* SCC statistical information */
-
-struct scc_stat {
-        long rxints;            /* Receiver interrupts */
-        long txints;            /* Transmitter interrupts */
-        long exints;            /* External/status interrupts */
-        long spints;            /* Special receiver interrupts */
-
-        long txframes;          /* Packets sent */
-        long rxframes;          /* Number of Frames Actually Received */
-        long rxerrs;            /* CRC Errors */
-        long txerrs;		/* KISS errors */
-        
-	unsigned int nospace;	/* "Out of buffers" */
-	unsigned int rx_over;	/* Receiver Overruns */
-	unsigned int tx_under;	/* Transmitter Underruns */
-
-	unsigned int tx_state;	/* Transmitter state */
-	int tx_queued;		/* tx frames enqueued */
-
-	unsigned int maxqueue;	/* allocated tx_buffers */
-	unsigned int bufsize;	/* used buffersize */
-};
-
-struct scc_modem {
-	long speed;		/* Line speed, bps */
-	char clocksrc;		/* 0 = DPLL, 1 = external, 2 = divider */
-	char nrz;		/* NRZ instead of NRZI */	
-};
-
-struct scc_kiss_cmd {
-	int  	 command;	/* one of the KISS-Commands defined above */
-	unsigned param;		/* KISS-Param */
-};
-
-struct scc_hw_config {
-	io_port data_a;		/* data port channel A */
-	io_port ctrl_a;		/* control port channel A */
-	io_port data_b;		/* data port channel B */
-	io_port ctrl_b;		/* control port channel B */
-	io_port vector_latch;	/* INTACK-Latch (#) */
-	io_port	special;	/* special function port */
-
-	int	irq;		/* irq */
-	long	clock;		/* clock */
-	char	option;		/* command for function port */
-
-	char brand;		/* hardware type */
-	char escc;		/* use ext. features of a 8580/85180/85280 */
-};
-
-/* (#) only one INTACK latch allowed. */
-
-
-struct scc_mem_config {
-	unsigned int dummy;
-	unsigned int bufsize;
-};
-
-struct scc_calibrate {
-	unsigned int time;
-	unsigned char pattern;
-};
-
-#endif /* _UAPI_SCC_H */
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
deleted file mode 100644
index c8b2dc5c1bec..000000000000
--- a/drivers/net/hamradio/6pack.c
+++ /dev/null
@@ -1,912 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * 6pack.c	This module implements the 6pack protocol for kernel-based
- *		devices like TTY. It interfaces between a raw TTY and the
- *		kernel's AX.25 protocol layers.
- *
- * Authors:	Andreas Könsgen <ajk@comnets.uni-bremen.de>
- *              Ralf Baechle DL5RB <ralf@linux-mips.org>
- *
- * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by
- *
- *		Laurence Culhane, <loz@holmes.demon.co.uk>
- *		Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
- */
-
-#include <linux/module.h>
-#include <linux/uaccess.h>
-#include <linux/bitops.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/in.h>
-#include <linux/tty.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/timer.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/rtnetlink.h>
-#include <linux/spinlock.h>
-#include <linux/if_arp.h>
-#include <linux/init.h>
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#include <linux/semaphore.h>
-#include <linux/refcount.h>
-
-/* sixpack priority commands */
-#define SIXP_SEOF		0x40	/* start and end of a 6pack frame */
-#define SIXP_TX_URUN		0x48	/* transmit overrun */
-#define SIXP_RX_ORUN		0x50	/* receive overrun */
-#define SIXP_RX_BUF_OVL		0x58	/* receive buffer overflow */
-
-#define SIXP_CHKSUM		0xFF	/* valid checksum of a 6pack frame */
-
-/* masks to get certain bits out of the status bytes sent by the TNC */
-
-#define SIXP_CMD_MASK		0xC0
-#define SIXP_CHN_MASK		0x07
-#define SIXP_PRIO_CMD_MASK	0x80
-#define SIXP_STD_CMD_MASK	0x40
-#define SIXP_PRIO_DATA_MASK	0x38
-#define SIXP_TX_MASK		0x20
-#define SIXP_RX_MASK		0x10
-#define SIXP_RX_DCD_MASK	0x18
-#define SIXP_LEDS_ON		0x78
-#define SIXP_LEDS_OFF		0x60
-#define SIXP_CON		0x08
-#define SIXP_STA		0x10
-
-#define SIXP_FOUND_TNC		0xe9
-#define SIXP_CON_ON		0x68
-#define SIXP_DCD_MASK		0x08
-#define SIXP_DAMA_OFF		0
-
-/* default level 2 parameters */
-#define SIXP_TXDELAY			25	/* 250 ms */
-#define SIXP_PERSIST			50	/* in 256ths */
-#define SIXP_SLOTTIME			10	/* 100 ms */
-#define SIXP_INIT_RESYNC_TIMEOUT	(3*HZ/2) /* in 1 s */
-#define SIXP_RESYNC_TIMEOUT		5*HZ	/* in 1 s */
-
-/* 6pack configuration. */
-#define SIXP_NRUNIT			31      /* MAX number of 6pack channels */
-#define SIXP_MTU			256	/* Default MTU */
-
-enum sixpack_flags {
-	SIXPF_ERROR,	/* Parity, etc. error	*/
-};
-
-struct sixpack {
-	/* Various fields. */
-	struct tty_struct	*tty;		/* ptr to TTY structure	*/
-	struct net_device	*dev;		/* easy for intr handling  */
-
-	/* These are pointers to the malloc()ed frame buffers. */
-	int			rcount;         /* received chars counter  */
-	unsigned char		*xbuff;		/* transmitter buffer	*/
-	unsigned char		*xhead;         /* next byte to XMIT */
-	int			xleft;          /* bytes left in XMIT queue  */
-
-	u8			raw_buf[4];
-	u8			cooked_buf[400];
-
-	unsigned int		rx_count;
-	unsigned int		rx_count_cooked;
-	spinlock_t		rxlock;
-
-	unsigned long		flags;		/* Flag values/ mode etc */
-	unsigned char		mode;		/* 6pack mode */
-
-	/* 6pack stuff */
-	unsigned char		tx_delay;
-	unsigned char		persistence;
-	unsigned char		slottime;
-	unsigned char		duplex;
-	unsigned char		led_state;
-	u8			status;
-	u8			status1;
-	unsigned char		status2;
-	unsigned char		tx_enable;
-	unsigned char		tnc_state;
-
-	struct timer_list	tx_t;
-	struct timer_list	resync_t;
-	spinlock_t		lock;
-};
-
-#define AX25_6PACK_HEADER_LEN 0
-
-static void sixpack_decode(struct sixpack *, const u8 *, size_t);
-static int encode_sixpack(unsigned char *, unsigned char *, int, unsigned char);
-
-/*
- * Perform the persistence/slottime algorithm for CSMA access. If the
- * persistence check was successful, write the data to the serial driver.
- * Note that in case of DAMA operation, the data is not sent here.
- */
-
-static void sp_xmit_on_air(struct timer_list *t)
-{
-	struct sixpack *sp = timer_container_of(sp, t, tx_t);
-	int actual, when = sp->slottime;
-	static unsigned char random;
-
-	random = random * 17 + 41;
-
-	if (((sp->status1 & SIXP_DCD_MASK) == 0) && (random < sp->persistence)) {
-		sp->led_state = 0x70;
-		sp->tty->ops->write(sp->tty, &sp->led_state, 1);
-		sp->tx_enable = 1;
-		actual = sp->tty->ops->write(sp->tty, sp->xbuff, sp->status2);
-		sp->xleft -= actual;
-		sp->xhead += actual;
-		sp->led_state = 0x60;
-		sp->tty->ops->write(sp->tty, &sp->led_state, 1);
-		sp->status2 = 0;
-	} else
-		mod_timer(&sp->tx_t, jiffies + ((when + 1) * HZ) / 100);
-}
-
-/* ----> 6pack timer interrupt handler and friends. <---- */
-
-/* Encapsulate one AX.25 frame and stuff into a TTY queue. */
-static void sp_encaps(struct sixpack *sp, unsigned char *icp, int len)
-{
-	unsigned char *msg, *p = icp;
-	int actual, count;
-
-	if (len > AX25_MTU + 73) {
-		msg = "oversized transmit packet!";
-		goto out_drop;
-	}
-
-	if (p[0] > 5) {
-		msg = "invalid KISS command";
-		goto out_drop;
-	}
-
-	if ((p[0] != 0) && (len > 2)) {
-		msg = "KISS control packet too long";
-		goto out_drop;
-	}
-
-	if ((p[0] == 0) && (len < 15)) {
-		msg = "bad AX.25 packet to transmit";
-		goto out_drop;
-	}
-
-	count = encode_sixpack(p, sp->xbuff, len, sp->tx_delay);
-	set_bit(TTY_DO_WRITE_WAKEUP, &sp->tty->flags);
-
-	switch (p[0]) {
-	case 1:	sp->tx_delay = p[1];
-		return;
-	case 2:	sp->persistence = p[1];
-		return;
-	case 3:	sp->slottime = p[1];
-		return;
-	case 4:	/* ignored */
-		return;
-	case 5:	sp->duplex = p[1];
-		return;
-	}
-
-	if (p[0] != 0)
-		return;
-
-	/*
-	 * In case of fullduplex or DAMA operation, we don't take care about the
-	 * state of the DCD or of any timers, as the determination of the
-	 * correct time to send is the job of the AX.25 layer. We send
-	 * immediately after data has arrived.
-	 */
-	if (sp->duplex == 1) {
-		sp->led_state = 0x70;
-		sp->tty->ops->write(sp->tty, &sp->led_state, 1);
-		sp->tx_enable = 1;
-		actual = sp->tty->ops->write(sp->tty, sp->xbuff, count);
-		sp->xleft = count - actual;
-		sp->xhead = sp->xbuff + actual;
-		sp->led_state = 0x60;
-		sp->tty->ops->write(sp->tty, &sp->led_state, 1);
-	} else {
-		sp->xleft = count;
-		sp->xhead = sp->xbuff;
-		sp->status2 = count;
-		sp_xmit_on_air(&sp->tx_t);
-	}
-
-	return;
-
-out_drop:
-	sp->dev->stats.tx_dropped++;
-	netif_start_queue(sp->dev);
-	if (net_ratelimit())
-		printk(KERN_DEBUG "%s: %s - dropped.\n", sp->dev->name, msg);
-}
-
-/* Encapsulate an IP datagram and kick it into a TTY queue. */
-
-static netdev_tx_t sp_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct sixpack *sp = netdev_priv(dev);
-
-	if (skb->protocol == htons(ETH_P_IP))
-		return ax25_ip_xmit(skb);
-
-	spin_lock_bh(&sp->lock);
-	/* We were not busy, so we are now... :-) */
-	netif_stop_queue(dev);
-	dev->stats.tx_bytes += skb->len;
-	sp_encaps(sp, skb->data, skb->len);
-	spin_unlock_bh(&sp->lock);
-
-	dev_kfree_skb(skb);
-
-	return NETDEV_TX_OK;
-}
-
-static int sp_open_dev(struct net_device *dev)
-{
-	struct sixpack *sp = netdev_priv(dev);
-
-	if (sp->tty == NULL)
-		return -ENODEV;
-	return 0;
-}
-
-/* Close the low-level part of the 6pack channel. */
-static int sp_close(struct net_device *dev)
-{
-	struct sixpack *sp = netdev_priv(dev);
-
-	spin_lock_bh(&sp->lock);
-	if (sp->tty) {
-		/* TTY discipline is running. */
-		clear_bit(TTY_DO_WRITE_WAKEUP, &sp->tty->flags);
-	}
-	netif_stop_queue(dev);
-	spin_unlock_bh(&sp->lock);
-
-	return 0;
-}
-
-static int sp_set_mac_address(struct net_device *dev, void *addr)
-{
-	struct sockaddr_ax25 *sa = addr;
-
-	netif_tx_lock_bh(dev);
-	netif_addr_lock(dev);
-	__dev_addr_set(dev, &sa->sax25_call, AX25_ADDR_LEN);
-	netif_addr_unlock(dev);
-	netif_tx_unlock_bh(dev);
-
-	return 0;
-}
-
-static const struct net_device_ops sp_netdev_ops = {
-	.ndo_open		= sp_open_dev,
-	.ndo_stop		= sp_close,
-	.ndo_start_xmit		= sp_xmit,
-	.ndo_set_mac_address    = sp_set_mac_address,
-};
-
-static void sp_setup(struct net_device *dev)
-{
-	/* Finish setting up the DEVICE info. */
-	dev->netdev_ops		= &sp_netdev_ops;
-	dev->mtu		= SIXP_MTU;
-	dev->hard_header_len	= AX25_MAX_HEADER_LEN;
-	dev->header_ops 	= &ax25_header_ops;
-
-	dev->addr_len		= AX25_ADDR_LEN;
-	dev->type		= ARPHRD_AX25;
-	dev->tx_queue_len	= 10;
-
-	/* Only activated in AX.25 mode */
-	memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
-	dev_addr_set(dev, (u8 *)&ax25_defaddr);
-
-	dev->flags		= 0;
-}
-
-/* Send one completely decapsulated IP datagram to the IP layer. */
-
-/*
- * This is the routine that sends the received data to the kernel AX.25.
- * 'cmd' is the KISS command. For AX.25 data, it is zero.
- */
-
-static void sp_bump(struct sixpack *sp, char cmd)
-{
-	struct sk_buff *skb;
-	int count;
-	u8 *ptr;
-
-	count = sp->rcount + 1;
-
-	sp->dev->stats.rx_bytes += count;
-
-	if ((skb = dev_alloc_skb(count + 1)) == NULL)
-		goto out_mem;
-
-	ptr = skb_put(skb, count + 1);
-	*ptr++ = cmd;	/* KISS command */
-
-	memcpy(ptr, sp->cooked_buf + 1, count);
-	skb->protocol = ax25_type_trans(skb, sp->dev);
-	netif_rx(skb);
-	sp->dev->stats.rx_packets++;
-
-	return;
-
-out_mem:
-	sp->dev->stats.rx_dropped++;
-}
-
-
-/* ----------------------------------------------------------------------- */
-
-/*
- * Called by the TTY driver when there's room for more data.  If we have
- * more packets to send, we send them here.
- */
-static void sixpack_write_wakeup(struct tty_struct *tty)
-{
-	struct sixpack *sp = tty->disc_data;
-	int actual;
-
-	if (!sp)
-		return;
-	if (sp->xleft <= 0)  {
-		/* Now serial buffer is almost free & we can start
-		 * transmission of another packet */
-		sp->dev->stats.tx_packets++;
-		clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-		sp->tx_enable = 0;
-		netif_wake_queue(sp->dev);
-		return;
-	}
-
-	if (sp->tx_enable) {
-		actual = tty->ops->write(tty, sp->xhead, sp->xleft);
-		sp->xleft -= actual;
-		sp->xhead += actual;
-	}
-}
-
-/* ----------------------------------------------------------------------- */
-
-/*
- * Handle the 'receiver data ready' interrupt.
- * This function is called by the tty module in the kernel when
- * a block of 6pack data has been received, which can now be decapsulated
- * and sent on to some IP layer for further processing.
- */
-static void sixpack_receive_buf(struct tty_struct *tty, const u8 *cp,
-				const u8 *fp, size_t count)
-{
-	struct sixpack *sp;
-
-	if (!count)
-		return;
-
-	sp = tty->disc_data;
-	if (!sp)
-		return;
-
-	/* Read the characters out of the buffer */
-	while (count--) {
-		if (fp && *fp++) {
-			if (!test_and_set_bit(SIXPF_ERROR, &sp->flags))
-				sp->dev->stats.rx_errors++;
-			cp++;
-			continue;
-		}
-		sixpack_decode(sp, cp, 1);
-		cp++;
-	}
-
-	tty_unthrottle(tty);
-}
-
-/*
- * Try to resync the TNC. Called by the resync timer defined in
- * decode_prio_command
- */
-
-#define TNC_UNINITIALIZED	0
-#define TNC_UNSYNC_STARTUP	1
-#define TNC_UNSYNCED		2
-#define TNC_IN_SYNC		3
-
-static void __tnc_set_sync_state(struct sixpack *sp, int new_tnc_state)
-{
-	char *msg;
-
-	switch (new_tnc_state) {
-	default:			/* gcc oh piece-o-crap ... */
-	case TNC_UNSYNC_STARTUP:
-		msg = "Synchronizing with TNC";
-		break;
-	case TNC_UNSYNCED:
-		msg = "Lost synchronization with TNC\n";
-		break;
-	case TNC_IN_SYNC:
-		msg = "Found TNC";
-		break;
-	}
-
-	sp->tnc_state = new_tnc_state;
-	printk(KERN_INFO "%s: %s\n", sp->dev->name, msg);
-}
-
-static inline void tnc_set_sync_state(struct sixpack *sp, int new_tnc_state)
-{
-	int old_tnc_state = sp->tnc_state;
-
-	if (old_tnc_state != new_tnc_state)
-		__tnc_set_sync_state(sp, new_tnc_state);
-}
-
-static void resync_tnc(struct timer_list *t)
-{
-	struct sixpack *sp = timer_container_of(sp, t, resync_t);
-	static char resync_cmd = 0xe8;
-
-	/* clear any data that might have been received */
-
-	sp->rx_count = 0;
-	sp->rx_count_cooked = 0;
-
-	/* reset state machine */
-
-	sp->status = 1;
-	sp->status1 = 1;
-	sp->status2 = 0;
-
-	/* resync the TNC */
-
-	sp->led_state = 0x60;
-	sp->tty->ops->write(sp->tty, &sp->led_state, 1);
-	sp->tty->ops->write(sp->tty, &resync_cmd, 1);
-
-
-	/* Start resync timer again -- the TNC might be still absent */
-	mod_timer(&sp->resync_t, jiffies + SIXP_RESYNC_TIMEOUT);
-}
-
-static inline int tnc_init(struct sixpack *sp)
-{
-	unsigned char inbyte = 0xe8;
-
-	tnc_set_sync_state(sp, TNC_UNSYNC_STARTUP);
-
-	sp->tty->ops->write(sp->tty, &inbyte, 1);
-
-	mod_timer(&sp->resync_t, jiffies + SIXP_RESYNC_TIMEOUT);
-
-	return 0;
-}
-
-/*
- * Open the high-level part of the 6pack channel.
- * This function is called by the TTY module when the
- * 6pack line discipline is called for.  Because we are
- * sure the tty line exists, we only have to link it to
- * a free 6pcack channel...
- */
-static int sixpack_open(struct tty_struct *tty)
-{
-	char *xbuff = NULL;
-	struct net_device *dev;
-	struct sixpack *sp;
-	unsigned long len;
-	int err = 0;
-
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-	if (tty->ops->write == NULL)
-		return -EOPNOTSUPP;
-
-	dev = alloc_netdev(sizeof(struct sixpack), "sp%d", NET_NAME_UNKNOWN,
-			   sp_setup);
-	if (!dev) {
-		err = -ENOMEM;
-		goto out;
-	}
-
-	sp = netdev_priv(dev);
-	sp->dev = dev;
-
-	spin_lock_init(&sp->lock);
-	spin_lock_init(&sp->rxlock);
-
-	/* !!! length of the buffers. MTU is IP MTU, not PACLEN!  */
-
-	len = dev->mtu * 2;
-
-	xbuff = kmalloc(len + 4, GFP_KERNEL);
-	if (xbuff == NULL) {
-		err = -ENOBUFS;
-		goto out_free;
-	}
-
-	spin_lock_bh(&sp->lock);
-
-	sp->tty = tty;
-
-	sp->xbuff	= xbuff;
-
-	sp->rcount	= 0;
-	sp->rx_count	= 0;
-	sp->rx_count_cooked = 0;
-	sp->xleft	= 0;
-
-	sp->flags	= 0;		/* Clear ESCAPE & ERROR flags */
-
-	sp->duplex	= 0;
-	sp->tx_delay    = SIXP_TXDELAY;
-	sp->persistence = SIXP_PERSIST;
-	sp->slottime    = SIXP_SLOTTIME;
-	sp->led_state   = 0x60;
-	sp->status      = 1;
-	sp->status1     = 1;
-	sp->status2     = 0;
-	sp->tx_enable   = 0;
-
-	netif_start_queue(dev);
-
-	timer_setup(&sp->tx_t, sp_xmit_on_air, 0);
-
-	timer_setup(&sp->resync_t, resync_tnc, 0);
-
-	spin_unlock_bh(&sp->lock);
-
-	/* Done.  We have linked the TTY line to a channel. */
-	tty->disc_data = sp;
-	tty->receive_room = 65536;
-
-	/* Now we're ready to register. */
-	err = register_netdev(dev);
-	if (err)
-		goto out_free;
-
-	tnc_init(sp);
-
-	return 0;
-
-out_free:
-	kfree(xbuff);
-
-	free_netdev(dev);
-
-out:
-	return err;
-}
-
-
-/*
- * Close down a 6pack channel.
- * This means flushing out any pending queues, and then restoring the
- * TTY line discipline to what it was before it got hooked to 6pack
- * (which usually is TTY again).
- */
-static void sixpack_close(struct tty_struct *tty)
-{
-	struct sixpack *sp;
-
-	sp = tty->disc_data;
-	if (!sp)
-		return;
-
-	tty->disc_data = NULL;
-
-	/* We must stop the queue to avoid potentially scribbling
-	 * on the free buffers. The sp->dead completion is not sufficient
-	 * to protect us from sp->xbuff access.
-	 */
-	netif_stop_queue(sp->dev);
-
-	unregister_netdev(sp->dev);
-
-	timer_delete_sync(&sp->tx_t);
-	timer_delete_sync(&sp->resync_t);
-
-	/* Free all 6pack frame buffers after unreg. */
-	kfree(sp->xbuff);
-
-	free_netdev(sp->dev);
-}
-
-/* Perform I/O control on an active 6pack channel. */
-static int sixpack_ioctl(struct tty_struct *tty, unsigned int cmd,
-		unsigned long arg)
-{
-	struct sixpack *sp = tty->disc_data;
-	struct net_device *dev;
-	unsigned int tmp, err;
-
-	if (!sp)
-		return -ENXIO;
-	dev = sp->dev;
-
-	switch(cmd) {
-	case SIOCGIFNAME:
-		err = copy_to_user((void __user *) arg, dev->name,
-		                   strlen(dev->name) + 1) ? -EFAULT : 0;
-		break;
-
-	case SIOCGIFENCAP:
-		err = put_user(0, (int __user *) arg);
-		break;
-
-	case SIOCSIFENCAP:
-		if (get_user(tmp, (int __user *) arg)) {
-			err = -EFAULT;
-			break;
-		}
-
-		sp->mode = tmp;
-		dev->addr_len        = AX25_ADDR_LEN;
-		dev->hard_header_len = AX25_KISS_HEADER_LEN +
-		                       AX25_MAX_HEADER_LEN + 3;
-		dev->type            = ARPHRD_AX25;
-
-		err = 0;
-		break;
-
-	case SIOCSIFHWADDR: {
-			char addr[AX25_ADDR_LEN];
-
-			if (copy_from_user(&addr,
-					   (void __user *)arg, AX25_ADDR_LEN)) {
-				err = -EFAULT;
-				break;
-			}
-
-			netif_tx_lock_bh(dev);
-			__dev_addr_set(dev, &addr, AX25_ADDR_LEN);
-			netif_tx_unlock_bh(dev);
-			err = 0;
-			break;
-		}
-	default:
-		err = tty_mode_ioctl(tty, cmd, arg);
-	}
-
-	return err;
-}
-
-static struct tty_ldisc_ops sp_ldisc = {
-	.owner		= THIS_MODULE,
-	.num		= N_6PACK,
-	.name		= "6pack",
-	.open		= sixpack_open,
-	.close		= sixpack_close,
-	.ioctl		= sixpack_ioctl,
-	.receive_buf	= sixpack_receive_buf,
-	.write_wakeup	= sixpack_write_wakeup,
-};
-
-/* Initialize 6pack control device -- register 6pack line discipline */
-
-static int __init sixpack_init_driver(void)
-{
-	int status;
-
-	/* Register the provided line protocol discipline */
-	status = tty_register_ldisc(&sp_ldisc);
-	if (status)
-		pr_err("6pack: can't register line discipline (err = %d)\n", status);
-
-	return status;
-}
-
-static void __exit sixpack_exit_driver(void)
-{
-	tty_unregister_ldisc(&sp_ldisc);
-}
-
-/* encode an AX.25 packet into 6pack */
-
-static int encode_sixpack(unsigned char *tx_buf, unsigned char *tx_buf_raw,
-	int length, unsigned char tx_delay)
-{
-	int count = 0;
-	unsigned char checksum = 0, buf[400];
-	int raw_count = 0;
-
-	tx_buf_raw[raw_count++] = SIXP_PRIO_CMD_MASK | SIXP_TX_MASK;
-	tx_buf_raw[raw_count++] = SIXP_SEOF;
-
-	buf[0] = tx_delay;
-	for (count = 1; count < length; count++)
-		buf[count] = tx_buf[count];
-
-	for (count = 0; count < length; count++)
-		checksum += buf[count];
-	buf[length] = (unsigned char) 0xff - checksum;
-
-	for (count = 0; count <= length; count++) {
-		if ((count % 3) == 0) {
-			tx_buf_raw[raw_count++] = (buf[count] & 0x3f);
-			tx_buf_raw[raw_count] = ((buf[count] >> 2) & 0x30);
-		} else if ((count % 3) == 1) {
-			tx_buf_raw[raw_count++] |= (buf[count] & 0x0f);
-			tx_buf_raw[raw_count] =	((buf[count] >> 2) & 0x3c);
-		} else {
-			tx_buf_raw[raw_count++] |= (buf[count] & 0x03);
-			tx_buf_raw[raw_count++] = (buf[count] >> 2);
-		}
-	}
-	if ((length % 3) != 2)
-		raw_count++;
-	tx_buf_raw[raw_count++] = SIXP_SEOF;
-	return raw_count;
-}
-
-/* decode 4 sixpack-encoded bytes into 3 data bytes */
-
-static void decode_data(struct sixpack *sp, u8 inbyte)
-{
-	u8 *buf;
-
-	if (sp->rx_count != 3) {
-		sp->raw_buf[sp->rx_count++] = inbyte;
-
-		return;
-	}
-
-	if (sp->rx_count_cooked + 2 >= sizeof(sp->cooked_buf)) {
-		pr_err("6pack: cooked buffer overrun, data loss\n");
-		sp->rx_count = 0;
-		return;
-	}
-
-	buf = sp->raw_buf;
-	sp->cooked_buf[sp->rx_count_cooked++] =
-		buf[0] | ((buf[1] << 2) & 0xc0);
-	sp->cooked_buf[sp->rx_count_cooked++] =
-		(buf[1] & 0x0f) | ((buf[2] << 2) & 0xf0);
-	sp->cooked_buf[sp->rx_count_cooked++] =
-		(buf[2] & 0x03) | (inbyte << 2);
-	sp->rx_count = 0;
-}
-
-/* identify and execute a 6pack priority command byte */
-
-static void decode_prio_command(struct sixpack *sp, u8 cmd)
-{
-	ssize_t actual;
-
-	if ((cmd & SIXP_PRIO_DATA_MASK) != 0) {     /* idle ? */
-
-	/* RX and DCD flags can only be set in the same prio command,
-	   if the DCD flag has been set without the RX flag in the previous
-	   prio command. If DCD has not been set before, something in the
-	   transmission has gone wrong. In this case, RX and DCD are
-	   cleared in order to prevent the decode_data routine from
-	   reading further data that might be corrupt. */
-
-		if (((sp->status & SIXP_DCD_MASK) == 0) &&
-			((cmd & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)) {
-				if (sp->status != 1)
-					printk(KERN_DEBUG "6pack: protocol violation\n");
-				else
-					sp->status = 0;
-				cmd &= ~SIXP_RX_DCD_MASK;
-		}
-		sp->status = cmd & SIXP_PRIO_DATA_MASK;
-	} else { /* output watchdog char if idle */
-		if ((sp->status2 != 0) && (sp->duplex == 1)) {
-			sp->led_state = 0x70;
-			sp->tty->ops->write(sp->tty, &sp->led_state, 1);
-			sp->tx_enable = 1;
-			actual = sp->tty->ops->write(sp->tty, sp->xbuff, sp->status2);
-			sp->xleft -= actual;
-			sp->xhead += actual;
-			sp->led_state = 0x60;
-			sp->status2 = 0;
-
-		}
-	}
-
-	/* needed to trigger the TNC watchdog */
-	sp->tty->ops->write(sp->tty, &sp->led_state, 1);
-
-        /* if the state byte has been received, the TNC is present,
-           so the resync timer can be reset. */
-
-	if (sp->tnc_state == TNC_IN_SYNC)
-		mod_timer(&sp->resync_t, jiffies + SIXP_INIT_RESYNC_TIMEOUT);
-
-	sp->status1 = cmd & SIXP_PRIO_DATA_MASK;
-}
-
-/* identify and execute a standard 6pack command byte */
-
-static void decode_std_command(struct sixpack *sp, u8 cmd)
-{
-	u8 checksum = 0, rest = 0;
-	short i;
-
-	switch (cmd & SIXP_CMD_MASK) {     /* normal command */
-	case SIXP_SEOF:
-		if ((sp->rx_count == 0) && (sp->rx_count_cooked == 0)) {
-			if ((sp->status & SIXP_RX_DCD_MASK) ==
-				SIXP_RX_DCD_MASK) {
-				sp->led_state = 0x68;
-				sp->tty->ops->write(sp->tty, &sp->led_state, 1);
-			}
-		} else {
-			sp->led_state = 0x60;
-			/* fill trailing bytes with zeroes */
-			sp->tty->ops->write(sp->tty, &sp->led_state, 1);
-			spin_lock_bh(&sp->rxlock);
-			rest = sp->rx_count;
-			if (rest != 0)
-				 for (i = rest; i <= 3; i++)
-					decode_data(sp, 0);
-			if (rest == 2)
-				sp->rx_count_cooked -= 2;
-			else if (rest == 3)
-				sp->rx_count_cooked -= 1;
-			for (i = 0; i < sp->rx_count_cooked; i++)
-				checksum += sp->cooked_buf[i];
-			if (checksum != SIXP_CHKSUM) {
-				printk(KERN_DEBUG "6pack: bad checksum %2.2x\n", checksum);
-			} else {
-				sp->rcount = sp->rx_count_cooked-2;
-				sp_bump(sp, 0);
-			}
-			sp->rx_count_cooked = 0;
-			spin_unlock_bh(&sp->rxlock);
-		}
-		break;
-	case SIXP_TX_URUN: printk(KERN_DEBUG "6pack: TX underrun\n");
-		break;
-	case SIXP_RX_ORUN: printk(KERN_DEBUG "6pack: RX overrun\n");
-		break;
-	case SIXP_RX_BUF_OVL:
-		printk(KERN_DEBUG "6pack: RX buffer overflow\n");
-	}
-}
-
-/* decode a 6pack packet */
-
-static void
-sixpack_decode(struct sixpack *sp, const u8 *pre_rbuff, size_t count)
-{
-	size_t count1;
-	u8 inbyte;
-
-	for (count1 = 0; count1 < count; count1++) {
-		inbyte = pre_rbuff[count1];
-		if (inbyte == SIXP_FOUND_TNC) {
-			tnc_set_sync_state(sp, TNC_IN_SYNC);
-			timer_delete(&sp->resync_t);
-		}
-		if ((inbyte & SIXP_PRIO_CMD_MASK) != 0)
-			decode_prio_command(sp, inbyte);
-		else if ((inbyte & SIXP_STD_CMD_MASK) != 0)
-			decode_std_command(sp, inbyte);
-		else if ((sp->status & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK) {
-			spin_lock_bh(&sp->rxlock);
-			decode_data(sp, inbyte);
-			spin_unlock_bh(&sp->rxlock);
-		}
-	}
-}
-
-MODULE_AUTHOR("Ralf Baechle DO1GRB <ralf@linux-mips.org>");
-MODULE_DESCRIPTION("6pack driver for AX.25");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_LDISC(N_6PACK);
-
-module_init(sixpack_init_driver);
-module_exit(sixpack_exit_driver);
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
deleted file mode 100644
index 5fda7a0fcce0..000000000000
--- a/drivers/net/hamradio/baycom_epp.c
+++ /dev/null
@@ -1,1316 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*****************************************************************************/
-
-/*
- *	baycom_epp.c  -- baycom epp radio modem driver.
- *
- *	Copyright (C) 1998-2000
- *          Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *  Please note that the GPL allows you to use the driver, NOT the radio.
- *  In order to use the radio, you need a license from the communications
- *  authority of your country.
- *
- *  History:
- *   0.1  xx.xx.1998  Initial version by Matthias Welwarsky (dg2fef)
- *   0.2  21.04.1998  Massive rework by Thomas Sailer
- *                    Integrated FPGA EPP modem configuration routines
- *   0.3  11.05.1998  Took FPGA config out and moved it into a separate program
- *   0.4  26.07.1999  Adapted to new lowlevel parport driver interface
- *   0.5  03.08.1999  adapt to Linus' new __setup/__initcall
- *                    removed some pre-2.2 kernel compatibility cruft
- *   0.6  10.08.1999  Check if parport can do SPP and is safe to access during interrupt contexts
- *   0.7  12.02.2000  adapted to softnet driver interface
- */
-
-/*****************************************************************************/
-
-#include <linux/crc-ccitt.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/workqueue.h>
-#include <linux/fs.h>
-#include <linux/parport.h>
-#include <linux/if_arp.h>
-#include <linux/hdlcdrv.h>
-#include <linux/baycom.h>
-#include <linux/jiffies.h>
-#include <linux/random.h>
-#include <net/ax25.h> 
-#include <linux/uaccess.h>
-
-/* --------------------------------------------------------------------- */
-
-#define BAYCOM_DEBUG
-#define BAYCOM_MAGIC 19730510
-
-/* --------------------------------------------------------------------- */
-
-static const char paranoia_str[] = KERN_ERR 
-	"baycom_epp: bad magic number for hdlcdrv_state struct in routine %s\n";
-
-static const char bc_drvname[] = "baycom_epp";
-static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998-2000 Thomas Sailer, HB9JNX/AE4WA\n"
-"baycom_epp: version 0.7\n";
-
-/* --------------------------------------------------------------------- */
-
-#define NR_PORTS 4
-
-static struct net_device *baycom_device[NR_PORTS];
-
-/* --------------------------------------------------------------------- */
-
-/* EPP status register */
-#define EPP_DCDBIT      0x80
-#define EPP_PTTBIT      0x08
-#define EPP_NREF        0x01
-#define EPP_NRAEF       0x02
-#define EPP_NRHF        0x04
-#define EPP_NTHF        0x20
-#define EPP_NTAEF       0x10
-#define EPP_NTEF        EPP_PTTBIT
-
-/* EPP control register */
-#define EPP_TX_FIFO_ENABLE 0x10
-#define EPP_RX_FIFO_ENABLE 0x08
-#define EPP_MODEM_ENABLE   0x20
-#define EPP_LEDS           0xC0
-#define EPP_IRQ_ENABLE     0x10
-
-/* LPT registers */
-#define LPTREG_ECONTROL       0x402
-#define LPTREG_CONFIGB        0x401
-#define LPTREG_CONFIGA        0x400
-#define LPTREG_EPPDATA        0x004
-#define LPTREG_EPPADDR        0x003
-#define LPTREG_CONTROL        0x002
-#define LPTREG_STATUS         0x001
-#define LPTREG_DATA           0x000
-
-/* LPT control register */
-#define LPTCTRL_PROGRAM       0x04   /* 0 to reprogram */
-#define LPTCTRL_WRITE         0x01
-#define LPTCTRL_ADDRSTB       0x08
-#define LPTCTRL_DATASTB       0x02
-#define LPTCTRL_INTEN         0x10
-
-/* LPT status register */
-#define LPTSTAT_SHIFT_NINTR   6
-#define LPTSTAT_WAIT          0x80
-#define LPTSTAT_NINTR         (1<<LPTSTAT_SHIFT_NINTR)
-#define LPTSTAT_PE            0x20
-#define LPTSTAT_DONE          0x10
-#define LPTSTAT_NERROR        0x08
-#define LPTSTAT_EPPTIMEOUT    0x01
-
-/* LPT data register */
-#define LPTDATA_SHIFT_TDI     0
-#define LPTDATA_SHIFT_TMS     2
-#define LPTDATA_TDI           (1<<LPTDATA_SHIFT_TDI)
-#define LPTDATA_TCK           0x02
-#define LPTDATA_TMS           (1<<LPTDATA_SHIFT_TMS)
-#define LPTDATA_INITBIAS      0x80
-
-
-/* EPP modem config/status bits */
-#define EPP_DCDBIT            0x80
-#define EPP_PTTBIT            0x08
-#define EPP_RXEBIT            0x01
-#define EPP_RXAEBIT           0x02
-#define EPP_RXHFULL           0x04
-
-#define EPP_NTHF              0x20
-#define EPP_NTAEF             0x10
-#define EPP_NTEF              EPP_PTTBIT
-
-#define EPP_TX_FIFO_ENABLE    0x10
-#define EPP_RX_FIFO_ENABLE    0x08
-#define EPP_MODEM_ENABLE      0x20
-#define EPP_LEDS              0xC0
-#define EPP_IRQ_ENABLE        0x10
-
-/* Xilinx 4k JTAG instructions */
-#define XC4K_IRLENGTH   3
-#define XC4K_EXTEST     0
-#define XC4K_PRELOAD    1
-#define XC4K_CONFIGURE  5
-#define XC4K_BYPASS     7
-
-#define EPP_CONVENTIONAL  0
-#define EPP_FPGA          1
-#define EPP_FPGAEXTSTATUS 2
-
-#define TXBUFFER_SIZE     ((HDLCDRV_MAXFLEN*6/5)+8)
-
-/* ---------------------------------------------------------------------- */
-/*
- * Information that need to be kept for each board.
- */
-
-struct baycom_state {
-	int magic;
-
-        struct pardevice *pdev;
-	struct net_device *dev;
-	unsigned int work_running;
-	struct delayed_work run_work;
-	unsigned int modem;
-	unsigned int bitrate;
-	unsigned char stat;
-
-	struct {
-		unsigned int intclk;
-		unsigned int fclk;
-		unsigned int bps;
-		unsigned int extmodem;
-		unsigned int loopback;
-	} cfg;
-
-        struct hdlcdrv_channel_params ch_params;
-
-        struct {
-		unsigned int bitbuf, bitstream, numbits, state;
-		unsigned char *bufptr;
-		int bufcnt;
-		unsigned char buf[TXBUFFER_SIZE];
-        } hdlcrx;
-
-        struct {
-		int calibrate;
-                int slotcnt;
-		int flags;
-		enum { tx_idle = 0, tx_keyup, tx_data, tx_tail } state;
-		unsigned char *bufptr;
-		int bufcnt;
-		unsigned char buf[TXBUFFER_SIZE];
-        } hdlctx;
-
-	unsigned int ptt_keyed;
-	struct sk_buff *skb;  /* next transmit packet  */
-
-#ifdef BAYCOM_DEBUG
-	struct debug_vals {
-		unsigned long last_jiffies;
-		unsigned cur_intcnt;
-		unsigned last_intcnt;
-		int cur_pllcorr;
-		int last_pllcorr;
-		unsigned int mod_cycles;
-		unsigned int demod_cycles;
-	} debug_vals;
-#endif /* BAYCOM_DEBUG */
-};
-
-/* --------------------------------------------------------------------- */
-
-#define KISS_VERBOSE
-
-/* --------------------------------------------------------------------- */
-
-#define PARAM_TXDELAY   1
-#define PARAM_PERSIST   2
-#define PARAM_SLOTTIME  3
-#define PARAM_TXTAIL    4
-#define PARAM_FULLDUP   5
-#define PARAM_HARDWARE  6
-#define PARAM_RETURN    255
-
-/* --------------------------------------------------------------------- */
-/*
- * the CRC routines are stolen from WAMPES
- * by Dieter Deyke
- */
-
-
-/*---------------------------------------------------------------------------*/
-
-#if 0
-static inline void append_crc_ccitt(unsigned char *buffer, int len)
-{
-	unsigned int crc = 0xffff;
-
-	for (;len>0;len--)
-		crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buffer++) & 0xff];
-	crc ^= 0xffff;
-	*buffer++ = crc;
-	*buffer++ = crc >> 8;
-}
-#endif
-
-/*---------------------------------------------------------------------------*/
-
-static inline int check_crc_ccitt(const unsigned char *buf, int cnt)
-{
-	return (crc_ccitt(0xffff, buf, cnt) & 0xffff) == 0xf0b8;
-}
-
-/*---------------------------------------------------------------------------*/
-
-static inline int calc_crc_ccitt(const unsigned char *buf, int cnt)
-{
-	return (crc_ccitt(0xffff, buf, cnt) ^ 0xffff) & 0xffff;
-}
-
-/* ---------------------------------------------------------------------- */
-
-#define tenms_to_flags(bc,tenms) ((tenms * bc->bitrate) / 800)
-
-/* --------------------------------------------------------------------- */
-
-static inline void baycom_int_freq(struct baycom_state *bc)
-{
-#ifdef BAYCOM_DEBUG
-	unsigned long cur_jiffies = jiffies;
-	/*
-	 * measure the interrupt frequency
-	 */
-	bc->debug_vals.cur_intcnt++;
-	if (time_after_eq(cur_jiffies, bc->debug_vals.last_jiffies + HZ)) {
-		bc->debug_vals.last_jiffies = cur_jiffies;
-		bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt;
-		bc->debug_vals.cur_intcnt = 0;
-		bc->debug_vals.last_pllcorr = bc->debug_vals.cur_pllcorr;
-		bc->debug_vals.cur_pllcorr = 0;
-	}
-#endif /* BAYCOM_DEBUG */
-}
-
-/* ---------------------------------------------------------------------- */
-/*
- *    eppconfig_path should be setable  via /proc/sys.
- */
-
-static char const eppconfig_path[] = "/usr/sbin/eppfpga";
-
-static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL };
-
-/* eppconfig: called during ifconfig up to configure the modem */
-static int eppconfig(struct baycom_state *bc)
-{
-	char modearg[256];
-	char portarg[16];
-        char *argv[] = {
-		(char *)eppconfig_path,
-		"-s",
-		"-p", portarg,
-		"-m", modearg,
-		NULL };
-
-	/* set up arguments */
-	sprintf(modearg, "%sclk,%smodem,fclk=%d,bps=%d,divider=%d%s,extstat",
-		bc->cfg.intclk ? "int" : "ext",
-		bc->cfg.extmodem ? "ext" : "int", bc->cfg.fclk, bc->cfg.bps,
-		(bc->cfg.fclk + 8 * bc->cfg.bps) / (16 * bc->cfg.bps),
-		bc->cfg.loopback ? ",loopback" : "");
-	sprintf(portarg, "%ld", bc->pdev->port->base);
-	printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg);
-
-	return call_usermodehelper(eppconfig_path, argv, envp, UMH_WAIT_PROC);
-}
-
-/* ---------------------------------------------------------------------- */
-
-static inline void do_kiss_params(struct baycom_state *bc,
-				  unsigned char *data, unsigned long len)
-{
-
-#ifdef KISS_VERBOSE
-#define PKP(a,b) printk(KERN_INFO "baycomm_epp: channel params: " a "\n", b)
-#else /* KISS_VERBOSE */	      
-#define PKP(a,b) 
-#endif /* KISS_VERBOSE */	      
-
-	if (len < 2)
-		return;
-	switch(data[0]) {
-	case PARAM_TXDELAY:
-		bc->ch_params.tx_delay = data[1];
-		PKP("TX delay = %ums", 10 * bc->ch_params.tx_delay);
-		break;
-	case PARAM_PERSIST:   
-		bc->ch_params.ppersist = data[1];
-		PKP("p persistence = %u", bc->ch_params.ppersist);
-		break;
-	case PARAM_SLOTTIME:  
-		bc->ch_params.slottime = data[1];
-		PKP("slot time = %ums", bc->ch_params.slottime);
-		break;
-	case PARAM_TXTAIL:    
-		bc->ch_params.tx_tail = data[1];
-		PKP("TX tail = %ums", bc->ch_params.tx_tail);
-		break;
-	case PARAM_FULLDUP:   
-		bc->ch_params.fulldup = !!data[1];
-		PKP("%s duplex", bc->ch_params.fulldup ? "full" : "half");
-		break;
-	default:
-		break;
-	}
-#undef PKP
-}
-
-/* --------------------------------------------------------------------- */
-
-static void encode_hdlc(struct baycom_state *bc)
-{
-	struct sk_buff *skb;
-	unsigned char *wp, *bp;
-	int pkt_len;
-        unsigned bitstream, notbitstream, bitbuf, numbit, crc;
-	unsigned char crcarr[2];
-	int j;
-	
-	if (bc->hdlctx.bufcnt > 0)
-		return;
-	skb = bc->skb;
-	if (!skb)
-		return;
-	bc->skb = NULL;
-	pkt_len = skb->len-1; /* strip KISS byte */
-	wp = bc->hdlctx.buf;
-	bp = skb->data+1;
-	crc = calc_crc_ccitt(bp, pkt_len);
-	crcarr[0] = crc;
-	crcarr[1] = crc >> 8;
-	*wp++ = 0x7e;
-	bitstream = bitbuf = numbit = 0;
-	while (pkt_len > -2) {
-		bitstream >>= 8;
-		bitstream |= ((unsigned int)*bp) << 8;
-		bitbuf |= ((unsigned int)*bp) << numbit;
-		notbitstream = ~bitstream;
-		bp++;
-		pkt_len--;
-		if (!pkt_len)
-			bp = crcarr;
-		for (j = 0; j < 8; j++)
-			if (unlikely(!(notbitstream & (0x1f0 << j)))) {
-				bitstream &= ~(0x100 << j);
-				bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) |
-					((bitbuf & ~(((2 << j) << numbit) - 1)) << 1);
-				numbit++;
-				notbitstream = ~bitstream;
-			}
-		numbit += 8;
-		while (numbit >= 8) {
-			*wp++ = bitbuf;
-			bitbuf >>= 8;
-			numbit -= 8;
-		}
-	}
-	bitbuf |= 0x7e7e << numbit;
-	numbit += 16;
-	while (numbit >= 8) {
-		*wp++ = bitbuf;
-		bitbuf >>= 8;
-		numbit -= 8;
-	}
-	bc->hdlctx.bufptr = bc->hdlctx.buf;
-	bc->hdlctx.bufcnt = wp - bc->hdlctx.buf;
-	dev_kfree_skb(skb);
-	bc->dev->stats.tx_packets++;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static int transmit(struct baycom_state *bc, int cnt, unsigned char stat)
-{
-	struct parport *pp = bc->pdev->port;
-	unsigned char tmp[128];
-	int i, j;
-
-	if (bc->hdlctx.state == tx_tail && !(stat & EPP_PTTBIT))
-		bc->hdlctx.state = tx_idle;
-	if (bc->hdlctx.state == tx_idle && bc->hdlctx.calibrate <= 0) {
-		if (bc->hdlctx.bufcnt <= 0)
-			encode_hdlc(bc);
-		if (bc->hdlctx.bufcnt <= 0)
-			return 0;
-		if (!bc->ch_params.fulldup) {
-			if (!(stat & EPP_DCDBIT)) {
-				bc->hdlctx.slotcnt = bc->ch_params.slottime;
-				return 0;
-			}
-			if ((--bc->hdlctx.slotcnt) > 0)
-				return 0;
-			bc->hdlctx.slotcnt = bc->ch_params.slottime;
-			if (get_random_u8() > bc->ch_params.ppersist)
-				return 0;
-		}
-	}
-	if (bc->hdlctx.state == tx_idle && bc->hdlctx.bufcnt > 0) {
-		bc->hdlctx.state = tx_keyup;
-		bc->hdlctx.flags = tenms_to_flags(bc, bc->ch_params.tx_delay);
-		bc->ptt_keyed++;
-	}
-	while (cnt > 0) {
-		switch (bc->hdlctx.state) {
-		case tx_keyup:
-			i = min_t(int, cnt, bc->hdlctx.flags);
-			cnt -= i;
-			bc->hdlctx.flags -= i;
-			if (bc->hdlctx.flags <= 0)
-				bc->hdlctx.state = tx_data;
-			memset(tmp, 0x7e, sizeof(tmp));
-			while (i > 0) {
-				j = (i > sizeof(tmp)) ? sizeof(tmp) : i;
-				if (j != pp->ops->epp_write_data(pp, tmp, j, 0))
-					return -1;
-				i -= j;
-			}
-			break;
-
-		case tx_data:
-			if (bc->hdlctx.bufcnt <= 0) {
-				encode_hdlc(bc);
-				if (bc->hdlctx.bufcnt <= 0) {
-					bc->hdlctx.state = tx_tail;
-					bc->hdlctx.flags = tenms_to_flags(bc, bc->ch_params.tx_tail);
-					break;
-				}
-			}
-			i = min_t(int, cnt, bc->hdlctx.bufcnt);
-			bc->hdlctx.bufcnt -= i;
-			cnt -= i;
-			if (i != pp->ops->epp_write_data(pp, bc->hdlctx.bufptr, i, 0))
-					return -1;
-			bc->hdlctx.bufptr += i;
-			break;
-			
-		case tx_tail:
-			encode_hdlc(bc);
-			if (bc->hdlctx.bufcnt > 0) {
-				bc->hdlctx.state = tx_data;
-				break;
-			}
-			i = min_t(int, cnt, bc->hdlctx.flags);
-			if (i) {
-				cnt -= i;
-				bc->hdlctx.flags -= i;
-				memset(tmp, 0x7e, sizeof(tmp));
-				while (i > 0) {
-					j = (i > sizeof(tmp)) ? sizeof(tmp) : i;
-					if (j != pp->ops->epp_write_data(pp, tmp, j, 0))
-						return -1;
-					i -= j;
-				}
-				break;
-			}
-			fallthrough;
-
-		default:
-			if (bc->hdlctx.calibrate <= 0)
-				return 0;
-			i = min_t(int, cnt, bc->hdlctx.calibrate);
-			cnt -= i;
-			bc->hdlctx.calibrate -= i;
-			memset(tmp, 0, sizeof(tmp));
-			while (i > 0) {
-				j = (i > sizeof(tmp)) ? sizeof(tmp) : i;
-				if (j != pp->ops->epp_write_data(pp, tmp, j, 0))
-					return -1;
-				i -= j;
-			}
-			break;
-		}
-	}
-	return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static void do_rxpacket(struct net_device *dev)
-{
-	struct baycom_state *bc = netdev_priv(dev);
-	struct sk_buff *skb;
-	unsigned char *cp;
-	unsigned pktlen;
-
-	if (bc->hdlcrx.bufcnt < 4) 
-		return;
-	if (!check_crc_ccitt(bc->hdlcrx.buf, bc->hdlcrx.bufcnt)) 
-		return;
-	pktlen = bc->hdlcrx.bufcnt-2+1; /* KISS kludge */
-	if (!(skb = dev_alloc_skb(pktlen))) {
-		printk("%s: memory squeeze, dropping packet\n", dev->name);
-		dev->stats.rx_dropped++;
-		return;
-	}
-	cp = skb_put(skb, pktlen);
-	*cp++ = 0; /* KISS kludge */
-	memcpy(cp, bc->hdlcrx.buf, pktlen - 1);
-	skb->protocol = ax25_type_trans(skb, dev);
-	netif_rx(skb);
-	dev->stats.rx_packets++;
-}
-
-static int receive(struct net_device *dev, int cnt)
-{
-	struct baycom_state *bc = netdev_priv(dev);
-	struct parport *pp = bc->pdev->port;
-        unsigned int bitbuf, notbitstream, bitstream, numbits, state;
-	unsigned char tmp[128];
-        unsigned char *cp;
-	int cnt2, ret = 0;
-	int j;
-        
-        numbits = bc->hdlcrx.numbits;
-	state = bc->hdlcrx.state;
-	bitstream = bc->hdlcrx.bitstream;
-	bitbuf = bc->hdlcrx.bitbuf;
-	while (cnt > 0) {
-		cnt2 = (cnt > sizeof(tmp)) ? sizeof(tmp) : cnt;
-		cnt -= cnt2;
-		if (cnt2 != pp->ops->epp_read_data(pp, tmp, cnt2, 0)) {
-			ret = -1;
-			break;
-		}
-		cp = tmp;
-		for (; cnt2 > 0; cnt2--, cp++) {
-			bitstream >>= 8;
-			bitstream |= (*cp) << 8;
-			bitbuf >>= 8;
-			bitbuf |= (*cp) << 8;
-			numbits += 8;
-			notbitstream = ~bitstream;
-			for (j = 0; j < 8; j++) {
-
-				/* flag or abort */
-			        if (unlikely(!(notbitstream & (0x0fc << j)))) {
-
-					/* abort received */
-					if (!(notbitstream & (0x1fc << j)))
-						state = 0;
-
-					/* flag received */
-					else if ((bitstream & (0x1fe << j)) == (0x0fc << j)) {
-						if (state)
-							do_rxpacket(dev);
-						bc->hdlcrx.bufcnt = 0;
-						bc->hdlcrx.bufptr = bc->hdlcrx.buf;
-						state = 1;
-						numbits = 7-j;
-					}
-				}
-
-				/* stuffed bit */
-				else if (unlikely((bitstream & (0x1f8 << j)) == (0xf8 << j))) {
-					numbits--;
-					bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1);
-					}
-				}
-			while (state && numbits >= 8) {
-				if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) {
-					state = 0;
-				} else {
-					*(bc->hdlcrx.bufptr)++ = bitbuf >> (16-numbits);
-					bc->hdlcrx.bufcnt++;
-					numbits -= 8;
-				}
-			}
-		}
-	}
-        bc->hdlcrx.numbits = numbits;
-	bc->hdlcrx.state = state;
-	bc->hdlcrx.bitstream = bitstream;
-	bc->hdlcrx.bitbuf = bitbuf;
-	return ret;
-}
-
-/* --------------------------------------------------------------------- */
-
-#define GETTICK(x)						\
-({								\
-	x = (unsigned int)get_cycles();				\
-})
-
-static void epp_bh(struct work_struct *work)
-{
-	struct net_device *dev;
-	struct baycom_state *bc;
-	struct parport *pp;
-	unsigned char stat;
-	unsigned char tmp[2];
-	unsigned int time1 = 0, time2 = 0, time3 = 0;
-	int cnt, cnt2;
-
-	bc = container_of(work, struct baycom_state, run_work.work);
-	dev = bc->dev;
-	if (!bc->work_running)
-		return;
-	baycom_int_freq(bc);
-	pp = bc->pdev->port;
-	/* update status */
-	if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1)
-		goto epptimeout;
-	bc->stat = stat;
-	bc->debug_vals.last_pllcorr = stat;
-	GETTICK(time1);
-	if (bc->modem == EPP_FPGAEXTSTATUS) {
-		/* get input count */
-		tmp[0] = EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE|1;
-		if (pp->ops->epp_write_addr(pp, tmp, 1, 0) != 1)
-			goto epptimeout;
-		if (pp->ops->epp_read_addr(pp, tmp, 2, 0) != 2)
-			goto epptimeout;
-		cnt = tmp[0] | (tmp[1] << 8);
-		cnt &= 0x7fff;
-		/* get output count */
-		tmp[0] = EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE|2;
-		if (pp->ops->epp_write_addr(pp, tmp, 1, 0) != 1)
-			goto epptimeout;
-		if (pp->ops->epp_read_addr(pp, tmp, 2, 0) != 2)
-			goto epptimeout;
-		cnt2 = tmp[0] | (tmp[1] << 8);
-		cnt2 = 16384 - (cnt2 & 0x7fff);
-		/* return to normal */
-		tmp[0] = EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE;
-		if (pp->ops->epp_write_addr(pp, tmp, 1, 0) != 1)
-			goto epptimeout;
-		if (transmit(bc, cnt2, stat))
-			goto epptimeout;
-		GETTICK(time2);
-		if (receive(dev, cnt))
-			goto epptimeout;
-		if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1)
-			goto epptimeout;
-		bc->stat = stat;
-	} else {
-		/* try to tx */
-		switch (stat & (EPP_NTAEF|EPP_NTHF)) {
-		case EPP_NTHF:
-			cnt = 2048 - 256;
-			break;
-		
-		case EPP_NTAEF:
-			cnt = 2048 - 1793;
-			break;
-		
-		case 0:
-			cnt = 0;
-			break;
-		
-		default:
-			cnt = 2048 - 1025;
-			break;
-		}
-		if (transmit(bc, cnt, stat))
-			goto epptimeout;
-		GETTICK(time2);
-		/* do receiver */
-		while ((stat & (EPP_NRAEF|EPP_NRHF)) != EPP_NRHF) {
-			switch (stat & (EPP_NRAEF|EPP_NRHF)) {
-			case EPP_NRAEF:
-				cnt = 1025;
-				break;
-
-			case 0:
-				cnt = 1793;
-				break;
-
-			default:
-				cnt = 256;
-				break;
-			}
-			if (receive(dev, cnt))
-				goto epptimeout;
-			if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1)
-				goto epptimeout;
-		}
-		cnt = 0;
-		if (bc->bitrate < 50000)
-			cnt = 256;
-		else if (bc->bitrate < 100000)
-			cnt = 128;
-		while (cnt > 0 && stat & EPP_NREF) {
-			if (receive(dev, 1))
-				goto epptimeout;
-			cnt--;
-			if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1)
-				goto epptimeout;
-		}
-	}
-	GETTICK(time3);
-#ifdef BAYCOM_DEBUG
-	bc->debug_vals.mod_cycles = time2 - time1;
-	bc->debug_vals.demod_cycles = time3 - time2;
-#endif /* BAYCOM_DEBUG */
-	schedule_delayed_work(&bc->run_work, 1);
-	if (!bc->skb)
-		netif_wake_queue(dev);
-	return;
- epptimeout:
-	printk(KERN_ERR "%s: EPP timeout!\n", bc_drvname);
-}
-
-/* ---------------------------------------------------------------------- */
-/*
- * ===================== network driver interface =========================
- */
-
-static netdev_tx_t baycom_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
-	struct baycom_state *bc = netdev_priv(dev);
-
-	if (skb->protocol == htons(ETH_P_IP))
-		return ax25_ip_xmit(skb);
-
-	if (skb->data[0] != 0) {
-		do_kiss_params(bc, skb->data, skb->len);
-		dev_kfree_skb(skb);
-		return NETDEV_TX_OK;
-	}
-	if (bc->skb) {
-		dev_kfree_skb(skb);
-		return NETDEV_TX_OK;
-	}
-	/* strip KISS byte */
-	if (skb->len >= HDLCDRV_MAXFLEN+1 || skb->len < 3) {
-		dev_kfree_skb(skb);
-		return NETDEV_TX_OK;
-	}
-	netif_stop_queue(dev);
-	bc->skb = skb;
-	return NETDEV_TX_OK;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int baycom_set_mac_address(struct net_device *dev, void *addr)
-{
-	struct sockaddr *sa = (struct sockaddr *)addr;
-
-	/* addr is an AX.25 shifted ASCII mac address */
-	dev_addr_set(dev, sa->sa_data);
-	return 0;                                         
-}
-
-/* --------------------------------------------------------------------- */
-
-static void epp_wakeup(void *handle)
-{
-        struct net_device *dev = (struct net_device *)handle;
-        struct baycom_state *bc = netdev_priv(dev);
-
-        printk(KERN_DEBUG "baycom_epp: %s: why am I being woken up?\n", dev->name);
-        if (!parport_claim(bc->pdev))
-                printk(KERN_DEBUG "baycom_epp: %s: I'm broken.\n", dev->name);
-}
-
-/* --------------------------------------------------------------------- */
-
-/*
- * Open/initialize the board. This is called (in the current kernel)
- * sometime after booting when the 'ifconfig' program is run.
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is non-reboot way to recover if something goes wrong.
- */
-
-static int epp_open(struct net_device *dev)
-{
-	struct baycom_state *bc = netdev_priv(dev);
-        struct parport *pp = parport_find_base(dev->base_addr);
-	unsigned int i, j;
-	unsigned char tmp[128];
-	unsigned char stat;
-	unsigned long tstart;
-	struct pardev_cb par_cb;
-	
-        if (!pp) {
-                printk(KERN_ERR "%s: parport at 0x%lx unknown\n", bc_drvname, dev->base_addr);
-                return -ENXIO;
-        }
-#if 0
-        if (pp->irq < 0) {
-                printk(KERN_ERR "%s: parport at 0x%lx has no irq\n", bc_drvname, pp->base);
-		parport_put_port(pp);
-                return -ENXIO;
-        }
-#endif
-	if ((~pp->modes) & (PARPORT_MODE_TRISTATE | PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT)) {
-                printk(KERN_ERR "%s: parport at 0x%lx cannot be used\n",
-		       bc_drvname, pp->base);
-		parport_put_port(pp);
-                return -EIO;
-	}
-	memset(&bc->modem, 0, sizeof(bc->modem));
-	memset(&par_cb, 0, sizeof(par_cb));
-	par_cb.wakeup = epp_wakeup;
-	par_cb.private = (void *)dev;
-	par_cb.flags = PARPORT_DEV_EXCL;
-	for (i = 0; i < NR_PORTS; i++)
-		if (baycom_device[i] == dev)
-			break;
-
-	if (i == NR_PORTS) {
-		pr_err("%s: no device found\n", bc_drvname);
-		parport_put_port(pp);
-		return -ENODEV;
-	}
-
-	bc->pdev = parport_register_dev_model(pp, dev->name, &par_cb, i);
-	parport_put_port(pp);
-        if (!bc->pdev) {
-                printk(KERN_ERR "%s: cannot register parport at 0x%lx\n", bc_drvname, pp->base);
-                return -ENXIO;
-        }
-        if (parport_claim(bc->pdev)) {
-                printk(KERN_ERR "%s: parport at 0x%lx busy\n", bc_drvname, pp->base);
-                parport_unregister_device(bc->pdev);
-                return -EBUSY;
-        }
-        dev->irq = /*pp->irq*/ 0;
-	INIT_DELAYED_WORK(&bc->run_work, epp_bh);
-	bc->work_running = 1;
-	bc->modem = EPP_CONVENTIONAL;
-	if (eppconfig(bc))
-		printk(KERN_INFO "%s: no FPGA detected, assuming conventional EPP modem\n", bc_drvname);
-	else
-		bc->modem = /*EPP_FPGA*/ EPP_FPGAEXTSTATUS;
-	parport_write_control(pp, LPTCTRL_PROGRAM); /* prepare EPP mode; we aren't using interrupts */
-	/* reset the modem */
-	tmp[0] = 0;
-	tmp[1] = EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE;
-	if (pp->ops->epp_write_addr(pp, tmp, 2, 0) != 2)
-		goto epptimeout;
-	/* autoprobe baud rate */
-	tstart = jiffies;
-	i = 0;
-	while (time_before(jiffies, tstart + HZ/3)) {
-		if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1)
-			goto epptimeout;
-		if ((stat & (EPP_NRAEF|EPP_NRHF)) == EPP_NRHF) {
-			schedule();
-			continue;
-		}
-		if (pp->ops->epp_read_data(pp, tmp, 128, 0) != 128)
-			goto epptimeout;
-		if (pp->ops->epp_read_data(pp, tmp, 128, 0) != 128)
-			goto epptimeout;
-		i += 256;
-	}
-	for (j = 0; j < 256; j++) {
-		if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1)
-			goto epptimeout;
-		if (!(stat & EPP_NREF))
-			break;
-		if (pp->ops->epp_read_data(pp, tmp, 1, 0) != 1)
-			goto epptimeout;
-		i++;
-	}
-	tstart = jiffies - tstart;
-	bc->bitrate = i * (8 * HZ) / tstart;
-	j = 1;
-	i = bc->bitrate >> 3;
-	while (j < 7 && i > 150) {
-		j++;
-		i >>= 1;
-	}
-	printk(KERN_INFO "%s: autoprobed bitrate: %d  int divider: %d  int rate: %d\n", 
-	       bc_drvname, bc->bitrate, j, bc->bitrate >> (j+2));
-	tmp[0] = EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE/*|j*/;
-	if (pp->ops->epp_write_addr(pp, tmp, 1, 0) != 1)
-		goto epptimeout;
-	/*
-	 * initialise hdlc variables
-	 */
-	bc->hdlcrx.state = 0;
-	bc->hdlcrx.numbits = 0;
-	bc->hdlctx.state = tx_idle;
-	bc->hdlctx.bufcnt = 0;
-	bc->hdlctx.slotcnt = bc->ch_params.slottime;
-	bc->hdlctx.calibrate = 0;
-	/* start the bottom half stuff */
-	schedule_delayed_work(&bc->run_work, 1);
-	netif_start_queue(dev);
-	return 0;
-
- epptimeout:
-	printk(KERN_ERR "%s: epp timeout during bitrate probe\n", bc_drvname);
-	parport_write_control(pp, 0); /* reset the adapter */
-        parport_release(bc->pdev);
-        parport_unregister_device(bc->pdev);
-	return -EIO;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int epp_close(struct net_device *dev)
-{
-	struct baycom_state *bc = netdev_priv(dev);
-	struct parport *pp = bc->pdev->port;
-	unsigned char tmp[1];
-
-	bc->work_running = 0;
-	cancel_delayed_work_sync(&bc->run_work);
-	bc->stat = EPP_DCDBIT;
-	tmp[0] = 0;
-	pp->ops->epp_write_addr(pp, tmp, 1, 0);
-	parport_write_control(pp, 0); /* reset the adapter */
-        parport_release(bc->pdev);
-        parport_unregister_device(bc->pdev);
-	dev_kfree_skb(bc->skb);
-	bc->skb = NULL;
-	printk(KERN_INFO "%s: close epp at iobase 0x%lx irq %u\n",
-	       bc_drvname, dev->base_addr, dev->irq);
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int baycom_setmode(struct baycom_state *bc, const char *modestr)
-{
-	const char *cp;
-
-	if (strstr(modestr,"intclk"))
-		bc->cfg.intclk = 1;
-	if (strstr(modestr,"extclk"))
-		bc->cfg.intclk = 0;
-	if (strstr(modestr,"intmodem"))
-		bc->cfg.extmodem = 0;
-	if (strstr(modestr,"extmodem"))
-		bc->cfg.extmodem = 1;
-	if (strstr(modestr,"loopback"))
-		bc->cfg.loopback = 1;
-	if (strstr(modestr, "noloopback"))
-		bc->cfg.loopback = 0;
-	if ((cp = strstr(modestr,"fclk="))) {
-		bc->cfg.fclk = simple_strtoul(cp+5, NULL, 0);
-		if (bc->cfg.fclk < 1000000)
-			bc->cfg.fclk = 1000000;
-		if (bc->cfg.fclk > 25000000)
-			bc->cfg.fclk = 25000000;
-	}
-	if ((cp = strstr(modestr,"bps="))) {
-		bc->cfg.bps = simple_strtoul(cp+4, NULL, 0);
-		if (bc->cfg.bps < 1000)
-			bc->cfg.bps = 1000;
-		if (bc->cfg.bps > 1500000)
-			bc->cfg.bps = 1500000;
-	}
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int baycom_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
-				 void __user *data, int cmd)
-{
-	struct baycom_state *bc = netdev_priv(dev);
-	struct hdlcdrv_ioctl hi;
-
-	if (cmd != SIOCDEVPRIVATE)
-		return -ENOIOCTLCMD;
-
-	if (copy_from_user(&hi, data, sizeof(hi)))
-		return -EFAULT;
-	switch (hi.cmd) {
-	default:
-		return -ENOIOCTLCMD;
-
-	case HDLCDRVCTL_GETCHANNELPAR:
-		hi.data.cp.tx_delay = bc->ch_params.tx_delay;
-		hi.data.cp.tx_tail = bc->ch_params.tx_tail;
-		hi.data.cp.slottime = bc->ch_params.slottime;
-		hi.data.cp.ppersist = bc->ch_params.ppersist;
-		hi.data.cp.fulldup = bc->ch_params.fulldup;
-		break;
-
-	case HDLCDRVCTL_SETCHANNELPAR:
-		if (!capable(CAP_NET_ADMIN))
-			return -EACCES;
-		bc->ch_params.tx_delay = hi.data.cp.tx_delay;
-		bc->ch_params.tx_tail = hi.data.cp.tx_tail;
-		bc->ch_params.slottime = hi.data.cp.slottime;
-		bc->ch_params.ppersist = hi.data.cp.ppersist;
-		bc->ch_params.fulldup = hi.data.cp.fulldup;
-		bc->hdlctx.slotcnt = 1;
-		return 0;
-		
-	case HDLCDRVCTL_GETMODEMPAR:
-		hi.data.mp.iobase = dev->base_addr;
-		hi.data.mp.irq = dev->irq;
-		hi.data.mp.dma = dev->dma;
-		hi.data.mp.dma2 = 0;
-		hi.data.mp.seriobase = 0;
-		hi.data.mp.pariobase = 0;
-		hi.data.mp.midiiobase = 0;
-		break;
-
-	case HDLCDRVCTL_SETMODEMPAR:
-		if ((!capable(CAP_SYS_RAWIO)) || netif_running(dev))
-			return -EACCES;
-		dev->base_addr = hi.data.mp.iobase;
-		dev->irq = /*hi.data.mp.irq*/0;
-		dev->dma = /*hi.data.mp.dma*/0;
-		return 0;	
-		
-	case HDLCDRVCTL_GETSTAT:
-		hi.data.cs.ptt = !!(bc->stat & EPP_PTTBIT);
-		hi.data.cs.dcd = !(bc->stat & EPP_DCDBIT);
-		hi.data.cs.ptt_keyed = bc->ptt_keyed;
-		hi.data.cs.tx_packets = dev->stats.tx_packets;
-		hi.data.cs.tx_errors = dev->stats.tx_errors;
-		hi.data.cs.rx_packets = dev->stats.rx_packets;
-		hi.data.cs.rx_errors = dev->stats.rx_errors;
-		break;		
-
-	case HDLCDRVCTL_OLDGETSTAT:
-		hi.data.ocs.ptt = !!(bc->stat & EPP_PTTBIT);
-		hi.data.ocs.dcd = !(bc->stat & EPP_DCDBIT);
-		hi.data.ocs.ptt_keyed = bc->ptt_keyed;
-		break;		
-
-	case HDLCDRVCTL_CALIBRATE:
-		if (!capable(CAP_SYS_RAWIO))
-			return -EACCES;
-		bc->hdlctx.calibrate = hi.data.calibrate * bc->bitrate / 8;
-		return 0;
-
-	case HDLCDRVCTL_DRIVERNAME:
-		strscpy_pad(hi.data.drivername, "baycom_epp");
-		break;
-		
-	case HDLCDRVCTL_GETMODE:
-		sprintf(hi.data.modename, "%sclk,%smodem,fclk=%d,bps=%d%s", 
-			bc->cfg.intclk ? "int" : "ext",
-			bc->cfg.extmodem ? "ext" : "int", bc->cfg.fclk, bc->cfg.bps,
-			bc->cfg.loopback ? ",loopback" : "");
-		break;
-
-	case HDLCDRVCTL_SETMODE:
-		if (!capable(CAP_NET_ADMIN) || netif_running(dev))
-			return -EACCES;
-		hi.data.modename[sizeof(hi.data.modename)-1] = '\0';
-		return baycom_setmode(bc, hi.data.modename);
-
-	case HDLCDRVCTL_MODELIST:
-		strscpy_pad(hi.data.modename, "intclk,extclk,intmodem,extmodem,divider=x");
-		break;
-
-	case HDLCDRVCTL_MODEMPARMASK:
-		return HDLCDRV_PARMASK_IOBASE;
-
-	}
-	if (copy_to_user(data, &hi, sizeof(hi)))
-		return -EFAULT;
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static const struct net_device_ops baycom_netdev_ops = {
-	.ndo_open	     = epp_open,
-	.ndo_stop	     = epp_close,
-	.ndo_siocdevprivate  = baycom_siocdevprivate,
-	.ndo_start_xmit      = baycom_send_packet,
-	.ndo_set_mac_address = baycom_set_mac_address,
-};
-
-/*
- * Check for a network adaptor of this type, and return '0' if one exists.
- * If dev->base_addr == 0, probe all likely locations.
- * If dev->base_addr == 1, always return failure.
- * If dev->base_addr == 2, allocate space for the device and return success
- * (detachable devices only).
- */
-static void baycom_probe(struct net_device *dev)
-{
-	const struct hdlcdrv_channel_params dflt_ch_params = { 
-		20, 2, 10, 40, 0 
-	};
-	struct baycom_state *bc;
-
-	/*
-	 * not a real probe! only initialize data structures
-	 */
-	bc = netdev_priv(dev);
-	/*
-	 * initialize the baycom_state struct
-	 */
-	bc->ch_params = dflt_ch_params;
-	bc->ptt_keyed = 0;
-
-	/*
-	 * initialize the device struct
-	 */
-
-	/* Fill in the fields of the device structure */
-	bc->skb = NULL;
-	
-	dev->netdev_ops = &baycom_netdev_ops;
-	dev->header_ops = &ax25_header_ops;
-	
-	dev->type = ARPHRD_AX25;           /* AF_AX25 device */
-	dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
-	dev->mtu = AX25_DEF_PACLEN;        /* eth_mtu is the default */
-	dev->addr_len = AX25_ADDR_LEN;     /* sizeof an ax.25 address */
-	memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
-	dev_addr_set(dev, (u8 *)&null_ax25_address);
-	dev->tx_queue_len = 16;
-
-	/* New style flags */
-	dev->flags = 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-/*
- * command line settable parameters
- */
-static char *mode[NR_PORTS] = { "", };
-static int iobase[NR_PORTS] = { 0x378, };
-
-module_param_array(mode, charp, NULL, 0);
-MODULE_PARM_DESC(mode, "baycom operating mode");
-module_param_hw_array(iobase, int, ioport, NULL, 0);
-MODULE_PARM_DESC(iobase, "baycom io base address");
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("Baycom epp amateur radio modem driver");
-MODULE_LICENSE("GPL");
-
-/* --------------------------------------------------------------------- */
-
-static int baycom_epp_par_probe(struct pardevice *par_dev)
-{
-	struct device_driver *drv = par_dev->dev.driver;
-	int len = strlen(drv->name);
-
-	if (strncmp(par_dev->name, drv->name, len))
-		return -ENODEV;
-
-	return 0;
-}
-
-static struct parport_driver baycom_epp_par_driver = {
-	.name = "bce",
-	.probe = baycom_epp_par_probe,
-};
-
-static void __init baycom_epp_dev_setup(struct net_device *dev)
-{
-	struct baycom_state *bc = netdev_priv(dev);
-
-	/*
-	 * initialize part of the baycom_state struct
-	 */
-	bc->dev = dev;
-	bc->magic = BAYCOM_MAGIC;
-	bc->cfg.fclk = 19666600;
-	bc->cfg.bps = 9600;
-	/*
-	 * initialize part of the device struct
-	 */
-	baycom_probe(dev);
-}
-
-static int __init init_baycomepp(void)
-{
-	int i, found = 0, ret;
-	char set_hw = 1;
-
-	printk(bc_drvinfo);
-
-	ret = parport_register_driver(&baycom_epp_par_driver);
-	if (ret)
-		return ret;
-
-	/*
-	 * register net devices
-	 */
-	for (i = 0; i < NR_PORTS; i++) {
-		struct net_device *dev;
-		
-		dev = alloc_netdev(sizeof(struct baycom_state), "bce%d",
-				   NET_NAME_UNKNOWN, baycom_epp_dev_setup);
-
-		if (!dev) {
-			printk(KERN_WARNING "bce%d : out of memory\n", i);
-			return found ? 0 : -ENOMEM;
-		}
-			
-		sprintf(dev->name, "bce%d", i);
-		dev->base_addr = iobase[i];
-
-		if (!mode[i])
-			set_hw = 0;
-		if (!set_hw)
-			iobase[i] = 0;
-
-		if (register_netdev(dev)) {
-			printk(KERN_WARNING "%s: cannot register net device %s\n", bc_drvname, dev->name);
-			free_netdev(dev);
-			break;
-		}
-		if (set_hw && baycom_setmode(netdev_priv(dev), mode[i]))
-			set_hw = 0;
-		baycom_device[i] = dev;
-		found++;
-	}
-
-	if (found == 0) {
-		parport_unregister_driver(&baycom_epp_par_driver);
-		return -ENXIO;
-	}
-
-	return 0;
-}
-
-static void __exit cleanup_baycomepp(void)
-{
-	int i;
-
-	for(i = 0; i < NR_PORTS; i++) {
-		struct net_device *dev = baycom_device[i];
-
-		if (dev) {
-			struct baycom_state *bc = netdev_priv(dev);
-			if (bc->magic == BAYCOM_MAGIC) {
-				unregister_netdev(dev);
-				free_netdev(dev);
-			} else
-				printk(paranoia_str, "cleanup_module");
-		}
-	}
-	parport_unregister_driver(&baycom_epp_par_driver);
-}
-
-module_init(init_baycomepp);
-module_exit(cleanup_baycomepp);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/*
- * format: baycom_epp=io,mode
- * mode: fpga config options
- */
-
-static int __init baycom_epp_setup(char *str)
-{
-        static unsigned __initdata nr_dev = 0;
-	int ints[2];
-
-        if (nr_dev >= NR_PORTS)
-                return 0;
-	str = get_options(str, 2, ints);
-	if (ints[0] < 1)
-		return 0;
-	mode[nr_dev] = str;
-	iobase[nr_dev] = ints[1];
-	nr_dev++;
-	return 1;
-}
-
-__setup("baycom_epp=", baycom_epp_setup);
-
-#endif /* MODULE */
-/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c
deleted file mode 100644
index f03797103c6a..000000000000
--- a/drivers/net/hamradio/baycom_par.c
+++ /dev/null
@@ -1,598 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*****************************************************************************/
-
-/*
- *	baycom_par.c  -- baycom par96 and picpar radio modem driver.
- *
- *	Copyright (C) 1996-2000  Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *  Please note that the GPL allows you to use the driver, NOT the radio.
- *  In order to use the radio, you need a license from the communications
- *  authority of your country.
- *
- *  Supported modems
- *
- *  par96:  This is a modem for 9600 baud FSK compatible to the G3RUH standard.
- *          The modem does all the filtering and regenerates the receiver clock.
- *          Data is transferred from and to the PC via a shift register.
- *          The shift register is filled with 16 bits and an interrupt is
- *          signalled. The PC then empties the shift register in a burst. This
- *          modem connects to the parallel port, hence the name. The modem
- *          leaves the implementation of the HDLC protocol and the scrambler
- *          polynomial to the PC. This modem is no longer available (at least
- *          from Baycom) and has been replaced by the PICPAR modem (see below).
- *          You may however still build one from the schematics published in
- *          cq-DL :-).
- *
- *  picpar: This is a redesign of the par96 modem by Henning Rech, DF9IC. The
- *          modem is protocol compatible to par96, but uses only three low
- *          power ICs and can therefore be fed from the parallel port and
- *          does not require an additional power supply. It features
- *          built in DCD circuitry. The driver should therefore be configured
- *          for hardware DCD.
- *
- *  Command line options (insmod command line)
- *
- *  mode     driver mode string. Valid choices are par96 and picpar.
- *  iobase   base address of the port; common values are 0x378, 0x278, 0x3bc
- *
- *  History:
- *   0.1  26.06.1996  Adapted from baycom.c and made network driver interface
- *        18.10.1996  Changed to new user space access routines (copy_{to,from}_user)
- *   0.3  26.04.1997  init code/data tagged
- *   0.4  08.07.1997  alternative ser12 decoding algorithm (uses delta CTS ints)
- *   0.5  11.11.1997  split into separate files for ser12/par96
- *   0.6  03.08.1999  adapt to Linus' new __setup/__initcall
- *                    removed some pre-2.2 kernel compatibility cruft
- *   0.7  10.08.1999  Check if parport can do SPP and is safe to access during interrupt contexts
- *   0.8  12.02.2000  adapted to softnet driver interface
- *                    removed direct parport access, uses parport driver methods
- *   0.9  03.07.2000  fix interface name handling
- */
-
-/*****************************************************************************/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/hdlcdrv.h>
-#include <linux/baycom.h>
-#include <linux/parport.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-
-#include <linux/uaccess.h>
-
-/* --------------------------------------------------------------------- */
-
-#define BAYCOM_DEBUG
-
-/*
- * modem options; bit mask
- */
-#define BAYCOM_OPTIONS_SOFTDCD  1
-
-/* --------------------------------------------------------------------- */
-
-static const char bc_drvname[] = "baycom_par";
-static const char bc_drvinfo[] = KERN_INFO "baycom_par: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
-"baycom_par: version 0.9\n";
-
-/* --------------------------------------------------------------------- */
-
-#define NR_PORTS 4
-
-static struct net_device *baycom_device[NR_PORTS];
-
-/* --------------------------------------------------------------------- */
-
-#define PAR96_BURSTBITS 16
-#define PAR96_BURST     4
-#define PAR96_PTT       2
-#define PAR96_TXBIT     1
-#define PAR96_ACK       0x40
-#define PAR96_RXBIT     0x20
-#define PAR96_DCD       0x10
-#define PAR97_POWER     0xf8
-
-/* ---------------------------------------------------------------------- */
-/*
- * Information that need to be kept for each board.
- */
-
-struct baycom_state {
-	struct hdlcdrv_state hdrv;
-
-	struct pardevice *pdev;
-	unsigned int options;
-
-	struct modem_state {
-		short arb_divider;
-		unsigned char flags;
-		unsigned int shreg;
-		struct modem_state_par96 {
-			int dcd_count;
-			unsigned int dcd_shreg;
-			unsigned long descram;
-			unsigned long scram;
-		} par96;
-	} modem;
-
-#ifdef BAYCOM_DEBUG
-	struct debug_vals {
-		unsigned long last_jiffies;
-		unsigned cur_intcnt;
-		unsigned last_intcnt;
-		int cur_pllcorr;
-		int last_pllcorr;
-	} debug_vals;
-#endif /* BAYCOM_DEBUG */
-};
-
-/* --------------------------------------------------------------------- */
-
-static inline void baycom_int_freq(struct baycom_state *bc)
-{
-#ifdef BAYCOM_DEBUG
-	unsigned long cur_jiffies = jiffies;
-	/*
-	 * measure the interrupt frequency
-	 */
-	bc->debug_vals.cur_intcnt++;
-	if (time_after_eq(cur_jiffies, bc->debug_vals.last_jiffies + HZ)) {
-		bc->debug_vals.last_jiffies = cur_jiffies;
-		bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt;
-		bc->debug_vals.cur_intcnt = 0;
-		bc->debug_vals.last_pllcorr = bc->debug_vals.cur_pllcorr;
-		bc->debug_vals.cur_pllcorr = 0;
-	}
-#endif /* BAYCOM_DEBUG */
-}
-
-/* --------------------------------------------------------------------- */
-/*
- * ===================== PAR96 specific routines =========================
- */
-
-#define PAR96_DESCRAM_TAP1 0x20000
-#define PAR96_DESCRAM_TAP2 0x01000
-#define PAR96_DESCRAM_TAP3 0x00001
-
-#define PAR96_DESCRAM_TAPSH1 17
-#define PAR96_DESCRAM_TAPSH2 12
-#define PAR96_DESCRAM_TAPSH3 0
-
-#define PAR96_SCRAM_TAP1 0x20000 /* X^17 */
-#define PAR96_SCRAM_TAPN 0x00021 /* X^0+X^5 */
-
-/* --------------------------------------------------------------------- */
-
-static inline void par96_tx(struct net_device *dev, struct baycom_state *bc)
-{
-	int i;
-	unsigned int data = hdlcdrv_getbits(&bc->hdrv);
-	struct parport *pp = bc->pdev->port;
-
-	for(i = 0; i < PAR96_BURSTBITS; i++, data >>= 1) {
-		unsigned char val = PAR97_POWER;
-		bc->modem.par96.scram = ((bc->modem.par96.scram << 1) |
-					 (bc->modem.par96.scram & 1));
-		if (!(data & 1))
-			bc->modem.par96.scram ^= 1;
-		if (bc->modem.par96.scram & (PAR96_SCRAM_TAP1 << 1))
-			bc->modem.par96.scram ^=
-				(PAR96_SCRAM_TAPN << 1);
-		if (bc->modem.par96.scram & (PAR96_SCRAM_TAP1 << 2))
-			val |= PAR96_TXBIT;
-		pp->ops->write_data(pp, val);
-		pp->ops->write_data(pp, val | PAR96_BURST);
-	}
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void par96_rx(struct net_device *dev, struct baycom_state *bc)
-{
-	int i;
-	unsigned int data, mask, mask2, descx;
-	struct parport *pp = bc->pdev->port;
-
-	/*
-	 * do receiver; differential decode and descramble on the fly
-	 */
-	for(data = i = 0; i < PAR96_BURSTBITS; i++) {
-		bc->modem.par96.descram = (bc->modem.par96.descram << 1);
-		if (pp->ops->read_status(pp) & PAR96_RXBIT)
-			bc->modem.par96.descram |= 1;
-		descx = bc->modem.par96.descram ^
-			(bc->modem.par96.descram >> 1);
-		/* now the diff decoded data is inverted in descram */
-		pp->ops->write_data(pp, PAR97_POWER | PAR96_PTT);
-		descx ^= ((descx >> PAR96_DESCRAM_TAPSH1) ^
-			  (descx >> PAR96_DESCRAM_TAPSH2));
-		data >>= 1;
-		if (!(descx & 1))
-			data |= 0x8000;
-		pp->ops->write_data(pp, PAR97_POWER | PAR96_PTT | PAR96_BURST);
-	}
-	hdlcdrv_putbits(&bc->hdrv, data);
-	/*
-	 * do DCD algorithm
-	 */
-	if (bc->options & BAYCOM_OPTIONS_SOFTDCD) {
-		bc->modem.par96.dcd_shreg = (bc->modem.par96.dcd_shreg >> 16)
-			| (data << 16);
-		/* search for flags and set the dcd counter appropriately */
-		for(mask = 0x1fe00, mask2 = 0xfc00, i = 0;
-		    i < PAR96_BURSTBITS; i++, mask <<= 1, mask2 <<= 1)
-			if ((bc->modem.par96.dcd_shreg & mask) == mask2)
-				bc->modem.par96.dcd_count = HDLCDRV_MAXFLEN+4;
-		/* check for abort/noise sequences */
-		for(mask = 0x1fe00, mask2 = 0x1fe00, i = 0;
-		    i < PAR96_BURSTBITS; i++, mask <<= 1, mask2 <<= 1)
-			if (((bc->modem.par96.dcd_shreg & mask) == mask2) &&
-			    (bc->modem.par96.dcd_count >= 0))
-				bc->modem.par96.dcd_count -= HDLCDRV_MAXFLEN-10;
-		/* decrement and set the dcd variable */
-		if (bc->modem.par96.dcd_count >= 0)
-			bc->modem.par96.dcd_count -= 2;
-		hdlcdrv_setdcd(&bc->hdrv, bc->modem.par96.dcd_count > 0);
-	} else {
-		hdlcdrv_setdcd(&bc->hdrv, !!(pp->ops->read_status(pp) & PAR96_DCD));
-	}
-}
-
-/* --------------------------------------------------------------------- */
-
-static void par96_interrupt(void *dev_id)
-{
-	struct net_device *dev = dev_id;
-	struct baycom_state *bc = netdev_priv(dev);
-
-	baycom_int_freq(bc);
-	/*
-	 * check if transmitter active
-	 */
-	if (hdlcdrv_ptt(&bc->hdrv))
-		par96_tx(dev, bc);
-	else {
-		par96_rx(dev, bc);
-		if (--bc->modem.arb_divider <= 0) {
-			bc->modem.arb_divider = 6;
-			local_irq_enable();
-			hdlcdrv_arbitrate(dev, &bc->hdrv);
-		}
-	}
-	local_irq_enable();
-	hdlcdrv_transmitter(dev, &bc->hdrv);
-	hdlcdrv_receiver(dev, &bc->hdrv);
-        local_irq_disable();
-}
-
-/* --------------------------------------------------------------------- */
-
-static void par96_wakeup(void *handle)
-{
-        struct net_device *dev = (struct net_device *)handle;
-	struct baycom_state *bc = netdev_priv(dev);
-
-	printk(KERN_DEBUG "baycom_par: %s: why am I being woken up?\n", dev->name);
-	if (!parport_claim(bc->pdev))
-		printk(KERN_DEBUG "baycom_par: %s: I'm broken.\n", dev->name);
-}
-
-/* --------------------------------------------------------------------- */
-
-static int par96_open(struct net_device *dev)
-{
-	struct baycom_state *bc = netdev_priv(dev);
-	struct pardev_cb par_cb;
-	struct parport *pp;
-	int i;
-
-	if (!dev || !bc)
-		return -ENXIO;
-	pp = parport_find_base(dev->base_addr);
-	if (!pp) {
-		printk(KERN_ERR "baycom_par: parport at 0x%lx unknown\n", dev->base_addr);
-		return -ENXIO;
-	}
-	if (pp->irq < 0) {
-		printk(KERN_ERR "baycom_par: parport at 0x%lx has no irq\n", pp->base);
-		parport_put_port(pp);
-		return -ENXIO;
-	}
-	if ((~pp->modes) & (PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT)) {
-		printk(KERN_ERR "baycom_par: parport at 0x%lx cannot be used\n", pp->base);
-		parport_put_port(pp);
-		return -ENXIO;
-	}
-	memset(&bc->modem, 0, sizeof(bc->modem));
-	bc->hdrv.par.bitrate = 9600;
-	memset(&par_cb, 0, sizeof(par_cb));
-	par_cb.wakeup = par96_wakeup;
-	par_cb.irq_func = par96_interrupt;
-	par_cb.private = (void *)dev;
-	par_cb.flags = PARPORT_DEV_EXCL;
-	for (i = 0; i < NR_PORTS; i++)
-		if (baycom_device[i] == dev)
-			break;
-
-	if (i == NR_PORTS) {
-		pr_err("%s: no device found\n", bc_drvname);
-		parport_put_port(pp);
-		return -ENODEV;
-	}
-	bc->pdev = parport_register_dev_model(pp, dev->name, &par_cb, i);
-	parport_put_port(pp);
-	if (!bc->pdev) {
-		printk(KERN_ERR "baycom_par: cannot register parport at 0x%lx\n", dev->base_addr);
-		return -ENXIO;
-	}
-	if (parport_claim(bc->pdev)) {
-		printk(KERN_ERR "baycom_par: parport at 0x%lx busy\n", pp->base);
-		parport_unregister_device(bc->pdev);
-		return -EBUSY;
-	}
-	pp = bc->pdev->port;
-	dev->irq = pp->irq;
-	pp->ops->data_forward(pp);
-        bc->hdrv.par.bitrate = 9600;
-	pp->ops->write_data(pp, PAR96_PTT | PAR97_POWER); /* switch off PTT */
-	pp->ops->enable_irq(pp);
-	printk(KERN_INFO "%s: par96 at iobase 0x%lx irq %u options 0x%x\n",
-	       bc_drvname, dev->base_addr, dev->irq, bc->options);
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int par96_close(struct net_device *dev)
-{
-	struct baycom_state *bc = netdev_priv(dev);
-	struct parport *pp;
-
-	if (!dev || !bc)
-		return -EINVAL;
-	pp = bc->pdev->port;
-	/* disable interrupt */
-	pp->ops->disable_irq(pp);
-	/* switch off PTT */
-	pp->ops->write_data(pp, PAR96_PTT | PAR97_POWER);
-	parport_release(bc->pdev);
-	parport_unregister_device(bc->pdev);
-	printk(KERN_INFO "%s: close par96 at iobase 0x%lx irq %u\n",
-	       bc_drvname, dev->base_addr, dev->irq);
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-/*
- * ===================== hdlcdrv driver interface =========================
- */
-
-static int baycom_ioctl(struct net_device *dev, void __user *data,
-			struct hdlcdrv_ioctl *hi, int cmd);
-
-/* --------------------------------------------------------------------- */
-
-static const struct hdlcdrv_ops par96_ops = {
-	.drvname = bc_drvname,
-	.drvinfo = bc_drvinfo,
-	.open    = par96_open,
-	.close   = par96_close,
-	.ioctl   = baycom_ioctl
-};
-
-/* --------------------------------------------------------------------- */
-
-static int baycom_setmode(struct baycom_state *bc, const char *modestr)
-{
-	if (!strncmp(modestr, "picpar", 6))
-		bc->options = 0;
-	else if (!strncmp(modestr, "par96", 5))
-		bc->options = BAYCOM_OPTIONS_SOFTDCD;
-	else
-		bc->options = !!strchr(modestr, '*');
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int baycom_ioctl(struct net_device *dev, void __user *data,
-			struct hdlcdrv_ioctl *hi, int cmd)
-{
-	struct baycom_state *bc;
-	struct baycom_ioctl bi;
-
-	if (!dev)
-		return -EINVAL;
-
-	bc = netdev_priv(dev);
-	BUG_ON(bc->hdrv.magic != HDLCDRV_MAGIC);
-
-	if (cmd != SIOCDEVPRIVATE)
-		return -ENOIOCTLCMD;
-	switch (hi->cmd) {
-	default:
-		break;
-
-	case HDLCDRVCTL_GETMODE:
-		strscpy(hi->data.modename, bc->options ? "par96" : "picpar");
-		if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl)))
-			return -EFAULT;
-		return 0;
-
-	case HDLCDRVCTL_SETMODE:
-		if (netif_running(dev) || !capable(CAP_NET_ADMIN))
-			return -EACCES;
-		hi->data.modename[sizeof(hi->data.modename)-1] = '\0';
-		return baycom_setmode(bc, hi->data.modename);
-
-	case HDLCDRVCTL_MODELIST:
-		strscpy(hi->data.modename, "par96,picpar");
-		if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl)))
-			return -EFAULT;
-		return 0;
-
-	case HDLCDRVCTL_MODEMPARMASK:
-		return HDLCDRV_PARMASK_IOBASE;
-
-	}
-
-	if (copy_from_user(&bi, data, sizeof(bi)))
-		return -EFAULT;
-	switch (bi.cmd) {
-	default:
-		return -ENOIOCTLCMD;
-
-#ifdef BAYCOM_DEBUG
-	case BAYCOMCTL_GETDEBUG:
-		bi.data.dbg.debug1 = bc->hdrv.ptt_keyed;
-		bi.data.dbg.debug2 = bc->debug_vals.last_intcnt;
-		bi.data.dbg.debug3 = bc->debug_vals.last_pllcorr;
-		break;
-#endif /* BAYCOM_DEBUG */
-
-	}
-	if (copy_to_user(data, &bi, sizeof(bi)))
-		return -EFAULT;
-	return 0;
-
-}
-
-/* --------------------------------------------------------------------- */
-
-/*
- * command line settable parameters
- */
-static char *mode[NR_PORTS] = { "picpar", };
-static int iobase[NR_PORTS] = { 0x378, };
-
-module_param_array(mode, charp, NULL, 0);
-MODULE_PARM_DESC(mode, "baycom operating mode; eg. par96 or picpar");
-module_param_hw_array(iobase, int, ioport, NULL, 0);
-MODULE_PARM_DESC(iobase, "baycom io base address");
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("Baycom par96 and picpar amateur radio modem driver");
-MODULE_LICENSE("GPL");
-
-/* --------------------------------------------------------------------- */
-
-static int baycom_par_probe(struct pardevice *par_dev)
-{
-	struct device_driver *drv = par_dev->dev.driver;
-	int len = strlen(drv->name);
-
-	if (strncmp(par_dev->name, drv->name, len))
-		return -ENODEV;
-
-	return 0;
-}
-
-static struct parport_driver baycom_par_driver = {
-	.name = "bcp",
-	.probe = baycom_par_probe,
-};
-
-static int __init init_baycompar(void)
-{
-	int i, found = 0, ret;
-	char set_hw = 1;
-
-	printk(bc_drvinfo);
-
-	ret = parport_register_driver(&baycom_par_driver);
-	if (ret)
-		return ret;
-
-	/*
-	 * register net devices
-	 */
-	for (i = 0; i < NR_PORTS; i++) {
-		struct net_device *dev;
-		struct baycom_state *bc;
-		char ifname[IFNAMSIZ];
-
-		sprintf(ifname, "bcp%d", i);
-
-		if (!mode[i])
-			set_hw = 0;
-		if (!set_hw)
-			iobase[i] = 0;
-
-		dev = hdlcdrv_register(&par96_ops,
-				       sizeof(struct baycom_state),
-				       ifname, iobase[i], 0, 0);
-		if (IS_ERR(dev)) 
-			break;
-
-		bc = netdev_priv(dev);
-		if (set_hw && baycom_setmode(bc, mode[i]))
-			set_hw = 0;
-		found++;
-		baycom_device[i] = dev;
-	}
-
-	if (!found) {
-		parport_unregister_driver(&baycom_par_driver);
-		return -ENXIO;
-	}
-	return 0;
-}
-
-static void __exit cleanup_baycompar(void)
-{
-	int i;
-
-	for(i = 0; i < NR_PORTS; i++) {
-		struct net_device *dev = baycom_device[i];
-
-		if (dev)
-			hdlcdrv_unregister(dev);
-	}
-	parport_unregister_driver(&baycom_par_driver);
-}
-
-module_init(init_baycompar);
-module_exit(cleanup_baycompar);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/*
- * format: baycom_par=io,mode
- * mode: par96,picpar
- */
-
-static int __init baycom_par_setup(char *str)
-{
-        static unsigned nr_dev;
-	int ints[2];
-
-        if (nr_dev >= NR_PORTS)
-                return 0;
-        str = get_options(str, 2, ints);
-        if (ints[0] < 1)
-                return 0;
-        mode[nr_dev] = str;
-        iobase[nr_dev] = ints[1];
-	nr_dev++;
-	return 1;
-}
-
-__setup("baycom_par=", baycom_par_setup);
-
-#endif /* MODULE */
-/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c
deleted file mode 100644
index ee5bd3c12040..000000000000
--- a/drivers/net/hamradio/baycom_ser_fdx.c
+++ /dev/null
@@ -1,678 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*****************************************************************************/
-
-/*
- *	baycom_ser_fdx.c  -- baycom ser12 fullduplex radio modem driver.
- *
- *	Copyright (C) 1996-2000  Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *  Please note that the GPL allows you to use the driver, NOT the radio.
- *  In order to use the radio, you need a license from the communications
- *  authority of your country.
- *
- *  Supported modems
- *
- *  ser12:  This is a very simple 1200 baud AFSK modem. The modem consists only
- *          of a modulator/demodulator chip, usually a TI TCM3105. The computer
- *          is responsible for regenerating the receiver bit clock, as well as
- *          for handling the HDLC protocol. The modem connects to a serial port,
- *          hence the name. Since the serial port is not used as an async serial
- *          port, the kernel driver for serial ports cannot be used, and this
- *          driver only supports standard serial hardware (8250, 16450, 16550A)
- *
- *          This modem usually draws its supply current out of the otherwise unused
- *          TXD pin of the serial port. Thus a contiguous stream of 0x00-bytes
- *          is transmitted to achieve a positive supply voltage.
- *
- *  hsk:    This is a 4800 baud FSK modem, designed for TNC use. It works fine
- *          in 'baycom-mode' :-)  In contrast to the TCM3105 modem, power is
- *          externally supplied. So there's no need to provide the 0x00-byte-stream
- *          when receiving or idle, which drastically reduces interrupt load.
- *
- *  Command line options (insmod command line)
- *
- *  mode     ser#    hardware DCD
- *           ser#*   software DCD
- *           ser#+   hardware DCD, inverted signal at DCD pin
- *           '#' denotes the baud rate / 100, eg. ser12* is '1200 baud, soft DCD'
- *  iobase   base address of the port; common values are 0x3f8, 0x2f8, 0x3e8, 0x2e8
- *  baud     baud rate (between 300 and 4800)
- *  irq      interrupt line of the port; common values are 4,3
- *
- *  History:
- *   0.1  26.06.1996  Adapted from baycom.c and made network driver interface
- *        18.10.1996  Changed to new user space access routines (copy_{to,from}_user)
- *   0.3  26.04.1997  init code/data tagged
- *   0.4  08.07.1997  alternative ser12 decoding algorithm (uses delta CTS ints)
- *   0.5  11.11.1997  ser12/par96 split into separate files
- *   0.6  24.01.1998  Thorsten Kranzkowski, dl8bcu and Thomas Sailer:
- *                    reduced interrupt load in transmit case
- *                    reworked receiver
- *   0.7  03.08.1999  adapt to Linus' new __setup/__initcall
- *   0.8  10.08.1999  use module_init/module_exit
- *   0.9  12.02.2000  adapted to softnet driver interface
- *   0.10 03.07.2000  fix interface name handling
- */
-
-/*****************************************************************************/
-
-#include <linux/capability.h>
-#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/hdlcdrv.h>
-#include <linux/baycom.h>
-#include <linux/jiffies.h>
-#include <linux/time64.h>
-
-#include <linux/uaccess.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-/* --------------------------------------------------------------------- */
-
-#define BAYCOM_DEBUG
-
-/* --------------------------------------------------------------------- */
-
-static const char bc_drvname[] = "baycom_ser_fdx";
-static const char bc_drvinfo[] = KERN_INFO "baycom_ser_fdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
-"baycom_ser_fdx: version 0.10\n";
-
-/* --------------------------------------------------------------------- */
-
-#define NR_PORTS 4
-
-static struct net_device *baycom_device[NR_PORTS];
-
-/* --------------------------------------------------------------------- */
-
-#define RBR(iobase) (iobase+0)
-#define THR(iobase) (iobase+0)
-#define IER(iobase) (iobase+1)
-#define IIR(iobase) (iobase+2)
-#define FCR(iobase) (iobase+2)
-#define LCR(iobase) (iobase+3)
-#define MCR(iobase) (iobase+4)
-#define LSR(iobase) (iobase+5)
-#define MSR(iobase) (iobase+6)
-#define SCR(iobase) (iobase+7)
-#define DLL(iobase) (iobase+0)
-#define DLM(iobase) (iobase+1)
-
-#define SER12_EXTENT 8
-
-/* ---------------------------------------------------------------------- */
-/*
- * Information that need to be kept for each board.
- */
-
-struct baycom_state {
-	struct hdlcdrv_state hdrv;
-
-	unsigned int baud, baud_us, baud_arbdiv, baud_uartdiv, baud_dcdtimeout;
-	int opt_dcd;
-
-	struct modem_state {
-		unsigned char flags;
-		unsigned char ptt;
-		unsigned int shreg;
-		struct modem_state_ser12 {
-			unsigned char tx_bit;
-			unsigned char last_rxbit;
-			int dcd_sum0, dcd_sum1, dcd_sum2;
-			int dcd_time;
-			unsigned int pll_time;
-			unsigned int txshreg;
-		} ser12;
-	} modem;
-
-#ifdef BAYCOM_DEBUG
-	struct debug_vals {
-		unsigned long last_jiffies;
-		unsigned cur_intcnt;
-		unsigned last_intcnt;
-		int cur_pllcorr;
-		int last_pllcorr;
-	} debug_vals;
-#endif /* BAYCOM_DEBUG */
-};
-
-/* --------------------------------------------------------------------- */
-
-static inline void baycom_int_freq(struct baycom_state *bc)
-{
-#ifdef BAYCOM_DEBUG
-	unsigned long cur_jiffies = jiffies;
-	/*
-	 * measure the interrupt frequency
-	 */
-	bc->debug_vals.cur_intcnt++;
-	if (time_after_eq(cur_jiffies, bc->debug_vals.last_jiffies + HZ)) {
-		bc->debug_vals.last_jiffies = cur_jiffies;
-		bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt;
-		bc->debug_vals.cur_intcnt = 0;
-		bc->debug_vals.last_pllcorr = bc->debug_vals.cur_pllcorr;
-		bc->debug_vals.cur_pllcorr = 0;
-	}
-#endif /* BAYCOM_DEBUG */
-}
-
-/* --------------------------------------------------------------------- */
-/*
- * ===================== SER12 specific routines =========================
- */
-
-/* --------------------------------------------------------------------- */
-
-static inline void ser12_set_divisor(struct net_device *dev,
-                                     unsigned int divisor)
-{
-        outb(0x81, LCR(dev->base_addr));        /* DLAB = 1 */
-        outb(divisor, DLL(dev->base_addr));
-        outb(divisor >> 8, DLM(dev->base_addr));
-        outb(0x01, LCR(dev->base_addr));        /* word length = 6 */
-        /*
-         * make sure the next interrupt is generated;
-         * 0 must be used to power the modem; the modem draws its
-         * power from the TxD line
-         */
-        outb(0x00, THR(dev->base_addr));
-        /*
-         * it is important not to set the divider while transmitting;
-         * this reportedly makes some UARTs generating interrupts
-         * in the hundredthousands per second region
-         * Reported by: Ignacio.Arenaza@studi.epfl.ch (Ignacio Arenaza Nuno)
-         */
-}
-
-static __inline__ void ser12_rx(struct net_device *dev, struct baycom_state *bc, struct timespec64 *ts, unsigned char curs)
-{
-	int timediff;
-	int bdus8 = bc->baud_us >> 3;
-	int bdus4 = bc->baud_us >> 2;
-	int bdus2 = bc->baud_us >> 1;
-
-	timediff = 1000000 + ts->tv_nsec / NSEC_PER_USEC -
-					bc->modem.ser12.pll_time;
-	while (timediff >= 500000)
-		timediff -= 1000000;
-	while (timediff >= bdus2) {
-		timediff -= bc->baud_us;
-		bc->modem.ser12.pll_time += bc->baud_us;
-		bc->modem.ser12.dcd_time--;
-		/* first check if there is room to add a bit */
-		if (bc->modem.shreg & 1) {
-			hdlcdrv_putbits(&bc->hdrv, (bc->modem.shreg >> 1) ^ 0xffff);
-			bc->modem.shreg = 0x10000;
-		}
-		/* add a one bit */
-		bc->modem.shreg >>= 1;
-	}
-	if (bc->modem.ser12.dcd_time <= 0) {
-		if (!bc->opt_dcd)
-			hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 + 
-						   bc->modem.ser12.dcd_sum1 + 
-						   bc->modem.ser12.dcd_sum2) < 0);
-		bc->modem.ser12.dcd_sum2 = bc->modem.ser12.dcd_sum1;
-		bc->modem.ser12.dcd_sum1 = bc->modem.ser12.dcd_sum0;
-		bc->modem.ser12.dcd_sum0 = 2; /* slight bias */
-		bc->modem.ser12.dcd_time += 120;
-	}
-	if (bc->modem.ser12.last_rxbit != curs) {
-		bc->modem.ser12.last_rxbit = curs;
-		bc->modem.shreg |= 0x10000;
-		/* adjust the PLL */
-		if (timediff > 0)
-			bc->modem.ser12.pll_time += bdus8;
-		else
-			bc->modem.ser12.pll_time += 1000000 - bdus8;
-		/* update DCD */
-		if (abs(timediff) > bdus4)
-			bc->modem.ser12.dcd_sum0 += 4;
-		else
-			bc->modem.ser12.dcd_sum0--;
-#ifdef BAYCOM_DEBUG
-		bc->debug_vals.cur_pllcorr = timediff;
-#endif /* BAYCOM_DEBUG */
-	}
-	while (bc->modem.ser12.pll_time >= 1000000)
-		bc->modem.ser12.pll_time -= 1000000;
-}
-
-/* --------------------------------------------------------------------- */
-
-static irqreturn_t ser12_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev = (struct net_device *)dev_id;
-	struct baycom_state *bc = netdev_priv(dev);
-	struct timespec64 ts;
-	unsigned char iir, msr;
-	unsigned int txcount = 0;
-
-	if (!bc || bc->hdrv.magic != HDLCDRV_MAGIC)
-		return IRQ_NONE;
-	/* fast way out for shared irq */
-	if ((iir = inb(IIR(dev->base_addr))) & 1) 	
-		return IRQ_NONE;
-	/* get current time */
-	ktime_get_ts64(&ts);
-	msr = inb(MSR(dev->base_addr));
-	/* delta DCD */
-	if ((msr & 8) && bc->opt_dcd)
-		hdlcdrv_setdcd(&bc->hdrv, !((msr ^ bc->opt_dcd) & 0x80));
-	do {
-		switch (iir & 6) {
-		case 6:
-			inb(LSR(dev->base_addr));
-			break;
-			
-		case 4:
-			inb(RBR(dev->base_addr));
-			break;
-			
-		case 2:
-			/*
-			 * make sure the next interrupt is generated;
-			 * 0 must be used to power the modem; the modem draws its
-			 * power from the TxD line
-			 */
-			outb(0x00, THR(dev->base_addr));
-			baycom_int_freq(bc);
-			txcount++;
-			/*
-			 * first output the last bit (!) then call HDLC transmitter,
-			 * since this may take quite long
-			 */
-			if (bc->modem.ptt)
-				outb(0x0e | (!!bc->modem.ser12.tx_bit), MCR(dev->base_addr));
-			else
-				outb(0x0d, MCR(dev->base_addr));       /* transmitter off */
-			break;
-			
-		default:
-			msr = inb(MSR(dev->base_addr));
-			/* delta DCD */
-			if ((msr & 8) && bc->opt_dcd) 
-				hdlcdrv_setdcd(&bc->hdrv, !((msr ^ bc->opt_dcd) & 0x80));
-			break;
-		}
-		iir = inb(IIR(dev->base_addr));
-	} while (!(iir & 1));
-	ser12_rx(dev, bc, &ts, msr & 0x10); /* CTS */
-	if (bc->modem.ptt && txcount) {
-		if (bc->modem.ser12.txshreg <= 1) {
-			bc->modem.ser12.txshreg = 0x10000 | hdlcdrv_getbits(&bc->hdrv);
-			if (!hdlcdrv_ptt(&bc->hdrv)) {
-				ser12_set_divisor(dev, 115200/100/8);
-				bc->modem.ptt = 0;
-				goto end_transmit;
-			}
-		}
-		bc->modem.ser12.tx_bit = !(bc->modem.ser12.tx_bit ^ (bc->modem.ser12.txshreg & 1));
-		bc->modem.ser12.txshreg >>= 1;
-	}
- end_transmit:
-	local_irq_enable();
-	if (!bc->modem.ptt && txcount) {
-		hdlcdrv_arbitrate(dev, &bc->hdrv);
-		if (hdlcdrv_ptt(&bc->hdrv)) {
-			ser12_set_divisor(dev, bc->baud_uartdiv);
-			bc->modem.ser12.txshreg = 1;
-			bc->modem.ptt = 1;
-		}
-	}
-	hdlcdrv_transmitter(dev, &bc->hdrv);
-	hdlcdrv_receiver(dev, &bc->hdrv);
-	local_irq_disable();
-	return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-enum uart { c_uart_unknown, c_uart_8250,
-	    c_uart_16450, c_uart_16550, c_uart_16550A};
-static const char *uart_str[] = { 
-	"unknown", "8250", "16450", "16550", "16550A" 
-};
-
-static enum uart ser12_check_uart(unsigned int iobase)
-{
-	unsigned char b1,b2,b3;
-	enum uart u;
-	enum uart uart_tab[] =
-		{ c_uart_16450, c_uart_unknown, c_uart_16550, c_uart_16550A };
-
-	b1 = inb(MCR(iobase));
-	outb(b1 | 0x10, MCR(iobase));	/* loopback mode */
-	b2 = inb(MSR(iobase));
-	outb(0x1a, MCR(iobase));
-	b3 = inb(MSR(iobase)) & 0xf0;
-	outb(b1, MCR(iobase));			/* restore old values */
-	outb(b2, MSR(iobase));
-	if (b3 != 0x90)
-		return c_uart_unknown;
-	inb(RBR(iobase));
-	inb(RBR(iobase));
-	outb(0x01, FCR(iobase));		/* enable FIFOs */
-	u = uart_tab[(inb(IIR(iobase)) >> 6) & 3];
-	if (u == c_uart_16450) {
-		outb(0x5a, SCR(iobase));
-		b1 = inb(SCR(iobase));
-		outb(0xa5, SCR(iobase));
-		b2 = inb(SCR(iobase));
-		if ((b1 != 0x5a) || (b2 != 0xa5))
-			u = c_uart_8250;
-	}
-	return u;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int ser12_open(struct net_device *dev)
-{
-	const unsigned int nr_irqs = irq_get_nr_irqs();
-	struct baycom_state *bc = netdev_priv(dev);
-	enum uart u;
-
-	if (!dev || !bc)
-		return -ENXIO;
-	if (!dev->base_addr || dev->base_addr > 0xffff-SER12_EXTENT ||
-	    dev->irq < 2 || dev->irq > nr_irqs) {
-		printk(KERN_INFO "baycom_ser_fdx: invalid portnumber (max %u) "
-				"or irq (2 <= irq <= %d)\n",
-				0xffff-SER12_EXTENT, nr_irqs);
-		return -ENXIO;
-	}
-	if (bc->baud < 300 || bc->baud > 4800) {
-		printk(KERN_INFO "baycom_ser_fdx: invalid baudrate "
-				"(300...4800)\n");
-		return -EINVAL;
-	}
-	if (!request_region(dev->base_addr, SER12_EXTENT, "baycom_ser_fdx")) {
-		printk(KERN_WARNING "BAYCOM_SER_FSX: I/O port 0x%04lx busy\n",
-		       dev->base_addr);
-		return -EACCES;
-	}
-	memset(&bc->modem, 0, sizeof(bc->modem));
-	bc->hdrv.par.bitrate = bc->baud;
-	bc->baud_us = 1000000/bc->baud;
-	bc->baud_uartdiv = (115200/8)/bc->baud;
-	if ((u = ser12_check_uart(dev->base_addr)) == c_uart_unknown){
-		release_region(dev->base_addr, SER12_EXTENT);
-		return -EIO;
-	}
-	outb(0, FCR(dev->base_addr));  /* disable FIFOs */
-	outb(0x0d, MCR(dev->base_addr));
-	outb(0, IER(dev->base_addr));
-	if (request_irq(dev->irq, ser12_interrupt, IRQF_SHARED,
-			"baycom_ser_fdx", dev)) {
-		release_region(dev->base_addr, SER12_EXTENT);
-		return -EBUSY;
-	}
-	/*
-	 * set the SIO to 6 Bits/character; during receive,
-	 * the baud rate is set to produce 100 ints/sec
-	 * to feed the channel arbitration process,
-	 * during transmit to baud ints/sec to run
-	 * the transmitter
-	 */
-	ser12_set_divisor(dev, 115200/100/8);
-	/*
-	 * enable transmitter empty interrupt and modem status interrupt
-	 */
-	outb(0x0a, IER(dev->base_addr));
-	/*
-	 * make sure the next interrupt is generated;
-	 * 0 must be used to power the modem; the modem draws its
-	 * power from the TxD line
-	 */
-	outb(0x00, THR(dev->base_addr));
-	hdlcdrv_setdcd(&bc->hdrv, 0);
-	printk(KERN_INFO "%s: ser_fdx at iobase 0x%lx irq %u baud %u uart %s\n",
-	       bc_drvname, dev->base_addr, dev->irq, bc->baud, uart_str[u]);
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int ser12_close(struct net_device *dev)
-{
-	struct baycom_state *bc = netdev_priv(dev);
-
-	if (!dev || !bc)
-		return -EINVAL;
-	/*
-	 * disable interrupts
-	 */
-	outb(0, IER(dev->base_addr));
-	outb(1, MCR(dev->base_addr));
-	free_irq(dev->irq, dev);
-	release_region(dev->base_addr, SER12_EXTENT);
-	printk(KERN_INFO "%s: close ser_fdx at iobase 0x%lx irq %u\n",
-	       bc_drvname, dev->base_addr, dev->irq);
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-/*
- * ===================== hdlcdrv driver interface =========================
- */
-
-/* --------------------------------------------------------------------- */
-
-static int baycom_ioctl(struct net_device *dev, void __user *data,
-			struct hdlcdrv_ioctl *hi, int cmd);
-
-/* --------------------------------------------------------------------- */
-
-static const struct hdlcdrv_ops ser12_ops = {
-	.drvname = bc_drvname,
-	.drvinfo = bc_drvinfo,
-	.open    = ser12_open,
-	.close   = ser12_close,
-	.ioctl   = baycom_ioctl,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int baycom_setmode(struct baycom_state *bc, const char *modestr)
-{
-	unsigned int baud;
-
-	if (!strncmp(modestr, "ser", 3)) {
-		baud = simple_strtoul(modestr+3, NULL, 10);
-		if (baud >= 3 && baud <= 48)
-			bc->baud = baud*100;
-	}
-	if (strchr(modestr, '*'))
-		bc->opt_dcd = 0;
-	else if (strchr(modestr, '+'))
-		bc->opt_dcd = -1;
-	else
-		bc->opt_dcd = 1;
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int baycom_ioctl(struct net_device *dev, void __user *data,
-			struct hdlcdrv_ioctl *hi, int cmd)
-{
-	struct baycom_state *bc;
-	struct baycom_ioctl bi;
-
-	if (!dev)
-		return -EINVAL;
-
-	bc = netdev_priv(dev);
-	BUG_ON(bc->hdrv.magic != HDLCDRV_MAGIC);
-
-	if (cmd != SIOCDEVPRIVATE)
-		return -ENOIOCTLCMD;
-	switch (hi->cmd) {
-	default:
-		break;
-
-	case HDLCDRVCTL_GETMODE:
-		sprintf(hi->data.modename, "ser%u", bc->baud / 100);
-		if (bc->opt_dcd <= 0)
-			strcat(hi->data.modename, (!bc->opt_dcd) ? "*" : "+");
-		if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl)))
-			return -EFAULT;
-		return 0;
-
-	case HDLCDRVCTL_SETMODE:
-		if (netif_running(dev) || !capable(CAP_NET_ADMIN))
-			return -EACCES;
-		hi->data.modename[sizeof(hi->data.modename)-1] = '\0';
-		return baycom_setmode(bc, hi->data.modename);
-
-	case HDLCDRVCTL_MODELIST:
-		strscpy(hi->data.modename, "ser12,ser3,ser24");
-		if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl)))
-			return -EFAULT;
-		return 0;
-
-	case HDLCDRVCTL_MODEMPARMASK:
-		return HDLCDRV_PARMASK_IOBASE | HDLCDRV_PARMASK_IRQ;
-
-	}
-
-	if (copy_from_user(&bi, data, sizeof(bi)))
-		return -EFAULT;
-	switch (bi.cmd) {
-	default:
-		return -ENOIOCTLCMD;
-
-#ifdef BAYCOM_DEBUG
-	case BAYCOMCTL_GETDEBUG:
-		bi.data.dbg.debug1 = bc->hdrv.ptt_keyed;
-		bi.data.dbg.debug2 = bc->debug_vals.last_intcnt;
-		bi.data.dbg.debug3 = bc->debug_vals.last_pllcorr;
-		break;
-#endif /* BAYCOM_DEBUG */
-
-	}
-	if (copy_to_user(data, &bi, sizeof(bi)))
-		return -EFAULT;
-	return 0;
-
-}
-
-/* --------------------------------------------------------------------- */
-
-/*
- * command line settable parameters
- */
-static char *mode[NR_PORTS] = { "ser12*", };
-static int iobase[NR_PORTS] = { 0x3f8, };
-static int irq[NR_PORTS] = { 4, };
-static int baud[NR_PORTS] = { [0 ... NR_PORTS-1] = 1200 };
-
-module_param_array(mode, charp, NULL, 0);
-MODULE_PARM_DESC(mode, "baycom operating mode; * for software DCD");
-module_param_hw_array(iobase, int, ioport, NULL, 0);
-MODULE_PARM_DESC(iobase, "baycom io base address");
-module_param_hw_array(irq, int, irq, NULL, 0);
-MODULE_PARM_DESC(irq, "baycom irq number");
-module_param_array(baud, int, NULL, 0);
-MODULE_PARM_DESC(baud, "baycom baud rate (300 to 4800)");
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("Baycom ser12 full duplex amateur radio modem driver");
-MODULE_LICENSE("GPL");
-
-/* --------------------------------------------------------------------- */
-
-static int __init init_baycomserfdx(void)
-{
-	int i, found = 0;
-	char set_hw = 1;
-
-	printk(bc_drvinfo);
-	/*
-	 * register net devices
-	 */
-	for (i = 0; i < NR_PORTS; i++) {
-		struct net_device *dev;
-		struct baycom_state *bc;
-		char ifname[IFNAMSIZ];
-
-		sprintf(ifname, "bcsf%d", i);
-
-		if (!mode[i])
-			set_hw = 0;
-		if (!set_hw)
-			iobase[i] = irq[i] = 0;
-
-		dev = hdlcdrv_register(&ser12_ops, 
-				       sizeof(struct baycom_state),
-				       ifname, iobase[i], irq[i], 0);
-		if (IS_ERR(dev)) 
-			break;
-
-		bc = netdev_priv(dev);
-		if (set_hw && baycom_setmode(bc, mode[i]))
-			set_hw = 0;
-		bc->baud = baud[i];
-		found++;
-		baycom_device[i] = dev;
-	}
-
-	if (!found)
-		return -ENXIO;
-	return 0;
-}
-
-static void __exit cleanup_baycomserfdx(void)
-{
-	int i;
-
-	for(i = 0; i < NR_PORTS; i++) {
-		struct net_device *dev = baycom_device[i];
-		if (dev) 
-			hdlcdrv_unregister(dev);
-	}
-}
-
-module_init(init_baycomserfdx);
-module_exit(cleanup_baycomserfdx);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/*
- * format: baycom_ser_fdx=io,irq,mode
- * mode: ser#    hardware DCD
- *       ser#*   software DCD
- *       ser#+   hardware DCD, inverted signal at DCD pin
- * '#' denotes the baud rate / 100, eg. ser12* is '1200 baud, soft DCD'
- */
-
-static int __init baycom_ser_fdx_setup(char *str)
-{
-        static unsigned nr_dev;
-        int ints[4];
-
-        if (nr_dev >= NR_PORTS)
-                return 0;
-        str = get_options(str, 4, ints);
-        if (ints[0] < 2)
-                return 0;
-        mode[nr_dev] = str;
-        iobase[nr_dev] = ints[1];
-        irq[nr_dev] = ints[2];
-	if (ints[0] >= 3)
-		baud[nr_dev] = ints[3];
-	nr_dev++;
-	return 1;
-}
-
-__setup("baycom_ser_fdx=", baycom_ser_fdx_setup);
-
-#endif /* MODULE */
-/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c
deleted file mode 100644
index 05bdad214799..000000000000
--- a/drivers/net/hamradio/baycom_ser_hdx.c
+++ /dev/null
@@ -1,727 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*****************************************************************************/
-
-/*
- *	baycom_ser_hdx.c  -- baycom ser12 halfduplex radio modem driver.
- *
- *	Copyright (C) 1996-2000  Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *  Please note that the GPL allows you to use the driver, NOT the radio.
- *  In order to use the radio, you need a license from the communications
- *  authority of your country.
- *
- *  Supported modems
- *
- *  ser12:  This is a very simple 1200 baud AFSK modem. The modem consists only
- *          of a modulator/demodulator chip, usually a TI TCM3105. The computer
- *          is responsible for regenerating the receiver bit clock, as well as
- *          for handling the HDLC protocol. The modem connects to a serial port,
- *          hence the name. Since the serial port is not used as an async serial
- *          port, the kernel driver for serial ports cannot be used, and this
- *          driver only supports standard serial hardware (8250, 16450, 16550A)
- *
- *  Command line options (insmod command line)
- *
- *  mode     ser12    hardware DCD
- *           ser12*   software DCD
- *           ser12@   hardware/software DCD, i.e. no explicit DCD signal but hardware
- *                    mutes audio input to the modem
- *           ser12+   hardware DCD, inverted signal at DCD pin
- *  iobase   base address of the port; common values are 0x3f8, 0x2f8, 0x3e8, 0x2e8
- *  irq      interrupt line of the port; common values are 4,3
- *
- *  History:
- *   0.1  26.06.1996  Adapted from baycom.c and made network driver interface
- *        18.10.1996  Changed to new user space access routines (copy_{to,from}_user)
- *   0.3  26.04.1997  init code/data tagged
- *   0.4  08.07.1997  alternative ser12 decoding algorithm (uses delta CTS ints)
- *   0.5  11.11.1997  ser12/par96 split into separate files
- *   0.6  14.04.1998  cleanups
- *   0.7  03.08.1999  adapt to Linus' new __setup/__initcall
- *   0.8  10.08.1999  use module_init/module_exit
- *   0.9  12.02.2000  adapted to softnet driver interface
- *   0.10 03.07.2000  fix interface name handling
- */
-
-/*****************************************************************************/
-
-#include <linux/capability.h>
-#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/uaccess.h>
-#include <asm/io.h>
-#include <linux/hdlcdrv.h>
-#include <linux/baycom.h>
-#include <linux/jiffies.h>
-
-/* --------------------------------------------------------------------- */
-
-#define BAYCOM_DEBUG
-
-/* --------------------------------------------------------------------- */
-
-static const char bc_drvname[] = "baycom_ser_hdx";
-static const char bc_drvinfo[] = KERN_INFO "baycom_ser_hdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
-"baycom_ser_hdx: version 0.10\n";
-
-/* --------------------------------------------------------------------- */
-
-#define NR_PORTS 4
-
-static struct net_device *baycom_device[NR_PORTS];
-
-/* --------------------------------------------------------------------- */
-
-#define RBR(iobase) (iobase+0)
-#define THR(iobase) (iobase+0)
-#define IER(iobase) (iobase+1)
-#define IIR(iobase) (iobase+2)
-#define FCR(iobase) (iobase+2)
-#define LCR(iobase) (iobase+3)
-#define MCR(iobase) (iobase+4)
-#define LSR(iobase) (iobase+5)
-#define MSR(iobase) (iobase+6)
-#define SCR(iobase) (iobase+7)
-#define DLL(iobase) (iobase+0)
-#define DLM(iobase) (iobase+1)
-
-#define SER12_EXTENT 8
-
-/* ---------------------------------------------------------------------- */
-/*
- * Information that need to be kept for each board.
- */
-
-struct baycom_state {
-	struct hdlcdrv_state hdrv;
-
-	int opt_dcd;
-
-	struct modem_state {
-		short arb_divider;
-		unsigned char flags;
-		unsigned int shreg;
-		struct modem_state_ser12 {
-			unsigned char tx_bit;
-			int dcd_sum0, dcd_sum1, dcd_sum2;
-			unsigned char last_sample;
-			unsigned char last_rxbit;
-			unsigned int dcd_shreg;
-			unsigned int dcd_time;
-			unsigned int bit_pll;
-			unsigned char interm_sample;
-		} ser12;
-	} modem;
-
-#ifdef BAYCOM_DEBUG
-	struct debug_vals {
-		unsigned long last_jiffies;
-		unsigned cur_intcnt;
-		unsigned last_intcnt;
-		int cur_pllcorr;
-		int last_pllcorr;
-	} debug_vals;
-#endif /* BAYCOM_DEBUG */
-};
-
-/* --------------------------------------------------------------------- */
-
-static inline void baycom_int_freq(struct baycom_state *bc)
-{
-#ifdef BAYCOM_DEBUG
-	unsigned long cur_jiffies = jiffies;
-	/*
-	 * measure the interrupt frequency
-	 */
-	bc->debug_vals.cur_intcnt++;
-	if (time_after_eq(cur_jiffies, bc->debug_vals.last_jiffies + HZ)) {
-		bc->debug_vals.last_jiffies = cur_jiffies;
-		bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt;
-		bc->debug_vals.cur_intcnt = 0;
-		bc->debug_vals.last_pllcorr = bc->debug_vals.cur_pllcorr;
-		bc->debug_vals.cur_pllcorr = 0;
-	}
-#endif /* BAYCOM_DEBUG */
-}
-
-/* --------------------------------------------------------------------- */
-/*
- * ===================== SER12 specific routines =========================
- */
-
-static inline void ser12_set_divisor(struct net_device *dev,
-				     unsigned char divisor)
-{
-	outb(0x81, LCR(dev->base_addr));	/* DLAB = 1 */
-	outb(divisor, DLL(dev->base_addr));
-	outb(0, DLM(dev->base_addr));
-	outb(0x01, LCR(dev->base_addr));	/* word length = 6 */
-	/*
-	 * make sure the next interrupt is generated;
-	 * 0 must be used to power the modem; the modem draws its
-	 * power from the TxD line
-	 */
-	outb(0x00, THR(dev->base_addr));
-	/*
-	 * it is important not to set the divider while transmitting;
-	 * this reportedly makes some UARTs generating interrupts
-	 * in the hundredthousands per second region
-	 * Reported by: Ignacio.Arenaza@studi.epfl.ch (Ignacio Arenaza Nuno)
-	 */
-}
-
-/* --------------------------------------------------------------------- */
-
-/*
- * must call the TX arbitrator every 10ms
- */
-#define SER12_ARB_DIVIDER(bc)  (bc->opt_dcd ? 24 : 36)
-			       
-#define SER12_DCD_INTERVAL(bc) (bc->opt_dcd ? 12 : 240)
-
-static inline void ser12_tx(struct net_device *dev, struct baycom_state *bc)
-{
-	/* one interrupt per channel bit */
-	ser12_set_divisor(dev, 12);
-	/*
-	 * first output the last bit (!) then call HDLC transmitter,
-	 * since this may take quite long
-	 */
-	outb(0x0e | (!!bc->modem.ser12.tx_bit), MCR(dev->base_addr));
-	if (bc->modem.shreg <= 1)
-		bc->modem.shreg = 0x10000 | hdlcdrv_getbits(&bc->hdrv);
-	bc->modem.ser12.tx_bit = !(bc->modem.ser12.tx_bit ^
-				   (bc->modem.shreg & 1));
-	bc->modem.shreg >>= 1;
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void ser12_rx(struct net_device *dev, struct baycom_state *bc)
-{
-	unsigned char cur_s;
-	/*
-	 * do demodulator
-	 */
-	cur_s = inb(MSR(dev->base_addr)) & 0x10;	/* the CTS line */
-	hdlcdrv_channelbit(&bc->hdrv, cur_s);
-	bc->modem.ser12.dcd_shreg = (bc->modem.ser12.dcd_shreg << 1) |
-		(cur_s != bc->modem.ser12.last_sample);
-	bc->modem.ser12.last_sample = cur_s;
-	if(bc->modem.ser12.dcd_shreg & 1) {
-		if (!bc->opt_dcd) {
-			unsigned int dcdspos, dcdsneg;
-
-			dcdspos = dcdsneg = 0;
-			dcdspos += ((bc->modem.ser12.dcd_shreg >> 1) & 1);
-			if (!(bc->modem.ser12.dcd_shreg & 0x7ffffffe))
-				dcdspos += 2;
-			dcdsneg += ((bc->modem.ser12.dcd_shreg >> 2) & 1);
-			dcdsneg += ((bc->modem.ser12.dcd_shreg >> 3) & 1);
-			dcdsneg += ((bc->modem.ser12.dcd_shreg >> 4) & 1);
-
-			bc->modem.ser12.dcd_sum0 += 16*dcdspos - dcdsneg;
-		} else
-			bc->modem.ser12.dcd_sum0--;
-	}
-	if(!bc->modem.ser12.dcd_time) {
-		hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 +
-					   bc->modem.ser12.dcd_sum1 +
-					   bc->modem.ser12.dcd_sum2) < 0);
-		bc->modem.ser12.dcd_sum2 = bc->modem.ser12.dcd_sum1;
-		bc->modem.ser12.dcd_sum1 = bc->modem.ser12.dcd_sum0;
-		/* offset to ensure DCD off on silent input */
-		bc->modem.ser12.dcd_sum0 = 2;
-		bc->modem.ser12.dcd_time = SER12_DCD_INTERVAL(bc);
-	}
-	bc->modem.ser12.dcd_time--;
-	if (!bc->opt_dcd) {
-		/*
-		 * PLL code for the improved software DCD algorithm
-		 */
-		if (bc->modem.ser12.interm_sample) {
-			/*
-			 * intermediate sample; set timing correction to normal
-			 */
-			ser12_set_divisor(dev, 4);
-		} else {
-			/*
-			 * do PLL correction and call HDLC receiver
-			 */
-			switch (bc->modem.ser12.dcd_shreg & 7) {
-			case 1: /* transition too late */
-				ser12_set_divisor(dev, 5);
-#ifdef BAYCOM_DEBUG
-				bc->debug_vals.cur_pllcorr++;
-#endif /* BAYCOM_DEBUG */
-				break;
-			case 4:	/* transition too early */
-				ser12_set_divisor(dev, 3);
-#ifdef BAYCOM_DEBUG
-				bc->debug_vals.cur_pllcorr--;
-#endif /* BAYCOM_DEBUG */
-				break;
-			default:
-				ser12_set_divisor(dev, 4);
-				break;
-			}
-			bc->modem.shreg >>= 1;
-			if (bc->modem.ser12.last_sample ==
-			    bc->modem.ser12.last_rxbit)
-				bc->modem.shreg |= 0x10000;
-			bc->modem.ser12.last_rxbit =
-				bc->modem.ser12.last_sample;
-		}
-		if (++bc->modem.ser12.interm_sample >= 3)
-			bc->modem.ser12.interm_sample = 0;
-		/*
-		 * DCD stuff
-		 */
-		if (bc->modem.ser12.dcd_shreg & 1) {
-			unsigned int dcdspos, dcdsneg;
-
-			dcdspos = dcdsneg = 0;
-			dcdspos += ((bc->modem.ser12.dcd_shreg >> 1) & 1);
-			dcdspos += (!(bc->modem.ser12.dcd_shreg & 0x7ffffffe))
-				<< 1;
-			dcdsneg += ((bc->modem.ser12.dcd_shreg >> 2) & 1);
-			dcdsneg += ((bc->modem.ser12.dcd_shreg >> 3) & 1);
-			dcdsneg += ((bc->modem.ser12.dcd_shreg >> 4) & 1);
-
-			bc->modem.ser12.dcd_sum0 += 16*dcdspos - dcdsneg;
-		}
-	} else {
-		/*
-		 * PLL algorithm for the hardware squelch DCD algorithm
-		 */
-		if (bc->modem.ser12.interm_sample) {
-			/*
-			 * intermediate sample; set timing correction to normal
-			 */
-			ser12_set_divisor(dev, 6);
-		} else {
-			/*
-			 * do PLL correction and call HDLC receiver
-			 */
-			switch (bc->modem.ser12.dcd_shreg & 3) {
-			case 1: /* transition too late */
-				ser12_set_divisor(dev, 7);
-#ifdef BAYCOM_DEBUG
-				bc->debug_vals.cur_pllcorr++;
-#endif /* BAYCOM_DEBUG */
-				break;
-			case 2:	/* transition too early */
-				ser12_set_divisor(dev, 5);
-#ifdef BAYCOM_DEBUG
-				bc->debug_vals.cur_pllcorr--;
-#endif /* BAYCOM_DEBUG */
-				break;
-			default:
-				ser12_set_divisor(dev, 6);
-				break;
-			}
-			bc->modem.shreg >>= 1;
-			if (bc->modem.ser12.last_sample ==
-			    bc->modem.ser12.last_rxbit)
-				bc->modem.shreg |= 0x10000;
-			bc->modem.ser12.last_rxbit =
-				bc->modem.ser12.last_sample;
-		}
-		bc->modem.ser12.interm_sample = !bc->modem.ser12.interm_sample;
-		/*
-		 * DCD stuff
-		 */
-		bc->modem.ser12.dcd_sum0 -= (bc->modem.ser12.dcd_shreg & 1);
-	}
-	outb(0x0d, MCR(dev->base_addr));		/* transmitter off */
-	if (bc->modem.shreg & 1) {
-		hdlcdrv_putbits(&bc->hdrv, bc->modem.shreg >> 1);
-		bc->modem.shreg = 0x10000;
-	}
-	if(!bc->modem.ser12.dcd_time) {
-		if (bc->opt_dcd & 1) 
-			hdlcdrv_setdcd(&bc->hdrv, !((inb(MSR(dev->base_addr)) ^ bc->opt_dcd) & 0x80));
-		else
-			hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 +
-						   bc->modem.ser12.dcd_sum1 +
-						   bc->modem.ser12.dcd_sum2) < 0);
-		bc->modem.ser12.dcd_sum2 = bc->modem.ser12.dcd_sum1;
-		bc->modem.ser12.dcd_sum1 = bc->modem.ser12.dcd_sum0;
-		/* offset to ensure DCD off on silent input */
-		bc->modem.ser12.dcd_sum0 = 2;
-		bc->modem.ser12.dcd_time = SER12_DCD_INTERVAL(bc);
-	}
-	bc->modem.ser12.dcd_time--;
-}
-
-/* --------------------------------------------------------------------- */
-
-static irqreturn_t ser12_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev = (struct net_device *)dev_id;
-	struct baycom_state *bc = netdev_priv(dev);
-	unsigned char iir;
-
-	if (!dev || !bc || bc->hdrv.magic != HDLCDRV_MAGIC)
-		return IRQ_NONE;
-	/* fast way out */
-	if ((iir = inb(IIR(dev->base_addr))) & 1)
-		return IRQ_NONE;
-	baycom_int_freq(bc);
-	do {
-		switch (iir & 6) {
-		case 6:
-			inb(LSR(dev->base_addr));
-			break;
-			
-		case 4:
-			inb(RBR(dev->base_addr));
-			break;
-			
-		case 2:
-			/*
-			 * check if transmitter active
-			 */
-			if (hdlcdrv_ptt(&bc->hdrv))
-				ser12_tx(dev, bc);
-			else {
-				ser12_rx(dev, bc);
-				bc->modem.arb_divider--;
-			}
-			outb(0x00, THR(dev->base_addr));
-			break;
-			
-		default:
-			inb(MSR(dev->base_addr));
-			break;
-		}
-		iir = inb(IIR(dev->base_addr));
-	} while (!(iir & 1));
-	if (bc->modem.arb_divider <= 0) {
-		bc->modem.arb_divider = SER12_ARB_DIVIDER(bc);
-		local_irq_enable();
-		hdlcdrv_arbitrate(dev, &bc->hdrv);
-	}
-	local_irq_enable();
-	hdlcdrv_transmitter(dev, &bc->hdrv);
-	hdlcdrv_receiver(dev, &bc->hdrv);
-	local_irq_disable();
-	return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-enum uart { c_uart_unknown, c_uart_8250,
-	    c_uart_16450, c_uart_16550, c_uart_16550A};
-static const char *uart_str[] = { 
-	"unknown", "8250", "16450", "16550", "16550A" 
-};
-
-static enum uart ser12_check_uart(unsigned int iobase)
-{
-	unsigned char b1,b2,b3;
-	enum uart u;
-	enum uart uart_tab[] =
-		{ c_uart_16450, c_uart_unknown, c_uart_16550, c_uart_16550A };
-
-	b1 = inb(MCR(iobase));
-	outb(b1 | 0x10, MCR(iobase));	/* loopback mode */
-	b2 = inb(MSR(iobase));
-	outb(0x1a, MCR(iobase));
-	b3 = inb(MSR(iobase)) & 0xf0;
-	outb(b1, MCR(iobase));			/* restore old values */
-	outb(b2, MSR(iobase));
-	if (b3 != 0x90)
-		return c_uart_unknown;
-	inb(RBR(iobase));
-	inb(RBR(iobase));
-	outb(0x01, FCR(iobase));		/* enable FIFOs */
-	u = uart_tab[(inb(IIR(iobase)) >> 6) & 3];
-	if (u == c_uart_16450) {
-		outb(0x5a, SCR(iobase));
-		b1 = inb(SCR(iobase));
-		outb(0xa5, SCR(iobase));
-		b2 = inb(SCR(iobase));
-		if ((b1 != 0x5a) || (b2 != 0xa5))
-			u = c_uart_8250;
-	}
-	return u;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int ser12_open(struct net_device *dev)
-{
-	struct baycom_state *bc = netdev_priv(dev);
-	enum uart u;
-
-	if (!dev || !bc)
-		return -ENXIO;
-	if (!dev->base_addr || dev->base_addr > 0x1000-SER12_EXTENT ||
-	    dev->irq < 2 || dev->irq > 15)
-		return -ENXIO;
-	if (!request_region(dev->base_addr, SER12_EXTENT, "baycom_ser12"))
-		return -EACCES;
-	memset(&bc->modem, 0, sizeof(bc->modem));
-	bc->hdrv.par.bitrate = 1200;
-	if ((u = ser12_check_uart(dev->base_addr)) == c_uart_unknown) {
-		release_region(dev->base_addr, SER12_EXTENT);       
-		return -EIO;
-	}
-	outb(0, FCR(dev->base_addr));  /* disable FIFOs */
-	outb(0x0d, MCR(dev->base_addr));
-	outb(0, IER(dev->base_addr));
-	if (request_irq(dev->irq, ser12_interrupt, IRQF_SHARED,
-			"baycom_ser12", dev)) {
-		release_region(dev->base_addr, SER12_EXTENT);       
-		return -EBUSY;
-	}
-	/*
-	 * enable transmitter empty interrupt
-	 */
-	outb(2, IER(dev->base_addr));
-	/*
-	 * set the SIO to 6 Bits/character and 19200 or 28800 baud, so that
-	 * we get exactly (hopefully) 2 or 3 interrupts per radio symbol,
-	 * depending on the usage of the software DCD routine
-	 */
-	ser12_set_divisor(dev, bc->opt_dcd ? 6 : 4);
-	printk(KERN_INFO "%s: ser12 at iobase 0x%lx irq %u uart %s\n", 
-	       bc_drvname, dev->base_addr, dev->irq, uart_str[u]);
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int ser12_close(struct net_device *dev)
-{
-	struct baycom_state *bc = netdev_priv(dev);
-
-	if (!dev || !bc)
-		return -EINVAL;
-	/*
-	 * disable interrupts
-	 */
-	outb(0, IER(dev->base_addr));
-	outb(1, MCR(dev->base_addr));
-	free_irq(dev->irq, dev);
-	release_region(dev->base_addr, SER12_EXTENT);
-	printk(KERN_INFO "%s: close ser12 at iobase 0x%lx irq %u\n",
-	       bc_drvname, dev->base_addr, dev->irq);
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-/*
- * ===================== hdlcdrv driver interface =========================
- */
-
-/* --------------------------------------------------------------------- */
-
-static int baycom_ioctl(struct net_device *dev, void __user *data,
-			struct hdlcdrv_ioctl *hi, int cmd);
-
-/* --------------------------------------------------------------------- */
-
-static const struct hdlcdrv_ops ser12_ops = {
-	.drvname = bc_drvname,
-	.drvinfo = bc_drvinfo,
-	.open    = ser12_open,
-	.close   = ser12_close,
-	.ioctl   = baycom_ioctl,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int baycom_setmode(struct baycom_state *bc, const char *modestr)
-{
-	if (strchr(modestr, '*'))
-		bc->opt_dcd = 0;
-	else if (strchr(modestr, '+'))
-		bc->opt_dcd = -1;
-	else if (strchr(modestr, '@'))
-		bc->opt_dcd = -2;
-	else
-		bc->opt_dcd = 1;
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int baycom_ioctl(struct net_device *dev, void __user *data,
-			struct hdlcdrv_ioctl *hi, int cmd)
-{
-	struct baycom_state *bc;
-	struct baycom_ioctl bi;
-
-	if (!dev)
-		return -EINVAL;
-
-	bc = netdev_priv(dev);
-	BUG_ON(bc->hdrv.magic != HDLCDRV_MAGIC);
-
-	if (cmd != SIOCDEVPRIVATE)
-		return -ENOIOCTLCMD;
-	switch (hi->cmd) {
-	default:
-		break;
-
-	case HDLCDRVCTL_GETMODE:
-		strscpy(hi->data.modename, "ser12");
-		if (bc->opt_dcd <= 0)
-			strcat(hi->data.modename, (!bc->opt_dcd) ? "*" : (bc->opt_dcd == -2) ? "@" : "+");
-		if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl)))
-			return -EFAULT;
-		return 0;
-
-	case HDLCDRVCTL_SETMODE:
-		if (netif_running(dev) || !capable(CAP_NET_ADMIN))
-			return -EACCES;
-		hi->data.modename[sizeof(hi->data.modename)-1] = '\0';
-		return baycom_setmode(bc, hi->data.modename);
-
-	case HDLCDRVCTL_MODELIST:
-		strscpy(hi->data.modename, "ser12");
-		if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl)))
-			return -EFAULT;
-		return 0;
-
-	case HDLCDRVCTL_MODEMPARMASK:
-		return HDLCDRV_PARMASK_IOBASE | HDLCDRV_PARMASK_IRQ;
-
-	}
-
-	if (copy_from_user(&bi, data, sizeof(bi)))
-		return -EFAULT;
-	switch (bi.cmd) {
-	default:
-		return -ENOIOCTLCMD;
-
-#ifdef BAYCOM_DEBUG
-	case BAYCOMCTL_GETDEBUG:
-		bi.data.dbg.debug1 = bc->hdrv.ptt_keyed;
-		bi.data.dbg.debug2 = bc->debug_vals.last_intcnt;
-		bi.data.dbg.debug3 = bc->debug_vals.last_pllcorr;
-		break;
-#endif /* BAYCOM_DEBUG */
-
-	}
-	if (copy_to_user(data, &bi, sizeof(bi)))
-		return -EFAULT;
-	return 0;
-
-}
-
-/* --------------------------------------------------------------------- */
-
-/*
- * command line settable parameters
- */
-static char *mode[NR_PORTS] = { "ser12*", };
-static int iobase[NR_PORTS] = { 0x3f8, };
-static int irq[NR_PORTS] = { 4, };
-
-module_param_array(mode, charp, NULL, 0);
-MODULE_PARM_DESC(mode, "baycom operating mode; * for software DCD");
-module_param_hw_array(iobase, int, ioport, NULL, 0);
-MODULE_PARM_DESC(iobase, "baycom io base address");
-module_param_hw_array(irq, int, irq, NULL, 0);
-MODULE_PARM_DESC(irq, "baycom irq number");
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("Baycom ser12 half duplex amateur radio modem driver");
-MODULE_LICENSE("GPL");
-
-/* --------------------------------------------------------------------- */
-
-static int __init init_baycomserhdx(void)
-{
-	int i, found = 0;
-	char set_hw = 1;
-
-	printk(bc_drvinfo);
-	/*
-	 * register net devices
-	 */
-	for (i = 0; i < NR_PORTS; i++) {
-		struct net_device *dev;
-		struct baycom_state *bc;
-		char ifname[IFNAMSIZ];
-
-		sprintf(ifname, "bcsh%d", i);
-
-		if (!mode[i])
-			set_hw = 0;
-		if (!set_hw)
-			iobase[i] = irq[i] = 0;
-
-		dev = hdlcdrv_register(&ser12_ops, 
-				       sizeof(struct baycom_state),
-				       ifname, iobase[i], irq[i], 0);
-		if (IS_ERR(dev)) 
-			break;
-
-		bc = netdev_priv(dev);
-		if (set_hw && baycom_setmode(bc, mode[i]))
-			set_hw = 0;
-		found++;
-		baycom_device[i] = dev;
-	}
-
-	if (!found)
-		return -ENXIO;
-	return 0;
-}
-
-static void __exit cleanup_baycomserhdx(void)
-{
-	int i;
-
-	for(i = 0; i < NR_PORTS; i++) {
-		struct net_device *dev = baycom_device[i];
-
-		if (dev)
-			hdlcdrv_unregister(dev);
-	}
-}
-
-module_init(init_baycomserhdx);
-module_exit(cleanup_baycomserhdx);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/*
- * format: baycom_ser_hdx=io,irq,mode
- * mode: ser12    hardware DCD
- *       ser12*   software DCD
- *       ser12@   hardware/software DCD, i.e. no explicit DCD signal but hardware
- *                mutes audio input to the modem
- *       ser12+   hardware DCD, inverted signal at DCD pin
- */
-
-static int __init baycom_ser_hdx_setup(char *str)
-{
-        static unsigned nr_dev;
-	int ints[3];
-
-        if (nr_dev >= NR_PORTS)
-                return 0;
-	str = get_options(str, 3, ints);
-	if (ints[0] < 2)
-		return 0;
-	mode[nr_dev] = str;
-	iobase[nr_dev] = ints[1];
-	irq[nr_dev] = ints[2];
-	nr_dev++;
-	return 1;
-}
-
-__setup("baycom_ser_hdx=", baycom_ser_hdx_setup);
-
-#endif /* MODULE */
-/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
deleted file mode 100644
index 214fd1f819a1..000000000000
--- a/drivers/net/hamradio/bpqether.c
+++ /dev/null
@@ -1,593 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *	G8BPQ compatible "AX.25 via ethernet" driver release 004
- *
- *	This code REQUIRES 2.0.0 or higher/ NET3.029
- *
- *	This is a "pseudo" network driver to allow AX.25 over Ethernet
- *	using G8BPQ encapsulation. It has been extracted from the protocol
- *	implementation because
- *
- *		- things got unreadable within the protocol stack
- *		- to cure the protocol stack from "feature-ism"
- *		- a protocol implementation shouldn't need to know on
- *		  which hardware it is running
- *		- user-level programs like the AX.25 utilities shouldn't
- *		  need to know about the hardware.
- *		- IP over ethernet encapsulated AX.25 was impossible
- *		- rxecho.c did not work
- *		- to have room for extensions
- *		- it just deserves to "live" as an own driver
- *
- *	This driver can use any ethernet destination address, and can be
- *	limited to accept frames from one dedicated ethernet card only.
- *
- *	Note that the driver sets up the BPQ devices automagically on
- *	startup or (if started before the "insmod" of an ethernet device)
- *	on "ifconfig up". It hopefully will remove the BPQ on "rmmod"ing
- *	the ethernet device (in fact: as soon as another ethernet or bpq
- *	device gets "ifconfig"ured).
- *
- *	I have heard that several people are thinking of experiments
- *	with highspeed packet radio using existing ethernet cards.
- *	Well, this driver is prepared for this purpose, just add
- *	your tx key control and a txdelay / tailtime algorithm,
- *	probably some buffering, and /voila/...
- *
- *	History
- *	BPQ   001	Joerg(DL1BKE)		Extracted BPQ code from AX.25
- *						protocol stack and added my own
- *						yet existing patches
- *	BPQ   002	Joerg(DL1BKE)		Scan network device list on
- *						startup.
- *	BPQ   003	Joerg(DL1BKE)		Ethernet destination address
- *						and accepted source address
- *						can be configured by an ioctl()
- *						call.
- *						Fixed to match Linux networking
- *						changes - 2.1.15.
- *	BPQ   004	Joerg(DL1BKE)		Fixed to not lock up on ifconfig.
- */
-
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/notifier.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/stat.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/rtnetlink.h>
-
-#include <net/ip.h>
-#include <net/arp.h>
-#include <net/netdev_lock.h>
-#include <net/net_namespace.h>
-
-#include <linux/bpqether.h>
-
-static const char banner[] __initconst = KERN_INFO \
-	"AX.25: bpqether driver version 004\n";
-
-static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *);
-static int bpq_device_event(struct notifier_block *, unsigned long, void *);
-
-static struct packet_type bpq_packet_type __read_mostly = {
-	.type	= cpu_to_be16(ETH_P_BPQ),
-	.func	= bpq_rcv,
-};
-
-static struct notifier_block bpq_dev_notifier = {
-	.notifier_call = bpq_device_event,
-};
-
-
-struct bpqdev {
-	struct list_head bpq_list;	/* list of bpq devices chain */
-	struct net_device *ethdev;	/* link to ethernet device */
-	struct net_device *axdev;	/* bpq device (bpq#) */
-	char   dest_addr[6];		/* ether destination address */
-	char   acpt_addr[6];		/* accept ether frames from this address only */
-};
-
-static LIST_HEAD(bpq_devices);
-
-/* ------------------------------------------------------------------------ */
-
-
-/*
- *	Get the ethernet device for a BPQ device
- */
-static inline struct net_device *bpq_get_ether_dev(struct net_device *dev)
-{
-	struct bpqdev *bpq = netdev_priv(dev);
-
-	return bpq ? bpq->ethdev : NULL;
-}
-
-/*
- *	Get the BPQ device for the ethernet device
- */
-static inline struct net_device *bpq_get_ax25_dev(struct net_device *dev)
-{
-	struct bpqdev *bpq;
-
-	list_for_each_entry_rcu(bpq, &bpq_devices, bpq_list,
-				lockdep_rtnl_is_held()) {
-		if (bpq->ethdev == dev)
-			return bpq->axdev;
-	}
-	return NULL;
-}
-
-static inline int dev_is_ethdev(struct net_device *dev)
-{
-	return dev->type == ARPHRD_ETHER && !netdev_need_ops_lock(dev);
-}
-
-/* ------------------------------------------------------------------------ */
-
-
-/*
- *	Receive an AX.25 frame via an ethernet interface.
- */
-static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev)
-{
-	int len;
-	char * ptr;
-	struct ethhdr *eth;
-	struct bpqdev *bpq;
-
-	if (!net_eq(dev_net(dev), &init_net))
-		goto drop;
-
-	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
-		return NET_RX_DROP;
-
-	if (!pskb_may_pull(skb, sizeof(struct ethhdr)))
-		goto drop;
-
-	rcu_read_lock();
-	dev = bpq_get_ax25_dev(dev);
-
-	if (dev == NULL || !netif_running(dev)) 
-		goto drop_unlock;
-
-	/*
-	 * if we want to accept frames from just one ethernet device
-	 * we check the source address of the sender.
-	 */
-
-	bpq = netdev_priv(dev);
-
-	eth = eth_hdr(skb);
-
-	if (!(bpq->acpt_addr[0] & 0x01) &&
-	    !ether_addr_equal(eth->h_source, bpq->acpt_addr))
-		goto drop_unlock;
-
-	if (skb_cow(skb, sizeof(struct ethhdr)))
-		goto drop_unlock;
-
-	len = skb->data[0] + skb->data[1] * 256 - 5;
-
-	if (len < 0 || len > skb->len - 2)
-		goto drop_unlock;
-
-	skb_pull(skb, 2);	/* Remove the length bytes */
-	skb_trim(skb, len);	/* Set the length of the data */
-
-	dev->stats.rx_packets++;
-	dev->stats.rx_bytes += len;
-
-	ptr = skb_push(skb, 1);
-	*ptr = 0;
-
-	skb->protocol = ax25_type_trans(skb, dev);
-	netif_rx(skb);
-unlock:
-
-	rcu_read_unlock();
-
-	return 0;
-drop_unlock:
-	kfree_skb(skb);
-	goto unlock;
-
-drop:
-	kfree_skb(skb);
-	return 0;
-}
-
-/*
- * 	Send an AX.25 frame via an ethernet interface
- */
-static netdev_tx_t bpq_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	unsigned char *ptr;
-	struct bpqdev *bpq;
-	struct net_device *orig_dev;
-	int size;
-
-	if (skb->protocol == htons(ETH_P_IP))
-		return ax25_ip_xmit(skb);
-
-	/*
-	 * Just to be *really* sure not to send anything if the interface
-	 * is down, the ethernet device may have gone.
-	 */
-	if (!netif_running(dev)) {
-		kfree_skb(skb);
-		return NETDEV_TX_OK;
-	}
-
-	skb_pull(skb, 1);			/* Drop KISS byte */
-	size = skb->len;
-
-	/*
-	 * We're about to mess with the skb which may still shared with the
-	 * generic networking code so unshare and ensure it's got enough
-	 * space for the BPQ headers.
-	 */
-	if (skb_cow(skb, AX25_BPQ_HEADER_LEN)) {
-		if (net_ratelimit())
-			pr_err("bpqether: out of memory\n");
-		kfree_skb(skb);
-
-		return NETDEV_TX_OK;
-	}
-
-	ptr = skb_push(skb, 2);			/* Make space for length */
-
-	*ptr++ = (size + 5) % 256;
-	*ptr++ = (size + 5) / 256;
-
-	bpq = netdev_priv(dev);
-
-	orig_dev = dev;
-	if ((dev = bpq_get_ether_dev(dev)) == NULL) {
-		orig_dev->stats.tx_dropped++;
-		kfree_skb(skb);
-		return NETDEV_TX_OK;
-	}
-
-	skb->protocol = ax25_type_trans(skb, dev);
-	skb_reset_network_header(skb);
-	dev_hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
-	dev->stats.tx_packets++;
-	dev->stats.tx_bytes+=skb->len;
-  
-	dev_queue_xmit(skb);
-	netif_wake_queue(dev);
-	return NETDEV_TX_OK;
-}
-
-/*
- *	Set AX.25 callsign
- */
-static int bpq_set_mac_address(struct net_device *dev, void *addr)
-{
-    struct sockaddr *sa = (struct sockaddr *)addr;
-
-    dev_addr_set(dev, sa->sa_data);
-
-    return 0;
-}
-
-/*	Ioctl commands
- *
- *		SIOCSBPQETHOPT		reserved for enhancements
- *		SIOCSBPQETHADDR		set the destination and accepted
- *					source ethernet address (broadcast
- *					or multicast: accept all)
- */
-static int bpq_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
-			      void __user *data, int cmd)
-{
-	struct bpq_ethaddr __user *ethaddr = data;
-	struct bpqdev *bpq = netdev_priv(dev);
-	struct bpq_req req;
-
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
-	switch (cmd) {
-		case SIOCSBPQETHOPT:
-			if (copy_from_user(&req, data, sizeof(struct bpq_req)))
-				return -EFAULT;
-			switch (req.cmd) {
-				case SIOCGBPQETHPARAM:
-				case SIOCSBPQETHPARAM:
-				default:
-					return -EINVAL;
-			}
-
-			break;
-
-		case SIOCSBPQETHADDR:
-			if (copy_from_user(bpq->dest_addr, ethaddr->destination, ETH_ALEN))
-				return -EFAULT;
-			if (copy_from_user(bpq->acpt_addr, ethaddr->accept, ETH_ALEN))
-				return -EFAULT;
-			break;
-
-		default:
-			return -EINVAL;
-	}
-
-	return 0;
-}
-
-/*
- * open/close a device
- */
-static int bpq_open(struct net_device *dev)
-{
-	netif_start_queue(dev);
-	return 0;
-}
-
-static int bpq_close(struct net_device *dev)
-{
-	netif_stop_queue(dev);
-	return 0;
-}
-
-
-/* ------------------------------------------------------------------------ */
-
-#ifdef CONFIG_PROC_FS
-/*
- *	Proc filesystem
- */
-static void *bpq_seq_start(struct seq_file *seq, loff_t *pos)
-	__acquires(RCU)
-{
-	int i = 1;
-	struct bpqdev *bpqdev;
-
-	rcu_read_lock();
-
-	if (*pos == 0)
-		return SEQ_START_TOKEN;
-	
-	list_for_each_entry_rcu(bpqdev, &bpq_devices, bpq_list) {
-		if (i == *pos)
-			return bpqdev;
-	}
-	return NULL;
-}
-
-static void *bpq_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	struct list_head *p;
-	struct bpqdev *bpqdev = v;
-
-	++*pos;
-
-	if (v == SEQ_START_TOKEN)
-		p = rcu_dereference(list_next_rcu(&bpq_devices));
-	else
-		p = rcu_dereference(list_next_rcu(&bpqdev->bpq_list));
-
-	return (p == &bpq_devices) ? NULL 
-		: list_entry(p, struct bpqdev, bpq_list);
-}
-
-static void bpq_seq_stop(struct seq_file *seq, void *v)
-	__releases(RCU)
-{
-	rcu_read_unlock();
-}
-
-
-static int bpq_seq_show(struct seq_file *seq, void *v)
-{
-	if (v == SEQ_START_TOKEN)
-		seq_puts(seq, 
-			 "dev   ether      destination        accept from\n");
-	else {
-		const struct bpqdev *bpqdev = v;
-
-		seq_printf(seq, "%-5s %-10s %pM  ",
-			bpqdev->axdev->name, bpqdev->ethdev->name,
-			bpqdev->dest_addr);
-
-		if (is_multicast_ether_addr(bpqdev->acpt_addr))
-			seq_printf(seq, "*\n");
-		else
-			seq_printf(seq, "%pM\n", bpqdev->acpt_addr);
-
-	}
-	return 0;
-}
-
-static const struct seq_operations bpq_seqops = {
-	.start = bpq_seq_start,
-	.next = bpq_seq_next,
-	.stop = bpq_seq_stop,
-	.show = bpq_seq_show,
-};
-#endif
-/* ------------------------------------------------------------------------ */
-
-static const struct net_device_ops bpq_netdev_ops = {
-	.ndo_open	     = bpq_open,
-	.ndo_stop	     = bpq_close,
-	.ndo_start_xmit	     = bpq_xmit,
-	.ndo_set_mac_address = bpq_set_mac_address,
-	.ndo_siocdevprivate  = bpq_siocdevprivate,
-};
-
-static void bpq_setup(struct net_device *dev)
-{
-	netdev_lockdep_set_classes(dev);
-
-	dev->netdev_ops	     = &bpq_netdev_ops;
-	dev->needs_free_netdev = true;
-
-	dev->flags      = 0;
-	dev->lltx = true;	/* Allow recursion */
-
-#if IS_ENABLED(CONFIG_AX25)
-	dev->header_ops      = &ax25_header_ops;
-#endif
-
-	dev->type            = ARPHRD_AX25;
-	dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
-	dev->mtu             = AX25_DEF_PACLEN;
-	dev->addr_len        = AX25_ADDR_LEN;
-
-	memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
-	dev_addr_set(dev, (u8 *)&ax25_defaddr);
-}
-
-/*
- *	Setup a new device.
- */
-static int bpq_new_device(struct net_device *edev)
-{
-	int err;
-	struct net_device *ndev;
-	struct bpqdev *bpq;
-
-	ndev = alloc_netdev(sizeof(struct bpqdev), "bpq%d", NET_NAME_UNKNOWN,
-			    bpq_setup);
-	if (!ndev)
-		return -ENOMEM;
-
-		
-	bpq = netdev_priv(ndev);
-	dev_hold(edev);
-	bpq->ethdev = edev;
-	bpq->axdev = ndev;
-
-	eth_broadcast_addr(bpq->dest_addr);
-	eth_broadcast_addr(bpq->acpt_addr);
-
-	err = register_netdevice(ndev);
-	if (err)
-		goto error;
-
-	/* List protected by RTNL */
-	list_add_rcu(&bpq->bpq_list, &bpq_devices);
-	return 0;
-
- error:
-	dev_put(edev);
-	free_netdev(ndev);
-	return err;
-	
-}
-
-static void bpq_free_device(struct net_device *ndev)
-{
-	struct bpqdev *bpq = netdev_priv(ndev);
-
-	dev_put(bpq->ethdev);
-	list_del_rcu(&bpq->bpq_list);
-
-	unregister_netdevice(ndev);
-}
-
-/*
- *	Handle device status changes.
- */
-static int bpq_device_event(struct notifier_block *this,
-			    unsigned long event, void *ptr)
-{
-	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
-
-	if (!net_eq(dev_net(dev), &init_net))
-		return NOTIFY_DONE;
-
-	if (!dev_is_ethdev(dev) && !bpq_get_ax25_dev(dev))
-		return NOTIFY_DONE;
-
-	switch (event) {
-	case NETDEV_UP:		/* new ethernet device -> new BPQ interface */
-		if (bpq_get_ax25_dev(dev) == NULL)
-			bpq_new_device(dev);
-		break;
-
-	case NETDEV_DOWN:	/* ethernet device closed -> close BPQ interface */
-		if ((dev = bpq_get_ax25_dev(dev)) != NULL)
-			dev_close(dev);
-		break;
-
-	case NETDEV_UNREGISTER:	/* ethernet device removed -> free BPQ interface */
-		if ((dev = bpq_get_ax25_dev(dev)) != NULL)
-			bpq_free_device(dev);
-		break;
-	default:
-		break;
-	}
-
-	return NOTIFY_DONE;
-}
-
-
-/* ------------------------------------------------------------------------ */
-
-/*
- * Initialize driver. To be called from af_ax25 if not compiled as a
- * module
- */
-static int __init bpq_init_driver(void)
-{
-#ifdef CONFIG_PROC_FS
-	if (!proc_create_seq("bpqether", 0444, init_net.proc_net, &bpq_seqops)) {
-		printk(KERN_ERR
-			"bpq: cannot create /proc/net/bpqether entry.\n");
-		return -ENOENT;
-	}
-#endif  /* CONFIG_PROC_FS */
-
-	dev_add_pack(&bpq_packet_type);
-
-	register_netdevice_notifier(&bpq_dev_notifier);
-
-	printk(banner);
-
-	return 0;
-}
-
-static void __exit bpq_cleanup_driver(void)
-{
-	struct bpqdev *bpq;
-
-	dev_remove_pack(&bpq_packet_type);
-
-	unregister_netdevice_notifier(&bpq_dev_notifier);
-
-	remove_proc_entry("bpqether", init_net.proc_net);
-
-	rtnl_lock();
-	while (!list_empty(&bpq_devices)) {
-		bpq = list_entry(bpq_devices.next, struct bpqdev, bpq_list);
-		bpq_free_device(bpq->axdev);
-	}
-	rtnl_unlock();
-}
-
-MODULE_AUTHOR("Joerg Reuter DL1BKE <jreuter@yaina.de>");
-MODULE_DESCRIPTION("Transmit and receive AX.25 packets over Ethernet");
-MODULE_LICENSE("GPL");
-module_init(bpq_init_driver);
-module_exit(bpq_cleanup_driver);
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
deleted file mode 100644
index 3b88e465d08f..000000000000
--- a/drivers/net/hamradio/hdlcdrv.c
+++ /dev/null
@@ -1,747 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*****************************************************************************/
-
-/*
- *	hdlcdrv.c  -- HDLC packet radio network driver.
- *
- *	Copyright (C) 1996-2000  Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *  Please note that the GPL allows you to use the driver, NOT the radio.
- *  In order to use the radio, you need a license from the communications
- *  authority of your country.
- *
- *  The driver was derived from Donald Beckers skeleton.c
- *	Written 1993-94 by Donald Becker.
- *
- *  History:
- *   0.1  21.09.1996  Started
- *        18.10.1996  Changed to new user space access routines 
- *                    (copy_{to,from}_user)
- *   0.2  21.11.1996  various small changes
- *   0.3  03.03.1997  fixed (hopefully) IP not working with ax.25 as a module
- *   0.4  16.04.1997  init code/data tagged
- *   0.5  30.07.1997  made HDLC buffers bigger (solves a problem with the
- *                    soundmodem driver)
- *   0.6  05.04.1998  add spinlocks
- *   0.7  03.08.1999  removed some old compatibility cruft
- *   0.8  12.02.2000  adapted to softnet driver interface
- */
-
-/*****************************************************************************/
-
-#include <linux/capability.h>
-#include <linux/compat.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/net.h>
-#include <linux/in.h>
-#include <linux/if.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <linux/hdlcdrv.h>
-#include <linux/random.h>
-#include <net/ax25.h> 
-#include <linux/uaccess.h>
-
-#include <linux/crc-ccitt.h>
-
-/* --------------------------------------------------------------------- */
-
-#define KISS_VERBOSE
-
-/* --------------------------------------------------------------------- */
-
-#define PARAM_TXDELAY   1
-#define PARAM_PERSIST   2
-#define PARAM_SLOTTIME  3
-#define PARAM_TXTAIL    4
-#define PARAM_FULLDUP   5
-#define PARAM_HARDWARE  6
-#define PARAM_RETURN    255
-
-/* --------------------------------------------------------------------- */
-/*
- * the CRC routines are stolen from WAMPES
- * by Dieter Deyke
- */
-
-
-/*---------------------------------------------------------------------------*/
-
-static inline void append_crc_ccitt(unsigned char *buffer, int len)
-{
-	unsigned int crc = crc_ccitt(0xffff, buffer, len) ^ 0xffff;
-	buffer += len;
-	*buffer++ = crc;
-	*buffer++ = crc >> 8;
-}
-
-/*---------------------------------------------------------------------------*/
-
-static inline int check_crc_ccitt(const unsigned char *buf, int cnt)
-{
-	return (crc_ccitt(0xffff, buf, cnt) & 0xffff) == 0xf0b8;
-}
-
-/*---------------------------------------------------------------------------*/
-
-#if 0
-static int calc_crc_ccitt(const unsigned char *buf, int cnt)
-{
-	unsigned int crc = 0xffff;
-
-	for (; cnt > 0; cnt--)
-		crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff];
-	crc ^= 0xffff;
-	return crc & 0xffff;
-}
-#endif
-
-/* ---------------------------------------------------------------------- */
-
-#define tenms_to_2flags(s,tenms) ((tenms * s->par.bitrate) / 100 / 16)
-
-/* ---------------------------------------------------------------------- */
-/*
- * The HDLC routines
- */
-
-static int hdlc_rx_add_bytes(struct hdlcdrv_state *s, unsigned int bits, 
-			     int num)
-{
-	int added = 0;
-	
-	while (s->hdlcrx.rx_state && num >= 8) {
-		if (s->hdlcrx.len >= sizeof(s->hdlcrx.buffer)) {
-			s->hdlcrx.rx_state = 0;
-			return 0;
-		}
-		*s->hdlcrx.bp++ = bits >> (32-num);
-		s->hdlcrx.len++;
-		num -= 8;
-		added += 8;
-	}
-	return added;
-}
-
-static void hdlc_rx_flag(struct net_device *dev, struct hdlcdrv_state *s)
-{
-	struct sk_buff *skb;
-	int pkt_len;
-	unsigned char *cp;
-
-	if (s->hdlcrx.len < 4) 
-		return;
-	if (!check_crc_ccitt(s->hdlcrx.buffer, s->hdlcrx.len)) 
-		return;
-	pkt_len = s->hdlcrx.len - 2 + 1; /* KISS kludge */
-	if (!(skb = dev_alloc_skb(pkt_len))) {
-		printk("%s: memory squeeze, dropping packet\n", dev->name);
-		dev->stats.rx_dropped++;
-		return;
-	}
-	cp = skb_put(skb, pkt_len);
-	*cp++ = 0; /* KISS kludge */
-	memcpy(cp, s->hdlcrx.buffer, pkt_len - 1);
-	skb->protocol = ax25_type_trans(skb, dev);
-	netif_rx(skb);
-	dev->stats.rx_packets++;
-}
-
-void hdlcdrv_receiver(struct net_device *dev, struct hdlcdrv_state *s)
-{
-	int i;
-	unsigned int mask1, mask2, mask3, mask4, mask5, mask6, word;
-	
-	if (!s || s->magic != HDLCDRV_MAGIC) 
-		return;
-	if (test_and_set_bit(0, &s->hdlcrx.in_hdlc_rx))
-		return;
-
-	while (!hdlcdrv_hbuf_empty(&s->hdlcrx.hbuf)) {
-		word = hdlcdrv_hbuf_get(&s->hdlcrx.hbuf);	
-
-#ifdef HDLCDRV_DEBUG
-		hdlcdrv_add_bitbuffer_word(&s->bitbuf_hdlc, word);
-#endif /* HDLCDRV_DEBUG */
-	       	s->hdlcrx.bitstream >>= 16;
-		s->hdlcrx.bitstream |= word << 16;
-		s->hdlcrx.bitbuf >>= 16;
-		s->hdlcrx.bitbuf |= word << 16;
-		s->hdlcrx.numbits += 16;
-		for(i = 15, mask1 = 0x1fc00, mask2 = 0x1fe00, mask3 = 0x0fc00,
-		    mask4 = 0x1f800, mask5 = 0xf800, mask6 = 0xffff; 
-		    i >= 0; 
-		    i--, mask1 <<= 1, mask2 <<= 1, mask3 <<= 1, mask4 <<= 1, 
-		    mask5 <<= 1, mask6 = (mask6 << 1) | 1) {
-			if ((s->hdlcrx.bitstream & mask1) == mask1)
-				s->hdlcrx.rx_state = 0; /* abort received */
-			else if ((s->hdlcrx.bitstream & mask2) == mask3) {
-				/* flag received */
-				if (s->hdlcrx.rx_state) {
-					hdlc_rx_add_bytes(s, s->hdlcrx.bitbuf 
-							  << (8+i),
-							  s->hdlcrx.numbits
-							  -8-i);
-					hdlc_rx_flag(dev, s);
-				}
-				s->hdlcrx.len = 0;
-				s->hdlcrx.bp = s->hdlcrx.buffer;
-				s->hdlcrx.rx_state = 1;
-				s->hdlcrx.numbits = i;
-			} else if ((s->hdlcrx.bitstream & mask4) == mask5) {
-				/* stuffed bit */
-				s->hdlcrx.numbits--;
-				s->hdlcrx.bitbuf = (s->hdlcrx.bitbuf & (~mask6)) |
-					((s->hdlcrx.bitbuf & mask6) << 1);
-			}
-		}
-		s->hdlcrx.numbits -= hdlc_rx_add_bytes(s, s->hdlcrx.bitbuf,
-						       s->hdlcrx.numbits);
-	}
-	clear_bit(0, &s->hdlcrx.in_hdlc_rx);
-}
-
-/* ---------------------------------------------------------------------- */
-
-static inline void do_kiss_params(struct hdlcdrv_state *s,
-				  unsigned char *data, unsigned long len)
-{
-
-#ifdef KISS_VERBOSE
-#define PKP(a,b) printk(KERN_INFO "hdlcdrv.c: channel params: " a "\n", b)
-#else /* KISS_VERBOSE */	      
-#define PKP(a,b) 
-#endif /* KISS_VERBOSE */	      
-
-	if (len < 2)
-		return;
-	switch(data[0]) {
-	case PARAM_TXDELAY:
-		s->ch_params.tx_delay = data[1];
-		PKP("TX delay = %ums", 10 * s->ch_params.tx_delay);
-		break;
-	case PARAM_PERSIST:   
-		s->ch_params.ppersist = data[1];
-		PKP("p persistence = %u", s->ch_params.ppersist);
-		break;
-	case PARAM_SLOTTIME:  
-		s->ch_params.slottime = data[1];
-		PKP("slot time = %ums", s->ch_params.slottime);
-		break;
-	case PARAM_TXTAIL:    
-		s->ch_params.tx_tail = data[1];
-		PKP("TX tail = %ums", s->ch_params.tx_tail);
-		break;
-	case PARAM_FULLDUP:   
-		s->ch_params.fulldup = !!data[1];
-		PKP("%s duplex", s->ch_params.fulldup ? "full" : "half");
-		break;
-	default:
-		break;
-	}
-#undef PKP
-}
-
-/* ---------------------------------------------------------------------- */
-
-void hdlcdrv_transmitter(struct net_device *dev, struct hdlcdrv_state *s)
-{
-	unsigned int mask1, mask2, mask3;
-	int i;
-	struct sk_buff *skb;
-	int pkt_len;
-
-	if (!s || s->magic != HDLCDRV_MAGIC) 
-		return;
-	if (test_and_set_bit(0, &s->hdlctx.in_hdlc_tx))
-		return;
-	for (;;) {
-		if (s->hdlctx.numbits >= 16) {
-			if (hdlcdrv_hbuf_full(&s->hdlctx.hbuf)) {
-				clear_bit(0, &s->hdlctx.in_hdlc_tx);
-				return;
-			}
-			hdlcdrv_hbuf_put(&s->hdlctx.hbuf, s->hdlctx.bitbuf);
-			s->hdlctx.bitbuf >>= 16;
-			s->hdlctx.numbits -= 16;
-		}
-		switch (s->hdlctx.tx_state) {
-		default:
-			clear_bit(0, &s->hdlctx.in_hdlc_tx);
-			return;
-		case 0:
-		case 1:
-			if (s->hdlctx.numflags) {
-				s->hdlctx.numflags--;
-				s->hdlctx.bitbuf |= 
-					0x7e7e << s->hdlctx.numbits;
-				s->hdlctx.numbits += 16;
-				break;
-			}
-			if (s->hdlctx.tx_state == 1) {
-				clear_bit(0, &s->hdlctx.in_hdlc_tx);
-				return;
-			}
-			if (!(skb = s->skb)) {
-				int flgs = tenms_to_2flags(s, s->ch_params.tx_tail);
-				if (flgs < 2)
-					flgs = 2;
-				s->hdlctx.tx_state = 1;
-				s->hdlctx.numflags = flgs;
-				break;
-			}
-			s->skb = NULL;
-			netif_wake_queue(dev);
-			pkt_len = skb->len-1; /* strip KISS byte */
-			if (pkt_len >= HDLCDRV_MAXFLEN || pkt_len < 2) {
-				s->hdlctx.tx_state = 0;
-				s->hdlctx.numflags = 1;
-				dev_kfree_skb_irq(skb);
-				break;
-			}
-			skb_copy_from_linear_data_offset(skb, 1,
-							 s->hdlctx.buffer,
-							 pkt_len);
-			dev_kfree_skb_irq(skb);
-			s->hdlctx.bp = s->hdlctx.buffer;
-			append_crc_ccitt(s->hdlctx.buffer, pkt_len);
-			s->hdlctx.len = pkt_len+2; /* the appended CRC */
-			s->hdlctx.tx_state = 2;
-			s->hdlctx.bitstream = 0;
-			dev->stats.tx_packets++;
-			break;
-		case 2:
-			if (!s->hdlctx.len) {
-				s->hdlctx.tx_state = 0;
-				s->hdlctx.numflags = 1;
-				break;
-			}
-			s->hdlctx.len--;
-			s->hdlctx.bitbuf |= *s->hdlctx.bp <<
-				s->hdlctx.numbits;
-			s->hdlctx.bitstream >>= 8;
-			s->hdlctx.bitstream |= (*s->hdlctx.bp++) << 16;
-			mask1 = 0x1f000;
-			mask2 = 0x10000;
-			mask3 = 0xffffffff >> (31-s->hdlctx.numbits);
-			s->hdlctx.numbits += 8;
-			for(i = 0; i < 8; i++, mask1 <<= 1, mask2 <<= 1, 
-			    mask3 = (mask3 << 1) | 1) {
-				if ((s->hdlctx.bitstream & mask1) != mask1) 
-					continue;
-				s->hdlctx.bitstream &= ~mask2;
-				s->hdlctx.bitbuf = 
-					(s->hdlctx.bitbuf & mask3) |
-						((s->hdlctx.bitbuf & 
-						 (~mask3)) << 1);
-				s->hdlctx.numbits++;
-				mask3 = (mask3 << 1) | 1;
-			}
-			break;
-		}
-	}
-}
-
-/* ---------------------------------------------------------------------- */
-
-static void start_tx(struct net_device *dev, struct hdlcdrv_state *s)
-{
-	s->hdlctx.tx_state = 0;
-	s->hdlctx.numflags = tenms_to_2flags(s, s->ch_params.tx_delay);
-	s->hdlctx.bitbuf = s->hdlctx.bitstream = s->hdlctx.numbits = 0;
-	hdlcdrv_transmitter(dev, s);
-	s->hdlctx.ptt = 1;
-	s->ptt_keyed++;
-}
-
-/* ---------------------------------------------------------------------- */
-
-void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s)
-{
-	if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt || !s->skb) 
-		return;
-	if (s->ch_params.fulldup) {
-		start_tx(dev, s);
-		return;
-	}
-	if (s->hdlcrx.dcd) {
-		s->hdlctx.slotcnt = s->ch_params.slottime;
-		return;
-	}
-	if ((--s->hdlctx.slotcnt) > 0)
-		return;
-	s->hdlctx.slotcnt = s->ch_params.slottime;
-	if (get_random_u8() > s->ch_params.ppersist)
-		return;
-	start_tx(dev, s);
-}
-
-/* --------------------------------------------------------------------- */
-/*
- * ===================== network driver interface =========================
- */
-
-static netdev_tx_t hdlcdrv_send_packet(struct sk_buff *skb,
-				       struct net_device *dev)
-{
-	struct hdlcdrv_state *sm = netdev_priv(dev);
-
-	if (skb->protocol == htons(ETH_P_IP))
-		return ax25_ip_xmit(skb);
-
-	if (skb->data[0] != 0) {
-		do_kiss_params(sm, skb->data, skb->len);
-		dev_kfree_skb(skb);
-		return NETDEV_TX_OK;
-	}
-	if (sm->skb) {
-		dev_kfree_skb(skb);
-		return NETDEV_TX_OK;
-	}
-	netif_stop_queue(dev);
-	sm->skb = skb;
-	return NETDEV_TX_OK;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int hdlcdrv_set_mac_address(struct net_device *dev, void *addr)
-{
-	struct sockaddr *sa = (struct sockaddr *)addr;
-
-	/* addr is an AX.25 shifted ASCII mac address */
-	dev_addr_set(dev, sa->sa_data);
-	return 0;                                         
-}
-
-/* --------------------------------------------------------------------- */
-/*
- * Open/initialize the board. This is called (in the current kernel)
- * sometime after booting when the 'ifconfig' program is run.
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is non-reboot way to recover if something goes wrong.
- */
-
-static int hdlcdrv_open(struct net_device *dev)
-{
-	struct hdlcdrv_state *s = netdev_priv(dev);
-	int i;
-
-	if (!s->ops || !s->ops->open)
-		return -ENODEV;
-
-	/*
-	 * initialise some variables
-	 */
-	s->opened = 1;
-	s->hdlcrx.hbuf.rd = s->hdlcrx.hbuf.wr = 0;
-	s->hdlcrx.in_hdlc_rx = 0;
-	s->hdlcrx.rx_state = 0;
-	
-	s->hdlctx.hbuf.rd = s->hdlctx.hbuf.wr = 0;
-	s->hdlctx.in_hdlc_tx = 0;
-	s->hdlctx.tx_state = 1;
-	s->hdlctx.numflags = 0;
-	s->hdlctx.bitstream = s->hdlctx.bitbuf = s->hdlctx.numbits = 0;
-	s->hdlctx.ptt = 0;
-	s->hdlctx.slotcnt = s->ch_params.slottime;
-	s->hdlctx.calibrate = 0;
-
-	i = s->ops->open(dev);
-	if (i)
-		return i;
-	netif_start_queue(dev);
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-/* 
- * The inverse routine to hdlcdrv_open(). 
- */
-
-static int hdlcdrv_close(struct net_device *dev)
-{
-	struct hdlcdrv_state *s = netdev_priv(dev);
-	int i = 0;
-
-	netif_stop_queue(dev);
-
-	if (s->ops && s->ops->close)
-		i = s->ops->close(dev);
-	dev_kfree_skb(s->skb);
-	s->skb = NULL;
-	s->opened = 0;
-	return i;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int hdlcdrv_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
-				  void __user *data, int cmd)
-{
-	struct hdlcdrv_state *s = netdev_priv(dev);
-	struct hdlcdrv_ioctl bi;
-
-	if (cmd != SIOCDEVPRIVATE)
-		return -ENOIOCTLCMD;
-
-	if (in_compat_syscall()) /* to be implemented */
-		return -ENOIOCTLCMD;
-
-	if (copy_from_user(&bi, data, sizeof(bi)))
-		return -EFAULT;
-
-	switch (bi.cmd) {
-	default:
-		if (s->ops && s->ops->ioctl)
-			return s->ops->ioctl(dev, data, &bi, cmd);
-		return -ENOIOCTLCMD;
-
-	case HDLCDRVCTL_GETCHANNELPAR:
-		bi.data.cp.tx_delay = s->ch_params.tx_delay;
-		bi.data.cp.tx_tail = s->ch_params.tx_tail;
-		bi.data.cp.slottime = s->ch_params.slottime;
-		bi.data.cp.ppersist = s->ch_params.ppersist;
-		bi.data.cp.fulldup = s->ch_params.fulldup;
-		break;
-
-	case HDLCDRVCTL_SETCHANNELPAR:
-		if (!capable(CAP_NET_ADMIN))
-			return -EACCES;
-		s->ch_params.tx_delay = bi.data.cp.tx_delay;
-		s->ch_params.tx_tail = bi.data.cp.tx_tail;
-		s->ch_params.slottime = bi.data.cp.slottime;
-		s->ch_params.ppersist = bi.data.cp.ppersist;
-		s->ch_params.fulldup = bi.data.cp.fulldup;
-		s->hdlctx.slotcnt = 1;
-		return 0;
-		
-	case HDLCDRVCTL_GETMODEMPAR:
-		bi.data.mp.iobase = dev->base_addr;
-		bi.data.mp.irq = dev->irq;
-		bi.data.mp.dma = dev->dma;
-		bi.data.mp.dma2 = s->ptt_out.dma2;
-		bi.data.mp.seriobase = s->ptt_out.seriobase;
-		bi.data.mp.pariobase = s->ptt_out.pariobase;
-		bi.data.mp.midiiobase = s->ptt_out.midiiobase;
-		break;
-
-	case HDLCDRVCTL_SETMODEMPAR:
-		if ((!capable(CAP_SYS_RAWIO)) || netif_running(dev))
-			return -EACCES;
-		dev->base_addr = bi.data.mp.iobase;
-		dev->irq = bi.data.mp.irq;
-		dev->dma = bi.data.mp.dma;
-		s->ptt_out.dma2 = bi.data.mp.dma2;
-		s->ptt_out.seriobase = bi.data.mp.seriobase;
-		s->ptt_out.pariobase = bi.data.mp.pariobase;
-		s->ptt_out.midiiobase = bi.data.mp.midiiobase;
-		return 0;	
-	
-	case HDLCDRVCTL_GETSTAT:
-		bi.data.cs.ptt = hdlcdrv_ptt(s);
-		bi.data.cs.dcd = s->hdlcrx.dcd;
-		bi.data.cs.ptt_keyed = s->ptt_keyed;
-		bi.data.cs.tx_packets = dev->stats.tx_packets;
-		bi.data.cs.tx_errors = dev->stats.tx_errors;
-		bi.data.cs.rx_packets = dev->stats.rx_packets;
-		bi.data.cs.rx_errors = dev->stats.rx_errors;
-		break;		
-
-	case HDLCDRVCTL_OLDGETSTAT:
-		bi.data.ocs.ptt = hdlcdrv_ptt(s);
-		bi.data.ocs.dcd = s->hdlcrx.dcd;
-		bi.data.ocs.ptt_keyed = s->ptt_keyed;
-		break;		
-
-	case HDLCDRVCTL_CALIBRATE:
-		if(!capable(CAP_SYS_RAWIO))
-			return -EPERM;
-		if (s->par.bitrate <= 0)
-			return -EINVAL;
-		if (bi.data.calibrate > INT_MAX / s->par.bitrate)
-			return -EINVAL;
-		s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16;
-		return 0;
-
-	case HDLCDRVCTL_GETSAMPLES:
-#ifndef HDLCDRV_DEBUG
-		return -EPERM;
-#else /* HDLCDRV_DEBUG */
-		if (s->bitbuf_channel.rd == s->bitbuf_channel.wr) 
-			return -EAGAIN;
-		bi.data.bits = 
-			s->bitbuf_channel.buffer[s->bitbuf_channel.rd];
-		s->bitbuf_channel.rd = (s->bitbuf_channel.rd+1) %
-			sizeof(s->bitbuf_channel.buffer);
-		break;
-#endif /* HDLCDRV_DEBUG */
-				
-	case HDLCDRVCTL_GETBITS:
-#ifndef HDLCDRV_DEBUG
-		return -EPERM;
-#else /* HDLCDRV_DEBUG */
-		if (s->bitbuf_hdlc.rd == s->bitbuf_hdlc.wr) 
-			return -EAGAIN;
-		bi.data.bits = 
-			s->bitbuf_hdlc.buffer[s->bitbuf_hdlc.rd];
-		s->bitbuf_hdlc.rd = (s->bitbuf_hdlc.rd+1) %
-			sizeof(s->bitbuf_hdlc.buffer);
-		break;		
-#endif /* HDLCDRV_DEBUG */
-
-	case HDLCDRVCTL_DRIVERNAME:
-		if (s->ops && s->ops->drvname) {
-			strscpy(bi.data.drivername, s->ops->drvname,
-				sizeof(bi.data.drivername));
-			break;
-		}
-		bi.data.drivername[0] = '\0';
-		break;
-		
-	}
-	if (copy_to_user(data, &bi, sizeof(bi)))
-		return -EFAULT;
-	return 0;
-
-}
-
-/* --------------------------------------------------------------------- */
-
-static const struct net_device_ops hdlcdrv_netdev = {
-	.ndo_open	= hdlcdrv_open,
-	.ndo_stop	= hdlcdrv_close,
-	.ndo_start_xmit = hdlcdrv_send_packet,
-	.ndo_siocdevprivate  = hdlcdrv_siocdevprivate,
-	.ndo_set_mac_address = hdlcdrv_set_mac_address,
-};
-
-/*
- * Initialize fields in hdlcdrv
- */
-static void hdlcdrv_setup(struct net_device *dev)
-{
-	static const struct hdlcdrv_channel_params dflt_ch_params = { 
-		20, 2, 10, 40, 0 
-	};
-	struct hdlcdrv_state *s = netdev_priv(dev);
-
-	/*
-	 * initialize the hdlcdrv_state struct
-	 */
-	s->ch_params = dflt_ch_params;
-	s->ptt_keyed = 0;
-
-	spin_lock_init(&s->hdlcrx.hbuf.lock);
-	s->hdlcrx.hbuf.rd = s->hdlcrx.hbuf.wr = 0;
-	s->hdlcrx.in_hdlc_rx = 0;
-	s->hdlcrx.rx_state = 0;
-	
-	spin_lock_init(&s->hdlctx.hbuf.lock);
-	s->hdlctx.hbuf.rd = s->hdlctx.hbuf.wr = 0;
-	s->hdlctx.in_hdlc_tx = 0;
-	s->hdlctx.tx_state = 1;
-	s->hdlctx.numflags = 0;
-	s->hdlctx.bitstream = s->hdlctx.bitbuf = s->hdlctx.numbits = 0;
-	s->hdlctx.ptt = 0;
-	s->hdlctx.slotcnt = s->ch_params.slottime;
-	s->hdlctx.calibrate = 0;
-
-#ifdef HDLCDRV_DEBUG
-	s->bitbuf_channel.rd = s->bitbuf_channel.wr = 0;
-	s->bitbuf_channel.shreg = 0x80;
-
-	s->bitbuf_hdlc.rd = s->bitbuf_hdlc.wr = 0;
-	s->bitbuf_hdlc.shreg = 0x80;
-#endif /* HDLCDRV_DEBUG */
-
-
-	/* Fill in the fields of the device structure */
-
-	s->skb = NULL;
-	
-	dev->netdev_ops = &hdlcdrv_netdev;
-	dev->header_ops = &ax25_header_ops;
-	
-	dev->type = ARPHRD_AX25;           /* AF_AX25 device */
-	dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
-	dev->mtu = AX25_DEF_PACLEN;        /* eth_mtu is the default */
-	dev->addr_len = AX25_ADDR_LEN;     /* sizeof an ax.25 address */
-	memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
-	dev_addr_set(dev, (u8 *)&ax25_defaddr);
-	dev->tx_queue_len = 16;
-}
-
-/* --------------------------------------------------------------------- */
-struct net_device *hdlcdrv_register(const struct hdlcdrv_ops *ops,
-				    unsigned int privsize, const char *ifname,
-				    unsigned int baseaddr, unsigned int irq, 
-				    unsigned int dma) 
-{
-	struct net_device *dev;
-	struct hdlcdrv_state *s;
-	int err;
-
-	if (privsize < sizeof(struct hdlcdrv_state))
-		privsize = sizeof(struct hdlcdrv_state);
-
-	dev = alloc_netdev(privsize, ifname, NET_NAME_UNKNOWN, hdlcdrv_setup);
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	/*
-	 * initialize part of the hdlcdrv_state struct
-	 */
-	s = netdev_priv(dev);
-	s->magic = HDLCDRV_MAGIC;
-	s->ops = ops;
-	dev->base_addr = baseaddr;
-	dev->irq = irq;
-	dev->dma = dma;
-
-	err = register_netdev(dev);
-	if (err < 0) {
-		printk(KERN_WARNING "hdlcdrv: cannot register net "
-		       "device %s\n", dev->name);
-		free_netdev(dev);
-		dev = ERR_PTR(err);
-	}
-	return dev;
-}
-
-/* --------------------------------------------------------------------- */
-
-void hdlcdrv_unregister(struct net_device *dev) 
-{
-	struct hdlcdrv_state *s = netdev_priv(dev);
-
-	BUG_ON(s->magic != HDLCDRV_MAGIC);
-
-	if (s->opened && s->ops->close)
-		s->ops->close(dev);
-	unregister_netdev(dev);
-	
-	free_netdev(dev);
-}
-
-/* --------------------------------------------------------------------- */
-
-EXPORT_SYMBOL(hdlcdrv_receiver);
-EXPORT_SYMBOL(hdlcdrv_transmitter);
-EXPORT_SYMBOL(hdlcdrv_arbitrate);
-EXPORT_SYMBOL(hdlcdrv_register);
-EXPORT_SYMBOL(hdlcdrv_unregister);
-
-/* --------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("Packet Radio network interface HDLC encoder/decoder");
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
deleted file mode 100644
index 5f38a002bd9e..000000000000
--- a/drivers/net/hamradio/mkiss.c
+++ /dev/null
@@ -1,980 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *
- * Copyright (C) Hans Alblas PE1AYX <hans@esrac.ele.tue.nl>
- * Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf@linux-mips.org>
- * Copyright (C) 2004, 05 Thomas Osterried DL9SAU <thomas@x-berg.in-berlin.de>
- */
-#include <linux/module.h>
-#include <linux/bitops.h>
-#include <linux/uaccess.h>
-#include <linux/crc16.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/slab.h>
-#include <linux/tty.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/major.h>
-#include <linux/init.h>
-#include <linux/rtnetlink.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/jiffies.h>
-#include <linux/refcount.h>
-
-#include <net/ax25.h>
-
-#define AX_MTU		236
-
-/* some arch define END as assembly function ending, just undef it */
-#undef	END
-/* SLIP/KISS protocol characters. */
-#define END             0300		/* indicates end of frame	*/
-#define ESC             0333		/* indicates byte stuffing	*/
-#define ESC_END         0334		/* ESC ESC_END means END 'data'	*/
-#define ESC_ESC         0335		/* ESC ESC_ESC means ESC 'data'	*/
-
-struct mkiss {
-	struct tty_struct	*tty;	/* ptr to TTY structure		*/
-	struct net_device	*dev;	/* easy for intr handling	*/
-
-	/* These are pointers to the malloc()ed frame buffers. */
-	spinlock_t		buflock;/* lock for rbuf and xbuf */
-	unsigned char		*rbuff;	/* receiver buffer		*/
-	int			rcount;	/* received chars counter       */
-	unsigned char		*xbuff;	/* transmitter buffer		*/
-	unsigned char		*xhead;	/* pointer to next byte to XMIT */
-	int			xleft;	/* bytes left in XMIT queue     */
-
-	/* Detailed SLIP statistics. */
-	int		mtu;		/* Our mtu (to spot changes!)   */
-	int		buffsize;	/* Max buffers sizes            */
-
-	unsigned long	flags;		/* Flag values/ mode etc	*/
-					/* long req'd: used by set_bit --RR */
-#define AXF_INUSE	0		/* Channel in use               */
-#define AXF_ESCAPE	1               /* ESC received                 */
-#define AXF_ERROR	2               /* Parity, etc. error           */
-#define AXF_KEEPTEST	3		/* Keepalive test flag		*/
-#define AXF_OUTWAIT	4		/* is outpacket was flag	*/
-
-	int		mode;
-        int		crcmode;	/* MW: for FlexNet, SMACK etc.  */
-	int		crcauto;	/* CRC auto mode */
-
-#define CRC_MODE_NONE		0
-#define CRC_MODE_FLEX		1
-#define CRC_MODE_SMACK		2
-#define CRC_MODE_FLEX_TEST	3
-#define CRC_MODE_SMACK_TEST	4
-
-	refcount_t		refcnt;
-	struct completion	dead;
-};
-
-/*---------------------------------------------------------------------------*/
-
-static const unsigned short crc_flex_table[] = {
-	0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38,
-	0x83cf, 0x9246, 0xa0dd, 0xb154, 0xc5eb, 0xd462, 0xe6f9, 0xf770,
-	0x1f06, 0x0e8f, 0x3c14, 0x2d9d, 0x5922, 0x48ab, 0x7a30, 0x6bb9,
-	0x934e, 0x82c7, 0xb05c, 0xa1d5, 0xd56a, 0xc4e3, 0xf678, 0xe7f1,
-	0x2e85, 0x3f0c, 0x0d97, 0x1c1e, 0x68a1, 0x7928, 0x4bb3, 0x5a3a,
-	0xa2cd, 0xb344, 0x81df, 0x9056, 0xe4e9, 0xf560, 0xc7fb, 0xd672,
-	0x3e04, 0x2f8d, 0x1d16, 0x0c9f, 0x7820, 0x69a9, 0x5b32, 0x4abb,
-	0xb24c, 0xa3c5, 0x915e, 0x80d7, 0xf468, 0xe5e1, 0xd77a, 0xc6f3,
-	0x4d83, 0x5c0a, 0x6e91, 0x7f18, 0x0ba7, 0x1a2e, 0x28b5, 0x393c,
-	0xc1cb, 0xd042, 0xe2d9, 0xf350, 0x87ef, 0x9666, 0xa4fd, 0xb574,
-	0x5d02, 0x4c8b, 0x7e10, 0x6f99, 0x1b26, 0x0aaf, 0x3834, 0x29bd,
-	0xd14a, 0xc0c3, 0xf258, 0xe3d1, 0x976e, 0x86e7, 0xb47c, 0xa5f5,
-	0x6c81, 0x7d08, 0x4f93, 0x5e1a, 0x2aa5, 0x3b2c, 0x09b7, 0x183e,
-	0xe0c9, 0xf140, 0xc3db, 0xd252, 0xa6ed, 0xb764, 0x85ff, 0x9476,
-	0x7c00, 0x6d89, 0x5f12, 0x4e9b, 0x3a24, 0x2bad, 0x1936, 0x08bf,
-	0xf048, 0xe1c1, 0xd35a, 0xc2d3, 0xb66c, 0xa7e5, 0x957e, 0x84f7,
-	0x8b8f, 0x9a06, 0xa89d, 0xb914, 0xcdab, 0xdc22, 0xeeb9, 0xff30,
-	0x07c7, 0x164e, 0x24d5, 0x355c, 0x41e3, 0x506a, 0x62f1, 0x7378,
-	0x9b0e, 0x8a87, 0xb81c, 0xa995, 0xdd2a, 0xcca3, 0xfe38, 0xefb1,
-	0x1746, 0x06cf, 0x3454, 0x25dd, 0x5162, 0x40eb, 0x7270, 0x63f9,
-	0xaa8d, 0xbb04, 0x899f, 0x9816, 0xeca9, 0xfd20, 0xcfbb, 0xde32,
-	0x26c5, 0x374c, 0x05d7, 0x145e, 0x60e1, 0x7168, 0x43f3, 0x527a,
-	0xba0c, 0xab85, 0x991e, 0x8897, 0xfc28, 0xeda1, 0xdf3a, 0xceb3,
-	0x3644, 0x27cd, 0x1556, 0x04df, 0x7060, 0x61e9, 0x5372, 0x42fb,
-	0xc98b, 0xd802, 0xea99, 0xfb10, 0x8faf, 0x9e26, 0xacbd, 0xbd34,
-	0x45c3, 0x544a, 0x66d1, 0x7758, 0x03e7, 0x126e, 0x20f5, 0x317c,
-	0xd90a, 0xc883, 0xfa18, 0xeb91, 0x9f2e, 0x8ea7, 0xbc3c, 0xadb5,
-	0x5542, 0x44cb, 0x7650, 0x67d9, 0x1366, 0x02ef, 0x3074, 0x21fd,
-	0xe889, 0xf900, 0xcb9b, 0xda12, 0xaead, 0xbf24, 0x8dbf, 0x9c36,
-	0x64c1, 0x7548, 0x47d3, 0x565a, 0x22e5, 0x336c, 0x01f7, 0x107e,
-	0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7,
-	0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff
-};
-
-static unsigned short calc_crc_flex(unsigned char *cp, int size)
-{
-	unsigned short crc = 0xffff;
-
-	while (size--)
-		crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff];
-
-	return crc;
-}
-
-static int check_crc_flex(unsigned char *cp, int size)
-{
-	unsigned short crc = 0xffff;
-
-	if (size < 3)
-		return -1;
-
-	while (size--)
-		crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff];
-
-	if ((crc & 0xffff) != 0x7070)
-		return -1;
-
-	return 0;
-}
-
-static int check_crc_16(unsigned char *cp, int size)
-{
-	unsigned short crc = 0x0000;
-
-	if (size < 3)
-		return -1;
-
-	crc = crc16(0, cp, size);
-
-	if (crc != 0x0000)
-		return -1;
-
-	return 0;
-}
-
-/*
- * Standard encapsulation
- */
-
-static int kiss_esc(unsigned char *s, unsigned char *d, int len)
-{
-	unsigned char *ptr = d;
-	unsigned char c;
-
-	/*
-	 * Send an initial END character to flush out any data that may have
-	 * accumulated in the receiver due to line noise.
-	 */
-
-	*ptr++ = END;
-
-	while (len-- > 0) {
-		switch (c = *s++) {
-		case END:
-			*ptr++ = ESC;
-			*ptr++ = ESC_END;
-			break;
-		case ESC:
-			*ptr++ = ESC;
-			*ptr++ = ESC_ESC;
-			break;
-		default:
-			*ptr++ = c;
-			break;
-		}
-	}
-
-	*ptr++ = END;
-
-	return ptr - d;
-}
-
-/*
- * MW:
- * OK its ugly, but tell me a better solution without copying the
- * packet to a temporary buffer :-)
- */
-static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc,
-	int len)
-{
-	unsigned char *ptr = d;
-	unsigned char c=0;
-
-	*ptr++ = END;
-	while (len > 0) {
-		if (len > 2)
-			c = *s++;
-		else if (len > 1)
-			c = crc >> 8;
-		else
-			c = crc & 0xff;
-
-		len--;
-
-		switch (c) {
-		case END:
-			*ptr++ = ESC;
-			*ptr++ = ESC_END;
-			break;
-		case ESC:
-			*ptr++ = ESC;
-			*ptr++ = ESC_ESC;
-			break;
-		default:
-			*ptr++ = c;
-			break;
-		}
-	}
-	*ptr++ = END;
-
-	return ptr - d;
-}
-
-/* Send one completely decapsulated AX.25 packet to the AX.25 layer. */
-static void ax_bump(struct mkiss *ax)
-{
-	struct sk_buff *skb;
-	int count;
-
-	spin_lock_bh(&ax->buflock);
-	if (ax->rbuff[0] > 0x0f) {
-		if (ax->rbuff[0] & 0x80) {
-			if (check_crc_16(ax->rbuff, ax->rcount) < 0) {
-				ax->dev->stats.rx_errors++;
-				spin_unlock_bh(&ax->buflock);
-
-				return;
-			}
-			if (ax->crcmode != CRC_MODE_SMACK && ax->crcauto) {
-				printk(KERN_INFO
-				       "mkiss: %s: Switching to crc-smack\n",
-				       ax->dev->name);
-				ax->crcmode = CRC_MODE_SMACK;
-			}
-			ax->rcount -= 2;
-			*ax->rbuff &= ~0x80;
-		} else if (ax->rbuff[0] & 0x20)  {
-			if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
-				ax->dev->stats.rx_errors++;
-				spin_unlock_bh(&ax->buflock);
-				return;
-			}
-			if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) {
-				printk(KERN_INFO
-				       "mkiss: %s: Switching to crc-flexnet\n",
-				       ax->dev->name);
-				ax->crcmode = CRC_MODE_FLEX;
-			}
-			ax->rcount -= 2;
-
-			/*
-			 * dl9sau bugfix: the trailling two bytes flexnet crc
-			 * will not be passed to the kernel. thus we have to
-			 * correct the kissparm signature, because it indicates
-			 * a crc but there's none
-			 */
-			*ax->rbuff &= ~0x20;
-		}
-	}
-
-	count = ax->rcount;
-
-	if ((skb = dev_alloc_skb(count)) == NULL) {
-		printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n",
-		       ax->dev->name);
-		ax->dev->stats.rx_dropped++;
-		spin_unlock_bh(&ax->buflock);
-		return;
-	}
-
-	skb_put_data(skb, ax->rbuff, count);
-	skb->protocol = ax25_type_trans(skb, ax->dev);
-	netif_rx(skb);
-	ax->dev->stats.rx_packets++;
-	ax->dev->stats.rx_bytes += count;
-	spin_unlock_bh(&ax->buflock);
-}
-
-static void kiss_unesc(struct mkiss *ax, unsigned char s)
-{
-	switch (s) {
-	case END:
-		/* drop keeptest bit = VSV */
-		if (test_bit(AXF_KEEPTEST, &ax->flags))
-			clear_bit(AXF_KEEPTEST, &ax->flags);
-
-		if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2))
-			ax_bump(ax);
-
-		clear_bit(AXF_ESCAPE, &ax->flags);
-		ax->rcount = 0;
-		return;
-
-	case ESC:
-		set_bit(AXF_ESCAPE, &ax->flags);
-		return;
-	case ESC_ESC:
-		if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
-			s = ESC;
-		break;
-	case ESC_END:
-		if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
-			s = END;
-		break;
-	}
-
-	spin_lock_bh(&ax->buflock);
-	if (!test_bit(AXF_ERROR, &ax->flags)) {
-		if (ax->rcount < ax->buffsize) {
-			ax->rbuff[ax->rcount++] = s;
-			spin_unlock_bh(&ax->buflock);
-			return;
-		}
-
-		ax->dev->stats.rx_over_errors++;
-		set_bit(AXF_ERROR, &ax->flags);
-	}
-	spin_unlock_bh(&ax->buflock);
-}
-
-static int ax_set_mac_address(struct net_device *dev, void *addr)
-{
-	struct sockaddr_ax25 *sa = addr;
-
-	netif_tx_lock_bh(dev);
-	netif_addr_lock(dev);
-	__dev_addr_set(dev, &sa->sax25_call, AX25_ADDR_LEN);
-	netif_addr_unlock(dev);
-	netif_tx_unlock_bh(dev);
-
-	return 0;
-}
-
-/*---------------------------------------------------------------------------*/
-
-static void ax_changedmtu(struct mkiss *ax)
-{
-	struct net_device *dev = ax->dev;
-	unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
-	int len;
-
-	len = dev->mtu * 2;
-
-	/*
-	 * allow for arrival of larger UDP packets, even if we say not to
-	 * also fixes a bug in which SunOS sends 512-byte packets even with
-	 * an MSS of 128
-	 */
-	if (len < 576 * 2)
-		len = 576 * 2;
-
-	xbuff = kmalloc(len + 4, GFP_ATOMIC);
-	rbuff = kmalloc(len + 4, GFP_ATOMIC);
-
-	if (xbuff == NULL || rbuff == NULL)  {
-		printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, "
-		       "MTU change cancelled.\n",
-		       ax->dev->name);
-		dev->mtu = ax->mtu;
-		kfree(xbuff);
-		kfree(rbuff);
-		return;
-	}
-
-	spin_lock_bh(&ax->buflock);
-
-	oxbuff    = ax->xbuff;
-	ax->xbuff = xbuff;
-	orbuff    = ax->rbuff;
-	ax->rbuff = rbuff;
-
-	if (ax->xleft) {
-		if (ax->xleft <= len) {
-			memcpy(ax->xbuff, ax->xhead, ax->xleft);
-		} else  {
-			ax->xleft = 0;
-			dev->stats.tx_dropped++;
-		}
-	}
-
-	ax->xhead = ax->xbuff;
-
-	if (ax->rcount) {
-		if (ax->rcount <= len) {
-			memcpy(ax->rbuff, orbuff, ax->rcount);
-		} else  {
-			ax->rcount = 0;
-			dev->stats.rx_over_errors++;
-			set_bit(AXF_ERROR, &ax->flags);
-		}
-	}
-
-	ax->mtu      = dev->mtu + 73;
-	ax->buffsize = len;
-
-	spin_unlock_bh(&ax->buflock);
-
-	kfree(oxbuff);
-	kfree(orbuff);
-}
-
-/* Encapsulate one AX.25 packet and stuff into a TTY queue. */
-static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
-{
-	struct mkiss *ax = netdev_priv(dev);
-	unsigned char *p;
-	int actual, count;
-
-	if (ax->mtu != ax->dev->mtu + 73)	/* Someone has been ifconfigging */
-		ax_changedmtu(ax);
-
-	if (len > ax->mtu) {		/* Sigh, shouldn't occur BUT ... */
-		printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name);
-		dev->stats.tx_dropped++;
-		netif_start_queue(dev);
-		return;
-	}
-
-	p = icp;
-
-	spin_lock_bh(&ax->buflock);
-	if ((*p & 0x0f) != 0) {
-		/* Configuration Command (kissparms(1).
-		 * Protocol spec says: never append CRC.
-		 * This fixes a very old bug in the linux
-		 * kiss driver. -- dl9sau */
-		switch (*p & 0xff) {
-		case 0x85:
-			/* command from userspace especially for us,
-			 * not for delivery to the tnc */
-			if (len > 1) {
-				int cmd = (p[1] & 0xff);
-				switch(cmd) {
-				case 3:
-				  ax->crcmode = CRC_MODE_SMACK;
-				  break;
-				case 2:
-				  ax->crcmode = CRC_MODE_FLEX;
-				  break;
-				case 1:
-				  ax->crcmode = CRC_MODE_NONE;
-				  break;
-				case 0:
-				default:
-				  ax->crcmode = CRC_MODE_SMACK_TEST;
-				  cmd = 0;
-				}
-				ax->crcauto = (cmd ? 0 : 1);
-				printk(KERN_INFO "mkiss: %s: crc mode set to %d\n",
-				       ax->dev->name, cmd);
-			}
-			spin_unlock_bh(&ax->buflock);
-			netif_start_queue(dev);
-
-			return;
-		default:
-			count = kiss_esc(p, ax->xbuff, len);
-		}
-	} else {
-		unsigned short crc;
-		switch (ax->crcmode) {
-		case CRC_MODE_SMACK_TEST:
-			ax->crcmode  = CRC_MODE_FLEX_TEST;
-			printk(KERN_INFO "mkiss: %s: Trying crc-smack\n", ax->dev->name);
-			fallthrough;
-		case CRC_MODE_SMACK:
-			*p |= 0x80;
-			crc = swab16(crc16(0, p, len));
-			count = kiss_esc_crc(p, ax->xbuff, crc, len+2);
-			break;
-		case CRC_MODE_FLEX_TEST:
-			ax->crcmode = CRC_MODE_NONE;
-			printk(KERN_INFO "mkiss: %s: Trying crc-flexnet\n", ax->dev->name);
-			fallthrough;
-		case CRC_MODE_FLEX:
-			*p |= 0x20;
-			crc = calc_crc_flex(p, len);
-			count = kiss_esc_crc(p, ax->xbuff, crc, len+2);
-			break;
-
-		default:
-			count = kiss_esc(p, ax->xbuff, len);
-		}
-	}
-	spin_unlock_bh(&ax->buflock);
-
-	set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
-	actual = ax->tty->ops->write(ax->tty, ax->xbuff, count);
-	dev->stats.tx_packets++;
-	dev->stats.tx_bytes += actual;
-
-	netif_trans_update(ax->dev);
-	ax->xleft = count - actual;
-	ax->xhead = ax->xbuff + actual;
-}
-
-/* Encapsulate an AX.25 packet and kick it into a TTY queue. */
-static netdev_tx_t ax_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct mkiss *ax = netdev_priv(dev);
-
-	if (skb->protocol == htons(ETH_P_IP))
-		return ax25_ip_xmit(skb);
-
-	if (!netif_running(dev))  {
-		printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name);
-		return NETDEV_TX_BUSY;
-	}
-
-	if (netif_queue_stopped(dev)) {
-		/*
-		 * May be we must check transmitter timeout here ?
-		 *      14 Oct 1994 Dmitry Gorodchanin.
-		 */
-		if (time_before(jiffies, dev_trans_start(dev) + 20 * HZ)) {
-			/* 20 sec timeout not reached */
-			return NETDEV_TX_BUSY;
-		}
-
-		printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name,
-		       (tty_chars_in_buffer(ax->tty) || ax->xleft) ?
-		       "bad line quality" : "driver error");
-
-		ax->xleft = 0;
-		clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
-		netif_start_queue(dev);
-	}
-
-	/* We were not busy, so we are now... :-) */
-	netif_stop_queue(dev);
-	ax_encaps(dev, skb->data, skb->len);
-	kfree_skb(skb);
-
-	return NETDEV_TX_OK;
-}
-
-static int ax_open_dev(struct net_device *dev)
-{
-	struct mkiss *ax = netdev_priv(dev);
-
-	if (ax->tty == NULL)
-		return -ENODEV;
-
-	return 0;
-}
-
-/* Open the low-level part of the AX25 channel. Easy! */
-static int ax_open(struct net_device *dev)
-{
-	struct mkiss *ax = netdev_priv(dev);
-	unsigned long len;
-
-	if (ax->tty == NULL)
-		return -ENODEV;
-
-	/*
-	 * Allocate the frame buffers:
-	 *
-	 * rbuff	Receive buffer.
-	 * xbuff	Transmit buffer.
-	 */
-	len = dev->mtu * 2;
-
-	/*
-	 * allow for arrival of larger UDP packets, even if we say not to
-	 * also fixes a bug in which SunOS sends 512-byte packets even with
-	 * an MSS of 128
-	 */
-	if (len < 576 * 2)
-		len = 576 * 2;
-
-	if ((ax->rbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL)
-		goto norbuff;
-
-	if ((ax->xbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL)
-		goto noxbuff;
-
-	ax->mtu	     = dev->mtu + 73;
-	ax->buffsize = len;
-	ax->rcount   = 0;
-	ax->xleft    = 0;
-
-	ax->flags   &= (1 << AXF_INUSE);      /* Clear ESCAPE & ERROR flags */
-
-	spin_lock_init(&ax->buflock);
-
-	return 0;
-
-noxbuff:
-	kfree(ax->rbuff);
-
-norbuff:
-	return -ENOMEM;
-}
-
-
-/* Close the low-level part of the AX25 channel. Easy! */
-static int ax_close(struct net_device *dev)
-{
-	struct mkiss *ax = netdev_priv(dev);
-
-	if (ax->tty)
-		clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
-
-	netif_stop_queue(dev);
-
-	return 0;
-}
-
-static const struct net_device_ops ax_netdev_ops = {
-	.ndo_open            = ax_open_dev,
-	.ndo_stop            = ax_close,
-	.ndo_start_xmit	     = ax_xmit,
-	.ndo_set_mac_address = ax_set_mac_address,
-};
-
-static void ax_setup(struct net_device *dev)
-{
-	/* Finish setting up the DEVICE info. */
-	dev->mtu             = AX_MTU;
-	dev->hard_header_len = AX25_MAX_HEADER_LEN;
-	dev->addr_len        = AX25_ADDR_LEN;
-	dev->type            = ARPHRD_AX25;
-	dev->tx_queue_len    = 10;
-	dev->header_ops      = &ax25_header_ops;
-	dev->netdev_ops	     = &ax_netdev_ops;
-
-
-	memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
-	dev_addr_set(dev, (u8 *)&ax25_defaddr);
-
-	dev->flags      = IFF_BROADCAST | IFF_MULTICAST;
-}
-
-/*
- * We have a potential race on dereferencing tty->disc_data, because the tty
- * layer provides no locking at all - thus one cpu could be running
- * sixpack_receive_buf while another calls sixpack_close, which zeroes
- * tty->disc_data and frees the memory that sixpack_receive_buf is using.  The
- * best way to fix this is to use a rwlock in the tty struct, but for now we
- * use a single global rwlock for all ttys in ppp line discipline.
- */
-static DEFINE_RWLOCK(disc_data_lock);
-
-static struct mkiss *mkiss_get(struct tty_struct *tty)
-{
-	struct mkiss *ax;
-
-	read_lock(&disc_data_lock);
-	ax = tty->disc_data;
-	if (ax)
-		refcount_inc(&ax->refcnt);
-	read_unlock(&disc_data_lock);
-
-	return ax;
-}
-
-static void mkiss_put(struct mkiss *ax)
-{
-	if (refcount_dec_and_test(&ax->refcnt))
-		complete(&ax->dead);
-}
-
-static int crc_force = 0;	/* Can be overridden with insmod */
-
-static int mkiss_open(struct tty_struct *tty)
-{
-	struct net_device *dev;
-	struct mkiss *ax;
-	int err;
-
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-	if (tty->ops->write == NULL)
-		return -EOPNOTSUPP;
-
-	dev = alloc_netdev(sizeof(struct mkiss), "ax%d", NET_NAME_UNKNOWN,
-			   ax_setup);
-	if (!dev) {
-		err = -ENOMEM;
-		goto out;
-	}
-
-	ax = netdev_priv(dev);
-	ax->dev = dev;
-
-	spin_lock_init(&ax->buflock);
-	refcount_set(&ax->refcnt, 1);
-	init_completion(&ax->dead);
-
-	ax->tty = tty;
-	tty->disc_data = ax;
-	tty->receive_room = 65535;
-
-	tty_driver_flush_buffer(tty);
-
-	/* Restore default settings */
-	dev->type = ARPHRD_AX25;
-
-	/* Perform the low-level AX25 initialization. */
-	err = ax_open(ax->dev);
-	if (err)
-		goto out_free_netdev;
-
-	err = register_netdev(dev);
-	if (err)
-		goto out_free_buffers;
-
-	/* after register_netdev() - because else printk smashes the kernel */
-	switch (crc_force) {
-	case 3:
-		ax->crcmode  = CRC_MODE_SMACK;
-		printk(KERN_INFO "mkiss: %s: crc mode smack forced.\n",
-		       ax->dev->name);
-		break;
-	case 2:
-		ax->crcmode  = CRC_MODE_FLEX;
-		printk(KERN_INFO "mkiss: %s: crc mode flexnet forced.\n",
-		       ax->dev->name);
-		break;
-	case 1:
-		ax->crcmode  = CRC_MODE_NONE;
-		printk(KERN_INFO "mkiss: %s: crc mode disabled.\n",
-		       ax->dev->name);
-		break;
-	case 0:
-	default:
-		crc_force = 0;
-		printk(KERN_INFO "mkiss: %s: crc mode is auto.\n",
-		       ax->dev->name);
-		ax->crcmode  = CRC_MODE_SMACK_TEST;
-	}
-	ax->crcauto = (crc_force ? 0 : 1);
-
-	netif_start_queue(dev);
-
-	/* Done.  We have linked the TTY line to a channel. */
-	return 0;
-
-out_free_buffers:
-	kfree(ax->rbuff);
-	kfree(ax->xbuff);
-
-out_free_netdev:
-	free_netdev(dev);
-
-out:
-	return err;
-}
-
-static void mkiss_close(struct tty_struct *tty)
-{
-	struct mkiss *ax;
-
-	write_lock_irq(&disc_data_lock);
-	ax = tty->disc_data;
-	tty->disc_data = NULL;
-	write_unlock_irq(&disc_data_lock);
-
-	if (!ax)
-		return;
-
-	/*
-	 * We have now ensured that nobody can start using ap from now on, but
-	 * we have to wait for all existing users to finish.
-	 */
-	if (!refcount_dec_and_test(&ax->refcnt))
-		wait_for_completion(&ax->dead);
-	/*
-	 * Halt the transmit queue so that a new transmit cannot scribble
-	 * on our buffers
-	 */
-	netif_stop_queue(ax->dev);
-
-	unregister_netdev(ax->dev);
-
-	/* Free all AX25 frame buffers after unreg. */
-	kfree(ax->rbuff);
-	kfree(ax->xbuff);
-
-	ax->tty = NULL;
-
-	free_netdev(ax->dev);
-}
-
-/* Perform I/O control on an active ax25 channel. */
-static int mkiss_ioctl(struct tty_struct *tty, unsigned int cmd,
-		unsigned long arg)
-{
-	struct mkiss *ax = mkiss_get(tty);
-	struct net_device *dev;
-	unsigned int tmp, err;
-
-	/* First make sure we're connected. */
-	if (ax == NULL)
-		return -ENXIO;
-	dev = ax->dev;
-
-	switch (cmd) {
-	case SIOCGIFNAME:
-		err = copy_to_user((void __user *) arg, ax->dev->name,
-		                   strlen(ax->dev->name) + 1) ? -EFAULT : 0;
-		break;
-
-	case SIOCGIFENCAP:
-		err = put_user(4, (int __user *) arg);
-		break;
-
-	case SIOCSIFENCAP:
-		if (get_user(tmp, (int __user *) arg)) {
-			err = -EFAULT;
-			break;
-		}
-
-		ax->mode = tmp;
-		dev->addr_len        = AX25_ADDR_LEN;
-		dev->hard_header_len = AX25_KISS_HEADER_LEN +
-		                       AX25_MAX_HEADER_LEN + 3;
-		dev->type            = ARPHRD_AX25;
-
-		err = 0;
-		break;
-
-	case SIOCSIFHWADDR: {
-		char addr[AX25_ADDR_LEN];
-
-		if (copy_from_user(&addr,
-		                   (void __user *) arg, AX25_ADDR_LEN)) {
-			err = -EFAULT;
-			break;
-		}
-
-		netif_tx_lock_bh(dev);
-		__dev_addr_set(dev, addr, AX25_ADDR_LEN);
-		netif_tx_unlock_bh(dev);
-
-		err = 0;
-		break;
-	}
-	default:
-		err = -ENOIOCTLCMD;
-	}
-
-	mkiss_put(ax);
-
-	return err;
-}
-
-/*
- * Handle the 'receiver data ready' interrupt.
- * This function is called by the 'tty_io' module in the kernel when
- * a block of data has been received, which can now be decapsulated
- * and sent on to the AX.25 layer for further processing.
- */
-static void mkiss_receive_buf(struct tty_struct *tty, const u8 *cp,
-			      const u8 *fp, size_t count)
-{
-	struct mkiss *ax = mkiss_get(tty);
-
-	if (!ax)
-		return;
-
-	/*
-	 * Argh! mtu change time! - costs us the packet part received
-	 * at the change
-	 */
-	if (ax->mtu != ax->dev->mtu + 73)
-		ax_changedmtu(ax);
-
-	/* Read the characters out of the buffer */
-	while (count--) {
-		if (fp != NULL && *fp++) {
-			if (!test_and_set_bit(AXF_ERROR, &ax->flags))
-				ax->dev->stats.rx_errors++;
-			cp++;
-			continue;
-		}
-
-		kiss_unesc(ax, *cp++);
-	}
-
-	mkiss_put(ax);
-	tty_unthrottle(tty);
-}
-
-/*
- * Called by the driver when there's room for more data.  If we have
- * more packets to send, we send them here.
- */
-static void mkiss_write_wakeup(struct tty_struct *tty)
-{
-	struct mkiss *ax = mkiss_get(tty);
-	int actual;
-
-	if (!ax)
-		return;
-
-	if (ax->xleft <= 0)  {
-		/* Now serial buffer is almost free & we can start
-		 * transmission of another packet
-		 */
-		clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-
-		netif_wake_queue(ax->dev);
-		goto out;
-	}
-
-	actual = tty->ops->write(tty, ax->xhead, ax->xleft);
-	ax->xleft -= actual;
-	ax->xhead += actual;
-
-out:
-	mkiss_put(ax);
-}
-
-static struct tty_ldisc_ops ax_ldisc = {
-	.owner		= THIS_MODULE,
-	.num		= N_AX25,
-	.name		= "mkiss",
-	.open		= mkiss_open,
-	.close		= mkiss_close,
-	.ioctl		= mkiss_ioctl,
-	.receive_buf	= mkiss_receive_buf,
-	.write_wakeup	= mkiss_write_wakeup
-};
-
-static const char banner[] __initconst = KERN_INFO \
-	"mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n";
-static const char msg_regfail[] __initconst = KERN_ERR \
-	"mkiss: can't register line discipline (err = %d)\n";
-
-static int __init mkiss_init_driver(void)
-{
-	int status;
-
-	printk(banner);
-
-	status = tty_register_ldisc(&ax_ldisc);
-	if (status != 0)
-		printk(msg_regfail, status);
-
-	return status;
-}
-
-static void __exit mkiss_exit_driver(void)
-{
-	tty_unregister_ldisc(&ax_ldisc);
-}
-
-MODULE_AUTHOR("Ralf Baechle DL5RB <ralf@linux-mips.org>");
-MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs");
-module_param(crc_force, int, 0);
-MODULE_PARM_DESC(crc_force, "crc [0 = auto | 1 = none | 2 = flexnet | 3 = smack]");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_LDISC(N_AX25);
-
-module_init(mkiss_init_driver);
-module_exit(mkiss_exit_driver);
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
deleted file mode 100644
index 8569db4a7140..000000000000
--- a/drivers/net/hamradio/scc.c
+++ /dev/null
@@ -1,2179 +0,0 @@
-#define RCS_ID "$Id: scc.c,v 1.75 1998/11/04 15:15:01 jreuter Exp jreuter $"
-
-#define VERSION "3.0"
-
-/*
- * Please use z8530drv-utils-3.0 with this version.
- *            ------------------
- *
- * You can find a subset of the documentation in 
- * Documentation/networking/device_drivers/hamradio/z8530drv.rst.
- */
-
-/*
-   ********************************************************************
-   *   SCC.C - Linux driver for Z8530 based HDLC cards for AX.25      *
-   ********************************************************************
-
-
-   ********************************************************************
-
-	Copyright (c) 1993, 2000 Joerg Reuter DL1BKE
-
-	portions (c) 1993 Guido ten Dolle PE1NNZ
-
-   ********************************************************************
-   
-   The driver and the programs in the archive are UNDER CONSTRUCTION.
-   The code is likely to fail, and so your kernel could --- even 
-   a whole network. 
-
-   This driver is intended for Amateur Radio use. If you are running it
-   for commercial purposes, please drop me a note. I am nosy...
-
-   ...BUT:
- 
-   ! You  m u s t  recognize the appropriate legislations of your country !
-   ! before you connect a radio to the SCC board and start to transmit or !
-   ! receive. The GPL allows you to use the  d r i v e r,  NOT the RADIO! !
-
-   For non-Amateur-Radio use please note that you might need a special
-   allowance/licence from the designer of the SCC Board and/or the
-   MODEM. 
-
-   This program is free software; you can redistribute it and/or modify 
-   it under the terms of the (modified) GNU General Public License 
-   delivered with the Linux kernel source.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should find a copy of the GNU General Public License in 
-   /usr/src/linux/COPYING; 
-   
-   ******************************************************************** 
-
-		
-   Incomplete history of z8530drv:
-   -------------------------------
-
-   1994-09-13	started to write the driver, rescued most of my own
-		code (and Hans Alblas' memory buffer pool concept) from 
-		an earlier project "sccdrv" which was initiated by 
-		Guido ten Dolle. Not much of the old driver survived, 
-		though. The first version I put my hands on was sccdrv1.3
-		from August 1993. The memory buffer pool concept
-		appeared in an unauthorized sccdrv version (1.5) from
-		August 1994.
-
-   1995-01-31	changed copyright notice to GPL without limitations.
-   
-     .
-     .	<SNIP>
-     .
-   		  
-   1996-10-05	New semester, new driver... 
-
-   		  * KISS TNC emulator removed (TTY driver)
-   		  * Source moved to drivers/net/
-   		  * Includes Z8530 defines from drivers/net/z8530.h
-   		  * Uses sk_buffer memory management
-   		  * Reduced overhead of /proc/net/z8530drv output
-   		  * Streamlined quite a lot things
-   		  * Invents brand new bugs... ;-)
-
-   		  The move to version number 3.0 reflects theses changes.
-   		  You can use 'kissbridge' if you need a KISS TNC emulator.
-
-   1996-12-13	Fixed for Linux networking changes. (G4KLX)
-   1997-01-08	Fixed the remaining problems.
-   1997-04-02	Hopefully fixed the problems with the new *_timer()
-   		routines, added calibration code.
-   1997-10-12	Made SCC_DELAY a CONFIG option, added CONFIG_SCC_TRXECHO
-   1998-01-29	Small fix to avoid lock-up on initialization
-   1998-09-29	Fixed the "grouping" bugs, tx_inhibit works again,
-   		using dev->tx_queue_len now instead of MAXQUEUE now.
-   1998-10-21	Postponed the spinlock changes, would need a lot of
-   		testing I currently don't have the time to. Softdcd doesn't
-   		work.
-   1998-11-04	Softdcd does not work correctly in DPLL mode, in fact it 
-   		never did. The DPLL locks on noise, the SYNC unit sees
-   		flags that aren't... Restarting the DPLL does not help
-   		either, it resynchronizes too slow and the first received
-   		frame gets lost.
-   2000-02-13	Fixed for new network driver interface changes, still
-   		does TX timeouts itself since it uses its own queue
-   		scheme.
-
-   Thanks to all who contributed to this driver with ideas and bug
-   reports!
-   
-   NB -- if you find errors, change something, please let me know
-      	 first before you distribute it... And please don't touch
-   	 the version number. Just replace my callsign in
-   	 "v3.0.dl1bke" with your own. Just to avoid confusion...
-
-   If you want to add your modification to the linux distribution
-   please (!) contact me first.
-   
-   New versions of the driver will be announced on the linux-hams
-   mailing list on vger.kernel.org. To subscribe send an e-mail
-   to majordomo@vger.kernel.org with the following line in
-   the body of the mail:
-   
-	   subscribe linux-hams
-	   
-   The content of the "Subject" field will be ignored.
-
-   vy 73,
-   Joerg Reuter	ampr-net: dl1bke@db0pra.ampr.org
-		AX-25   : DL1BKE @ DB0ABH.#BAY.DEU.EU
-		Internet: jreuter@yaina.de
-		www     : http://yaina.de/jreuter
-*/
-
-/* ----------------------------------------------------------------------- */
-
-#undef  SCC_LDELAY		/* slow it even a bit more down */
-#undef  SCC_DONT_CHECK		/* don't look if the SCCs you specified are available */
-
-#define SCC_MAXCHIPS	4       /* number of max. supported chips */
-#define SCC_BUFSIZE	384     /* must not exceed 4096 */
-#undef	SCC_DEBUG
-
-#define SCC_DEFAULT_CLOCK	4915200 
-				/* default pclock if nothing is specified */
-
-/* ----------------------------------------------------------------------- */
-
-#include <linux/compat.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/in.h>
-#include <linux/fcntl.h>
-#include <linux/ptrace.h>
-#include <linux/delay.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/rtnetlink.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <linux/socket.h>
-#include <linux/init.h>
-#include <linux/scc.h>
-#include <linux/ctype.h>
-#include <linux/kernel.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/bitops.h>
-
-#include <net/net_namespace.h>
-#include <net/ax25.h>
-
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <linux/uaccess.h>
-
-#include "z8530.h"
-
-static const char banner[] __initconst = KERN_INFO \
-	"AX.25: Z8530 SCC driver version "VERSION".dl1bke\n";
-
-static void t_dwait(struct timer_list *t);
-static void t_txdelay(struct timer_list *t);
-static void t_tail(struct timer_list *t);
-static void t_busy(struct timer_list *);
-static void t_maxkeyup(struct timer_list *);
-static void t_idle(struct timer_list *t);
-static void scc_tx_done(struct scc_channel *);
-static void scc_start_tx_timer(struct scc_channel *,
-			       void (*)(struct timer_list *), unsigned long);
-static void scc_start_maxkeyup(struct scc_channel *);
-static void scc_start_defer(struct scc_channel *);
-
-static void z8530_init(void);
-
-static void init_channel(struct scc_channel *scc);
-static void scc_key_trx (struct scc_channel *scc, char tx);
-static void scc_init_timer(struct scc_channel *scc);
-
-static int scc_net_alloc(const char *name, struct scc_channel *scc);
-static void scc_net_setup(struct net_device *dev);
-static int scc_net_open(struct net_device *dev);
-static int scc_net_close(struct net_device *dev);
-static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb);
-static netdev_tx_t scc_net_tx(struct sk_buff *skb,
-			      struct net_device *dev);
-static int scc_net_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
-				  void __user *data, int cmd);
-static int scc_net_set_mac_address(struct net_device *dev, void *addr);
-static struct net_device_stats * scc_net_get_stats(struct net_device *dev);
-
-static unsigned char SCC_DriverName[] = "scc";
-
-static struct irqflags { unsigned char used : 1; } Ivec[NR_IRQS];
-	
-static struct scc_channel SCC_Info[2 * SCC_MAXCHIPS];	/* information per channel */
-
-static struct scc_ctrl {
-	io_port chan_A;
-	io_port chan_B;
-	int irq;
-} SCC_ctrl[SCC_MAXCHIPS+1];
-
-static unsigned char Driver_Initialized;
-static int Nchips;
-static io_port Vector_Latch;
-
-
-/* ******************************************************************** */
-/* *			Port Access Functions			      * */
-/* ******************************************************************** */
-
-/* These provide interrupt save 2-step access to the Z8530 registers */
-
-static DEFINE_SPINLOCK(iolock);	/* Guards paired accesses */
-
-static inline unsigned char InReg(io_port port, unsigned char reg)
-{
-	unsigned long flags;
-	unsigned char r;
-
-	spin_lock_irqsave(&iolock, flags);	
-#ifdef SCC_LDELAY
-	Outb(port, reg);
-	udelay(SCC_LDELAY);
-	r=Inb(port);
-	udelay(SCC_LDELAY);
-#else
-	Outb(port, reg);
-	r=Inb(port);
-#endif
-	spin_unlock_irqrestore(&iolock, flags);
-	return r;
-}
-
-static inline void OutReg(io_port port, unsigned char reg, unsigned char val)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&iolock, flags);
-#ifdef SCC_LDELAY
-	Outb(port, reg); udelay(SCC_LDELAY);
-	Outb(port, val); udelay(SCC_LDELAY);
-#else
-	Outb(port, reg);
-	Outb(port, val);
-#endif
-	spin_unlock_irqrestore(&iolock, flags);
-}
-
-static inline void wr(struct scc_channel *scc, unsigned char reg,
-	unsigned char val)
-{
-	OutReg(scc->ctrl, reg, (scc->wreg[reg] = val));
-}
-
-static inline void or(struct scc_channel *scc, unsigned char reg, unsigned char val)
-{
-	OutReg(scc->ctrl, reg, (scc->wreg[reg] |= val));
-}
-
-static inline void cl(struct scc_channel *scc, unsigned char reg, unsigned char val)
-{
-	OutReg(scc->ctrl, reg, (scc->wreg[reg] &= ~val));
-}
-
-/* ******************************************************************** */
-/* *			Some useful macros			      * */
-/* ******************************************************************** */
-
-static inline void scc_discard_buffers(struct scc_channel *scc)
-{
-	unsigned long flags;
-	
-	spin_lock_irqsave(&scc->lock, flags);	
-	if (scc->tx_buff != NULL)
-	{
-		dev_kfree_skb_irq(scc->tx_buff);
-		scc->tx_buff = NULL;
-	}
-	
-	while (!skb_queue_empty(&scc->tx_queue))
-		dev_kfree_skb_irq(skb_dequeue(&scc->tx_queue));
-
-	spin_unlock_irqrestore(&scc->lock, flags);
-}
-
-
-
-/* ******************************************************************** */
-/* *			Interrupt Service Routines		      * */
-/* ******************************************************************** */
-
-
-/* ----> subroutines for the interrupt handlers <---- */
-
-static inline void scc_notify(struct scc_channel *scc, int event)
-{
-	struct sk_buff *skb;
-	char *bp;
-	
-        if (scc->kiss.fulldup != KISS_DUPLEX_OPTIMA)
-		return;
-
-	skb = dev_alloc_skb(2);
-	if (skb != NULL)
-	{
-		bp = skb_put(skb, 2);
-		*bp++ = PARAM_HWEVENT;
-		*bp++ = event;
-		scc_net_rx(scc, skb);
-	} else
-		scc->stat.nospace++;
-}
-
-static inline void flush_rx_FIFO(struct scc_channel *scc)
-{
-	int k;
-	
-	for (k=0; k<3; k++)
-		Inb(scc->data);
-		
-	if(scc->rx_buff != NULL)		/* did we receive something? */
-	{
-		scc->stat.rxerrs++;  /* then count it as an error */
-		dev_kfree_skb_irq(scc->rx_buff);
-		scc->rx_buff = NULL;
-	}
-}
-
-static void start_hunt(struct scc_channel *scc)
-{
-	if ((scc->modem.clocksrc != CLK_EXTERNAL))
-		OutReg(scc->ctrl,R14,SEARCH|scc->wreg[R14]); /* DPLL: enter search mode */
-	or(scc,R3,ENT_HM|RxENABLE);  /* enable the receiver, hunt mode */
-}
-
-/* ----> four different interrupt handlers for Tx, Rx, changing of	*/
-/*       DCD/CTS and Rx/Tx errors					*/
-
-/* Transmitter interrupt handler */
-static inline void scc_txint(struct scc_channel *scc)
-{
-	struct sk_buff *skb;
-
-	scc->stat.txints++;
-	skb = scc->tx_buff;
-	
-	/* send first octet */
-	
-	if (skb == NULL)
-	{
-		skb = skb_dequeue(&scc->tx_queue);
-		scc->tx_buff = skb;
-		netif_wake_queue(scc->dev);
-
-		if (skb == NULL)
-		{
-			scc_tx_done(scc);
-			Outb(scc->ctrl, RES_Tx_P);
-			return;
-		}
-		
-		if (skb->len == 0)		/* Paranoia... */
-		{
-			dev_kfree_skb_irq(skb);
-			scc->tx_buff = NULL;
-			scc_tx_done(scc);
-			Outb(scc->ctrl, RES_Tx_P);
-			return;
-		}
-
-		scc->stat.tx_state = TXS_ACTIVE;
-
-		OutReg(scc->ctrl, R0, RES_Tx_CRC);
-						/* reset CRC generator */
-		or(scc,R10,ABUNDER);		/* re-install underrun protection */
-		Outb(scc->data,*skb->data);	/* send byte */
-		skb_pull(skb, 1);
-
-		if (!scc->enhanced)		/* reset EOM latch */
-			Outb(scc->ctrl,RES_EOM_L);
-		return;
-	}
-	
-	/* End Of Frame... */
-	
-	if (skb->len == 0)
-	{
-		Outb(scc->ctrl, RES_Tx_P);	/* reset pending int */
-		cl(scc, R10, ABUNDER);		/* send CRC */
-		dev_kfree_skb_irq(skb);
-		scc->tx_buff = NULL;
-		scc->stat.tx_state = TXS_NEWFRAME; /* next frame... */
-		return;
-	} 
-	
-	/* send octet */
-	
-	Outb(scc->data,*skb->data);		
-	skb_pull(skb, 1);
-}
-
-
-/* External/Status interrupt handler */
-static inline void scc_exint(struct scc_channel *scc)
-{
-	unsigned char status,changes,chg_and_stat;
-
-	scc->stat.exints++;
-
-	status = InReg(scc->ctrl,R0);
-	changes = status ^ scc->status;
-	chg_and_stat = changes & status;
-	
-	/* ABORT: generated whenever DCD drops while receiving */
-
-	if (chg_and_stat & BRK_ABRT)		/* Received an ABORT */
-		flush_rx_FIFO(scc);
-
-	/* HUNT: software DCD; on = waiting for SYNC, off = receiving frame */
-
-	if ((changes & SYNC_HUNT) && scc->kiss.softdcd)
-	{
-		if (status & SYNC_HUNT)
-		{
-			scc->dcd = 0;
-			flush_rx_FIFO(scc);
-			if ((scc->modem.clocksrc != CLK_EXTERNAL))
-				OutReg(scc->ctrl,R14,SEARCH|scc->wreg[R14]); /* DPLL: enter search mode */
-		} else {
-			scc->dcd = 1;
-		}
-
-		scc_notify(scc, scc->dcd? HWEV_DCD_OFF:HWEV_DCD_ON);
-	}
-
-	/* DCD: on = start to receive packet, off = ABORT condition */
-	/* (a successfully received packet generates a special condition int) */
-	
-	if((changes & DCD) && !scc->kiss.softdcd) /* DCD input changed state */
-	{
-		if(status & DCD)                /* DCD is now ON */
-		{
-			start_hunt(scc);
-			scc->dcd = 1;
-		} else {                        /* DCD is now OFF */
-			cl(scc,R3,ENT_HM|RxENABLE); /* disable the receiver */
-			flush_rx_FIFO(scc);
-			scc->dcd = 0;
-		}
-		
-		scc_notify(scc, scc->dcd? HWEV_DCD_ON:HWEV_DCD_OFF);
-	}
-
-#ifdef notdef
-	/* CTS: use external TxDelay (what's that good for?!)
-	 * Anyway: If we _could_ use it (BayCom USCC uses CTS for
-	 * own purposes) we _should_ use the "autoenable" feature
-	 * of the Z8530 and not this interrupt...
-	 */
-	 
-	if (chg_and_stat & CTS)			/* CTS is now ON */
-	{
-		if (scc->kiss.txdelay == 0)	/* zero TXDELAY = wait for CTS */
-			scc_start_tx_timer(scc, t_txdelay, 0);
-	}
-#endif
-	
-	if (scc->stat.tx_state == TXS_ACTIVE && (status & TxEOM))
-	{
-		scc->stat.tx_under++;	  /* oops, an underrun! count 'em */
-		Outb(scc->ctrl, RES_EXT_INT);	/* reset ext/status interrupts */
-
-		if (scc->tx_buff != NULL)
-		{
-			dev_kfree_skb_irq(scc->tx_buff);
-			scc->tx_buff = NULL;
-		}
-		
-		or(scc,R10,ABUNDER);
-		scc_start_tx_timer(scc, t_txdelay, 0);	/* restart transmission */
-	}
-		
-	scc->status = status;
-	Outb(scc->ctrl,RES_EXT_INT);
-}
-
-
-/* Receiver interrupt handler */
-static inline void scc_rxint(struct scc_channel *scc)
-{
-	struct sk_buff *skb;
-
-	scc->stat.rxints++;
-
-	if((scc->wreg[5] & RTS) && scc->kiss.fulldup == KISS_DUPLEX_HALF)
-	{
-		Inb(scc->data);		/* discard char */
-		or(scc,R3,ENT_HM);	/* enter hunt mode for next flag */
-		return;
-	}
-
-	skb = scc->rx_buff;
-	
-	if (skb == NULL)
-	{
-		skb = dev_alloc_skb(scc->stat.bufsize);
-		if (skb == NULL)
-		{
-			scc->dev_stat.rx_dropped++;
-			scc->stat.nospace++;
-			Inb(scc->data);
-			or(scc, R3, ENT_HM);
-			return;
-		}
-		
-		scc->rx_buff = skb;
-		skb_put_u8(skb, 0);	/* KISS data */
-	}
-	
-	if (skb->len >= scc->stat.bufsize)
-	{
-#ifdef notdef
-		printk(KERN_DEBUG "z8530drv: oops, scc_rxint() received huge frame...\n");
-#endif
-		dev_kfree_skb_irq(skb);
-		scc->rx_buff = NULL;
-		Inb(scc->data);
-		or(scc, R3, ENT_HM);
-		return;
-	}
-
-	skb_put_u8(skb, Inb(scc->data));
-}
-
-
-/* Receive Special Condition interrupt handler */
-static inline void scc_spint(struct scc_channel *scc)
-{
-	unsigned char status;
-	struct sk_buff *skb;
-
-	scc->stat.spints++;
-
-	status = InReg(scc->ctrl,R1);		/* read receiver status */
-	
-	Inb(scc->data);				/* throw away Rx byte */
-	skb = scc->rx_buff;
-
-	if(status & Rx_OVR)			/* receiver overrun */
-	{
-		scc->stat.rx_over++;             /* count them */
-		or(scc,R3,ENT_HM);               /* enter hunt mode for next flag */
-		
-		if (skb != NULL) 
-			dev_kfree_skb_irq(skb);
-		scc->rx_buff = skb = NULL;
-	}
-
-	if(status & END_FR && skb != NULL)	/* end of frame */
-	{
-		/* CRC okay, frame ends on 8 bit boundary and received something ? */
-		
-		if (!(status & CRC_ERR) && (status & 0xe) == RES8 && skb->len > 0)
-		{
-			/* ignore last received byte (first of the CRC bytes) */
-			skb_trim(skb, skb->len-1);
-			scc_net_rx(scc, skb);
-			scc->rx_buff = NULL;
-			scc->stat.rxframes++;
-		} else {				/* a bad frame */
-			dev_kfree_skb_irq(skb);
-			scc->rx_buff = NULL;
-			scc->stat.rxerrs++;
-		}
-	} 
-
-	Outb(scc->ctrl,ERR_RES);
-}
-
-
-/* ----> interrupt service routine for the Z8530 <---- */
-
-static void scc_isr_dispatch(struct scc_channel *scc, int vector)
-{
-	spin_lock(&scc->lock);
-	switch (vector & VECTOR_MASK)
-	{
-		case TXINT: scc_txint(scc); break;
-		case EXINT: scc_exint(scc); break;
-		case RXINT: scc_rxint(scc); break;
-		case SPINT: scc_spint(scc); break;
-	}
-	spin_unlock(&scc->lock);
-}
-
-/* If the card has a latch for the interrupt vector (like the PA0HZP card)
-   use it to get the number of the chip that generated the int.
-   If not: poll all defined chips.
- */
-
-#define SCC_IRQTIMEOUT 30000
-
-static irqreturn_t scc_isr(int irq, void *dev_id)
-{
-	int chip_irq = (long) dev_id;
-	unsigned char vector;	
-	struct scc_channel *scc;
-	struct scc_ctrl *ctrl;
-	int k;
-	
-	if (Vector_Latch)
-	{
-	    	for(k=0; k < SCC_IRQTIMEOUT; k++)
-    		{
-			Outb(Vector_Latch, 0);      /* Generate INTACK */
-        
-			/* Read the vector */
-			if((vector=Inb(Vector_Latch)) >= 16 * Nchips) break; 
-			if (vector & 0x01) break;
-        	 
-		        scc=&SCC_Info[vector >> 3 ^ 0x01];
-			if (!scc->dev) break;
-
-			scc_isr_dispatch(scc, vector);
-
-			OutReg(scc->ctrl,R0,RES_H_IUS);              /* Reset Highest IUS */
-		}  
-
-		if (k == SCC_IRQTIMEOUT)
-			printk(KERN_WARNING "z8530drv: endless loop in scc_isr()?\n");
-
-		return IRQ_HANDLED;
-	}
-
-	/* Find the SCC generating the interrupt by polling all attached SCCs
-	 * reading RR3A (the interrupt pending register)
-	 */
-
-	ctrl = SCC_ctrl;
-	while (ctrl->chan_A)
-	{
-		if (ctrl->irq != chip_irq)
-		{
-			ctrl++;
-			continue;
-		}
-
-		scc = NULL;
-		for (k = 0; InReg(ctrl->chan_A,R3) && k < SCC_IRQTIMEOUT; k++)
-		{
-			vector=InReg(ctrl->chan_B,R2);	/* Read the vector */
-			if (vector & 0x01) break; 
-
-			scc = &SCC_Info[vector >> 3 ^ 0x01];
-		        if (!scc->dev) break;
-
-			scc_isr_dispatch(scc, vector);
-		}
-
-		if (k == SCC_IRQTIMEOUT)
-		{
-			printk(KERN_WARNING "z8530drv: endless loop in scc_isr()?!\n");
-			break;
-		}
-
-		/* This looks weird and it is. At least the BayCom USCC doesn't
-		 * use the Interrupt Daisy Chain, thus we'll have to start
-		 * all over again to be sure not to miss an interrupt from 
-		 * (any of) the other chip(s)...
-		 * Honestly, the situation *is* braindamaged...
-		 */
-
-		if (scc != NULL)
-		{
-			OutReg(scc->ctrl,R0,RES_H_IUS);
-			ctrl = SCC_ctrl; 
-		} else
-			ctrl++;
-	}
-	return IRQ_HANDLED;
-}
-
-
-
-/* ******************************************************************** */
-/* *			Init Channel					*/
-/* ******************************************************************** */
-
-
-/* ----> set SCC channel speed <---- */
-
-static inline void set_brg(struct scc_channel *scc, unsigned int tc)
-{
-	cl(scc,R14,BRENABL);		/* disable baudrate generator */
-	wr(scc,R12,tc & 255);		/* brg rate LOW */
-	wr(scc,R13,tc >> 8);   		/* brg rate HIGH */
-	or(scc,R14,BRENABL);		/* enable baudrate generator */
-}
-
-static inline void set_speed(struct scc_channel *scc)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&scc->lock, flags);
-
-	if (scc->modem.speed > 0)	/* paranoia... */
-		set_brg(scc, (unsigned) (scc->clock / (scc->modem.speed * 64)) - 2);
-		
-	spin_unlock_irqrestore(&scc->lock, flags);
-}
-
-
-/* ----> initialize a SCC channel <---- */
-
-static inline void init_brg(struct scc_channel *scc)
-{
-	wr(scc, R14, BRSRC);				/* BRG source = PCLK */
-	OutReg(scc->ctrl, R14, SSBR|scc->wreg[R14]);	/* DPLL source = BRG */
-	OutReg(scc->ctrl, R14, SNRZI|scc->wreg[R14]);	/* DPLL NRZI mode */
-}
-
-/*
- * Initialization according to the Z8530 manual (SGS-Thomson's version):
- *
- * 1. Modes and constants
- *
- * WR9	11000000	chip reset
- * WR4	XXXXXXXX	Tx/Rx control, async or sync mode
- * WR1	0XX00X00	select W/REQ (optional)
- * WR2	XXXXXXXX	program interrupt vector
- * WR3	XXXXXXX0	select Rx control
- * WR5	XXXX0XXX	select Tx control
- * WR6	XXXXXXXX	sync character
- * WR7	XXXXXXXX	sync character
- * WR9	000X0XXX	select interrupt control
- * WR10	XXXXXXXX	miscellaneous control (optional)
- * WR11	XXXXXXXX	clock control
- * WR12	XXXXXXXX	time constant lower byte (optional)
- * WR13	XXXXXXXX	time constant upper byte (optional)
- * WR14	XXXXXXX0	miscellaneous control
- * WR14	XXXSSSSS	commands (optional)
- *
- * 2. Enables
- *
- * WR14	000SSSS1	baud rate enable
- * WR3	SSSSSSS1	Rx enable
- * WR5	SSSS1SSS	Tx enable
- * WR0	10000000	reset Tx CRG (optional)
- * WR1	XSS00S00	DMA enable (optional)
- *
- * 3. Interrupt status
- *
- * WR15	XXXXXXXX	enable external/status
- * WR0	00010000	reset external status
- * WR0	00010000	reset external status twice
- * WR1	SSSXXSXX	enable Rx, Tx and Ext/status
- * WR9	000SXSSS	enable master interrupt enable
- *
- * 1 = set to one, 0 = reset to zero
- * X = user defined, S = same as previous init
- *
- *
- * Note that the implementation differs in some points from above scheme.
- *
- */
- 
-static void init_channel(struct scc_channel *scc)
-{
-	timer_delete(&scc->tx_t);
-	timer_delete(&scc->tx_wdog);
-
-	disable_irq(scc->irq);
-
-	wr(scc,R4,X1CLK|SDLC);		/* *1 clock, SDLC mode */
-	wr(scc,R1,0);			/* no W/REQ operation */
-	wr(scc,R3,Rx8|RxCRC_ENAB);	/* RX 8 bits/char, CRC, disabled */	
-	wr(scc,R5,Tx8|DTR|TxCRC_ENAB);	/* TX 8 bits/char, disabled, DTR */
-	wr(scc,R6,0);			/* SDLC address zero (not used) */
-	wr(scc,R7,FLAG);		/* SDLC flag value */
-	wr(scc,R9,VIS);			/* vector includes status */
-	wr(scc,R10,(scc->modem.nrz? NRZ : NRZI)|CRCPS|ABUNDER); /* abort on underrun, preset CRC generator, NRZ(I) */
-	wr(scc,R14, 0);
-
-
-/* set clock sources:
-
-   CLK_DPLL: normal halfduplex operation
-   
-		RxClk: use DPLL
-		TxClk: use DPLL
-		TRxC mode DPLL output
-		
-   CLK_EXTERNAL: external clocking (G3RUH or DF9IC modem)
-   
-  	        BayCom: 		others:
-  	        
-  	        TxClk = pin RTxC	TxClk = pin TRxC
-  	        RxClk = pin TRxC 	RxClk = pin RTxC
-  	     
-
-   CLK_DIVIDER:
-   		RxClk = use DPLL
-   		TxClk = pin RTxC
-   		
-   		BayCom:			others:
-   		pin TRxC = DPLL		pin TRxC = BRG
-   		(RxClk * 1)		(RxClk * 32)
-*/  
-
-   		
-	switch(scc->modem.clocksrc)
-	{
-		case CLK_DPLL:
-			wr(scc, R11, RCDPLL|TCDPLL|TRxCOI|TRxCDP);
-			init_brg(scc);
-			break;
-
-		case CLK_DIVIDER:
-			wr(scc, R11, ((scc->brand & BAYCOM)? TRxCDP : TRxCBR) | RCDPLL|TCRTxCP|TRxCOI);
-			init_brg(scc);
-			break;
-
-		case CLK_EXTERNAL:
-			wr(scc, R11, (scc->brand & BAYCOM)? RCTRxCP|TCRTxCP : RCRTxCP|TCTRxCP);
-			OutReg(scc->ctrl, R14, DISDPLL);
-			break;
-
-	}
-	
-	set_speed(scc);			/* set baudrate */
-	
-	if(scc->enhanced)
-	{
-		or(scc,R15,SHDLCE|FIFOE);	/* enable FIFO, SDLC/HDLC Enhancements (From now R7 is R7') */
-		wr(scc,R7,AUTOEOM);
-	}
-
-	if(scc->kiss.softdcd || (InReg(scc->ctrl,R0) & DCD))
-						/* DCD is now ON */
-	{
-		start_hunt(scc);
-	}
-	
-	/* enable ABORT, DCD & SYNC/HUNT interrupts */
-
-	wr(scc,R15, BRKIE|TxUIE|(scc->kiss.softdcd? SYNCIE:DCDIE));
-
-	Outb(scc->ctrl,RES_EXT_INT);	/* reset ext/status interrupts */
-	Outb(scc->ctrl,RES_EXT_INT);	/* must be done twice */
-
-	or(scc,R1,INT_ALL_Rx|TxINT_ENAB|EXT_INT_ENAB); /* enable interrupts */
-	
-	scc->status = InReg(scc->ctrl,R0);	/* read initial status */
-	
-	or(scc,R9,MIE);			/* master interrupt enable */
-	
-	scc_init_timer(scc);
-			
-	enable_irq(scc->irq);
-}
-
-
-
-
-/* ******************************************************************** */
-/* *			SCC timer functions			      * */
-/* ******************************************************************** */
-
-
-/* ----> scc_key_trx sets the time constant for the baudrate 
-         generator and keys the transmitter		     <---- */
-
-static void scc_key_trx(struct scc_channel *scc, char tx)
-{
-	unsigned int time_const;
-		
-	if (scc->brand & PRIMUS)
-		Outb(scc->ctrl + 4, scc->option | (tx? 0x80 : 0));
-
-	if (scc->modem.speed < 300) 
-		scc->modem.speed = 1200;
-
-	time_const = (unsigned) (scc->clock / (scc->modem.speed * (tx? 2:64))) - 2;
-
-	disable_irq(scc->irq);
-
-	if (tx)
-	{
-		or(scc, R1, TxINT_ENAB);	/* t_maxkeyup may have reset these */
-		or(scc, R15, TxUIE);
-	}
-
-	if (scc->modem.clocksrc == CLK_DPLL)
-	{				/* force simplex operation */
-		if (tx)
-		{
-#ifdef CONFIG_SCC_TRXECHO
-			cl(scc, R3, RxENABLE|ENT_HM);	/* switch off receiver */
-			cl(scc, R15, DCDIE|SYNCIE);	/* No DCD changes, please */
-#endif
-			set_brg(scc, time_const);	/* reprogram baudrate generator */
-
-			/* DPLL -> Rx clk, BRG -> Tx CLK, TRxC mode output, TRxC = BRG */
-			wr(scc, R11, RCDPLL|TCBR|TRxCOI|TRxCBR);
-			
-			/* By popular demand: tx_inhibit */
-			if (scc->kiss.tx_inhibit)
-			{
-				or(scc,R5, TxENAB);
-				scc->wreg[R5] |= RTS;
-			} else {
-				or(scc,R5,RTS|TxENAB);	/* set the RTS line and enable TX */
-			}
-		} else {
-			cl(scc,R5,RTS|TxENAB);
-			
-			set_brg(scc, time_const);	/* reprogram baudrate generator */
-			
-			/* DPLL -> Rx clk, DPLL -> Tx CLK, TRxC mode output, TRxC = DPLL */
-			wr(scc, R11, RCDPLL|TCDPLL|TRxCOI|TRxCDP);
-
-#ifndef CONFIG_SCC_TRXECHO
-			if (scc->kiss.softdcd)
-#endif
-			{
-				or(scc,R15, scc->kiss.softdcd? SYNCIE:DCDIE);
-				start_hunt(scc);
-			}
-		}
-	} else {
-		if (tx)
-		{
-#ifdef CONFIG_SCC_TRXECHO
-			if (scc->kiss.fulldup == KISS_DUPLEX_HALF)
-			{
-				cl(scc, R3, RxENABLE);
-				cl(scc, R15, DCDIE|SYNCIE);
-			}
-#endif
-				
-			if (scc->kiss.tx_inhibit)
-			{
-				or(scc,R5, TxENAB);
-				scc->wreg[R5] |= RTS;
-			} else {	
-				or(scc,R5,RTS|TxENAB);	/* enable tx */
-			}
-		} else {
-			cl(scc,R5,RTS|TxENAB);		/* disable tx */
-
-			if ((scc->kiss.fulldup == KISS_DUPLEX_HALF) &&
-#ifndef CONFIG_SCC_TRXECHO
-			    scc->kiss.softdcd)
-#else
-			    1)
-#endif
-			{
-				or(scc, R15, scc->kiss.softdcd? SYNCIE:DCDIE);
-				start_hunt(scc);
-			}
-		}
-	}
-
-	enable_irq(scc->irq);
-}
-
-
-/* ----> SCC timer interrupt handler and friends. <---- */
-
-static void __scc_start_tx_timer(struct scc_channel *scc,
-				 void (*handler)(struct timer_list *t),
-				 unsigned long when)
-{
-	timer_delete(&scc->tx_t);
-
-	if (when == 0)
-	{
-		handler(&scc->tx_t);
-	} else 
-	if (when != TIMER_OFF)
-	{
-		scc->tx_t.function = handler;
-		scc->tx_t.expires = jiffies + (when*HZ)/100;
-		add_timer(&scc->tx_t);
-	}
-}
-
-static void scc_start_tx_timer(struct scc_channel *scc,
-			       void (*handler)(struct timer_list *t),
-			       unsigned long when)
-{
-	unsigned long flags;
-	
-	spin_lock_irqsave(&scc->lock, flags);
-	__scc_start_tx_timer(scc, handler, when);
-	spin_unlock_irqrestore(&scc->lock, flags);
-}
-
-static void scc_start_defer(struct scc_channel *scc)
-{
-	unsigned long flags;
-	
-	spin_lock_irqsave(&scc->lock, flags);
-	timer_delete(&scc->tx_wdog);
-	
-	if (scc->kiss.maxdefer != 0 && scc->kiss.maxdefer != TIMER_OFF)
-	{
-		scc->tx_wdog.function = t_busy;
-		scc->tx_wdog.expires = jiffies + HZ*scc->kiss.maxdefer;
-		add_timer(&scc->tx_wdog);
-	}
-	spin_unlock_irqrestore(&scc->lock, flags);
-}
-
-static void scc_start_maxkeyup(struct scc_channel *scc)
-{
-	unsigned long flags;
-	
-	spin_lock_irqsave(&scc->lock, flags);
-	timer_delete(&scc->tx_wdog);
-	
-	if (scc->kiss.maxkeyup != 0 && scc->kiss.maxkeyup != TIMER_OFF)
-	{
-		scc->tx_wdog.function = t_maxkeyup;
-		scc->tx_wdog.expires = jiffies + HZ*scc->kiss.maxkeyup;
-		add_timer(&scc->tx_wdog);
-	}
-	spin_unlock_irqrestore(&scc->lock, flags);
-}
-
-/* 
- * This is called from scc_txint() when there are no more frames to send.
- * Not exactly a timer function, but it is a close friend of the family...
- */
-
-static void scc_tx_done(struct scc_channel *scc)
-{
-	/* 
-	 * trx remains keyed in fulldup mode 2 until t_idle expires.
-	 */
-				 
-	switch (scc->kiss.fulldup)
-	{
-		case KISS_DUPLEX_LINK:
-			scc->stat.tx_state = TXS_IDLE2;
-			if (scc->kiss.idletime != TIMER_OFF)
-				scc_start_tx_timer(scc, t_idle,
-						   scc->kiss.idletime*100);
-			break;
-		case KISS_DUPLEX_OPTIMA:
-			scc_notify(scc, HWEV_ALL_SENT);
-			break;
-		default:
-			scc->stat.tx_state = TXS_BUSY;
-			scc_start_tx_timer(scc, t_tail, scc->kiss.tailtime);
-	}
-
-	netif_wake_queue(scc->dev);
-}
-
-
-static unsigned char Rand = 17;
-
-static inline int is_grouped(struct scc_channel *scc)
-{
-	int k;
-	struct scc_channel *scc2;
-	unsigned char grp1, grp2;
-
-	grp1 = scc->kiss.group;
-	
-	for (k = 0; k < (Nchips * 2); k++)
-	{
-		scc2 = &SCC_Info[k];
-		grp2 = scc2->kiss.group;
-		
-		if (scc2 == scc || !(scc2->dev && grp2))
-			continue;
-		
-		if ((grp1 & 0x3f) == (grp2 & 0x3f))
-		{
-			if ( (grp1 & TXGROUP) && (scc2->wreg[R5] & RTS) )
-				return 1;
-			
-			if ( (grp1 & RXGROUP) && scc2->dcd )
-				return 1;
-		}
-	}
-	return 0;
-}
-
-/* DWAIT and SLOTTIME expired
- *
- * fulldup == 0:  DCD is active or Rand > P-persistence: start t_busy timer
- *                else key trx and start txdelay
- * fulldup == 1:  key trx and start txdelay
- * fulldup == 2:  mintime expired, reset status or key trx and start txdelay
- */
-
-static void t_dwait(struct timer_list *t)
-{
-	struct scc_channel *scc = timer_container_of(scc, t, tx_t);
-	
-	if (scc->stat.tx_state == TXS_WAIT)	/* maxkeyup or idle timeout */
-	{
-		if (skb_queue_empty(&scc->tx_queue)) {	/* nothing to send */
-			scc->stat.tx_state = TXS_IDLE;
-			netif_wake_queue(scc->dev);	/* t_maxkeyup locked it. */
-			return;
-		}
-
-		scc->stat.tx_state = TXS_BUSY;
-	}
-
-	if (scc->kiss.fulldup == KISS_DUPLEX_HALF)
-	{
-		Rand = Rand * 17 + 31;
-		
-		if (scc->dcd || (scc->kiss.persist) < Rand || (scc->kiss.group && is_grouped(scc)) )
-		{
-			scc_start_defer(scc);
-			scc_start_tx_timer(scc, t_dwait, scc->kiss.slottime);
-			return ;
-		}
-	}
-
-	if ( !(scc->wreg[R5] & RTS) )
-	{
-		scc_key_trx(scc, TX_ON);
-		scc_start_tx_timer(scc, t_txdelay, scc->kiss.txdelay);
-	} else {
-		scc_start_tx_timer(scc, t_txdelay, 0);
-	}
-}
-
-
-/* TXDELAY expired
- *
- * kick transmission by a fake scc_txint(scc), start 'maxkeyup' watchdog.
- */
-
-static void t_txdelay(struct timer_list *t)
-{
-	struct scc_channel *scc = timer_container_of(scc, t, tx_t);
-
-	scc_start_maxkeyup(scc);
-
-	if (scc->tx_buff == NULL)
-	{
-		disable_irq(scc->irq);
-		scc_txint(scc);	
-		enable_irq(scc->irq);
-	}
-}
-	
-
-/* TAILTIME expired
- *
- * switch off transmitter. If we were stopped by Maxkeyup restart
- * transmission after 'mintime' seconds
- */
-
-static void t_tail(struct timer_list *t)
-{
-	struct scc_channel *scc = timer_container_of(scc, t, tx_t);
-	unsigned long flags;
-	
-	spin_lock_irqsave(&scc->lock, flags); 
-	timer_delete(&scc->tx_wdog);
-	scc_key_trx(scc, TX_OFF);
-	spin_unlock_irqrestore(&scc->lock, flags);
-
-	if (scc->stat.tx_state == TXS_TIMEOUT)		/* we had a timeout? */
-	{
-		scc->stat.tx_state = TXS_WAIT;
-		scc_start_tx_timer(scc, t_dwait, scc->kiss.mintime*100);
-		return;
-	}
-
-	scc->stat.tx_state = TXS_IDLE;
-	netif_wake_queue(scc->dev);
-}
-
-
-/* BUSY timeout
- *
- * throw away send buffers if DCD remains active too long.
- */
-
-static void t_busy(struct timer_list *t)
-{
-	struct scc_channel *scc = timer_container_of(scc, t, tx_wdog);
-
-	timer_delete(&scc->tx_t);
-	netif_stop_queue(scc->dev);	/* don't pile on the wabbit! */
-
-	scc_discard_buffers(scc);
-	scc->stat.txerrs++;
-	scc->stat.tx_state = TXS_IDLE;
-
-	netif_wake_queue(scc->dev);	
-}
-
-/* MAXKEYUP timeout
- *
- * this is our watchdog.
- */
-
-static void t_maxkeyup(struct timer_list *t)
-{
-	struct scc_channel *scc = timer_container_of(scc, t, tx_wdog);
-	unsigned long flags;
-
-	spin_lock_irqsave(&scc->lock, flags);
-	/* 
-	 * let things settle down before we start to
-	 * accept new data.
-	 */
-
-	netif_stop_queue(scc->dev);
-	scc_discard_buffers(scc);
-
-	timer_delete(&scc->tx_t);
-
-	cl(scc, R1, TxINT_ENAB);	/* force an ABORT, but don't */
-	cl(scc, R15, TxUIE);		/* count it. */
-	OutReg(scc->ctrl, R0, RES_Tx_P);
-
-	spin_unlock_irqrestore(&scc->lock, flags);
-
-	scc->stat.txerrs++;
-	scc->stat.tx_state = TXS_TIMEOUT;
-	scc_start_tx_timer(scc, t_tail, scc->kiss.tailtime);
-}
-
-/* IDLE timeout
- *
- * in fulldup mode 2 it keys down the transmitter after 'idle' seconds
- * of inactivity. We will not restart transmission before 'mintime'
- * expires.
- */
-
-static void t_idle(struct timer_list *t)
-{
-	struct scc_channel *scc = timer_container_of(scc, t, tx_t);
-	
-	timer_delete(&scc->tx_wdog);
-
-	scc_key_trx(scc, TX_OFF);
-	if(scc->kiss.mintime)
-		scc_start_tx_timer(scc, t_dwait, scc->kiss.mintime*100);
-	scc->stat.tx_state = TXS_WAIT;
-}
-
-static void scc_init_timer(struct scc_channel *scc)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&scc->lock, flags);	
-	scc->stat.tx_state = TXS_IDLE;
-	spin_unlock_irqrestore(&scc->lock, flags);
-}
-
-
-/* ******************************************************************** */
-/* *			Set/get L1 parameters			      * */
-/* ******************************************************************** */
-
-
-/*
- * this will set the "hardware" parameters through KISS commands or ioctl()
- */
-
-#define CAST(x) (unsigned long)(x)
-
-static unsigned int scc_set_param(struct scc_channel *scc, unsigned int cmd, unsigned int arg)
-{
-	switch (cmd)
-	{
-		case PARAM_TXDELAY:	scc->kiss.txdelay=arg;		break;
-		case PARAM_PERSIST:	scc->kiss.persist=arg;		break;
-		case PARAM_SLOTTIME:	scc->kiss.slottime=arg;		break;
-		case PARAM_TXTAIL:	scc->kiss.tailtime=arg;		break;
-		case PARAM_FULLDUP:	scc->kiss.fulldup=arg;		break;
-		case PARAM_DTR:		break; /* does someone need this? */
-		case PARAM_GROUP:	scc->kiss.group=arg;		break;
-		case PARAM_IDLE:	scc->kiss.idletime=arg;		break;
-		case PARAM_MIN:		scc->kiss.mintime=arg;		break;
-		case PARAM_MAXKEY:	scc->kiss.maxkeyup=arg;		break;
-		case PARAM_WAIT:	scc->kiss.waittime=arg;		break;
-		case PARAM_MAXDEFER:	scc->kiss.maxdefer=arg;		break;
-		case PARAM_TX:		scc->kiss.tx_inhibit=arg;	break;
-
-		case PARAM_SOFTDCD:	
-			scc->kiss.softdcd=arg;
-			if (arg)
-			{
-				or(scc, R15, SYNCIE);
-				cl(scc, R15, DCDIE);
-				start_hunt(scc);
-			} else {
-				or(scc, R15, DCDIE);
-				cl(scc, R15, SYNCIE);
-			}
-			break;
-				
-		case PARAM_SPEED:
-			if (arg < 256)
-				scc->modem.speed=arg*100;
-			else
-				scc->modem.speed=arg;
-
-			if (scc->stat.tx_state == 0)	/* only switch baudrate on rx... ;-) */
-				set_speed(scc);
-			break;
-			
-		case PARAM_RTS:	
-			if ( !(scc->wreg[R5] & RTS) )
-			{
-				if (arg != TX_OFF) {
-					scc_key_trx(scc, TX_ON);
-					scc_start_tx_timer(scc, t_txdelay, scc->kiss.txdelay);
-				}
-			} else {
-				if (arg == TX_OFF)
-				{
-					scc->stat.tx_state = TXS_BUSY;
-					scc_start_tx_timer(scc, t_tail, scc->kiss.tailtime);
-				}
-			}
-			break;
-			
-		case PARAM_HWEVENT:
-			scc_notify(scc, scc->dcd? HWEV_DCD_ON:HWEV_DCD_OFF);
-			break;
-
-		default:		return -EINVAL;
-	}
-	
-	return 0;
-}
-
-
- 
-static unsigned long scc_get_param(struct scc_channel *scc, unsigned int cmd)
-{
-	switch (cmd)
-	{
-		case PARAM_TXDELAY:	return CAST(scc->kiss.txdelay);
-		case PARAM_PERSIST:	return CAST(scc->kiss.persist);
-		case PARAM_SLOTTIME:	return CAST(scc->kiss.slottime);
-		case PARAM_TXTAIL:	return CAST(scc->kiss.tailtime);
-		case PARAM_FULLDUP:	return CAST(scc->kiss.fulldup);
-		case PARAM_SOFTDCD:	return CAST(scc->kiss.softdcd);
-		case PARAM_DTR:		return CAST((scc->wreg[R5] & DTR)? 1:0);
-		case PARAM_RTS:		return CAST((scc->wreg[R5] & RTS)? 1:0);
-		case PARAM_SPEED:	return CAST(scc->modem.speed);
-		case PARAM_GROUP:	return CAST(scc->kiss.group);
-		case PARAM_IDLE:	return CAST(scc->kiss.idletime);
-		case PARAM_MIN:		return CAST(scc->kiss.mintime);
-		case PARAM_MAXKEY:	return CAST(scc->kiss.maxkeyup);
-		case PARAM_WAIT:	return CAST(scc->kiss.waittime);
-		case PARAM_MAXDEFER:	return CAST(scc->kiss.maxdefer);
-		case PARAM_TX:		return CAST(scc->kiss.tx_inhibit);
-		default:		return NO_SUCH_PARAM;
-	}
-
-}
-
-#undef CAST
-
-/* ******************************************************************* */
-/* *			Send calibration pattern		     * */
-/* ******************************************************************* */
-
-static void scc_stop_calibrate(struct timer_list *t)
-{
-	struct scc_channel *scc = timer_container_of(scc, t, tx_wdog);
-	unsigned long flags;
-	
-	spin_lock_irqsave(&scc->lock, flags);
-	timer_delete(&scc->tx_wdog);
-	scc_key_trx(scc, TX_OFF);
-	wr(scc, R6, 0);
-	wr(scc, R7, FLAG);
-	Outb(scc->ctrl,RES_EXT_INT);	/* reset ext/status interrupts */
-	Outb(scc->ctrl,RES_EXT_INT);
-
-	netif_wake_queue(scc->dev);
-	spin_unlock_irqrestore(&scc->lock, flags);
-}
-
-
-static void
-scc_start_calibrate(struct scc_channel *scc, int duration, unsigned char pattern)
-{
-	unsigned long flags;
-	
-	spin_lock_irqsave(&scc->lock, flags);
-	netif_stop_queue(scc->dev);
-	scc_discard_buffers(scc);
-
-	timer_delete(&scc->tx_wdog);
-
-	scc->tx_wdog.function = scc_stop_calibrate;
-	scc->tx_wdog.expires = jiffies + HZ*duration;
-	add_timer(&scc->tx_wdog);
-
-	/* This doesn't seem to work. Why not? */	
-	wr(scc, R6, 0);
-	wr(scc, R7, pattern);
-
-	/* 
-	 * Don't know if this works. 
-	 * Damn, where is my Z8530 programming manual...? 
-	 */
-
-	Outb(scc->ctrl,RES_EXT_INT);	/* reset ext/status interrupts */
-	Outb(scc->ctrl,RES_EXT_INT);
-
-	scc_key_trx(scc, TX_ON);
-	spin_unlock_irqrestore(&scc->lock, flags);
-}
-
-/* ******************************************************************* */
-/* *		Init channel structures, special HW, etc...	     * */
-/* ******************************************************************* */
-
-/*
- * Reset the Z8530s and setup special hardware
- */
-
-static void z8530_init(void)
-{
-	const unsigned int nr_irqs = irq_get_nr_irqs();
-	struct scc_channel *scc;
-	int chip, k;
-	unsigned long flags;
-	char *flag;
-
-
-	printk(KERN_INFO "Init Z8530 driver: %u channels, IRQ", Nchips*2);
-	
-	flag=" ";
-	for (k = 0; k < nr_irqs; k++)
-		if (Ivec[k].used) 
-		{
-			printk("%s%d", flag, k);
-			flag=",";
-		}
-	printk("\n");
-
-
-	/* reset and pre-init all chips in the system */
-	for (chip = 0; chip < Nchips; chip++)
-	{
-		scc=&SCC_Info[2*chip];
-		if (!scc->ctrl) continue;
-
-		/* Special SCC cards */
-
-		if(scc->brand & EAGLE)			/* this is an EAGLE card */
-			Outb(scc->special,0x08);	/* enable interrupt on the board */
-			
-		if(scc->brand & (PC100 | PRIMUS))	/* this is a PC100/PRIMUS card */
-			Outb(scc->special,scc->option);	/* set the MODEM mode (0x22) */
-
-			
-		/* Reset and pre-init Z8530 */
-
-		spin_lock_irqsave(&scc->lock, flags);
-				
-		Outb(scc->ctrl, 0);
-		OutReg(scc->ctrl,R9,FHWRES);		/* force hardware reset */
-		udelay(100);				/* give it 'a bit' more time than required */
-		wr(scc, R2, chip*16);			/* interrupt vector */
-		wr(scc, R9, VIS);			/* vector includes status */
-		spin_unlock_irqrestore(&scc->lock, flags);		
-        }
-
- 
-	Driver_Initialized = 1;
-}
-
-/*
- * Allocate device structure, err, instance, and register driver
- */
-
-static int scc_net_alloc(const char *name, struct scc_channel *scc)
-{
-	int err;
-	struct net_device *dev;
-
-	dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, scc_net_setup);
-	if (!dev) 
-		return -ENOMEM;
-
-	dev->ml_priv = scc;
-	scc->dev = dev;
-	spin_lock_init(&scc->lock);
-	timer_setup(&scc->tx_t, NULL, 0);
-	timer_setup(&scc->tx_wdog, NULL, 0);
-
-	err = register_netdevice(dev);
-	if (err) {
-		printk(KERN_ERR "%s: can't register network device (%d)\n", 
-		       name, err);
-		free_netdev(dev);
-		scc->dev = NULL;
-		return err;
-	}
-
-	return 0;
-}
-
-
-
-/* ******************************************************************** */
-/* *			    Network driver methods		      * */
-/* ******************************************************************** */
-
-static const struct net_device_ops scc_netdev_ops = {
-	.ndo_open            = scc_net_open,
-	.ndo_stop	     = scc_net_close,
-	.ndo_start_xmit	     = scc_net_tx,
-	.ndo_set_mac_address = scc_net_set_mac_address,
-	.ndo_get_stats       = scc_net_get_stats,
-	.ndo_siocdevprivate  = scc_net_siocdevprivate,
-};
-
-/* ----> Initialize device <----- */
-
-static void scc_net_setup(struct net_device *dev)
-{
-	dev->tx_queue_len    = 16;	/* should be enough... */
-
-	dev->netdev_ops	     = &scc_netdev_ops;
-	dev->header_ops      = &ax25_header_ops;
-
-	dev->flags      = 0;
-
-	dev->type = ARPHRD_AX25;
-	dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
-	dev->mtu = AX25_DEF_PACLEN;
-	dev->addr_len = AX25_ADDR_LEN;
-
-	memcpy(dev->broadcast, &ax25_bcast,  AX25_ADDR_LEN);
-	dev_addr_set(dev, (u8 *)&ax25_defaddr);
-}
-
-/* ----> open network device <---- */
-
-static int scc_net_open(struct net_device *dev)
-{
-	struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
-
-	if (!scc->init)
-		return -EINVAL;
-
-	scc->tx_buff = NULL;
-	skb_queue_head_init(&scc->tx_queue);
- 
-	init_channel(scc);
-
-	netif_start_queue(dev);
-	return 0;
-}
-
-/* ----> close network device <---- */
-
-static int scc_net_close(struct net_device *dev)
-{
-	struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
-	unsigned long flags;
-
-	netif_stop_queue(dev);
-
-	spin_lock_irqsave(&scc->lock, flags);	
-	Outb(scc->ctrl,0);		/* Make sure pointer is written */
-	wr(scc,R1,0);			/* disable interrupts */
-	wr(scc,R3,0);
-	spin_unlock_irqrestore(&scc->lock, flags);
-
-	timer_delete_sync(&scc->tx_t);
-	timer_delete_sync(&scc->tx_wdog);
-	
-	scc_discard_buffers(scc);
-
-	return 0;
-}
-
-/* ----> receive frame, called from scc_rxint() <---- */
-
-static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb)
-{
-	if (skb->len == 0) {
-		dev_kfree_skb_irq(skb);
-		return;
-	}
-		
-	scc->dev_stat.rx_packets++;
-	scc->dev_stat.rx_bytes += skb->len;
-
-	skb->protocol = ax25_type_trans(skb, scc->dev);
-	
-	netif_rx(skb);
-}
-
-/* ----> transmit frame <---- */
-
-static netdev_tx_t scc_net_tx(struct sk_buff *skb, struct net_device *dev)
-{
-	struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
-	unsigned long flags;
-	char kisscmd;
-
-	if (skb->protocol == htons(ETH_P_IP))
-		return ax25_ip_xmit(skb);
-
-	if (skb->len > scc->stat.bufsize || skb->len < 2) {
-		scc->dev_stat.tx_dropped++;	/* bogus frame */
-		dev_kfree_skb(skb);
-		return NETDEV_TX_OK;
-	}
-	
-	scc->dev_stat.tx_packets++;
-	scc->dev_stat.tx_bytes += skb->len;
-	scc->stat.txframes++;
-	
-	kisscmd = *skb->data & 0x1f;
-	skb_pull(skb, 1);
-
-	if (kisscmd) {
-		scc_set_param(scc, kisscmd, *skb->data);
-		dev_kfree_skb(skb);
-		return NETDEV_TX_OK;
-	}
-
-	spin_lock_irqsave(&scc->lock, flags);
-		
-	if (skb_queue_len(&scc->tx_queue) > scc->dev->tx_queue_len) {
-		struct sk_buff *skb_del;
-		skb_del = skb_dequeue(&scc->tx_queue);
-		dev_kfree_skb_irq(skb_del);
-	}
-	skb_queue_tail(&scc->tx_queue, skb);
-	netif_trans_update(dev);
-	
-
-	/*
-	 * Start transmission if the trx state is idle or
-	 * t_idle hasn't expired yet. Use dwait/persistence/slottime
-	 * algorithm for normal halfduplex operation.
-	 */
-
-	if(scc->stat.tx_state == TXS_IDLE || scc->stat.tx_state == TXS_IDLE2) {
-		scc->stat.tx_state = TXS_BUSY;
-		if (scc->kiss.fulldup == KISS_DUPLEX_HALF)
-			__scc_start_tx_timer(scc, t_dwait, scc->kiss.waittime);
-		else
-			__scc_start_tx_timer(scc, t_dwait, 0);
-	}
-	spin_unlock_irqrestore(&scc->lock, flags);
-	return NETDEV_TX_OK;
-}
-
-/* ----> ioctl functions <---- */
-
-/*
- * SIOCSCCCFG		- configure driver	arg: (struct scc_hw_config *) arg
- * SIOCSCCINI		- initialize driver	arg: ---
- * SIOCSCCCHANINI	- initialize channel	arg: (struct scc_modem *) arg
- * SIOCSCCSMEM		- set memory		arg: (struct scc_mem_config *) arg
- * SIOCSCCGKISS		- get level 1 parameter	arg: (struct scc_kiss_cmd *) arg
- * SIOCSCCSKISS		- set level 1 parameter arg: (struct scc_kiss_cmd *) arg
- * SIOCSCCGSTAT		- get driver status	arg: (struct scc_stat *) arg
- * SIOCSCCCAL		- send calib. pattern	arg: (struct scc_calibrate *) arg
- */
-
-static int scc_net_siocdevprivate(struct net_device *dev,
-				  struct ifreq *ifr, void __user *arg, int cmd)
-{
-	struct scc_kiss_cmd kiss_cmd;
-	struct scc_mem_config memcfg;
-	struct scc_hw_config hwcfg;
-	struct scc_calibrate cal;
-	struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
-	int chan;
-	unsigned char device_name[IFNAMSIZ];
-	
-	if (!Driver_Initialized)
-	{
-		if (cmd == SIOCSCCCFG)
-		{
-			int found = 1;
-
-			if (!capable(CAP_SYS_RAWIO)) return -EPERM;
-			if (in_compat_syscall())
-				return -EOPNOTSUPP;
-
-			if (!arg) return -EFAULT;
-
-			if (Nchips >= SCC_MAXCHIPS) 
-				return -EINVAL;
-
-			if (copy_from_user(&hwcfg, arg, sizeof(hwcfg)))
-				return -EFAULT;
-
-			if (hwcfg.irq == 2) hwcfg.irq = 9;
-
-			if (hwcfg.irq < 0 || hwcfg.irq >= irq_get_nr_irqs())
-				return -EINVAL;
-				
-			if (!Ivec[hwcfg.irq].used && hwcfg.irq)
-			{
-				if (request_irq(hwcfg.irq, scc_isr,
-						0, "AX.25 SCC",
-						(void *)(long) hwcfg.irq))
-					printk(KERN_WARNING "z8530drv: warning, cannot get IRQ %d\n", hwcfg.irq);
-				else
-					Ivec[hwcfg.irq].used = 1;
-			}
-
-			if (hwcfg.vector_latch && !Vector_Latch) {
-				if (!request_region(hwcfg.vector_latch, 1, "scc vector latch"))
-					printk(KERN_WARNING "z8530drv: warning, cannot reserve vector latch port 0x%lx\n, disabled.", hwcfg.vector_latch);
-				else
-					Vector_Latch = hwcfg.vector_latch;
-			}
-
-			if (hwcfg.clock == 0)
-				hwcfg.clock = SCC_DEFAULT_CLOCK;
-
-#ifndef SCC_DONT_CHECK
-
-			if(request_region(hwcfg.ctrl_a, 1, "scc-probe"))
-			{
-				disable_irq(hwcfg.irq);
-				Outb(hwcfg.ctrl_a, 0);
-				OutReg(hwcfg.ctrl_a, R9, FHWRES);
-				udelay(100);
-				OutReg(hwcfg.ctrl_a,R13,0x55);		/* is this chip really there? */
-				udelay(5);
-
-				if (InReg(hwcfg.ctrl_a,R13) != 0x55)
-					found = 0;
-				enable_irq(hwcfg.irq);
-				release_region(hwcfg.ctrl_a, 1);
-			}
-			else
-				found = 0;
-#endif
-
-			if (found)
-			{
-				SCC_Info[2*Nchips  ].ctrl = hwcfg.ctrl_a;
-				SCC_Info[2*Nchips  ].data = hwcfg.data_a;
-				SCC_Info[2*Nchips  ].irq  = hwcfg.irq;
-				SCC_Info[2*Nchips+1].ctrl = hwcfg.ctrl_b;
-				SCC_Info[2*Nchips+1].data = hwcfg.data_b;
-				SCC_Info[2*Nchips+1].irq  = hwcfg.irq;
-			
-				SCC_ctrl[Nchips].chan_A = hwcfg.ctrl_a;
-				SCC_ctrl[Nchips].chan_B = hwcfg.ctrl_b;
-				SCC_ctrl[Nchips].irq    = hwcfg.irq;
-			}
-
-
-			for (chan = 0; chan < 2; chan++)
-			{
-				sprintf(device_name, "%s%i", SCC_DriverName, 2*Nchips+chan);
-
-				SCC_Info[2*Nchips+chan].special = hwcfg.special;
-				SCC_Info[2*Nchips+chan].clock = hwcfg.clock;
-				SCC_Info[2*Nchips+chan].brand = hwcfg.brand;
-				SCC_Info[2*Nchips+chan].option = hwcfg.option;
-				SCC_Info[2*Nchips+chan].enhanced = hwcfg.escc;
-
-#ifdef SCC_DONT_CHECK
-				printk(KERN_INFO "%s: data port = 0x%3.3x  control port = 0x%3.3x\n",
-					device_name, 
-					SCC_Info[2*Nchips+chan].data, 
-					SCC_Info[2*Nchips+chan].ctrl);
-
-#else
-				printk(KERN_INFO "%s: data port = 0x%3.3lx  control port = 0x%3.3lx -- %s\n",
-					device_name,
-					chan? hwcfg.data_b : hwcfg.data_a, 
-					chan? hwcfg.ctrl_b : hwcfg.ctrl_a,
-					found? "found" : "missing");
-#endif
-
-				if (found)
-				{
-					request_region(SCC_Info[2*Nchips+chan].ctrl, 1, "scc ctrl");
-					request_region(SCC_Info[2*Nchips+chan].data, 1, "scc data");
-					if (Nchips+chan != 0 &&
-					    scc_net_alloc(device_name, 
-							  &SCC_Info[2*Nchips+chan]))
-					    return -EINVAL;
-				}
-			}
-			
-			if (found) Nchips++;
-			
-			return 0;
-		}
-		
-		if (cmd == SIOCSCCINI)
-		{
-			if (!capable(CAP_SYS_RAWIO))
-				return -EPERM;
-				
-			if (Nchips == 0)
-				return -EINVAL;
-
-			z8530_init();
-			return 0;
-		}
-		
-		return -EINVAL;	/* confuse the user */
-	}
-	
-	if (!scc->init)
-	{
-		if (cmd == SIOCSCCCHANINI)
-		{
-			if (!capable(CAP_NET_ADMIN)) return -EPERM;
-			if (!arg) return -EINVAL;
-			
-			scc->stat.bufsize   = SCC_BUFSIZE;
-
-			if (copy_from_user(&scc->modem, arg, sizeof(struct scc_modem)))
-				return -EINVAL;
-			
-			/* default KISS Params */
-		
-			if (scc->modem.speed < 4800)
-			{
-				scc->kiss.txdelay = 36;		/* 360 ms */
-				scc->kiss.persist = 42;		/* 25% persistence */			/* was 25 */
-				scc->kiss.slottime = 16;	/* 160 ms */
-				scc->kiss.tailtime = 4;		/* minimal reasonable value */
-				scc->kiss.fulldup = 0;		/* CSMA */
-				scc->kiss.waittime = 50;	/* 500 ms */
-				scc->kiss.maxkeyup = 10;	/* 10 s */
-				scc->kiss.mintime = 3;		/* 3 s */
-				scc->kiss.idletime = 30;	/* 30 s */
-				scc->kiss.maxdefer = 120;	/* 2 min */
-				scc->kiss.softdcd = 0;		/* hardware dcd */
-			} else {
-				scc->kiss.txdelay = 10;		/* 100 ms */
-				scc->kiss.persist = 64;		/* 25% persistence */			/* was 25 */
-				scc->kiss.slottime = 8;		/* 160 ms */
-				scc->kiss.tailtime = 1;		/* minimal reasonable value */
-				scc->kiss.fulldup = 0;		/* CSMA */
-				scc->kiss.waittime = 50;	/* 500 ms */
-				scc->kiss.maxkeyup = 7;		/* 7 s */
-				scc->kiss.mintime = 3;		/* 3 s */
-				scc->kiss.idletime = 30;	/* 30 s */
-				scc->kiss.maxdefer = 120;	/* 2 min */
-				scc->kiss.softdcd = 0;		/* hardware dcd */
-			}
-			
-			scc->tx_buff = NULL;
-			skb_queue_head_init(&scc->tx_queue);
-			scc->init = 1;
-			
-			return 0;
-		}
-		
-		return -EINVAL;
-	}
-	
-	switch(cmd)
-	{
-		case SIOCSCCRESERVED:
-			return -ENOIOCTLCMD;
-
-		case SIOCSCCSMEM:
-			if (!capable(CAP_SYS_RAWIO)) return -EPERM;
-			if (!arg || copy_from_user(&memcfg, arg, sizeof(memcfg)))
-				return -EINVAL;
-			if (memcfg.bufsize < 16)
-				return -EINVAL;
-			scc->stat.bufsize   = memcfg.bufsize;
-			return 0;
-		
-		case SIOCSCCGSTAT:
-			if (!arg || copy_to_user(arg, &scc->stat, sizeof(scc->stat)))
-				return -EINVAL;
-			return 0;
-		
-		case SIOCSCCGKISS:
-			if (!arg || copy_from_user(&kiss_cmd, arg, sizeof(kiss_cmd)))
-				return -EINVAL;
-			kiss_cmd.param = scc_get_param(scc, kiss_cmd.command);
-			if (copy_to_user(arg, &kiss_cmd, sizeof(kiss_cmd)))
-				return -EINVAL;
-			return 0;
-		
-		case SIOCSCCSKISS:
-			if (!capable(CAP_NET_ADMIN)) return -EPERM;
-			if (!arg || copy_from_user(&kiss_cmd, arg, sizeof(kiss_cmd)))
-				return -EINVAL;
-			return scc_set_param(scc, kiss_cmd.command, kiss_cmd.param);
-		
-		case SIOCSCCCAL:
-			if (!capable(CAP_SYS_RAWIO)) return -EPERM;
-			if (!arg || copy_from_user(&cal, arg, sizeof(cal)) || cal.time == 0)
-				return -EINVAL;
-
-			scc_start_calibrate(scc, cal.time, cal.pattern);
-			return 0;
-
-		default:
-			return -ENOIOCTLCMD;
-		
-	}
-	
-	return -EINVAL;
-}
-
-/* ----> set interface callsign <---- */
-
-static int scc_net_set_mac_address(struct net_device *dev, void *addr)
-{
-	struct sockaddr *sa = (struct sockaddr *) addr;
-	dev_addr_set(dev, sa->sa_data);
-	return 0;
-}
-
-/* ----> get statistics <---- */
-
-static struct net_device_stats *scc_net_get_stats(struct net_device *dev)
-{
-	struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
-	
-	scc->dev_stat.rx_errors = scc->stat.rxerrs + scc->stat.rx_over;
-	scc->dev_stat.tx_errors = scc->stat.txerrs + scc->stat.tx_under;
-	scc->dev_stat.rx_fifo_errors = scc->stat.rx_over;
-	scc->dev_stat.tx_fifo_errors = scc->stat.tx_under;
-
-	return &scc->dev_stat;
-}
-
-/* ******************************************************************** */
-/* *		dump statistics to /proc/net/z8530drv		      * */
-/* ******************************************************************** */
-
-#ifdef CONFIG_PROC_FS
-
-static inline struct scc_channel *scc_net_seq_idx(loff_t pos)
-{
-	int k;
-
-	for (k = 0; k < Nchips*2; ++k) {
-		if (!SCC_Info[k].init) 
-			continue;
-		if (pos-- == 0)
-			return &SCC_Info[k];
-	}
-	return NULL;
-}
-
-static void *scc_net_seq_start(struct seq_file *seq, loff_t *pos)
-{
-	return *pos ? scc_net_seq_idx(*pos - 1) : SEQ_START_TOKEN;
-	
-}
-
-static void *scc_net_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	unsigned k;
-	struct scc_channel *scc = v;
-	++*pos;
-	
-	for (k = (v == SEQ_START_TOKEN) ? 0 : (scc - SCC_Info)+1;
-	     k < Nchips*2; ++k) {
-		if (SCC_Info[k].init) 
-			return &SCC_Info[k];
-	}
-	return NULL;
-}
-
-static void scc_net_seq_stop(struct seq_file *seq, void *v)
-{
-}
-
-static int scc_net_seq_show(struct seq_file *seq, void *v)
-{
-	if (v == SEQ_START_TOKEN) {
-		seq_puts(seq, "z8530drv-"VERSION"\n");
-	} else if (!Driver_Initialized) {
-		seq_puts(seq, "not initialized\n");
-	} else if (!Nchips) {
-		seq_puts(seq, "chips missing\n");
-	} else {
-		const struct scc_channel *scc = v;
-		const struct scc_stat *stat = &scc->stat;
-		const struct scc_kiss *kiss = &scc->kiss;
-
-
-		/* dev	data ctrl irq clock brand enh vector special option 
-		 *	baud nrz clocksrc softdcd bufsize
-		 *	rxints txints exints spints
-		 *	rcvd rxerrs over / xmit txerrs under / nospace bufsize
-		 *	txd pers slot tail ful wait min maxk idl defr txof grp
-		 *	W ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
-		 *	R ## ## XX ## ## ## ## ## XX ## ## ## ## ## ## ##
-		 */
-
-		seq_printf(seq, "%s\t%3.3lx %3.3lx %d %lu %2.2x %d %3.3lx %3.3lx %d\n",
-				scc->dev->name,
-				scc->data, scc->ctrl, scc->irq, scc->clock, scc->brand,
-				scc->enhanced, Vector_Latch, scc->special,
-				scc->option);
-		seq_printf(seq, "\t%lu %d %d %d %d\n",
-				scc->modem.speed, scc->modem.nrz,
-				scc->modem.clocksrc, kiss->softdcd,
-				stat->bufsize);
-		seq_printf(seq, "\t%lu %lu %lu %lu\n",
-				stat->rxints, stat->txints, stat->exints, stat->spints);
-		seq_printf(seq, "\t%lu %lu %d / %lu %lu %d / %d %d\n",
-				stat->rxframes, stat->rxerrs, stat->rx_over,
-				stat->txframes, stat->txerrs, stat->tx_under,
-				stat->nospace,  stat->tx_state);
-
-#define K(x) kiss->x
-		seq_printf(seq, "\t%d %d %d %d %d %d %d %d %d %d %d %d\n",
-				K(txdelay), K(persist), K(slottime), K(tailtime),
-				K(fulldup), K(waittime), K(mintime), K(maxkeyup),
-				K(idletime), K(maxdefer), K(tx_inhibit), K(group));
-#undef K
-#ifdef SCC_DEBUG
-		{
-			int reg;
-
-		seq_printf(seq, "\tW ");
-			for (reg = 0; reg < 16; reg++)
-				seq_printf(seq, "%2.2x ", scc->wreg[reg]);
-			seq_printf(seq, "\n");
-			
-		seq_printf(seq, "\tR %2.2x %2.2x XX ", InReg(scc->ctrl,R0), InReg(scc->ctrl,R1));
-			for (reg = 3; reg < 8; reg++)
-				seq_printf(seq, "%2.2x ", InReg(scc->ctrl, reg));
-			seq_printf(seq, "XX ");
-			for (reg = 9; reg < 16; reg++)
-				seq_printf(seq, "%2.2x ", InReg(scc->ctrl, reg));
-			seq_printf(seq, "\n");
-		}
-#endif
-		seq_putc(seq, '\n');
-	}
-
-        return 0;
-}
-
-static const struct seq_operations scc_net_seq_ops = {
-	.start  = scc_net_seq_start,
-	.next   = scc_net_seq_next,
-	.stop   = scc_net_seq_stop,
-	.show   = scc_net_seq_show,
-};
-#endif /* CONFIG_PROC_FS */
-
- 
-/* ******************************************************************** */
-/* * 			Init SCC driver 			      * */
-/* ******************************************************************** */
-
-static int __init scc_init_driver (void)
-{
-	char devname[IFNAMSIZ];
-	
-	printk(banner);
-	
-	sprintf(devname,"%s0", SCC_DriverName);
-	
-	rtnl_lock();
-	if (scc_net_alloc(devname, SCC_Info)) {
-		rtnl_unlock();
-		printk(KERN_ERR "z8530drv: cannot initialize module\n");
-		return -EIO;
-	}
-	rtnl_unlock();
-
-	proc_create_seq("z8530drv", 0, init_net.proc_net, &scc_net_seq_ops);
-
-	return 0;
-}
-
-static void __exit scc_cleanup_driver(void)
-{
-	const unsigned int nr_irqs = irq_get_nr_irqs();
-	io_port ctrl;
-	int k;
-	struct scc_channel *scc;
-	struct net_device *dev;
-	
-	if (Nchips == 0 && (dev = SCC_Info[0].dev)) 
-	{
-		unregister_netdev(dev);
-		free_netdev(dev);
-	}
-
-	/* Guard against chip prattle */
-	local_irq_disable();
-	
-	for (k = 0; k < Nchips; k++)
-		if ( (ctrl = SCC_ctrl[k].chan_A) )
-		{
-			Outb(ctrl, 0);
-			OutReg(ctrl,R9,FHWRES);	/* force hardware reset */
-			udelay(50);
-		}
-		
-	/* To unload the port must be closed so no real IRQ pending */
-	for (k = 0; k < nr_irqs ; k++)
-		if (Ivec[k].used) free_irq(k, NULL);
-		
-	local_irq_enable();
-		
-	/* Now clean up */
-	for (k = 0; k < Nchips*2; k++)
-	{
-		scc = &SCC_Info[k];
-		if (scc->ctrl)
-		{
-			release_region(scc->ctrl, 1);
-			release_region(scc->data, 1);
-		}
-		if (scc->dev)
-		{
-			unregister_netdev(scc->dev);
-			free_netdev(scc->dev);
-		}
-	}
-	
-		
-	if (Vector_Latch)
-		release_region(Vector_Latch, 1);
-
-	remove_proc_entry("z8530drv", init_net.proc_net);
-}
-
-MODULE_AUTHOR("Joerg Reuter <jreuter@yaina.de>");
-MODULE_DESCRIPTION("AX.25 Device Driver for Z8530 based HDLC cards");
-MODULE_LICENSE("GPL");
-module_init(scc_init_driver);
-module_exit(scc_cleanup_driver);
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
deleted file mode 100644
index 4106f0301ab4..000000000000
--- a/drivers/net/hamradio/yam.c
+++ /dev/null
@@ -1,1191 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*****************************************************************************/
-
-/*
- *    yam.c  -- YAM radio modem driver.
- *
- *      Copyright (C) 1998 Frederic Rible F1OAT (frible@teaser.fr)
- *      Adapted from baycom.c driver written by Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *  Please note that the GPL allows you to use the driver, NOT the radio.
- *  In order to use the radio, you need a license from the communications
- *  authority of your country.
- *
- *  History:
- *   0.0 F1OAT 06.06.98  Begin of work with baycom.c source code V 0.3
- *   0.1 F1OAT 07.06.98  Add timer polling routine for channel arbitration
- *   0.2 F6FBB 08.06.98  Added delay after FPGA programming
- *   0.3 F6FBB 29.07.98  Delayed PTT implementation for dupmode=2
- *   0.4 F6FBB 30.07.98  Added TxTail, Slottime and Persistence
- *   0.5 F6FBB 01.08.98  Shared IRQs, /proc/net and network statistics
- *   0.6 F6FBB 25.08.98  Added 1200Bds format
- *   0.7 F6FBB 12.09.98  Added to the kernel configuration
- *   0.8 F6FBB 14.10.98  Fixed slottime/persistence timing bug
- *       OK1ZIA 2.09.01  Fixed "kfree_skb on hard IRQ" 
- *                       using dev_kfree_skb_any(). (important in 2.4 kernel)
- */
-
-/*****************************************************************************/
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/net.h>
-#include <linux/in.h>
-#include <linux/if.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/bitops.h>
-#include <linux/random.h>
-#include <asm/io.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/firmware.h>
-#include <linux/platform_device.h>
-
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <net/ax25.h>
-
-#include <linux/kernel.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <net/net_namespace.h>
-
-#include <linux/uaccess.h>
-#include <linux/init.h>
-
-#include <linux/yam.h>
-
-/* --------------------------------------------------------------------- */
-
-static const char yam_drvname[] = "yam";
-static const char yam_drvinfo[] __initconst = KERN_INFO \
-	"YAM driver version 0.8 by F1OAT/F6FBB\n";
-
-/* --------------------------------------------------------------------- */
-
-#define FIRMWARE_9600	"yam/9600.bin"
-#define FIRMWARE_1200	"yam/1200.bin"
-
-#define YAM_9600	1
-#define YAM_1200	2
-
-#define NR_PORTS	4
-#define YAM_MAGIC	0xF10A7654
-
-/* Transmitter states */
-
-#define TX_OFF		0
-#define TX_HEAD		1
-#define TX_DATA		2
-#define TX_CRC1		3
-#define TX_CRC2		4
-#define TX_TAIL		5
-
-#define YAM_MAX_FRAME	1024
-
-#define DEFAULT_BITRATE	9600			/* bps */
-#define DEFAULT_HOLDD	10			/* sec */
-#define DEFAULT_TXD	300			/* ms */
-#define DEFAULT_TXTAIL	10			/* ms */
-#define DEFAULT_SLOT	100			/* ms */
-#define DEFAULT_PERS	64			/* 0->255 */
-
-struct yam_port {
-	int magic;
-	int bitrate;
-	int baudrate;
-	int iobase;
-	int irq;
-	int dupmode;
-
-	struct net_device *dev;
-
-	int nb_rxint;
-	int nb_mdint;
-
-	/* Parameters section */
-
-	int txd;				/* tx delay */
-	int holdd;				/* duplex ptt delay */
-	int txtail;				/* txtail delay */
-	int slot;				/* slottime */
-	int pers;				/* persistence */
-
-	/* Tx section */
-
-	int tx_state;
-	int tx_count;
-	int slotcnt;
-	unsigned char tx_buf[YAM_MAX_FRAME];
-	int tx_len;
-	int tx_crcl, tx_crch;
-	struct sk_buff_head send_queue;		/* Packets awaiting transmission */
-
-	/* Rx section */
-
-	int dcd;
-	unsigned char rx_buf[YAM_MAX_FRAME];
-	int rx_len;
-	int rx_crcl, rx_crch;
-};
-
-struct yam_mcs {
-	unsigned char bits[YAM_FPGA_SIZE];
-	int bitrate;
-	struct yam_mcs *next;
-};
-
-static struct net_device *yam_devs[NR_PORTS];
-
-static struct yam_mcs *yam_data;
-
-static DEFINE_TIMER(yam_timer, NULL);
-
-/* --------------------------------------------------------------------- */
-
-#define RBR(iobase)	(iobase+0)
-#define THR(iobase)	(iobase+0)
-#define IER(iobase)	(iobase+1)
-#define IIR(iobase)	(iobase+2)
-#define FCR(iobase)	(iobase+2)
-#define LCR(iobase)	(iobase+3)
-#define MCR(iobase)	(iobase+4)
-#define LSR(iobase)	(iobase+5)
-#define MSR(iobase)	(iobase+6)
-#define SCR(iobase)	(iobase+7)
-#define DLL(iobase)	(iobase+0)
-#define DLM(iobase)	(iobase+1)
-
-#define YAM_EXTENT	8
-
-/* Interrupt Identification Register Bit Masks */
-#define IIR_NOPEND	1
-#define IIR_MSR		0
-#define IIR_TX		2
-#define IIR_RX		4
-#define IIR_LSR		6
-#define IIR_TIMEOUT	12			/* Fifo mode only */
-
-#define IIR_MASK	0x0F
-
-/* Interrupt Enable Register Bit Masks */
-#define IER_RX		1			/* enable rx interrupt */
-#define IER_TX		2			/* enable tx interrupt */
-#define IER_LSR		4			/* enable line status interrupts */
-#define IER_MSR		8			/* enable modem status interrupts */
-
-/* Modem Control Register Bit Masks */
-#define MCR_DTR		0x01			/* DTR output */
-#define MCR_RTS		0x02			/* RTS output */
-#define MCR_OUT1	0x04			/* OUT1 output (not accessible in RS232) */
-#define MCR_OUT2	0x08			/* Master Interrupt enable (must be set on PCs) */
-#define MCR_LOOP	0x10			/* Loopback enable */
-
-/* Modem Status Register Bit Masks */
-#define MSR_DCTS	0x01			/* Delta CTS input */
-#define MSR_DDSR	0x02			/* Delta DSR */
-#define MSR_DRIN	0x04			/* Delta RI */
-#define MSR_DDCD	0x08			/* Delta DCD */
-#define MSR_CTS		0x10			/* CTS input */
-#define MSR_DSR		0x20			/* DSR input */
-#define MSR_RING	0x40			/* RI  input */
-#define MSR_DCD		0x80			/* DCD input */
-
-/* line status register bit mask */
-#define LSR_RXC		0x01
-#define LSR_OE		0x02
-#define LSR_PE		0x04
-#define LSR_FE		0x08
-#define LSR_BREAK	0x10
-#define LSR_THRE	0x20
-#define LSR_TSRE	0x40
-
-/* Line Control Register Bit Masks */
-#define LCR_DLAB	0x80
-#define LCR_BREAK	0x40
-#define LCR_PZERO	0x28
-#define LCR_PEVEN	0x18
-#define LCR_PODD	0x08
-#define LCR_STOP1	0x00
-#define LCR_STOP2	0x04
-#define LCR_BIT5	0x00
-#define LCR_BIT6	0x02
-#define LCR_BIT7	0x01
-#define LCR_BIT8	0x03
-
-/* YAM Modem <-> UART Port mapping */
-
-#define TX_RDY		MSR_DCTS		/* transmitter ready to send */
-#define RX_DCD		MSR_DCD			/* carrier detect */
-#define RX_FLAG		MSR_RING		/* hdlc flag received */
-#define FPGA_DONE	MSR_DSR			/* FPGA is configured */
-#define PTT_ON		(MCR_RTS|MCR_OUT2)	/* activate PTT */
-#define PTT_OFF		(MCR_DTR|MCR_OUT2)	/* release PTT */
-
-#define ENABLE_RXINT	IER_RX			/* enable uart rx interrupt during rx */
-#define ENABLE_TXINT	IER_MSR			/* enable uart ms interrupt during tx */
-#define ENABLE_RTXINT	(IER_RX|IER_MSR)	/* full duplex operations */
-
-
-/*************************************************************************
-* CRC Tables
-************************************************************************/
-
-static const unsigned char chktabl[256] =
-{0x00, 0x89, 0x12, 0x9b, 0x24, 0xad, 0x36, 0xbf, 0x48, 0xc1, 0x5a, 0xd3, 0x6c, 0xe5, 0x7e,
- 0xf7, 0x81, 0x08, 0x93, 0x1a, 0xa5, 0x2c, 0xb7, 0x3e, 0xc9, 0x40, 0xdb, 0x52, 0xed, 0x64,
- 0xff, 0x76, 0x02, 0x8b, 0x10, 0x99, 0x26, 0xaf, 0x34, 0xbd, 0x4a, 0xc3, 0x58, 0xd1, 0x6e,
- 0xe7, 0x7c, 0xf5, 0x83, 0x0a, 0x91, 0x18, 0xa7, 0x2e, 0xb5, 0x3c, 0xcb, 0x42, 0xd9, 0x50,
- 0xef, 0x66, 0xfd, 0x74, 0x04, 0x8d, 0x16, 0x9f, 0x20, 0xa9, 0x32, 0xbb, 0x4c, 0xc5, 0x5e,
- 0xd7, 0x68, 0xe1, 0x7a, 0xf3, 0x85, 0x0c, 0x97, 0x1e, 0xa1, 0x28, 0xb3, 0x3a, 0xcd, 0x44,
- 0xdf, 0x56, 0xe9, 0x60, 0xfb, 0x72, 0x06, 0x8f, 0x14, 0x9d, 0x22, 0xab, 0x30, 0xb9, 0x4e,
- 0xc7, 0x5c, 0xd5, 0x6a, 0xe3, 0x78, 0xf1, 0x87, 0x0e, 0x95, 0x1c, 0xa3, 0x2a, 0xb1, 0x38,
- 0xcf, 0x46, 0xdd, 0x54, 0xeb, 0x62, 0xf9, 0x70, 0x08, 0x81, 0x1a, 0x93, 0x2c, 0xa5, 0x3e,
- 0xb7, 0x40, 0xc9, 0x52, 0xdb, 0x64, 0xed, 0x76, 0xff, 0x89, 0x00, 0x9b, 0x12, 0xad, 0x24,
- 0xbf, 0x36, 0xc1, 0x48, 0xd3, 0x5a, 0xe5, 0x6c, 0xf7, 0x7e, 0x0a, 0x83, 0x18, 0x91, 0x2e,
- 0xa7, 0x3c, 0xb5, 0x42, 0xcb, 0x50, 0xd9, 0x66, 0xef, 0x74, 0xfd, 0x8b, 0x02, 0x99, 0x10,
- 0xaf, 0x26, 0xbd, 0x34, 0xc3, 0x4a, 0xd1, 0x58, 0xe7, 0x6e, 0xf5, 0x7c, 0x0c, 0x85, 0x1e,
- 0x97, 0x28, 0xa1, 0x3a, 0xb3, 0x44, 0xcd, 0x56, 0xdf, 0x60, 0xe9, 0x72, 0xfb, 0x8d, 0x04,
- 0x9f, 0x16, 0xa9, 0x20, 0xbb, 0x32, 0xc5, 0x4c, 0xd7, 0x5e, 0xe1, 0x68, 0xf3, 0x7a, 0x0e,
- 0x87, 0x1c, 0x95, 0x2a, 0xa3, 0x38, 0xb1, 0x46, 0xcf, 0x54, 0xdd, 0x62, 0xeb, 0x70, 0xf9,
- 0x8f, 0x06, 0x9d, 0x14, 0xab, 0x22, 0xb9, 0x30, 0xc7, 0x4e, 0xd5, 0x5c, 0xe3, 0x6a, 0xf1,
- 0x78};
-static const unsigned char chktabh[256] =
-{0x00, 0x11, 0x23, 0x32, 0x46, 0x57, 0x65, 0x74, 0x8c, 0x9d, 0xaf, 0xbe, 0xca, 0xdb, 0xe9,
- 0xf8, 0x10, 0x01, 0x33, 0x22, 0x56, 0x47, 0x75, 0x64, 0x9c, 0x8d, 0xbf, 0xae, 0xda, 0xcb,
- 0xf9, 0xe8, 0x21, 0x30, 0x02, 0x13, 0x67, 0x76, 0x44, 0x55, 0xad, 0xbc, 0x8e, 0x9f, 0xeb,
- 0xfa, 0xc8, 0xd9, 0x31, 0x20, 0x12, 0x03, 0x77, 0x66, 0x54, 0x45, 0xbd, 0xac, 0x9e, 0x8f,
- 0xfb, 0xea, 0xd8, 0xc9, 0x42, 0x53, 0x61, 0x70, 0x04, 0x15, 0x27, 0x36, 0xce, 0xdf, 0xed,
- 0xfc, 0x88, 0x99, 0xab, 0xba, 0x52, 0x43, 0x71, 0x60, 0x14, 0x05, 0x37, 0x26, 0xde, 0xcf,
- 0xfd, 0xec, 0x98, 0x89, 0xbb, 0xaa, 0x63, 0x72, 0x40, 0x51, 0x25, 0x34, 0x06, 0x17, 0xef,
- 0xfe, 0xcc, 0xdd, 0xa9, 0xb8, 0x8a, 0x9b, 0x73, 0x62, 0x50, 0x41, 0x35, 0x24, 0x16, 0x07,
- 0xff, 0xee, 0xdc, 0xcd, 0xb9, 0xa8, 0x9a, 0x8b, 0x84, 0x95, 0xa7, 0xb6, 0xc2, 0xd3, 0xe1,
- 0xf0, 0x08, 0x19, 0x2b, 0x3a, 0x4e, 0x5f, 0x6d, 0x7c, 0x94, 0x85, 0xb7, 0xa6, 0xd2, 0xc3,
- 0xf1, 0xe0, 0x18, 0x09, 0x3b, 0x2a, 0x5e, 0x4f, 0x7d, 0x6c, 0xa5, 0xb4, 0x86, 0x97, 0xe3,
- 0xf2, 0xc0, 0xd1, 0x29, 0x38, 0x0a, 0x1b, 0x6f, 0x7e, 0x4c, 0x5d, 0xb5, 0xa4, 0x96, 0x87,
- 0xf3, 0xe2, 0xd0, 0xc1, 0x39, 0x28, 0x1a, 0x0b, 0x7f, 0x6e, 0x5c, 0x4d, 0xc6, 0xd7, 0xe5,
- 0xf4, 0x80, 0x91, 0xa3, 0xb2, 0x4a, 0x5b, 0x69, 0x78, 0x0c, 0x1d, 0x2f, 0x3e, 0xd6, 0xc7,
- 0xf5, 0xe4, 0x90, 0x81, 0xb3, 0xa2, 0x5a, 0x4b, 0x79, 0x68, 0x1c, 0x0d, 0x3f, 0x2e, 0xe7,
- 0xf6, 0xc4, 0xd5, 0xa1, 0xb0, 0x82, 0x93, 0x6b, 0x7a, 0x48, 0x59, 0x2d, 0x3c, 0x0e, 0x1f,
- 0xf7, 0xe6, 0xd4, 0xc5, 0xb1, 0xa0, 0x92, 0x83, 0x7b, 0x6a, 0x58, 0x49, 0x3d, 0x2c, 0x1e,
- 0x0f};
-
-/*************************************************************************
-* FPGA functions
-************************************************************************/
-
-static void delay(int ms)
-{
-	unsigned long timeout = jiffies + ((ms * HZ) / 1000);
-	while (time_before(jiffies, timeout))
-		cpu_relax();
-}
-
-/*
- * reset FPGA
- */
-
-static void fpga_reset(int iobase)
-{
-	outb(0, IER(iobase));
-	outb(LCR_DLAB | LCR_BIT5, LCR(iobase));
-	outb(1, DLL(iobase));
-	outb(0, DLM(iobase));
-
-	outb(LCR_BIT5, LCR(iobase));
-	inb(LSR(iobase));
-	inb(MSR(iobase));
-	/* turn off FPGA supply voltage */
-	outb(MCR_OUT1 | MCR_OUT2, MCR(iobase));
-	delay(100);
-	/* turn on FPGA supply voltage again */
-	outb(MCR_DTR | MCR_RTS | MCR_OUT1 | MCR_OUT2, MCR(iobase));
-	delay(100);
-}
-
-/*
- * send one byte to FPGA
- */
-
-static int fpga_write(int iobase, unsigned char wrd)
-{
-	unsigned char bit;
-	int k;
-	unsigned long timeout = jiffies + HZ / 10;
-
-	for (k = 0; k < 8; k++) {
-		bit = (wrd & 0x80) ? (MCR_RTS | MCR_DTR) : MCR_DTR;
-		outb(bit | MCR_OUT1 | MCR_OUT2, MCR(iobase));
-		wrd <<= 1;
-		outb(0xfc, THR(iobase));
-		while ((inb(LSR(iobase)) & LSR_TSRE) == 0)
-			if (time_after(jiffies, timeout))
-				return -1;
-	}
-
-	return 0;
-}
-
-/*
- * predef should be 0 for loading user defined mcs
- * predef should be YAM_1200 for loading predef 1200 mcs
- * predef should be YAM_9600 for loading predef 9600 mcs
- */
-static unsigned char *add_mcs(unsigned char *bits, int bitrate,
-			      unsigned int predef)
-{
-	const char *fw_name[2] = {FIRMWARE_9600, FIRMWARE_1200};
-	const struct firmware *fw;
-	struct platform_device *pdev;
-	struct yam_mcs *p;
-	int err;
-
-	switch (predef) {
-	case 0:
-		fw = NULL;
-		break;
-	case YAM_1200:
-	case YAM_9600:
-		predef--;
-		pdev = platform_device_register_simple("yam", 0, NULL, 0);
-		if (IS_ERR(pdev)) {
-			printk(KERN_ERR "yam: Failed to register firmware\n");
-			return NULL;
-		}
-		err = request_firmware(&fw, fw_name[predef], &pdev->dev);
-		platform_device_unregister(pdev);
-		if (err) {
-			printk(KERN_ERR "Failed to load firmware \"%s\"\n",
-			       fw_name[predef]);
-			return NULL;
-		}
-		if (fw->size != YAM_FPGA_SIZE) {
-			printk(KERN_ERR "Bogus length %zu in firmware \"%s\"\n",
-			       fw->size, fw_name[predef]);
-			release_firmware(fw);
-			return NULL;
-		}
-		bits = (unsigned char *)fw->data;
-		break;
-	default:
-		printk(KERN_ERR "yam: Invalid predef number %u\n", predef);
-		return NULL;
-	}
-
-	/* If it already exists, replace the bit data */
-	p = yam_data;
-	while (p) {
-		if (p->bitrate == bitrate) {
-			memcpy(p->bits, bits, YAM_FPGA_SIZE);
-			goto out;
-		}
-		p = p->next;
-	}
-
-	/* Allocate a new mcs */
-	if ((p = kmalloc_obj(struct yam_mcs)) == NULL) {
-		release_firmware(fw);
-		return NULL;
-	}
-	memcpy(p->bits, bits, YAM_FPGA_SIZE);
-	p->bitrate = bitrate;
-	p->next = yam_data;
-	yam_data = p;
- out:
-	release_firmware(fw);
-	return p->bits;
-}
-
-static unsigned char *get_mcs(int bitrate)
-{
-	struct yam_mcs *p;
-
-	p = yam_data;
-	while (p) {
-		if (p->bitrate == bitrate)
-			return p->bits;
-		p = p->next;
-	}
-
-	/* Load predefined mcs data */
-	switch (bitrate) {
-	case 1200:
-		/* setting predef as YAM_1200 for loading predef 1200 mcs */
-		return add_mcs(NULL, bitrate, YAM_1200);
-	default:
-		/* setting predef as YAM_9600 for loading predef 9600 mcs */
-		return add_mcs(NULL, bitrate, YAM_9600);
-	}
-}
-
-/*
- * download bitstream to FPGA
- * data is contained in bits[] array in yam1200.h resp. yam9600.h
- */
-
-static int fpga_download(int iobase, int bitrate)
-{
-	int i, rc;
-	unsigned char *pbits;
-
-	pbits = get_mcs(bitrate);
-	if (pbits == NULL)
-		return -1;
-
-	fpga_reset(iobase);
-	for (i = 0; i < YAM_FPGA_SIZE; i++) {
-		if (fpga_write(iobase, pbits[i])) {
-			printk(KERN_ERR "yam: error in write cycle\n");
-			return -1;			/* write... */
-		}
-	}
-
-	fpga_write(iobase, 0xFF);
-	rc = inb(MSR(iobase));		/* check DONE signal */
-
-	/* Needed for some hardwares */
-	delay(50);
-
-	return (rc & MSR_DSR) ? 0 : -1;
-}
-
-
-/************************************************************************
-* Serial port init 
-************************************************************************/
-
-static void yam_set_uart(struct net_device *dev)
-{
-	struct yam_port *yp = netdev_priv(dev);
-	int divisor = 115200 / yp->baudrate;
-
-	outb(0, IER(dev->base_addr));
-	outb(LCR_DLAB | LCR_BIT8, LCR(dev->base_addr));
-	outb(divisor, DLL(dev->base_addr));
-	outb(0, DLM(dev->base_addr));
-	outb(LCR_BIT8, LCR(dev->base_addr));
-	outb(PTT_OFF, MCR(dev->base_addr));
-	outb(0x00, FCR(dev->base_addr));
-
-	/* Flush pending irq */
-
-	inb(RBR(dev->base_addr));
-	inb(MSR(dev->base_addr));
-
-	/* Enable rx irq */
-
-	outb(ENABLE_RTXINT, IER(dev->base_addr));
-}
-
-
-/* --------------------------------------------------------------------- */
-
-enum uart {
-	c_uart_unknown, c_uart_8250,
-	c_uart_16450, c_uart_16550, c_uart_16550A
-};
-
-static const char *uart_str[] =
-{"unknown", "8250", "16450", "16550", "16550A"};
-
-static enum uart yam_check_uart(unsigned int iobase)
-{
-	unsigned char b1, b2, b3;
-	enum uart u;
-	enum uart uart_tab[] =
-	{c_uart_16450, c_uart_unknown, c_uart_16550, c_uart_16550A};
-
-	b1 = inb(MCR(iobase));
-	outb(b1 | 0x10, MCR(iobase));	/* loopback mode */
-	b2 = inb(MSR(iobase));
-	outb(0x1a, MCR(iobase));
-	b3 = inb(MSR(iobase)) & 0xf0;
-	outb(b1, MCR(iobase));		/* restore old values */
-	outb(b2, MSR(iobase));
-	if (b3 != 0x90)
-		return c_uart_unknown;
-	inb(RBR(iobase));
-	inb(RBR(iobase));
-	outb(0x01, FCR(iobase));	/* enable FIFOs */
-	u = uart_tab[(inb(IIR(iobase)) >> 6) & 3];
-	if (u == c_uart_16450) {
-		outb(0x5a, SCR(iobase));
-		b1 = inb(SCR(iobase));
-		outb(0xa5, SCR(iobase));
-		b2 = inb(SCR(iobase));
-		if ((b1 != 0x5a) || (b2 != 0xa5))
-			u = c_uart_8250;
-	}
-	return u;
-}
-
-/******************************************************************************
-* Rx Section
-******************************************************************************/
-static inline void yam_rx_flag(struct net_device *dev, struct yam_port *yp)
-{
-	if (yp->dcd && yp->rx_len >= 3 && yp->rx_len < YAM_MAX_FRAME) {
-		int pkt_len = yp->rx_len - 2 + 1;	/* -CRC + kiss */
-		struct sk_buff *skb;
-
-		if ((yp->rx_crch & yp->rx_crcl) != 0xFF) {
-			/* Bad crc */
-		} else {
-			if (!(skb = dev_alloc_skb(pkt_len))) {
-				printk(KERN_WARNING "%s: memory squeeze, dropping packet\n", dev->name);
-				++dev->stats.rx_dropped;
-			} else {
-				unsigned char *cp;
-				cp = skb_put(skb, pkt_len);
-				*cp++ = 0;		/* KISS kludge */
-				memcpy(cp, yp->rx_buf, pkt_len - 1);
-				skb->protocol = ax25_type_trans(skb, dev);
-				netif_rx(skb);
-				++dev->stats.rx_packets;
-			}
-		}
-	}
-	yp->rx_len = 0;
-	yp->rx_crcl = 0x21;
-	yp->rx_crch = 0xf3;
-}
-
-static inline void yam_rx_byte(struct net_device *dev, struct yam_port *yp, unsigned char rxb)
-{
-	if (yp->rx_len < YAM_MAX_FRAME) {
-		unsigned char c = yp->rx_crcl;
-		yp->rx_crcl = (chktabl[c] ^ yp->rx_crch);
-		yp->rx_crch = (chktabh[c] ^ rxb);
-		yp->rx_buf[yp->rx_len++] = rxb;
-	}
-}
-
-/********************************************************************************
-* TX Section
-********************************************************************************/
-
-static void ptt_on(struct net_device *dev)
-{
-	outb(PTT_ON, MCR(dev->base_addr));
-}
-
-static void ptt_off(struct net_device *dev)
-{
-	outb(PTT_OFF, MCR(dev->base_addr));
-}
-
-static netdev_tx_t yam_send_packet(struct sk_buff *skb,
-					 struct net_device *dev)
-{
-	struct yam_port *yp = netdev_priv(dev);
-
-	if (skb->protocol == htons(ETH_P_IP))
-		return ax25_ip_xmit(skb);
-
-	skb_queue_tail(&yp->send_queue, skb);
-	netif_trans_update(dev);
-	return NETDEV_TX_OK;
-}
-
-static void yam_start_tx(struct net_device *dev, struct yam_port *yp)
-{
-	if ((yp->tx_state == TX_TAIL) || (yp->txd == 0))
-		yp->tx_count = 1;
-	else
-		yp->tx_count = (yp->bitrate * yp->txd) / 8000;
-	yp->tx_state = TX_HEAD;
-	ptt_on(dev);
-}
-
-static void yam_arbitrate(struct net_device *dev)
-{
-	struct yam_port *yp = netdev_priv(dev);
-
-	if (yp->magic != YAM_MAGIC || yp->tx_state != TX_OFF ||
-	    skb_queue_empty(&yp->send_queue))
-		return;
-	/* tx_state is TX_OFF and there is data to send */
-
-	if (yp->dupmode) {
-		/* Full duplex mode, don't wait */
-		yam_start_tx(dev, yp);
-		return;
-	}
-	if (yp->dcd) {
-		/* DCD on, wait slotime ... */
-		yp->slotcnt = yp->slot / 10;
-		return;
-	}
-	/* Is slottime passed ? */
-	if ((--yp->slotcnt) > 0)
-		return;
-
-	yp->slotcnt = yp->slot / 10;
-
-	/* is random > persist ? */
-	if (get_random_u8() > yp->pers)
-		return;
-
-	yam_start_tx(dev, yp);
-}
-
-static void yam_dotimer(struct timer_list *unused)
-{
-	int i;
-
-	for (i = 0; i < NR_PORTS; i++) {
-		struct net_device *dev = yam_devs[i];
-		if (dev && netif_running(dev))
-			yam_arbitrate(dev);
-	}
-	yam_timer.expires = jiffies + HZ / 100;
-	add_timer(&yam_timer);
-}
-
-static void yam_tx_byte(struct net_device *dev, struct yam_port *yp)
-{
-	struct sk_buff *skb;
-	unsigned char b, temp;
-
-	switch (yp->tx_state) {
-	case TX_OFF:
-		break;
-	case TX_HEAD:
-		if (--yp->tx_count <= 0) {
-			if (!(skb = skb_dequeue(&yp->send_queue))) {
-				ptt_off(dev);
-				yp->tx_state = TX_OFF;
-				break;
-			}
-			yp->tx_state = TX_DATA;
-			if (skb->data[0] != 0) {
-/*                              do_kiss_params(s, skb->data, skb->len); */
-				dev_kfree_skb_any(skb);
-				break;
-			}
-			yp->tx_len = skb->len - 1;	/* strip KISS byte */
-			if (yp->tx_len >= YAM_MAX_FRAME || yp->tx_len < 2) {
-				dev_kfree_skb_any(skb);
-				break;
-			}
-			skb_copy_from_linear_data_offset(skb, 1,
-							 yp->tx_buf,
-							 yp->tx_len);
-			dev_kfree_skb_any(skb);
-			yp->tx_count = 0;
-			yp->tx_crcl = 0x21;
-			yp->tx_crch = 0xf3;
-			yp->tx_state = TX_DATA;
-		}
-		break;
-	case TX_DATA:
-		b = yp->tx_buf[yp->tx_count++];
-		outb(b, THR(dev->base_addr));
-		temp = yp->tx_crcl;
-		yp->tx_crcl = chktabl[temp] ^ yp->tx_crch;
-		yp->tx_crch = chktabh[temp] ^ b;
-		if (yp->tx_count >= yp->tx_len) {
-			yp->tx_state = TX_CRC1;
-		}
-		break;
-	case TX_CRC1:
-		yp->tx_crch = chktabl[yp->tx_crcl] ^ yp->tx_crch;
-		yp->tx_crcl = chktabh[yp->tx_crcl] ^ chktabl[yp->tx_crch] ^ 0xff;
-		outb(yp->tx_crcl, THR(dev->base_addr));
-		yp->tx_state = TX_CRC2;
-		break;
-	case TX_CRC2:
-		outb(chktabh[yp->tx_crch] ^ 0xFF, THR(dev->base_addr));
-		if (skb_queue_empty(&yp->send_queue)) {
-			yp->tx_count = (yp->bitrate * yp->txtail) / 8000;
-			if (yp->dupmode == 2)
-				yp->tx_count += (yp->bitrate * yp->holdd) / 8;
-			if (yp->tx_count == 0)
-				yp->tx_count = 1;
-			yp->tx_state = TX_TAIL;
-		} else {
-			yp->tx_count = 1;
-			yp->tx_state = TX_HEAD;
-		}
-		++dev->stats.tx_packets;
-		break;
-	case TX_TAIL:
-		if (--yp->tx_count <= 0) {
-			yp->tx_state = TX_OFF;
-			ptt_off(dev);
-		}
-		break;
-	}
-}
-
-/***********************************************************************************
-* ISR routine
-************************************************************************************/
-
-static irqreturn_t yam_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev;
-	struct yam_port *yp;
-	unsigned char iir;
-	int counter = 100;
-	int i;
-	int handled = 0;
-
-	for (i = 0; i < NR_PORTS; i++) {
-		dev = yam_devs[i];
-		yp = netdev_priv(dev);
-
-		if (!netif_running(dev))
-			continue;
-
-		while ((iir = IIR_MASK & inb(IIR(dev->base_addr))) != IIR_NOPEND) {
-			unsigned char msr = inb(MSR(dev->base_addr));
-			unsigned char lsr = inb(LSR(dev->base_addr));
-			unsigned char rxb;
-
-			handled = 1;
-
-			if (lsr & LSR_OE)
-				++dev->stats.rx_fifo_errors;
-
-			yp->dcd = (msr & RX_DCD) ? 1 : 0;
-
-			if (--counter <= 0) {
-				printk(KERN_ERR "%s: too many irq iir=%d\n",
-						dev->name, iir);
-				goto out;
-			}
-			if (msr & TX_RDY) {
-				++yp->nb_mdint;
-				yam_tx_byte(dev, yp);
-			}
-			if (lsr & LSR_RXC) {
-				++yp->nb_rxint;
-				rxb = inb(RBR(dev->base_addr));
-				if (msr & RX_FLAG)
-					yam_rx_flag(dev, yp);
-				else
-					yam_rx_byte(dev, yp, rxb);
-			}
-		}
-	}
-out:
-	return IRQ_RETVAL(handled);
-}
-
-#ifdef CONFIG_PROC_FS
-
-static void *yam_seq_start(struct seq_file *seq, loff_t *pos)
-{
-	return (*pos < NR_PORTS) ? yam_devs[*pos] : NULL;
-}
-
-static void *yam_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	++*pos;
-	return (*pos < NR_PORTS) ? yam_devs[*pos] : NULL;
-}
-
-static void yam_seq_stop(struct seq_file *seq, void *v)
-{
-}
-
-static int yam_seq_show(struct seq_file *seq, void *v)
-{
-	struct net_device *dev = v;
-	const struct yam_port *yp = netdev_priv(dev);
-
-	seq_printf(seq, "Device %s\n", dev->name);
-	seq_printf(seq, "  Up       %d\n", netif_running(dev));
-	seq_printf(seq, "  Speed    %u\n", yp->bitrate);
-	seq_printf(seq, "  IoBase   0x%x\n", yp->iobase);
-	seq_printf(seq, "  BaudRate %u\n", yp->baudrate);
-	seq_printf(seq, "  IRQ      %u\n", yp->irq);
-	seq_printf(seq, "  TxState  %u\n", yp->tx_state);
-	seq_printf(seq, "  Duplex   %u\n", yp->dupmode);
-	seq_printf(seq, "  HoldDly  %u\n", yp->holdd);
-	seq_printf(seq, "  TxDelay  %u\n", yp->txd);
-	seq_printf(seq, "  TxTail   %u\n", yp->txtail);
-	seq_printf(seq, "  SlotTime %u\n", yp->slot);
-	seq_printf(seq, "  Persist  %u\n", yp->pers);
-	seq_printf(seq, "  TxFrames %lu\n", dev->stats.tx_packets);
-	seq_printf(seq, "  RxFrames %lu\n", dev->stats.rx_packets);
-	seq_printf(seq, "  TxInt    %u\n", yp->nb_mdint);
-	seq_printf(seq, "  RxInt    %u\n", yp->nb_rxint);
-	seq_printf(seq, "  RxOver   %lu\n", dev->stats.rx_fifo_errors);
-	seq_printf(seq, "\n");
-	return 0;
-}
-
-static const struct seq_operations yam_seqops = {
-	.start = yam_seq_start,
-	.next = yam_seq_next,
-	.stop = yam_seq_stop,
-	.show = yam_seq_show,
-};
-#endif
-
-
-/* --------------------------------------------------------------------- */
-
-static int yam_open(struct net_device *dev)
-{
-	struct yam_port *yp = netdev_priv(dev);
-	enum uart u;
-	int i;
-	int ret=0;
-
-	printk(KERN_INFO "Trying %s at iobase 0x%lx irq %u\n", dev->name, dev->base_addr, dev->irq);
-
-	if (!yp->bitrate)
-		return -ENXIO;
-	if (!dev->base_addr || dev->base_addr > 0x1000 - YAM_EXTENT ||
-		dev->irq < 2 || dev->irq > 15) {
-		return -ENXIO;
-	}
-	if (!request_region(dev->base_addr, YAM_EXTENT, dev->name))
-	{
-		printk(KERN_ERR "%s: cannot 0x%lx busy\n", dev->name, dev->base_addr);
-		return -EACCES;
-	}
-	if ((u = yam_check_uart(dev->base_addr)) == c_uart_unknown) {
-		printk(KERN_ERR "%s: cannot find uart type\n", dev->name);
-		ret = -EIO;
-		goto out_release_base;
-	}
-	if (fpga_download(dev->base_addr, yp->bitrate)) {
-		printk(KERN_ERR "%s: cannot init FPGA\n", dev->name);
-		ret = -EIO;
-		goto out_release_base;
-	}
-	outb(0, IER(dev->base_addr));
-	if (request_irq(dev->irq, yam_interrupt, IRQF_SHARED, dev->name, dev)) {
-		printk(KERN_ERR "%s: irq %d busy\n", dev->name, dev->irq);
-		ret = -EBUSY;
-		goto out_release_base;
-	}
-
-	yam_set_uart(dev);
-
-	netif_start_queue(dev);
-	
-	yp->slotcnt = yp->slot / 10;
-
-	/* Reset overruns for all ports - FPGA programming makes overruns */
-	for (i = 0; i < NR_PORTS; i++) {
-		struct net_device *yam_dev = yam_devs[i];
-
-		inb(LSR(yam_dev->base_addr));
-		yam_dev->stats.rx_fifo_errors = 0;
-	}
-
-	printk(KERN_INFO "%s at iobase 0x%lx irq %u uart %s\n", dev->name, dev->base_addr, dev->irq,
-		   uart_str[u]);
-	return 0;
-
-out_release_base:
-	release_region(dev->base_addr, YAM_EXTENT);
-	return ret;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int yam_close(struct net_device *dev)
-{
-	struct sk_buff *skb;
-	struct yam_port *yp = netdev_priv(dev);
-
-	if (!dev)
-		return -EINVAL;
-
-	/*
-	 * disable interrupts
-	 */
-	outb(0, IER(dev->base_addr));
-	outb(1, MCR(dev->base_addr));
-	/* Remove IRQ handler if last */
-	free_irq(dev->irq,dev);
-	release_region(dev->base_addr, YAM_EXTENT);
-	netif_stop_queue(dev);
-	while ((skb = skb_dequeue(&yp->send_queue)))
-		dev_kfree_skb(skb);
-
-	printk(KERN_INFO "%s: close yam at iobase 0x%lx irq %u\n",
-		   yam_drvname, dev->base_addr, dev->irq);
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int yam_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __user *data, int cmd)
-{
-	struct yam_port *yp = netdev_priv(dev);
-	struct yamdrv_ioctl_cfg yi;
-	struct yamdrv_ioctl_mcs *ym;
-	int ioctl_cmd;
-
-	if (copy_from_user(&ioctl_cmd, data, sizeof(int)))
-		return -EFAULT;
-
-	if (yp->magic != YAM_MAGIC)
-		return -EINVAL;
-
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
-	if (cmd != SIOCDEVPRIVATE)
-		return -EINVAL;
-
-	switch (ioctl_cmd) {
-
-	case SIOCYAMRESERVED:
-		return -EINVAL;			/* unused */
-
-	case SIOCYAMSMCS:
-		if (netif_running(dev))
-			return -EINVAL;		/* Cannot change this parameter when up */
-		ym = memdup_user(data, sizeof(struct yamdrv_ioctl_mcs));
-		if (IS_ERR(ym))
-			return PTR_ERR(ym);
-		if (ym->cmd != SIOCYAMSMCS || ym->bitrate > YAM_MAXBITRATE) {
-			kfree(ym);
-			return -EINVAL;
-		}
-		/* setting predef as 0 for loading userdefined mcs data */
-		add_mcs(ym->bits, ym->bitrate, 0);
-		kfree(ym);
-		break;
-
-	case SIOCYAMSCFG:
-		if (!capable(CAP_SYS_RAWIO))
-			return -EPERM;
-		if (copy_from_user(&yi, data, sizeof(struct yamdrv_ioctl_cfg)))
-			return -EFAULT;
-
-		if (yi.cmd != SIOCYAMSCFG)
-			return -EINVAL;
-		if ((yi.cfg.mask & YAM_IOBASE) && netif_running(dev))
-			return -EINVAL;		/* Cannot change this parameter when up */
-		if ((yi.cfg.mask & YAM_IRQ) && netif_running(dev))
-			return -EINVAL;		/* Cannot change this parameter when up */
-		if ((yi.cfg.mask & YAM_BITRATE) && netif_running(dev))
-			return -EINVAL;		/* Cannot change this parameter when up */
-		if ((yi.cfg.mask & YAM_BAUDRATE) && netif_running(dev))
-			return -EINVAL;		/* Cannot change this parameter when up */
-
-		if (yi.cfg.mask & YAM_IOBASE) {
-			yp->iobase = yi.cfg.iobase;
-			dev->base_addr = yi.cfg.iobase;
-		}
-		if (yi.cfg.mask & YAM_IRQ) {
-			if (yi.cfg.irq > 15)
-				return -EINVAL;
-			yp->irq = yi.cfg.irq;
-			dev->irq = yi.cfg.irq;
-		}
-		if (yi.cfg.mask & YAM_BITRATE) {
-			if (yi.cfg.bitrate > YAM_MAXBITRATE)
-				return -EINVAL;
-			yp->bitrate = yi.cfg.bitrate;
-		}
-		if (yi.cfg.mask & YAM_BAUDRATE) {
-			if (yi.cfg.baudrate > YAM_MAXBAUDRATE)
-				return -EINVAL;
-			yp->baudrate = yi.cfg.baudrate;
-		}
-		if (yi.cfg.mask & YAM_MODE) {
-			if (yi.cfg.mode > YAM_MAXMODE)
-				return -EINVAL;
-			yp->dupmode = yi.cfg.mode;
-		}
-		if (yi.cfg.mask & YAM_HOLDDLY) {
-			if (yi.cfg.holddly > YAM_MAXHOLDDLY)
-				return -EINVAL;
-			yp->holdd = yi.cfg.holddly;
-		}
-		if (yi.cfg.mask & YAM_TXDELAY) {
-			if (yi.cfg.txdelay > YAM_MAXTXDELAY)
-				return -EINVAL;
-			yp->txd = yi.cfg.txdelay;
-		}
-		if (yi.cfg.mask & YAM_TXTAIL) {
-			if (yi.cfg.txtail > YAM_MAXTXTAIL)
-				return -EINVAL;
-			yp->txtail = yi.cfg.txtail;
-		}
-		if (yi.cfg.mask & YAM_PERSIST) {
-			if (yi.cfg.persist > YAM_MAXPERSIST)
-				return -EINVAL;
-			yp->pers = yi.cfg.persist;
-		}
-		if (yi.cfg.mask & YAM_SLOTTIME) {
-			if (yi.cfg.slottime > YAM_MAXSLOTTIME)
-				return -EINVAL;
-			yp->slot = yi.cfg.slottime;
-			yp->slotcnt = yp->slot / 10;
-		}
-		break;
-
-	case SIOCYAMGCFG:
-		memset(&yi, 0, sizeof(yi));
-		yi.cfg.mask = 0xffffffff;
-		yi.cfg.iobase = yp->iobase;
-		yi.cfg.irq = yp->irq;
-		yi.cfg.bitrate = yp->bitrate;
-		yi.cfg.baudrate = yp->baudrate;
-		yi.cfg.mode = yp->dupmode;
-		yi.cfg.txdelay = yp->txd;
-		yi.cfg.holddly = yp->holdd;
-		yi.cfg.txtail = yp->txtail;
-		yi.cfg.persist = yp->pers;
-		yi.cfg.slottime = yp->slot;
-		if (copy_to_user(data, &yi, sizeof(struct yamdrv_ioctl_cfg)))
-			return -EFAULT;
-		break;
-
-	default:
-		return -EINVAL;
-
-	}
-
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int yam_set_mac_address(struct net_device *dev, void *addr)
-{
-	struct sockaddr *sa = (struct sockaddr *) addr;
-
-	/* addr is an AX.25 shifted ASCII mac address */
-	dev_addr_set(dev, sa->sa_data);
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static const struct net_device_ops yam_netdev_ops = {
-	.ndo_open	     = yam_open,
-	.ndo_stop	     = yam_close,
-	.ndo_start_xmit      = yam_send_packet,
-	.ndo_siocdevprivate  = yam_siocdevprivate,
-	.ndo_set_mac_address = yam_set_mac_address,
-};
-
-static void yam_setup(struct net_device *dev)
-{
-	struct yam_port *yp = netdev_priv(dev);
-
-	yp->magic = YAM_MAGIC;
-	yp->bitrate = DEFAULT_BITRATE;
-	yp->baudrate = DEFAULT_BITRATE * 2;
-	yp->iobase = 0;
-	yp->irq = 0;
-	yp->dupmode = 0;
-	yp->holdd = DEFAULT_HOLDD;
-	yp->txd = DEFAULT_TXD;
-	yp->txtail = DEFAULT_TXTAIL;
-	yp->slot = DEFAULT_SLOT;
-	yp->pers = DEFAULT_PERS;
-	yp->dev = dev;
-
-	dev->base_addr = yp->iobase;
-	dev->irq = yp->irq;
-
-	skb_queue_head_init(&yp->send_queue);
-
-	dev->netdev_ops = &yam_netdev_ops;
-	dev->header_ops = &ax25_header_ops;
-
-	dev->type = ARPHRD_AX25;
-	dev->hard_header_len = AX25_MAX_HEADER_LEN;
-	dev->mtu = AX25_MTU;
-	dev->addr_len = AX25_ADDR_LEN;
-	memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
-	dev_addr_set(dev, (u8 *)&ax25_defaddr);
-}
-
-static int __init yam_init_driver(void)
-{
-	struct net_device *dev;
-	int i, err;
-	char name[IFNAMSIZ];
-
-	printk(yam_drvinfo);
-
-	for (i = 0; i < NR_PORTS; i++) {
-		sprintf(name, "yam%d", i);
-		
-		dev = alloc_netdev(sizeof(struct yam_port), name,
-				   NET_NAME_UNKNOWN, yam_setup);
-		if (!dev) {
-			pr_err("yam: cannot allocate net device\n");
-			err = -ENOMEM;
-			goto error;
-		}
-		
-		err = register_netdev(dev);
-		if (err) {
-			printk(KERN_WARNING "yam: cannot register net device %s\n", dev->name);
-			free_netdev(dev);
-			goto error;
-		}
-		yam_devs[i] = dev;
-
-	}
-
-	timer_setup(&yam_timer, yam_dotimer, 0);
-	yam_timer.expires = jiffies + HZ / 100;
-	add_timer(&yam_timer);
-
-	proc_create_seq("yam", 0444, init_net.proc_net, &yam_seqops);
-	return 0;
- error:
-	while (--i >= 0) {
-		unregister_netdev(yam_devs[i]);
-		free_netdev(yam_devs[i]);
-	}
-	return err;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void __exit yam_cleanup_driver(void)
-{
-	struct yam_mcs *p;
-	int i;
-
-	timer_delete_sync(&yam_timer);
-	for (i = 0; i < NR_PORTS; i++) {
-		struct net_device *dev = yam_devs[i];
-		if (dev) {
-			unregister_netdev(dev);
-			free_netdev(dev);
-		}
-	}
-
-	while (yam_data) {
-		p = yam_data;
-		yam_data = yam_data->next;
-		kfree(p);
-	}
-
-	remove_proc_entry("yam", init_net.proc_net);
-}
-
-/* --------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Frederic Rible F1OAT frible@teaser.fr");
-MODULE_DESCRIPTION("Yam amateur radio modem driver");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(FIRMWARE_1200);
-MODULE_FIRMWARE(FIRMWARE_9600);
-
-module_init(yam_init_driver);
-module_exit(yam_cleanup_driver);
-
-/* --------------------------------------------------------------------- */
-
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
deleted file mode 100644
index 9d236e64f5f5..000000000000
--- a/net/ax25/af_ax25.c
+++ /dev/null
@@ -1,2089 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) Darryl Miles G7LED (dlm@g7led.demon.co.uk)
- * Copyright (C) Steven Whitehouse GW7RRM (stevew@acm.org)
- * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
- * Copyright (C) Hans-Joachim Hetscher DD8NE (dd8ne@bnv-bamberg.de)
- * Copyright (C) Hans Alblas PE1AYX (hans@esrac.ele.tue.nl)
- * Copyright (C) Frederic Rible F1OAT (frible@teaser.fr)
- */
-#include <linux/capability.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/sched/signal.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/termios.h>	/* For TIOCINQ/OUTQ */
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/notifier.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <linux/sysctl.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <net/net_namespace.h>
-#include <net/tcp_states.h>
-#include <net/ip.h>
-#include <net/arp.h>
-
-
-
-HLIST_HEAD(ax25_list);
-DEFINE_SPINLOCK(ax25_list_lock);
-
-static const struct proto_ops ax25_proto_ops;
-
-static void ax25_free_sock(struct sock *sk)
-{
-	ax25_cb_put(sk_to_ax25(sk));
-}
-
-/*
- *	Socket removal during an interrupt is now safe.
- */
-static void ax25_cb_del(ax25_cb *ax25)
-{
-	spin_lock_bh(&ax25_list_lock);
-	if (!hlist_unhashed(&ax25->ax25_node)) {
-		hlist_del_init(&ax25->ax25_node);
-		ax25_cb_put(ax25);
-	}
-	spin_unlock_bh(&ax25_list_lock);
-}
-
-/*
- *	Kill all bound sockets on a dropped device.
- */
-static void ax25_kill_by_device(struct net_device *dev)
-{
-	ax25_dev *ax25_dev;
-	ax25_cb *s;
-	struct sock *sk;
-
-	if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
-		return;
-	ax25_dev->device_up = false;
-
-	spin_lock_bh(&ax25_list_lock);
-again:
-	ax25_for_each(s, &ax25_list) {
-		if (s->ax25_dev == ax25_dev) {
-			sk = s->sk;
-			if (!sk) {
-				spin_unlock_bh(&ax25_list_lock);
-				ax25_disconnect(s, ENETUNREACH);
-				s->ax25_dev = NULL;
-				ax25_cb_del(s);
-				spin_lock_bh(&ax25_list_lock);
-				goto again;
-			}
-			sock_hold(sk);
-			spin_unlock_bh(&ax25_list_lock);
-			lock_sock(sk);
-			ax25_disconnect(s, ENETUNREACH);
-			s->ax25_dev = NULL;
-			if (sk->sk_socket) {
-				netdev_put(ax25_dev->dev,
-					   &s->dev_tracker);
-				ax25_dev_put(ax25_dev);
-			}
-			ax25_cb_del(s);
-			release_sock(sk);
-			spin_lock_bh(&ax25_list_lock);
-			sock_put(sk);
-			/* The entry could have been deleted from the
-			 * list meanwhile and thus the next pointer is
-			 * no longer valid.  Play it safe and restart
-			 * the scan.  Forward progress is ensured
-			 * because we set s->ax25_dev to NULL and we
-			 * are never passed a NULL 'dev' argument.
-			 */
-			goto again;
-		}
-	}
-	spin_unlock_bh(&ax25_list_lock);
-}
-
-/*
- *	Handle device status changes.
- */
-static int ax25_device_event(struct notifier_block *this, unsigned long event,
-			     void *ptr)
-{
-	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
-
-	if (!net_eq(dev_net(dev), &init_net))
-		return NOTIFY_DONE;
-
-	/* Reject non AX.25 devices */
-	if (dev->type != ARPHRD_AX25)
-		return NOTIFY_DONE;
-
-	switch (event) {
-	case NETDEV_UP:
-		ax25_dev_device_up(dev);
-		break;
-	case NETDEV_DOWN:
-		ax25_kill_by_device(dev);
-		ax25_rt_device_down(dev);
-		ax25_dev_device_down(dev);
-		break;
-	default:
-		break;
-	}
-
-	return NOTIFY_DONE;
-}
-
-/*
- *	Add a socket to the bound sockets list.
- */
-void ax25_cb_add(ax25_cb *ax25)
-{
-	spin_lock_bh(&ax25_list_lock);
-	ax25_cb_hold(ax25);
-	hlist_add_head(&ax25->ax25_node, &ax25_list);
-	spin_unlock_bh(&ax25_list_lock);
-}
-
-/*
- *	Find a socket that wants to accept the SABM we have just
- *	received.
- */
-struct sock *ax25_find_listener(ax25_address *addr, int digi,
-	struct net_device *dev, int type)
-{
-	ax25_cb *s;
-
-	spin_lock(&ax25_list_lock);
-	ax25_for_each(s, &ax25_list) {
-		if ((s->iamdigi && !digi) || (!s->iamdigi && digi))
-			continue;
-		if (s->sk && !ax25cmp(&s->source_addr, addr) &&
-		    s->sk->sk_type == type && s->sk->sk_state == TCP_LISTEN) {
-			/* If device is null we match any device */
-			if (s->ax25_dev == NULL || s->ax25_dev->dev == dev) {
-				sock_hold(s->sk);
-				spin_unlock(&ax25_list_lock);
-				return s->sk;
-			}
-		}
-	}
-	spin_unlock(&ax25_list_lock);
-
-	return NULL;
-}
-
-/*
- *	Find an AX.25 socket given both ends.
- */
-struct sock *ax25_get_socket(ax25_address *my_addr, ax25_address *dest_addr,
-	int type)
-{
-	struct sock *sk = NULL;
-	ax25_cb *s;
-
-	spin_lock(&ax25_list_lock);
-	ax25_for_each(s, &ax25_list) {
-		if (s->sk && !ax25cmp(&s->source_addr, my_addr) &&
-		    !ax25cmp(&s->dest_addr, dest_addr) &&
-		    s->sk->sk_type == type) {
-			sk = s->sk;
-			sock_hold(sk);
-			break;
-		}
-	}
-
-	spin_unlock(&ax25_list_lock);
-
-	return sk;
-}
-
-/*
- *	Find an AX.25 control block given both ends. It will only pick up
- *	floating AX.25 control blocks or non Raw socket bound control blocks.
- */
-ax25_cb *ax25_find_cb(const ax25_address *src_addr, ax25_address *dest_addr,
-	ax25_digi *digi, struct net_device *dev)
-{
-	ax25_cb *s;
-
-	spin_lock_bh(&ax25_list_lock);
-	ax25_for_each(s, &ax25_list) {
-		if (s->sk && s->sk->sk_type != SOCK_SEQPACKET)
-			continue;
-		if (s->ax25_dev == NULL)
-			continue;
-		if (ax25cmp(&s->source_addr, src_addr) == 0 && ax25cmp(&s->dest_addr, dest_addr) == 0 && s->ax25_dev->dev == dev) {
-			if (digi != NULL && digi->ndigi != 0) {
-				if (s->digipeat == NULL)
-					continue;
-				if (ax25digicmp(s->digipeat, digi) != 0)
-					continue;
-			} else {
-				if (s->digipeat != NULL && s->digipeat->ndigi != 0)
-					continue;
-			}
-			ax25_cb_hold(s);
-			spin_unlock_bh(&ax25_list_lock);
-
-			return s;
-		}
-	}
-	spin_unlock_bh(&ax25_list_lock);
-
-	return NULL;
-}
-
-EXPORT_SYMBOL(ax25_find_cb);
-
-void ax25_send_to_raw(ax25_address *addr, struct sk_buff *skb, int proto)
-{
-	ax25_cb *s;
-	struct sk_buff *copy;
-
-	spin_lock(&ax25_list_lock);
-	ax25_for_each(s, &ax25_list) {
-		if (s->sk != NULL && ax25cmp(&s->source_addr, addr) == 0 &&
-		    s->sk->sk_type == SOCK_RAW &&
-		    s->sk->sk_protocol == proto &&
-		    s->ax25_dev->dev == skb->dev &&
-		    atomic_read(&s->sk->sk_rmem_alloc) <= s->sk->sk_rcvbuf) {
-			if ((copy = skb_clone(skb, GFP_ATOMIC)) == NULL)
-				continue;
-			if (sock_queue_rcv_skb(s->sk, copy) != 0)
-				kfree_skb(copy);
-		}
-	}
-	spin_unlock(&ax25_list_lock);
-}
-
-/*
- *	Deferred destroy.
- */
-void ax25_destroy_socket(ax25_cb *);
-
-/*
- *	Handler for deferred kills.
- */
-static void ax25_destroy_timer(struct timer_list *t)
-{
-	ax25_cb *ax25 = timer_container_of(ax25, t, dtimer);
-	struct sock *sk;
-
-	sk=ax25->sk;
-
-	bh_lock_sock(sk);
-	sock_hold(sk);
-	ax25_destroy_socket(ax25);
-	bh_unlock_sock(sk);
-	sock_put(sk);
-}
-
-/*
- *	This is called from user mode and the timers. Thus it protects itself
- *	against interrupt users but doesn't worry about being called during
- *	work. Once it is removed from the queue no interrupt or bottom half
- *	will touch it and we are (fairly 8-) ) safe.
- */
-void ax25_destroy_socket(ax25_cb *ax25)
-{
-	struct sk_buff *skb;
-
-	ax25_cb_del(ax25);
-
-	ax25_stop_heartbeat(ax25);
-	ax25_stop_t1timer(ax25);
-	ax25_stop_t2timer(ax25);
-	ax25_stop_t3timer(ax25);
-	ax25_stop_idletimer(ax25);
-
-	ax25_clear_queues(ax25);	/* Flush the queues */
-
-	if (ax25->sk != NULL) {
-		while ((skb = skb_dequeue(&ax25->sk->sk_receive_queue)) != NULL) {
-			if (skb->sk != ax25->sk) {
-				/* A pending connection */
-				ax25_cb *sax25 = sk_to_ax25(skb->sk);
-
-				/* Queue the unaccepted socket for death */
-				sock_orphan(skb->sk);
-
-				/* 9A4GL: hack to release unaccepted sockets */
-				skb->sk->sk_state = TCP_LISTEN;
-
-				ax25_start_heartbeat(sax25);
-				sax25->state = AX25_STATE_0;
-			}
-
-			kfree_skb(skb);
-		}
-		skb_queue_purge(&ax25->sk->sk_write_queue);
-	}
-
-	if (ax25->sk != NULL) {
-		if (sk_has_allocations(ax25->sk)) {
-			/* Defer: outstanding buffers */
-			timer_setup(&ax25->dtimer, ax25_destroy_timer, 0);
-			ax25->dtimer.expires  = jiffies + 2 * HZ;
-			add_timer(&ax25->dtimer);
-		} else {
-			struct sock *sk=ax25->sk;
-			ax25->sk=NULL;
-			sock_put(sk);
-		}
-	} else {
-		ax25_cb_put(ax25);
-	}
-}
-
-/*
- * dl1bke 960311: set parameters for existing AX.25 connections,
- *		  includes a KILL command to abort any connection.
- *		  VERY useful for debugging ;-)
- */
-static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)
-{
-	struct ax25_ctl_struct ax25_ctl;
-	ax25_digi digi;
-	ax25_dev *ax25_dev;
-	ax25_cb *ax25;
-	unsigned int k;
-	int ret = 0;
-
-	if (copy_from_user(&ax25_ctl, arg, sizeof(ax25_ctl)))
-		return -EFAULT;
-
-	if (ax25_ctl.digi_count > AX25_MAX_DIGIS)
-		return -EINVAL;
-
-	if (ax25_ctl.arg > ULONG_MAX / HZ && ax25_ctl.cmd != AX25_KILL)
-		return -EINVAL;
-
-	ax25_dev = ax25_addr_ax25dev(&ax25_ctl.port_addr);
-	if (!ax25_dev)
-		return -ENODEV;
-
-	digi.ndigi = ax25_ctl.digi_count;
-	for (k = 0; k < digi.ndigi; k++)
-		digi.calls[k] = ax25_ctl.digi_addr[k];
-
-	ax25 = ax25_find_cb(&ax25_ctl.source_addr, &ax25_ctl.dest_addr, &digi, ax25_dev->dev);
-	if (!ax25) {
-		ax25_dev_put(ax25_dev);
-		return -ENOTCONN;
-	}
-
-	switch (ax25_ctl.cmd) {
-	case AX25_KILL:
-		ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
-#ifdef CONFIG_AX25_DAMA_SLAVE
-		if (ax25_dev->dama.slave && ax25->ax25_dev->values[AX25_VALUES_PROTOCOL] == AX25_PROTO_DAMA_SLAVE)
-			ax25_dama_off(ax25);
-#endif
-		ax25_disconnect(ax25, ENETRESET);
-		break;
-
-	case AX25_WINDOW:
-		if (ax25->modulus == AX25_MODULUS) {
-			if (ax25_ctl.arg < 1 || ax25_ctl.arg > 7)
-				goto einval_put;
-		} else {
-			if (ax25_ctl.arg < 1 || ax25_ctl.arg > 63)
-				goto einval_put;
-		}
-		ax25->window = ax25_ctl.arg;
-		break;
-
-	case AX25_T1:
-		if (ax25_ctl.arg < 1 || ax25_ctl.arg > ULONG_MAX / HZ)
-			goto einval_put;
-		ax25->rtt = (ax25_ctl.arg * HZ) / 2;
-		ax25->t1  = ax25_ctl.arg * HZ;
-		break;
-
-	case AX25_T2:
-		if (ax25_ctl.arg < 1 || ax25_ctl.arg > ULONG_MAX / HZ)
-			goto einval_put;
-		ax25->t2 = ax25_ctl.arg * HZ;
-		break;
-
-	case AX25_N2:
-		if (ax25_ctl.arg < 1 || ax25_ctl.arg > 31)
-			goto einval_put;
-		ax25->n2count = 0;
-		ax25->n2 = ax25_ctl.arg;
-		break;
-
-	case AX25_T3:
-		if (ax25_ctl.arg > ULONG_MAX / HZ)
-			goto einval_put;
-		ax25->t3 = ax25_ctl.arg * HZ;
-		break;
-
-	case AX25_IDLE:
-		if (ax25_ctl.arg > ULONG_MAX / (60 * HZ))
-			goto einval_put;
-
-		ax25->idle = ax25_ctl.arg * 60 * HZ;
-		break;
-
-	case AX25_PACLEN:
-		if (ax25_ctl.arg < 16 || ax25_ctl.arg > 65535)
-			goto einval_put;
-		ax25->paclen = ax25_ctl.arg;
-		break;
-
-	default:
-		goto einval_put;
-	  }
-
-out_put:
-	ax25_dev_put(ax25_dev);
-	ax25_cb_put(ax25);
-	return ret;
-
-einval_put:
-	ret = -EINVAL;
-	goto out_put;
-}
-
-static void ax25_fillin_cb_from_dev(ax25_cb *ax25, const ax25_dev *ax25_dev)
-{
-	ax25->rtt     = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]) / 2;
-	ax25->t1      = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]);
-	ax25->t2      = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T2]);
-	ax25->t3      = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T3]);
-	ax25->n2      = ax25_dev->values[AX25_VALUES_N2];
-	ax25->paclen  = ax25_dev->values[AX25_VALUES_PACLEN];
-	ax25->idle    = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_IDLE]);
-	ax25->backoff = ax25_dev->values[AX25_VALUES_BACKOFF];
-
-	if (ax25_dev->values[AX25_VALUES_AXDEFMODE]) {
-		ax25->modulus = AX25_EMODULUS;
-		ax25->window  = ax25_dev->values[AX25_VALUES_EWINDOW];
-	} else {
-		ax25->modulus = AX25_MODULUS;
-		ax25->window  = ax25_dev->values[AX25_VALUES_WINDOW];
-	}
-}
-
-/*
- *	Fill in a created AX.25 created control block with the default
- *	values for a particular device.
- */
-void ax25_fillin_cb(ax25_cb *ax25, ax25_dev *ax25_dev)
-{
-	ax25->ax25_dev = ax25_dev;
-
-	if (ax25->ax25_dev != NULL) {
-		ax25_fillin_cb_from_dev(ax25, ax25_dev);
-		return;
-	}
-
-	/*
-	 * No device, use kernel / AX.25 spec default values
-	 */
-	ax25->rtt     = msecs_to_jiffies(AX25_DEF_T1) / 2;
-	ax25->t1      = msecs_to_jiffies(AX25_DEF_T1);
-	ax25->t2      = msecs_to_jiffies(AX25_DEF_T2);
-	ax25->t3      = msecs_to_jiffies(AX25_DEF_T3);
-	ax25->n2      = AX25_DEF_N2;
-	ax25->paclen  = AX25_DEF_PACLEN;
-	ax25->idle    = msecs_to_jiffies(AX25_DEF_IDLE);
-	ax25->backoff = AX25_DEF_BACKOFF;
-
-	if (AX25_DEF_AXDEFMODE) {
-		ax25->modulus = AX25_EMODULUS;
-		ax25->window  = AX25_DEF_EWINDOW;
-	} else {
-		ax25->modulus = AX25_MODULUS;
-		ax25->window  = AX25_DEF_WINDOW;
-	}
-}
-
-/*
- * Create an empty AX.25 control block.
- */
-ax25_cb *ax25_create_cb(void)
-{
-	ax25_cb *ax25;
-
-	if ((ax25 = kzalloc_obj(*ax25, GFP_ATOMIC)) == NULL)
-		return NULL;
-
-	refcount_set(&ax25->refcount, 1);
-
-	skb_queue_head_init(&ax25->write_queue);
-	skb_queue_head_init(&ax25->frag_queue);
-	skb_queue_head_init(&ax25->ack_queue);
-	skb_queue_head_init(&ax25->reseq_queue);
-
-	ax25_setup_timers(ax25);
-
-	ax25_fillin_cb(ax25, NULL);
-
-	ax25->state = AX25_STATE_0;
-
-	return ax25;
-}
-
-/*
- *	Handling for system calls applied via the various interfaces to an
- *	AX25 socket object
- */
-
-static int ax25_setsockopt(struct socket *sock, int level, int optname,
-		sockptr_t optval, unsigned int optlen)
-{
-	struct sock *sk = sock->sk;
-	ax25_cb *ax25;
-	struct net_device *dev;
-	char devname[IFNAMSIZ];
-	unsigned int opt;
-	int res = 0;
-
-	if (level != SOL_AX25)
-		return -ENOPROTOOPT;
-
-	if (optlen < sizeof(unsigned int))
-		return -EINVAL;
-
-	if (copy_from_sockptr(&opt, optval, sizeof(unsigned int)))
-		return -EFAULT;
-
-	lock_sock(sk);
-	ax25 = sk_to_ax25(sk);
-
-	switch (optname) {
-	case AX25_WINDOW:
-		if (ax25->modulus == AX25_MODULUS) {
-			if (opt < 1 || opt > 7) {
-				res = -EINVAL;
-				break;
-			}
-		} else {
-			if (opt < 1 || opt > 63) {
-				res = -EINVAL;
-				break;
-			}
-		}
-		ax25->window = opt;
-		break;
-
-	case AX25_T1:
-		if (opt < 1 || opt > UINT_MAX / HZ) {
-			res = -EINVAL;
-			break;
-		}
-		ax25->rtt = (opt * HZ) >> 1;
-		ax25->t1  = opt * HZ;
-		break;
-
-	case AX25_T2:
-		if (opt < 1 || opt > UINT_MAX / HZ) {
-			res = -EINVAL;
-			break;
-		}
-		ax25->t2 = opt * HZ;
-		break;
-
-	case AX25_N2:
-		if (opt < 1 || opt > 31) {
-			res = -EINVAL;
-			break;
-		}
-		ax25->n2 = opt;
-		break;
-
-	case AX25_T3:
-		if (opt < 1 || opt > UINT_MAX / HZ) {
-			res = -EINVAL;
-			break;
-		}
-		ax25->t3 = opt * HZ;
-		break;
-
-	case AX25_IDLE:
-		if (opt > UINT_MAX / (60 * HZ)) {
-			res = -EINVAL;
-			break;
-		}
-		ax25->idle = opt * 60 * HZ;
-		break;
-
-	case AX25_BACKOFF:
-		if (opt > 2) {
-			res = -EINVAL;
-			break;
-		}
-		ax25->backoff = opt;
-		break;
-
-	case AX25_EXTSEQ:
-		ax25->modulus = opt ? AX25_EMODULUS : AX25_MODULUS;
-		break;
-
-	case AX25_PIDINCL:
-		ax25->pidincl = opt ? 1 : 0;
-		break;
-
-	case AX25_IAMDIGI:
-		ax25->iamdigi = opt ? 1 : 0;
-		break;
-
-	case AX25_PACLEN:
-		if (opt < 16 || opt > 65535) {
-			res = -EINVAL;
-			break;
-		}
-		ax25->paclen = opt;
-		break;
-
-	case SO_BINDTODEVICE:
-		if (optlen > IFNAMSIZ - 1)
-			optlen = IFNAMSIZ - 1;
-
-		memset(devname, 0, sizeof(devname));
-
-		if (copy_from_sockptr(devname, optval, optlen)) {
-			res = -EFAULT;
-			break;
-		}
-
-		if (sk->sk_type == SOCK_SEQPACKET &&
-		   (sock->state != SS_UNCONNECTED ||
-		    sk->sk_state == TCP_LISTEN)) {
-			res = -EADDRNOTAVAIL;
-			break;
-		}
-
-		rcu_read_lock();
-		dev = dev_get_by_name_rcu(&init_net, devname);
-		if (!dev) {
-			rcu_read_unlock();
-			res = -ENODEV;
-			break;
-		}
-
-		if (ax25->ax25_dev) {
-			if (dev == ax25->ax25_dev->dev) {
-				rcu_read_unlock();
-				break;
-			}
-			netdev_put(ax25->ax25_dev->dev, &ax25->dev_tracker);
-			ax25_dev_put(ax25->ax25_dev);
-		}
-
-		ax25->ax25_dev = ax25_dev_ax25dev(dev);
-		if (!ax25->ax25_dev) {
-			rcu_read_unlock();
-			res = -ENODEV;
-			break;
-		}
-		ax25_fillin_cb(ax25, ax25->ax25_dev);
-		netdev_hold(dev, &ax25->dev_tracker, GFP_ATOMIC);
-		ax25_dev_hold(ax25->ax25_dev);
-		rcu_read_unlock();
-		break;
-
-	default:
-		res = -ENOPROTOOPT;
-	}
-	release_sock(sk);
-
-	return res;
-}
-
-static int ax25_getsockopt(struct socket *sock, int level, int optname,
-	char __user *optval, int __user *optlen)
-{
-	struct sock *sk = sock->sk;
-	ax25_cb *ax25;
-	struct ax25_dev *ax25_dev;
-	char devname[IFNAMSIZ];
-	void *valptr;
-	int val = 0;
-	int maxlen, length;
-
-	if (level != SOL_AX25)
-		return -ENOPROTOOPT;
-
-	if (get_user(maxlen, optlen))
-		return -EFAULT;
-
-	if (maxlen < 1)
-		return -EFAULT;
-
-	valptr = &val;
-	length = min_t(unsigned int, maxlen, sizeof(int));
-
-	lock_sock(sk);
-	ax25 = sk_to_ax25(sk);
-
-	switch (optname) {
-	case AX25_WINDOW:
-		val = ax25->window;
-		break;
-
-	case AX25_T1:
-		val = ax25->t1 / HZ;
-		break;
-
-	case AX25_T2:
-		val = ax25->t2 / HZ;
-		break;
-
-	case AX25_N2:
-		val = ax25->n2;
-		break;
-
-	case AX25_T3:
-		val = ax25->t3 / HZ;
-		break;
-
-	case AX25_IDLE:
-		val = ax25->idle / (60 * HZ);
-		break;
-
-	case AX25_BACKOFF:
-		val = ax25->backoff;
-		break;
-
-	case AX25_EXTSEQ:
-		val = (ax25->modulus == AX25_EMODULUS);
-		break;
-
-	case AX25_PIDINCL:
-		val = ax25->pidincl;
-		break;
-
-	case AX25_IAMDIGI:
-		val = ax25->iamdigi;
-		break;
-
-	case AX25_PACLEN:
-		val = ax25->paclen;
-		break;
-
-	case SO_BINDTODEVICE:
-		ax25_dev = ax25->ax25_dev;
-
-		if (ax25_dev != NULL && ax25_dev->dev != NULL) {
-			strscpy(devname, ax25_dev->dev->name, sizeof(devname));
-			length = strlen(devname) + 1;
-		} else {
-			*devname = '\0';
-			length = 1;
-		}
-
-		valptr = devname;
-		break;
-
-	default:
-		release_sock(sk);
-		return -ENOPROTOOPT;
-	}
-	release_sock(sk);
-
-	if (put_user(length, optlen))
-		return -EFAULT;
-
-	return copy_to_user(optval, valptr, length) ? -EFAULT : 0;
-}
-
-static int ax25_listen(struct socket *sock, int backlog)
-{
-	struct sock *sk = sock->sk;
-	int res = 0;
-
-	lock_sock(sk);
-	if (sk->sk_type == SOCK_SEQPACKET && sk->sk_state != TCP_LISTEN) {
-		sk->sk_max_ack_backlog = backlog;
-		sk->sk_state           = TCP_LISTEN;
-		goto out;
-	}
-	res = -EOPNOTSUPP;
-
-out:
-	release_sock(sk);
-
-	return res;
-}
-
-/*
- * XXX: when creating ax25_sock we should update the .obj_size setting
- * below.
- */
-static struct proto ax25_proto = {
-	.name	  = "AX25",
-	.owner	  = THIS_MODULE,
-	.obj_size = sizeof(struct ax25_sock),
-};
-
-static int ax25_create(struct net *net, struct socket *sock, int protocol,
-		       int kern)
-{
-	struct sock *sk;
-	ax25_cb *ax25;
-
-	if (protocol < 0 || protocol > U8_MAX)
-		return -EINVAL;
-
-	if (!net_eq(net, &init_net))
-		return -EAFNOSUPPORT;
-
-	switch (sock->type) {
-	case SOCK_DGRAM:
-		if (protocol == 0 || protocol == PF_AX25)
-			protocol = AX25_P_TEXT;
-		break;
-
-	case SOCK_SEQPACKET:
-		switch (protocol) {
-		case 0:
-		case PF_AX25:	/* For CLX */
-			protocol = AX25_P_TEXT;
-			break;
-		case AX25_P_SEGMENT:
-#ifdef CONFIG_INET
-		case AX25_P_ARP:
-		case AX25_P_IP:
-#endif
-#ifdef CONFIG_NETROM
-		case AX25_P_NETROM:
-#endif
-#ifdef CONFIG_ROSE
-		case AX25_P_ROSE:
-#endif
-			return -ESOCKTNOSUPPORT;
-#ifdef CONFIG_NETROM_MODULE
-		case AX25_P_NETROM:
-			if (ax25_protocol_is_registered(AX25_P_NETROM))
-				return -ESOCKTNOSUPPORT;
-			break;
-#endif
-#ifdef CONFIG_ROSE_MODULE
-		case AX25_P_ROSE:
-			if (ax25_protocol_is_registered(AX25_P_ROSE))
-				return -ESOCKTNOSUPPORT;
-			break;
-#endif
-		default:
-			break;
-		}
-		break;
-
-	case SOCK_RAW:
-		if (!capable(CAP_NET_RAW))
-			return -EPERM;
-		break;
-	default:
-		return -ESOCKTNOSUPPORT;
-	}
-
-	sk = sk_alloc(net, PF_AX25, GFP_ATOMIC, &ax25_proto, kern);
-	if (sk == NULL)
-		return -ENOMEM;
-
-	ax25 = ax25_sk(sk)->cb = ax25_create_cb();
-	if (!ax25) {
-		sk_free(sk);
-		return -ENOMEM;
-	}
-
-	sock_init_data(sock, sk);
-
-	sk->sk_destruct = ax25_free_sock;
-	sock->ops    = &ax25_proto_ops;
-	sk->sk_protocol = protocol;
-
-	ax25->sk    = sk;
-
-	return 0;
-}
-
-struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
-{
-	struct sock *sk;
-	ax25_cb *ax25, *oax25;
-
-	sk = sk_alloc(sock_net(osk), PF_AX25, GFP_ATOMIC, osk->sk_prot, 0);
-	if (sk == NULL)
-		return NULL;
-
-	if ((ax25 = ax25_create_cb()) == NULL) {
-		sk_free(sk);
-		return NULL;
-	}
-
-	switch (osk->sk_type) {
-	case SOCK_DGRAM:
-		break;
-	case SOCK_SEQPACKET:
-		break;
-	default:
-		sk_free(sk);
-		ax25_cb_put(ax25);
-		return NULL;
-	}
-
-	sock_init_data(NULL, sk);
-
-	sk->sk_type     = osk->sk_type;
-	sk->sk_priority = READ_ONCE(osk->sk_priority);
-	sk->sk_protocol = osk->sk_protocol;
-	sk->sk_rcvbuf   = osk->sk_rcvbuf;
-	sk->sk_sndbuf   = osk->sk_sndbuf;
-	sk->sk_state    = TCP_ESTABLISHED;
-	sock_copy_flags(sk, osk);
-
-	oax25 = sk_to_ax25(osk);
-
-	ax25->modulus = oax25->modulus;
-	ax25->backoff = oax25->backoff;
-	ax25->pidincl = oax25->pidincl;
-	ax25->iamdigi = oax25->iamdigi;
-	ax25->rtt     = oax25->rtt;
-	ax25->t1      = oax25->t1;
-	ax25->t2      = oax25->t2;
-	ax25->t3      = oax25->t3;
-	ax25->n2      = oax25->n2;
-	ax25->idle    = oax25->idle;
-	ax25->paclen  = oax25->paclen;
-	ax25->window  = oax25->window;
-
-	ax25->ax25_dev    = ax25_dev;
-	ax25->source_addr = oax25->source_addr;
-
-	if (oax25->digipeat != NULL) {
-		ax25->digipeat = kmemdup(oax25->digipeat, sizeof(ax25_digi),
-					 GFP_ATOMIC);
-		if (ax25->digipeat == NULL) {
-			sk_free(sk);
-			ax25_cb_put(ax25);
-			return NULL;
-		}
-	}
-
-	ax25_sk(sk)->cb = ax25;
-	sk->sk_destruct = ax25_free_sock;
-	ax25->sk    = sk;
-
-	return sk;
-}
-
-static int ax25_release(struct socket *sock)
-{
-	struct sock *sk = sock->sk;
-	ax25_cb *ax25;
-	ax25_dev *ax25_dev;
-
-	if (sk == NULL)
-		return 0;
-
-	sock_hold(sk);
-	lock_sock(sk);
-	sock_orphan(sk);
-	ax25 = sk_to_ax25(sk);
-	ax25_dev = ax25->ax25_dev;
-
-	if (sk->sk_type == SOCK_SEQPACKET) {
-		switch (ax25->state) {
-		case AX25_STATE_0:
-			if (!sock_flag(ax25->sk, SOCK_DEAD)) {
-				release_sock(sk);
-				ax25_disconnect(ax25, 0);
-				lock_sock(sk);
-			}
-			ax25_destroy_socket(ax25);
-			break;
-
-		case AX25_STATE_1:
-		case AX25_STATE_2:
-			ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
-			release_sock(sk);
-			ax25_disconnect(ax25, 0);
-			lock_sock(sk);
-			if (!sock_flag(ax25->sk, SOCK_DESTROY))
-				ax25_destroy_socket(ax25);
-			break;
-
-		case AX25_STATE_3:
-		case AX25_STATE_4:
-			ax25_clear_queues(ax25);
-			ax25->n2count = 0;
-
-			switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
-			case AX25_PROTO_STD_SIMPLEX:
-			case AX25_PROTO_STD_DUPLEX:
-				ax25_send_control(ax25,
-						  AX25_DISC,
-						  AX25_POLLON,
-						  AX25_COMMAND);
-				ax25_stop_t2timer(ax25);
-				ax25_stop_t3timer(ax25);
-				ax25_stop_idletimer(ax25);
-				break;
-#ifdef CONFIG_AX25_DAMA_SLAVE
-			case AX25_PROTO_DAMA_SLAVE:
-				ax25_stop_t3timer(ax25);
-				ax25_stop_idletimer(ax25);
-				break;
-#endif
-			}
-			ax25_calculate_t1(ax25);
-			ax25_start_t1timer(ax25);
-			ax25->state = AX25_STATE_2;
-			sk->sk_state                = TCP_CLOSE;
-			sk->sk_shutdown            |= SEND_SHUTDOWN;
-			sk->sk_state_change(sk);
-			sock_set_flag(sk, SOCK_DESTROY);
-			break;
-
-		default:
-			break;
-		}
-	} else {
-		sk->sk_state     = TCP_CLOSE;
-		sk->sk_shutdown |= SEND_SHUTDOWN;
-		sk->sk_state_change(sk);
-		ax25_destroy_socket(ax25);
-	}
-	if (ax25_dev) {
-		if (!ax25_dev->device_up) {
-			timer_delete_sync(&ax25->timer);
-			timer_delete_sync(&ax25->t1timer);
-			timer_delete_sync(&ax25->t2timer);
-			timer_delete_sync(&ax25->t3timer);
-			timer_delete_sync(&ax25->idletimer);
-		}
-		netdev_put(ax25_dev->dev, &ax25->dev_tracker);
-		ax25_dev_put(ax25_dev);
-	}
-
-	sock->sk   = NULL;
-	release_sock(sk);
-	sock_put(sk);
-
-	return 0;
-}
-
-/*
- *	We support a funny extension here so you can (as root) give any callsign
- *	digipeated via a local address as source. This hack is obsolete now
- *	that we've implemented support for SO_BINDTODEVICE. It is however small
- *	and trivially backward compatible.
- */
-static int ax25_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int addr_len)
-{
-	struct sock *sk = sock->sk;
-	struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr;
-	ax25_dev *ax25_dev = NULL;
-	ax25_uid_assoc *user;
-	ax25_address call;
-	ax25_cb *ax25;
-	int err = 0;
-
-	if (addr_len != sizeof(struct sockaddr_ax25) &&
-	    addr_len != sizeof(struct full_sockaddr_ax25))
-		/* support for old structure may go away some time
-		 * ax25_bind(): uses old (6 digipeater) socket structure.
-		 */
-		if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
-		    (addr_len > sizeof(struct full_sockaddr_ax25)))
-			return -EINVAL;
-
-	if (addr->fsa_ax25.sax25_family != AF_AX25)
-		return -EINVAL;
-
-	user = ax25_findbyuid(current_euid());
-	if (user) {
-		call = user->call;
-		ax25_uid_put(user);
-	} else {
-		if (ax25_uid_policy && !capable(CAP_NET_ADMIN))
-			return -EACCES;
-
-		call = addr->fsa_ax25.sax25_call;
-	}
-
-	lock_sock(sk);
-
-	ax25 = sk_to_ax25(sk);
-	if (!sock_flag(sk, SOCK_ZAPPED)) {
-		err = -EINVAL;
-		goto out;
-	}
-
-	ax25->source_addr = call;
-
-	/*
-	 * User already set interface with SO_BINDTODEVICE
-	 */
-	if (ax25->ax25_dev != NULL)
-		goto done;
-
-	if (addr_len > sizeof(struct sockaddr_ax25) && addr->fsa_ax25.sax25_ndigis == 1) {
-		if (ax25cmp(&addr->fsa_digipeater[0], &null_ax25_address) != 0 &&
-		    (ax25_dev = ax25_addr_ax25dev(&addr->fsa_digipeater[0])) == NULL) {
-			err = -EADDRNOTAVAIL;
-			goto out;
-		}
-	} else {
-		if ((ax25_dev = ax25_addr_ax25dev(&addr->fsa_ax25.sax25_call)) == NULL) {
-			err = -EADDRNOTAVAIL;
-			goto out;
-		}
-	}
-
-	if (ax25_dev) {
-		ax25_fillin_cb(ax25, ax25_dev);
-		netdev_hold(ax25_dev->dev, &ax25->dev_tracker, GFP_ATOMIC);
-	}
-
-done:
-	ax25_cb_add(ax25);
-	sock_reset_flag(sk, SOCK_ZAPPED);
-
-out:
-	release_sock(sk);
-
-	return err;
-}
-
-/*
- *	FIXME: nonblock behaviour looks like it may have a bug.
- */
-static int __must_check ax25_connect(struct socket *sock,
-	struct sockaddr_unsized *uaddr, int addr_len, int flags)
-{
-	struct sock *sk = sock->sk;
-	ax25_cb *ax25 = sk_to_ax25(sk), *ax25t;
-	struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)uaddr;
-	ax25_digi *digi = NULL;
-	int ct = 0, err = 0;
-
-	/*
-	 * some sanity checks. code further down depends on this
-	 */
-
-	if (addr_len == sizeof(struct sockaddr_ax25))
-		/* support for this will go away in early 2.5.x
-		 * ax25_connect(): uses obsolete socket structure
-		 */
-		;
-	else if (addr_len != sizeof(struct full_sockaddr_ax25))
-		/* support for old structure may go away some time
-		 * ax25_connect(): uses old (6 digipeater) socket structure.
-		 */
-		if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
-		    (addr_len > sizeof(struct full_sockaddr_ax25)))
-			return -EINVAL;
-
-
-	if (fsa->fsa_ax25.sax25_family != AF_AX25)
-		return -EINVAL;
-
-	lock_sock(sk);
-
-	/* deal with restarts */
-	if (sock->state == SS_CONNECTING) {
-		switch (sk->sk_state) {
-		case TCP_SYN_SENT: /* still trying */
-			err = -EINPROGRESS;
-			goto out_release;
-
-		case TCP_ESTABLISHED: /* connection established */
-			sock->state = SS_CONNECTED;
-			goto out_release;
-
-		case TCP_CLOSE: /* connection refused */
-			sock->state = SS_UNCONNECTED;
-			err = -ECONNREFUSED;
-			goto out_release;
-		}
-	}
-
-	if (sk->sk_state == TCP_ESTABLISHED && sk->sk_type == SOCK_SEQPACKET) {
-		err = -EISCONN;	/* No reconnect on a seqpacket socket */
-		goto out_release;
-	}
-
-	sk->sk_state   = TCP_CLOSE;
-	sock->state = SS_UNCONNECTED;
-
-	kfree(ax25->digipeat);
-	ax25->digipeat = NULL;
-
-	/*
-	 *	Handle digi-peaters to be used.
-	 */
-	if (addr_len > sizeof(struct sockaddr_ax25) &&
-	    fsa->fsa_ax25.sax25_ndigis != 0) {
-		/* Valid number of digipeaters ? */
-		if (fsa->fsa_ax25.sax25_ndigis < 1 ||
-		    fsa->fsa_ax25.sax25_ndigis > AX25_MAX_DIGIS ||
-		    addr_len < sizeof(struct sockaddr_ax25) +
-		    sizeof(ax25_address) * fsa->fsa_ax25.sax25_ndigis) {
-			err = -EINVAL;
-			goto out_release;
-		}
-
-		if ((digi = kmalloc_obj(ax25_digi)) == NULL) {
-			err = -ENOBUFS;
-			goto out_release;
-		}
-
-		digi->ndigi      = fsa->fsa_ax25.sax25_ndigis;
-		digi->lastrepeat = -1;
-
-		while (ct < fsa->fsa_ax25.sax25_ndigis) {
-			if ((fsa->fsa_digipeater[ct].ax25_call[6] &
-			     AX25_HBIT) && ax25->iamdigi) {
-				digi->repeated[ct] = 1;
-				digi->lastrepeat   = ct;
-			} else {
-				digi->repeated[ct] = 0;
-			}
-			digi->calls[ct] = fsa->fsa_digipeater[ct];
-			ct++;
-		}
-	}
-
-	/* Must bind first - autobinding does not work. */
-	if (sock_flag(sk, SOCK_ZAPPED)) {
-		kfree(digi);
-		err = -EINVAL;
-		goto out_release;
-	}
-
-	/* Check to see if the device has been filled in, error if it hasn't. */
-	if (ax25->ax25_dev == NULL) {
-		kfree(digi);
-		err = -EHOSTUNREACH;
-		goto out_release;
-	}
-
-	if (sk->sk_type == SOCK_SEQPACKET &&
-	    (ax25t=ax25_find_cb(&ax25->source_addr, &fsa->fsa_ax25.sax25_call, digi,
-			 ax25->ax25_dev->dev))) {
-		kfree(digi);
-		err = -EADDRINUSE;		/* Already such a connection */
-		ax25_cb_put(ax25t);
-		goto out_release;
-	}
-
-	ax25->dest_addr = fsa->fsa_ax25.sax25_call;
-	ax25->digipeat  = digi;
-
-	/* First the easy one */
-	if (sk->sk_type != SOCK_SEQPACKET) {
-		sock->state = SS_CONNECTED;
-		sk->sk_state   = TCP_ESTABLISHED;
-		goto out_release;
-	}
-
-	/* Move to connecting socket, ax.25 lapb WAIT_UA.. */
-	sock->state        = SS_CONNECTING;
-	sk->sk_state          = TCP_SYN_SENT;
-
-	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
-	case AX25_PROTO_STD_SIMPLEX:
-	case AX25_PROTO_STD_DUPLEX:
-		ax25_std_establish_data_link(ax25);
-		break;
-
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	case AX25_PROTO_DAMA_SLAVE:
-		ax25->modulus = AX25_MODULUS;
-		ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
-		if (ax25->ax25_dev->dama.slave)
-			ax25_ds_establish_data_link(ax25);
-		else
-			ax25_std_establish_data_link(ax25);
-		break;
-#endif
-	}
-
-	ax25->state = AX25_STATE_1;
-
-	ax25_start_heartbeat(ax25);
-
-	/* Now the loop */
-	if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) {
-		err = -EINPROGRESS;
-		goto out_release;
-	}
-
-	if (sk->sk_state == TCP_SYN_SENT) {
-		DEFINE_WAIT(wait);
-
-		for (;;) {
-			prepare_to_wait(sk_sleep(sk), &wait,
-					TASK_INTERRUPTIBLE);
-			if (sk->sk_state != TCP_SYN_SENT)
-				break;
-			if (!signal_pending(current)) {
-				release_sock(sk);
-				schedule();
-				lock_sock(sk);
-				continue;
-			}
-			err = -ERESTARTSYS;
-			break;
-		}
-		finish_wait(sk_sleep(sk), &wait);
-
-		if (err)
-			goto out_release;
-	}
-
-	if (sk->sk_state != TCP_ESTABLISHED) {
-		/* Not in ABM, not in WAIT_UA -> failed */
-		sock->state = SS_UNCONNECTED;
-		err = sock_error(sk);	/* Always set at this point */
-		goto out_release;
-	}
-
-	sock->state = SS_CONNECTED;
-
-	err = 0;
-out_release:
-	release_sock(sk);
-
-	return err;
-}
-
-static int ax25_accept(struct socket *sock, struct socket *newsock,
-		       struct proto_accept_arg *arg)
-{
-	struct sk_buff *skb;
-	struct sock *newsk;
-	ax25_dev *ax25_dev;
-	DEFINE_WAIT(wait);
-	struct sock *sk;
-	ax25_cb *ax25;
-	int err = 0;
-
-	if (sock->state != SS_UNCONNECTED)
-		return -EINVAL;
-
-	if ((sk = sock->sk) == NULL)
-		return -EINVAL;
-
-	lock_sock(sk);
-	if (sk->sk_type != SOCK_SEQPACKET) {
-		err = -EOPNOTSUPP;
-		goto out;
-	}
-
-	if (sk->sk_state != TCP_LISTEN) {
-		err = -EINVAL;
-		goto out;
-	}
-
-	/*
-	 *	The read queue this time is holding sockets ready to use
-	 *	hooked into the SABM we saved
-	 */
-	for (;;) {
-		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
-		skb = skb_dequeue(&sk->sk_receive_queue);
-		if (skb)
-			break;
-
-		if (arg->flags & O_NONBLOCK) {
-			err = -EWOULDBLOCK;
-			break;
-		}
-		if (!signal_pending(current)) {
-			release_sock(sk);
-			schedule();
-			lock_sock(sk);
-			continue;
-		}
-		err = -ERESTARTSYS;
-		break;
-	}
-	finish_wait(sk_sleep(sk), &wait);
-
-	if (err)
-		goto out;
-
-	newsk		 = skb->sk;
-	sock_graft(newsk, newsock);
-
-	/* Now attach up the new socket */
-	kfree_skb(skb);
-	sk_acceptq_removed(sk);
-	newsock->state = SS_CONNECTED;
-	ax25 = sk_to_ax25(newsk);
-	ax25_dev = ax25->ax25_dev;
-	netdev_hold(ax25_dev->dev, &ax25->dev_tracker, GFP_ATOMIC);
-	ax25_dev_hold(ax25_dev);
-
-out:
-	release_sock(sk);
-
-	return err;
-}
-
-static int ax25_getname(struct socket *sock, struct sockaddr *uaddr,
-	int peer)
-{
-	struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)uaddr;
-	struct sock *sk = sock->sk;
-	unsigned char ndigi, i;
-	ax25_cb *ax25;
-	int err = 0;
-
-	memset(fsa, 0, sizeof(*fsa));
-	lock_sock(sk);
-	ax25 = sk_to_ax25(sk);
-
-	if (peer != 0) {
-		if (sk->sk_state != TCP_ESTABLISHED) {
-			err = -ENOTCONN;
-			goto out;
-		}
-
-		fsa->fsa_ax25.sax25_family = AF_AX25;
-		fsa->fsa_ax25.sax25_call   = ax25->dest_addr;
-
-		if (ax25->digipeat != NULL) {
-			ndigi = ax25->digipeat->ndigi;
-			fsa->fsa_ax25.sax25_ndigis = ndigi;
-			for (i = 0; i < ndigi; i++)
-				fsa->fsa_digipeater[i] =
-						ax25->digipeat->calls[i];
-		}
-	} else {
-		fsa->fsa_ax25.sax25_family = AF_AX25;
-		fsa->fsa_ax25.sax25_call   = ax25->source_addr;
-		fsa->fsa_ax25.sax25_ndigis = 1;
-		if (ax25->ax25_dev != NULL) {
-			memcpy(&fsa->fsa_digipeater[0],
-			       ax25->ax25_dev->dev->dev_addr, AX25_ADDR_LEN);
-		} else {
-			fsa->fsa_digipeater[0] = null_ax25_address;
-		}
-	}
-	err = sizeof (struct full_sockaddr_ax25);
-
-out:
-	release_sock(sk);
-
-	return err;
-}
-
-static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
-{
-	DECLARE_SOCKADDR(struct sockaddr_ax25 *, usax, msg->msg_name);
-	struct sock *sk = sock->sk;
-	struct sockaddr_ax25 sax;
-	struct sk_buff *skb;
-	ax25_digi dtmp, *dp;
-	ax25_cb *ax25;
-	size_t size;
-	int lv, err, addr_len = msg->msg_namelen;
-
-	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
-		return -EINVAL;
-
-	lock_sock(sk);
-	ax25 = sk_to_ax25(sk);
-
-	if (sock_flag(sk, SOCK_ZAPPED)) {
-		err = -EADDRNOTAVAIL;
-		goto out;
-	}
-
-	if (sk->sk_shutdown & SEND_SHUTDOWN) {
-		send_sig(SIGPIPE, current, 0);
-		err = -EPIPE;
-		goto out;
-	}
-
-	if (ax25->ax25_dev == NULL) {
-		err = -ENETUNREACH;
-		goto out;
-	}
-
-	if (len > ax25->ax25_dev->dev->mtu) {
-		err = -EMSGSIZE;
-		goto out;
-	}
-
-	if (usax != NULL) {
-		if (usax->sax25_family != AF_AX25) {
-			err = -EINVAL;
-			goto out;
-		}
-
-		if (addr_len == sizeof(struct sockaddr_ax25))
-			/* ax25_sendmsg(): uses obsolete socket structure */
-			;
-		else if (addr_len != sizeof(struct full_sockaddr_ax25))
-			/* support for old structure may go away some time
-			 * ax25_sendmsg(): uses old (6 digipeater)
-			 * socket structure.
-			 */
-			if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
-			    (addr_len > sizeof(struct full_sockaddr_ax25))) {
-				err = -EINVAL;
-				goto out;
-			}
-
-
-		if (addr_len > sizeof(struct sockaddr_ax25) && usax->sax25_ndigis != 0) {
-			int ct           = 0;
-			struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)usax;
-
-			/* Valid number of digipeaters ? */
-			if (usax->sax25_ndigis < 1 ||
-			    usax->sax25_ndigis > AX25_MAX_DIGIS ||
-			    addr_len < sizeof(struct sockaddr_ax25) +
-			    sizeof(ax25_address) * usax->sax25_ndigis) {
-				err = -EINVAL;
-				goto out;
-			}
-
-			dtmp.ndigi      = usax->sax25_ndigis;
-
-			while (ct < usax->sax25_ndigis) {
-				dtmp.repeated[ct] = 0;
-				dtmp.calls[ct]    = fsa->fsa_digipeater[ct];
-				ct++;
-			}
-
-			dtmp.lastrepeat = 0;
-		}
-
-		sax = *usax;
-		if (sk->sk_type == SOCK_SEQPACKET &&
-		    ax25cmp(&ax25->dest_addr, &sax.sax25_call)) {
-			err = -EISCONN;
-			goto out;
-		}
-		if (usax->sax25_ndigis == 0)
-			dp = NULL;
-		else
-			dp = &dtmp;
-	} else {
-		/*
-		 *	FIXME: 1003.1g - if the socket is like this because
-		 *	it has become closed (not started closed) and is VC
-		 *	we ought to SIGPIPE, EPIPE
-		 */
-		if (sk->sk_state != TCP_ESTABLISHED) {
-			err = -ENOTCONN;
-			goto out;
-		}
-		sax.sax25_family = AF_AX25;
-		sax.sax25_call   = ax25->dest_addr;
-		dp = ax25->digipeat;
-	}
-
-	/* Build a packet */
-	/* Assume the worst case */
-	size = len + ax25->ax25_dev->dev->hard_header_len;
-
-	skb = sock_alloc_send_skb(sk, size, msg->msg_flags&MSG_DONTWAIT, &err);
-	if (skb == NULL)
-		goto out;
-
-	skb_reserve(skb, size - len);
-
-	/* User data follows immediately after the AX.25 data */
-	if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
-		err = -EFAULT;
-		kfree_skb(skb);
-		goto out;
-	}
-
-	skb_reset_network_header(skb);
-
-	/* Add the PID if one is not supplied by the user in the skb */
-	if (!ax25->pidincl)
-		*(u8 *)skb_push(skb, 1) = sk->sk_protocol;
-
-	if (sk->sk_type == SOCK_SEQPACKET) {
-		/* Connected mode sockets go via the LAPB machine */
-		if (sk->sk_state != TCP_ESTABLISHED) {
-			kfree_skb(skb);
-			err = -ENOTCONN;
-			goto out;
-		}
-
-		/* Shove it onto the queue and kick */
-		ax25_output(ax25, ax25->paclen, skb);
-
-		err = len;
-		goto out;
-	}
-
-	skb_push(skb, 1 + ax25_addr_size(dp));
-
-	/* Building AX.25 Header */
-
-	/* Build an AX.25 header */
-	lv = ax25_addr_build(skb->data, &ax25->source_addr, &sax.sax25_call,
-			     dp, AX25_COMMAND, AX25_MODULUS);
-
-	skb_set_transport_header(skb, lv);
-
-	*skb_transport_header(skb) = AX25_UI;
-
-	/* Datagram frames go straight out of the door as UI */
-	ax25_queue_xmit(skb, ax25->ax25_dev->dev);
-
-	err = len;
-
-out:
-	release_sock(sk);
-
-	return err;
-}
-
-static int ax25_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
-			int flags)
-{
-	struct sock *sk = sock->sk;
-	struct sk_buff *skb, *last;
-	struct sk_buff_head *sk_queue;
-	int copied;
-	int err = 0;
-	int off = 0;
-	long timeo;
-
-	lock_sock(sk);
-	/*
-	 * 	This works for seqpacket too. The receiver has ordered the
-	 *	queue for us! We do one quick check first though
-	 */
-	if (sk->sk_type == SOCK_SEQPACKET && sk->sk_state != TCP_ESTABLISHED) {
-		err =  -ENOTCONN;
-		goto out;
-	}
-
-	/*  We need support for non-blocking reads. */
-	sk_queue = &sk->sk_receive_queue;
-	skb = __skb_try_recv_datagram(sk, sk_queue, flags, &off, &err, &last);
-	/* If no packet is available, release_sock(sk) and try again. */
-	if (!skb) {
-		if (err != -EAGAIN)
-			goto out;
-		release_sock(sk);
-		timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
-		while (timeo && !__skb_wait_for_more_packets(sk, sk_queue, &err,
-							     &timeo, last)) {
-			skb = __skb_try_recv_datagram(sk, sk_queue, flags, &off,
-						      &err, &last);
-			if (skb)
-				break;
-
-			if (err != -EAGAIN)
-				goto done;
-		}
-		if (!skb)
-			goto done;
-		lock_sock(sk);
-	}
-
-	if (!sk_to_ax25(sk)->pidincl)
-		skb_pull(skb, 1);		/* Remove PID */
-
-	skb_reset_transport_header(skb);
-	copied = skb->len;
-
-	if (copied > size) {
-		copied = size;
-		msg->msg_flags |= MSG_TRUNC;
-	}
-
-	skb_copy_datagram_msg(skb, 0, msg, copied);
-
-	if (msg->msg_name) {
-		ax25_digi digi;
-		ax25_address src;
-		const unsigned char *mac = skb_mac_header(skb);
-		DECLARE_SOCKADDR(struct sockaddr_ax25 *, sax, msg->msg_name);
-
-		memset(sax, 0, sizeof(struct full_sockaddr_ax25));
-		ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
-				&digi, NULL, NULL);
-		sax->sax25_family = AF_AX25;
-		/* We set this correctly, even though we may not let the
-		   application know the digi calls further down (because it
-		   did NOT ask to know them).  This could get political... **/
-		sax->sax25_ndigis = digi.ndigi;
-		sax->sax25_call   = src;
-
-		if (sax->sax25_ndigis != 0) {
-			int ct;
-			struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)sax;
-
-			for (ct = 0; ct < digi.ndigi; ct++)
-				fsa->fsa_digipeater[ct] = digi.calls[ct];
-		}
-		msg->msg_namelen = sizeof(struct full_sockaddr_ax25);
-	}
-
-	skb_free_datagram(sk, skb);
-	err = copied;
-
-out:
-	release_sock(sk);
-
-done:
-	return err;
-}
-
-static int ax25_shutdown(struct socket *sk, int how)
-{
-	/* FIXME - generate DM and RNR states */
-	return -EOPNOTSUPP;
-}
-
-static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
-	struct sock *sk = sock->sk;
-	void __user *argp = (void __user *)arg;
-	int res = 0;
-
-	lock_sock(sk);
-	switch (cmd) {
-	case TIOCOUTQ: {
-		long amount;
-
-		amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
-		if (amount < 0)
-			amount = 0;
-		res = put_user(amount, (int __user *)argp);
-		break;
-	}
-
-	case TIOCINQ: {
-		struct sk_buff *skb;
-		long amount = 0L;
-		/* These two are safe on a single CPU system as only user tasks fiddle here */
-		if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
-			amount = skb->len;
-		res = put_user(amount, (int __user *) argp);
-		break;
-	}
-
-	case SIOCAX25ADDUID:	/* Add a uid to the uid/call map table */
-	case SIOCAX25DELUID:	/* Delete a uid from the uid/call map table */
-	case SIOCAX25GETUID: {
-		struct sockaddr_ax25 sax25;
-		if (copy_from_user(&sax25, argp, sizeof(sax25))) {
-			res = -EFAULT;
-			break;
-		}
-		res = ax25_uid_ioctl(cmd, &sax25);
-		break;
-	}
-
-	case SIOCAX25NOUID: {	/* Set the default policy (default/bar) */
-		long amount;
-		if (!capable(CAP_NET_ADMIN)) {
-			res = -EPERM;
-			break;
-		}
-		if (get_user(amount, (long __user *)argp)) {
-			res = -EFAULT;
-			break;
-		}
-		if (amount < 0 || amount > AX25_NOUID_BLOCK) {
-			res = -EINVAL;
-			break;
-		}
-		ax25_uid_policy = amount;
-		res = 0;
-		break;
-	}
-
-	case SIOCADDRT:
-	case SIOCDELRT:
-	case SIOCAX25OPTRT:
-		if (!capable(CAP_NET_ADMIN)) {
-			res = -EPERM;
-			break;
-		}
-		res = ax25_rt_ioctl(cmd, argp);
-		break;
-
-	case SIOCAX25CTLCON:
-		if (!capable(CAP_NET_ADMIN)) {
-			res = -EPERM;
-			break;
-		}
-		res = ax25_ctl_ioctl(cmd, argp);
-		break;
-
-	case SIOCAX25GETINFO:
-	case SIOCAX25GETINFOOLD: {
-		ax25_cb *ax25 = sk_to_ax25(sk);
-		struct ax25_info_struct ax25_info;
-
-		ax25_info.t1        = ax25->t1   / HZ;
-		ax25_info.t2        = ax25->t2   / HZ;
-		ax25_info.t3        = ax25->t3   / HZ;
-		ax25_info.idle      = ax25->idle / (60 * HZ);
-		ax25_info.n2        = ax25->n2;
-		ax25_info.t1timer   = ax25_display_timer(&ax25->t1timer)   / HZ;
-		ax25_info.t2timer   = ax25_display_timer(&ax25->t2timer)   / HZ;
-		ax25_info.t3timer   = ax25_display_timer(&ax25->t3timer)   / HZ;
-		ax25_info.idletimer = ax25_display_timer(&ax25->idletimer) / (60 * HZ);
-		ax25_info.n2count   = ax25->n2count;
-		ax25_info.state     = ax25->state;
-		ax25_info.rcv_q     = sk_rmem_alloc_get(sk);
-		ax25_info.snd_q     = sk_wmem_alloc_get(sk);
-		ax25_info.vs        = ax25->vs;
-		ax25_info.vr        = ax25->vr;
-		ax25_info.va        = ax25->va;
-		ax25_info.vs_max    = ax25->vs; /* reserved */
-		ax25_info.paclen    = ax25->paclen;
-		ax25_info.window    = ax25->window;
-
-		/* old structure? */
-		if (cmd == SIOCAX25GETINFOOLD) {
-			static int warned = 0;
-			if (!warned) {
-				printk(KERN_INFO "%s uses old SIOCAX25GETINFO\n",
-					current->comm);
-				warned=1;
-			}
-
-			if (copy_to_user(argp, &ax25_info, sizeof(struct ax25_info_struct_deprecated))) {
-				res = -EFAULT;
-				break;
-			}
-		} else {
-			if (copy_to_user(argp, &ax25_info, sizeof(struct ax25_info_struct))) {
-				res = -EINVAL;
-				break;
-			}
-		}
-		res = 0;
-		break;
-	}
-
-	case SIOCAX25ADDFWD:
-	case SIOCAX25DELFWD: {
-		struct ax25_fwd_struct ax25_fwd;
-		if (!capable(CAP_NET_ADMIN)) {
-			res = -EPERM;
-			break;
-		}
-		if (copy_from_user(&ax25_fwd, argp, sizeof(ax25_fwd))) {
-			res = -EFAULT;
-			break;
-		}
-		res = ax25_fwd_ioctl(cmd, &ax25_fwd);
-		break;
-	}
-
-	case SIOCGIFADDR:
-	case SIOCSIFADDR:
-	case SIOCGIFDSTADDR:
-	case SIOCSIFDSTADDR:
-	case SIOCGIFBRDADDR:
-	case SIOCSIFBRDADDR:
-	case SIOCGIFNETMASK:
-	case SIOCSIFNETMASK:
-	case SIOCGIFMETRIC:
-	case SIOCSIFMETRIC:
-		res = -EINVAL;
-		break;
-
-	default:
-		res = -ENOIOCTLCMD;
-		break;
-	}
-	release_sock(sk);
-
-	return res;
-}
-
-#ifdef CONFIG_PROC_FS
-
-static void *ax25_info_start(struct seq_file *seq, loff_t *pos)
-	__acquires(ax25_list_lock)
-{
-	spin_lock_bh(&ax25_list_lock);
-	return seq_hlist_start(&ax25_list, *pos);
-}
-
-static void *ax25_info_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	return seq_hlist_next(v, &ax25_list, pos);
-}
-
-static void ax25_info_stop(struct seq_file *seq, void *v)
-	__releases(ax25_list_lock)
-{
-	spin_unlock_bh(&ax25_list_lock);
-}
-
-static int ax25_info_show(struct seq_file *seq, void *v)
-{
-	ax25_cb *ax25 = hlist_entry(v, struct ax25_cb, ax25_node);
-	char buf[11];
-	int k;
-
-
-	/*
-	 * New format:
-	 * magic dev src_addr dest_addr,digi1,digi2,.. st vs vr va t1 t1 t2 t2 t3 t3 idle idle n2 n2 rtt window paclen Snd-Q Rcv-Q inode
-	 */
-
-	seq_printf(seq, "%p %s %s%s ",
-		   ax25,
-		   ax25->ax25_dev == NULL? "???" : ax25->ax25_dev->dev->name,
-		   ax2asc(buf, &ax25->source_addr),
-		   ax25->iamdigi? "*":"");
-	seq_printf(seq, "%s", ax2asc(buf, &ax25->dest_addr));
-
-	for (k=0; (ax25->digipeat != NULL) && (k < ax25->digipeat->ndigi); k++) {
-		seq_printf(seq, ",%s%s",
-			   ax2asc(buf, &ax25->digipeat->calls[k]),
-			   ax25->digipeat->repeated[k]? "*":"");
-	}
-
-	seq_printf(seq, " %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %d %d",
-		   ax25->state,
-		   ax25->vs, ax25->vr, ax25->va,
-		   ax25_display_timer(&ax25->t1timer) / HZ, ax25->t1 / HZ,
-		   ax25_display_timer(&ax25->t2timer) / HZ, ax25->t2 / HZ,
-		   ax25_display_timer(&ax25->t3timer) / HZ, ax25->t3 / HZ,
-		   ax25_display_timer(&ax25->idletimer) / (60 * HZ),
-		   ax25->idle / (60 * HZ),
-		   ax25->n2count, ax25->n2,
-		   ax25->rtt / HZ,
-		   ax25->window,
-		   ax25->paclen);
-
-	if (ax25->sk != NULL) {
-		seq_printf(seq, " %d %d %llu\n",
-			   sk_wmem_alloc_get(ax25->sk),
-			   sk_rmem_alloc_get(ax25->sk),
-			   sock_i_ino(ax25->sk));
-	} else {
-		seq_puts(seq, " * * *\n");
-	}
-	return 0;
-}
-
-static const struct seq_operations ax25_info_seqops = {
-	.start = ax25_info_start,
-	.next = ax25_info_next,
-	.stop = ax25_info_stop,
-	.show = ax25_info_show,
-};
-#endif
-
-static const struct net_proto_family ax25_family_ops = {
-	.family =	PF_AX25,
-	.create =	ax25_create,
-	.owner	=	THIS_MODULE,
-};
-
-static const struct proto_ops ax25_proto_ops = {
-	.family		= PF_AX25,
-	.owner		= THIS_MODULE,
-	.release	= ax25_release,
-	.bind		= ax25_bind,
-	.connect	= ax25_connect,
-	.socketpair	= sock_no_socketpair,
-	.accept		= ax25_accept,
-	.getname	= ax25_getname,
-	.poll		= datagram_poll,
-	.ioctl		= ax25_ioctl,
-	.gettstamp	= sock_gettstamp,
-	.listen		= ax25_listen,
-	.shutdown	= ax25_shutdown,
-	.setsockopt	= ax25_setsockopt,
-	.getsockopt	= ax25_getsockopt,
-	.sendmsg	= ax25_sendmsg,
-	.recvmsg	= ax25_recvmsg,
-	.mmap		= sock_no_mmap,
-};
-
-/*
- *	Called by socket.c on kernel start up
- */
-static struct packet_type ax25_packet_type __read_mostly = {
-	.type	=	cpu_to_be16(ETH_P_AX25),
-	.func	=	ax25_kiss_rcv,
-};
-
-static struct notifier_block ax25_dev_notifier = {
-	.notifier_call = ax25_device_event,
-};
-
-static int __init ax25_init(void)
-{
-	int rc = proto_register(&ax25_proto, 0);
-
-	if (rc != 0)
-		goto out;
-
-	sock_register(&ax25_family_ops);
-	dev_add_pack(&ax25_packet_type);
-	register_netdevice_notifier(&ax25_dev_notifier);
-
-	proc_create_seq("ax25_route", 0444, init_net.proc_net, &ax25_rt_seqops);
-	proc_create_seq("ax25", 0444, init_net.proc_net, &ax25_info_seqops);
-	proc_create_seq("ax25_calls", 0444, init_net.proc_net,
-			&ax25_uid_seqops);
-out:
-	return rc;
-}
-module_init(ax25_init);
-
-
-MODULE_AUTHOR("Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>");
-MODULE_DESCRIPTION("The amateur radio AX.25 link layer protocol");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_NETPROTO(PF_AX25);
-
-static void __exit ax25_exit(void)
-{
-	remove_proc_entry("ax25_route", init_net.proc_net);
-	remove_proc_entry("ax25", init_net.proc_net);
-	remove_proc_entry("ax25_calls", init_net.proc_net);
-
-	unregister_netdevice_notifier(&ax25_dev_notifier);
-
-	dev_remove_pack(&ax25_packet_type);
-
-	sock_unregister(PF_AX25);
-	proto_unregister(&ax25_proto);
-
-	ax25_rt_free();
-	ax25_uid_free();
-	ax25_dev_free();
-}
-module_exit(ax25_exit);
diff --git a/net/ax25/ax25_addr.c b/net/ax25/ax25_addr.c
deleted file mode 100644
index f68865a4d0ab..000000000000
--- a/net/ax25/ax25_addr.c
+++ /dev/null
@@ -1,303 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-/*
- * The default broadcast address of an interface is QST-0; the default address
- * is LINUX-1.  The null address is defined as a callsign of all spaces with
- * an SSID of zero.
- */
-
-const ax25_address ax25_bcast =
-	{{'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, 0 << 1}};
-const ax25_address ax25_defaddr =
-	{{'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, 1 << 1}};
-const ax25_address null_ax25_address =
-	{{' ' << 1, ' ' << 1, ' ' << 1, ' ' << 1, ' ' << 1, ' ' << 1, 0 << 1}};
-
-EXPORT_SYMBOL_GPL(ax25_bcast);
-EXPORT_SYMBOL_GPL(ax25_defaddr);
-EXPORT_SYMBOL(null_ax25_address);
-
-/*
- *	ax25 -> ascii conversion
- */
-char *ax2asc(char *buf, const ax25_address *a)
-{
-	char c, *s;
-	int n;
-
-	for (n = 0, s = buf; n < 6; n++) {
-		c = (a->ax25_call[n] >> 1) & 0x7F;
-
-		if (c != ' ') *s++ = c;
-	}
-
-	*s++ = '-';
-
-	if ((n = ((a->ax25_call[6] >> 1) & 0x0F)) > 9) {
-		*s++ = '1';
-		n -= 10;
-	}
-
-	*s++ = n + '0';
-	*s++ = '\0';
-
-	if (*buf == '\0' || *buf == '-')
-	   return "*";
-
-	return buf;
-
-}
-
-EXPORT_SYMBOL(ax2asc);
-
-/*
- *	ascii -> ax25 conversion
- */
-void asc2ax(ax25_address *addr, const char *callsign)
-{
-	const char *s;
-	int n;
-
-	for (s = callsign, n = 0; n < 6; n++) {
-		if (*s != '\0' && *s != '-')
-			addr->ax25_call[n] = *s++;
-		else
-			addr->ax25_call[n] = ' ';
-		addr->ax25_call[n] <<= 1;
-		addr->ax25_call[n] &= 0xFE;
-	}
-
-	if (*s++ == '\0') {
-		addr->ax25_call[6] = 0x00;
-		return;
-	}
-
-	addr->ax25_call[6] = *s++ - '0';
-
-	if (*s != '\0') {
-		addr->ax25_call[6] *= 10;
-		addr->ax25_call[6] += *s++ - '0';
-	}
-
-	addr->ax25_call[6] <<= 1;
-	addr->ax25_call[6] &= 0x1E;
-}
-
-EXPORT_SYMBOL(asc2ax);
-
-/*
- *	Compare two ax.25 addresses
- */
-int ax25cmp(const ax25_address *a, const ax25_address *b)
-{
-	int ct = 0;
-
-	while (ct < 6) {
-		if ((a->ax25_call[ct] & 0xFE) != (b->ax25_call[ct] & 0xFE))	/* Clean off repeater bits */
-			return 1;
-		ct++;
-	}
-
-	if ((a->ax25_call[ct] & 0x1E) == (b->ax25_call[ct] & 0x1E))	/* SSID without control bit */
-		return 0;
-
-	return 2;			/* Partial match */
-}
-
-EXPORT_SYMBOL(ax25cmp);
-
-/*
- *	Compare two AX.25 digipeater paths.
- */
-int ax25digicmp(const ax25_digi *digi1, const ax25_digi *digi2)
-{
-	int i;
-
-	if (digi1->ndigi != digi2->ndigi)
-		return 1;
-
-	if (digi1->lastrepeat != digi2->lastrepeat)
-		return 1;
-
-	for (i = 0; i < digi1->ndigi; i++)
-		if (ax25cmp(&digi1->calls[i], &digi2->calls[i]) != 0)
-			return 1;
-
-	return 0;
-}
-
-/*
- *	Given an AX.25 address pull of to, from, digi list, command/response and the start of data
- *
- */
-const unsigned char *ax25_addr_parse(const unsigned char *buf, int len,
-	ax25_address *src, ax25_address *dest, ax25_digi *digi, int *flags,
-	int *dama)
-{
-	int d = 0;
-
-	if (len < 14) return NULL;
-
-	if (flags != NULL) {
-		*flags = 0;
-
-		if (buf[6] & AX25_CBIT)
-			*flags = AX25_COMMAND;
-		if (buf[13] & AX25_CBIT)
-			*flags = AX25_RESPONSE;
-	}
-
-	if (dama != NULL)
-		*dama = ~buf[13] & AX25_DAMA_FLAG;
-
-	/* Copy to, from */
-	if (dest != NULL)
-		memcpy(dest, buf + 0, AX25_ADDR_LEN);
-	if (src != NULL)
-		memcpy(src,  buf + 7, AX25_ADDR_LEN);
-
-	buf += 2 * AX25_ADDR_LEN;
-	len -= 2 * AX25_ADDR_LEN;
-
-	digi->lastrepeat = -1;
-	digi->ndigi      = 0;
-
-	while (!(buf[-1] & AX25_EBIT)) {
-		if (d >= AX25_MAX_DIGIS)
-			return NULL;
-		if (len < AX25_ADDR_LEN)
-			return NULL;
-
-		memcpy(&digi->calls[d], buf, AX25_ADDR_LEN);
-		digi->ndigi = d + 1;
-
-		if (buf[6] & AX25_HBIT) {
-			digi->repeated[d] = 1;
-			digi->lastrepeat  = d;
-		} else {
-			digi->repeated[d] = 0;
-		}
-
-		buf += AX25_ADDR_LEN;
-		len -= AX25_ADDR_LEN;
-		d++;
-	}
-
-	return buf;
-}
-
-/*
- *	Assemble an AX.25 header from the bits
- */
-int ax25_addr_build(unsigned char *buf, const ax25_address *src,
-	const ax25_address *dest, const ax25_digi *d, int flag, int modulus)
-{
-	int len = 0;
-	int ct  = 0;
-
-	memcpy(buf, dest, AX25_ADDR_LEN);
-	buf[6] &= ~(AX25_EBIT | AX25_CBIT);
-	buf[6] |= AX25_SSSID_SPARE;
-
-	if (flag == AX25_COMMAND) buf[6] |= AX25_CBIT;
-
-	buf += AX25_ADDR_LEN;
-	len += AX25_ADDR_LEN;
-
-	memcpy(buf, src, AX25_ADDR_LEN);
-	buf[6] &= ~(AX25_EBIT | AX25_CBIT);
-	buf[6] &= ~AX25_SSSID_SPARE;
-
-	if (modulus == AX25_MODULUS)
-		buf[6] |= AX25_SSSID_SPARE;
-	else
-		buf[6] |= AX25_ESSID_SPARE;
-
-	if (flag == AX25_RESPONSE) buf[6] |= AX25_CBIT;
-
-	/*
-	 *	Fast path the normal digiless path
-	 */
-	if (d == NULL || d->ndigi == 0) {
-		buf[6] |= AX25_EBIT;
-		return 2 * AX25_ADDR_LEN;
-	}
-
-	buf += AX25_ADDR_LEN;
-	len += AX25_ADDR_LEN;
-
-	while (ct < d->ndigi) {
-		memcpy(buf, &d->calls[ct], AX25_ADDR_LEN);
-
-		if (d->repeated[ct])
-			buf[6] |= AX25_HBIT;
-		else
-			buf[6] &= ~AX25_HBIT;
-
-		buf[6] &= ~AX25_EBIT;
-		buf[6] |= AX25_SSSID_SPARE;
-
-		buf += AX25_ADDR_LEN;
-		len += AX25_ADDR_LEN;
-		ct++;
-	}
-
-	buf[-1] |= AX25_EBIT;
-
-	return len;
-}
-
-int ax25_addr_size(const ax25_digi *dp)
-{
-	if (dp == NULL)
-		return 2 * AX25_ADDR_LEN;
-
-	return AX25_ADDR_LEN * (2 + dp->ndigi);
-}
-
-/*
- *	Reverse Digipeat List. May not pass both parameters as same struct
- */
-void ax25_digi_invert(const ax25_digi *in, ax25_digi *out)
-{
-	int ct;
-
-	out->ndigi      = in->ndigi;
-	out->lastrepeat = in->ndigi - in->lastrepeat - 2;
-
-	/* Invert the digipeaters */
-	for (ct = 0; ct < in->ndigi; ct++) {
-		out->calls[ct] = in->calls[in->ndigi - ct - 1];
-
-		if (ct <= out->lastrepeat) {
-			out->calls[ct].ax25_call[6] |= AX25_HBIT;
-			out->repeated[ct]            = 1;
-		} else {
-			out->calls[ct].ax25_call[6] &= ~AX25_HBIT;
-			out->repeated[ct]            = 0;
-		}
-	}
-}
diff --git a/net/ax25/ax25_dev.c b/net/ax25/ax25_dev.c
deleted file mode 100644
index 3c0544fc4ad5..000000000000
--- a/net/ax25/ax25_dev.c
+++ /dev/null
@@ -1,200 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/slab.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/spinlock.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/list.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-
-static LIST_HEAD(ax25_dev_list);
-DEFINE_SPINLOCK(ax25_dev_lock);
-
-ax25_dev *ax25_addr_ax25dev(ax25_address *addr)
-{
-	ax25_dev *ax25_dev, *res = NULL;
-
-	spin_lock_bh(&ax25_dev_lock);
-	list_for_each_entry(ax25_dev, &ax25_dev_list, list)
-		if (ax25cmp(addr, (const ax25_address *)ax25_dev->dev->dev_addr) == 0) {
-			res = ax25_dev;
-			ax25_dev_hold(ax25_dev);
-			break;
-		}
-	spin_unlock_bh(&ax25_dev_lock);
-
-	return res;
-}
-
-/*
- *	This is called when an interface is brought up. These are
- *	reasonable defaults.
- */
-void ax25_dev_device_up(struct net_device *dev)
-{
-	ax25_dev *ax25_dev;
-
-	ax25_dev = kzalloc_obj(*ax25_dev);
-	if (!ax25_dev) {
-		printk(KERN_ERR "AX.25: ax25_dev_device_up - out of memory\n");
-		return;
-	}
-
-	refcount_set(&ax25_dev->refcount, 1);
-	ax25_dev->dev     = dev;
-	netdev_hold(dev, &ax25_dev->dev_tracker, GFP_KERNEL);
-	ax25_dev->forward = NULL;
-	ax25_dev->device_up = true;
-
-	ax25_dev->values[AX25_VALUES_IPDEFMODE] = AX25_DEF_IPDEFMODE;
-	ax25_dev->values[AX25_VALUES_AXDEFMODE] = AX25_DEF_AXDEFMODE;
-	ax25_dev->values[AX25_VALUES_BACKOFF]   = AX25_DEF_BACKOFF;
-	ax25_dev->values[AX25_VALUES_CONMODE]   = AX25_DEF_CONMODE;
-	ax25_dev->values[AX25_VALUES_WINDOW]    = AX25_DEF_WINDOW;
-	ax25_dev->values[AX25_VALUES_EWINDOW]   = AX25_DEF_EWINDOW;
-	ax25_dev->values[AX25_VALUES_T1]        = AX25_DEF_T1;
-	ax25_dev->values[AX25_VALUES_T2]        = AX25_DEF_T2;
-	ax25_dev->values[AX25_VALUES_T3]        = AX25_DEF_T3;
-	ax25_dev->values[AX25_VALUES_IDLE]	= AX25_DEF_IDLE;
-	ax25_dev->values[AX25_VALUES_N2]        = AX25_DEF_N2;
-	ax25_dev->values[AX25_VALUES_PACLEN]	= AX25_DEF_PACLEN;
-	ax25_dev->values[AX25_VALUES_PROTOCOL]  = AX25_DEF_PROTOCOL;
-
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	ax25_dev->values[AX25_VALUES_DS_TIMEOUT]= AX25_DEF_DS_TIMEOUT;
-
-	ax25_ds_setup_timer(ax25_dev);
-#endif
-
-	spin_lock_bh(&ax25_dev_lock);
-	list_add(&ax25_dev->list, &ax25_dev_list);
-	rcu_assign_pointer(dev->ax25_ptr, ax25_dev);
-	spin_unlock_bh(&ax25_dev_lock);
-
-	ax25_register_dev_sysctl(ax25_dev);
-}
-
-void ax25_dev_device_down(struct net_device *dev)
-{
-	ax25_dev *s, *ax25_dev;
-
-	if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
-		return;
-
-	ax25_unregister_dev_sysctl(ax25_dev);
-
-	spin_lock_bh(&ax25_dev_lock);
-
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	timer_shutdown_sync(&ax25_dev->dama.slave_timer);
-#endif
-
-	/*
-	 *	Remove any packet forwarding that points to this device.
-	 */
-	list_for_each_entry(s, &ax25_dev_list, list)
-		if (s->forward == dev)
-			s->forward = NULL;
-
-	list_for_each_entry(s, &ax25_dev_list, list) {
-		if (s == ax25_dev) {
-			list_del(&s->list);
-			break;
-		}
-	}
-
-	RCU_INIT_POINTER(dev->ax25_ptr, NULL);
-	spin_unlock_bh(&ax25_dev_lock);
-	netdev_put(dev, &ax25_dev->dev_tracker);
-	ax25_dev_put(ax25_dev);
-}
-
-int ax25_fwd_ioctl(unsigned int cmd, struct ax25_fwd_struct *fwd)
-{
-	ax25_dev *ax25_dev, *fwd_dev;
-
-	if ((ax25_dev = ax25_addr_ax25dev(&fwd->port_from)) == NULL)
-		return -EINVAL;
-
-	switch (cmd) {
-	case SIOCAX25ADDFWD:
-		fwd_dev = ax25_addr_ax25dev(&fwd->port_to);
-		if (!fwd_dev) {
-			ax25_dev_put(ax25_dev);
-			return -EINVAL;
-		}
-		if (ax25_dev->forward) {
-			ax25_dev_put(fwd_dev);
-			ax25_dev_put(ax25_dev);
-			return -EINVAL;
-		}
-		ax25_dev->forward = fwd_dev->dev;
-		ax25_dev_put(fwd_dev);
-		ax25_dev_put(ax25_dev);
-		break;
-
-	case SIOCAX25DELFWD:
-		if (!ax25_dev->forward) {
-			ax25_dev_put(ax25_dev);
-			return -EINVAL;
-		}
-		ax25_dev->forward = NULL;
-		ax25_dev_put(ax25_dev);
-		break;
-
-	default:
-		ax25_dev_put(ax25_dev);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-struct net_device *ax25_fwd_dev(struct net_device *dev)
-{
-	ax25_dev *ax25_dev;
-
-	if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
-		return dev;
-
-	if (ax25_dev->forward == NULL)
-		return dev;
-
-	return ax25_dev->forward;
-}
-
-/*
- *	Free all memory associated with device structures.
- */
-void __exit ax25_dev_free(void)
-{
-	ax25_dev *s, *n;
-
-	spin_lock_bh(&ax25_dev_lock);
-	list_for_each_entry_safe(s, n, &ax25_dev_list, list) {
-		netdev_put(s->dev, &s->dev_tracker);
-		list_del(&s->list);
-		ax25_dev_put(s);
-	}
-	spin_unlock_bh(&ax25_dev_lock);
-}
diff --git a/net/ax25/ax25_ds_in.c b/net/ax25/ax25_ds_in.c
deleted file mode 100644
index c62f8fb06189..000000000000
--- a/net/ax25/ax25_ds_in.c
+++ /dev/null
@@ -1,298 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-/*
- *	State machine for state 1, Awaiting Connection State.
- *	The handling of the timer(s) is in file ax25_ds_timer.c.
- *	Handling of state 0 and connection release is in ax25.c.
- */
-static int ax25_ds_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
-{
-	switch (frametype) {
-	case AX25_SABM:
-		ax25->modulus = AX25_MODULUS;
-		ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
-		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
-		break;
-
-	case AX25_SABME:
-		ax25->modulus = AX25_EMODULUS;
-		ax25->window  =  ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
-		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
-		break;
-
-	case AX25_DISC:
-		ax25_send_control(ax25, AX25_DM, pf, AX25_RESPONSE);
-		break;
-
-	case AX25_UA:
-		ax25_calculate_rtt(ax25);
-		ax25_stop_t1timer(ax25);
-		ax25_start_t3timer(ax25);
-		ax25_start_idletimer(ax25);
-		ax25->vs      = 0;
-		ax25->va      = 0;
-		ax25->vr      = 0;
-		ax25->state   = AX25_STATE_3;
-		ax25->n2count = 0;
-		if (ax25->sk != NULL) {
-			bh_lock_sock(ax25->sk);
-			ax25->sk->sk_state = TCP_ESTABLISHED;
-			/*
-			 * For WAIT_SABM connections we will produce an accept
-			 * ready socket here
-			 */
-			if (!sock_flag(ax25->sk, SOCK_DEAD))
-				ax25->sk->sk_state_change(ax25->sk);
-			bh_unlock_sock(ax25->sk);
-		}
-		ax25_dama_on(ax25);
-
-		/* according to DK4EG's spec we are required to
-		 * send a RR RESPONSE FINAL NR=0.
-		 */
-
-		ax25_std_enquiry_response(ax25);
-		break;
-
-	case AX25_DM:
-		if (pf)
-			ax25_disconnect(ax25, ECONNREFUSED);
-		break;
-
-	default:
-		if (pf)
-			ax25_send_control(ax25, AX25_SABM, AX25_POLLON, AX25_COMMAND);
-		break;
-	}
-
-	return 0;
-}
-
-/*
- *	State machine for state 2, Awaiting Release State.
- *	The handling of the timer(s) is in file ax25_ds_timer.c
- *	Handling of state 0 and connection release is in ax25.c.
- */
-static int ax25_ds_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
-{
-	switch (frametype) {
-	case AX25_SABM:
-	case AX25_SABME:
-		ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
-		ax25_dama_off(ax25);
-		break;
-
-	case AX25_DISC:
-		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
-		ax25_dama_off(ax25);
-		ax25_disconnect(ax25, 0);
-		break;
-
-	case AX25_DM:
-	case AX25_UA:
-		if (pf) {
-			ax25_dama_off(ax25);
-			ax25_disconnect(ax25, 0);
-		}
-		break;
-
-	case AX25_I:
-	case AX25_REJ:
-	case AX25_RNR:
-	case AX25_RR:
-		if (pf) {
-			ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
-			ax25_dama_off(ax25);
-		}
-		break;
-
-	default:
-		break;
-	}
-
-	return 0;
-}
-
-/*
- *	State machine for state 3, Connected State.
- *	The handling of the timer(s) is in file ax25_timer.c
- *	Handling of state 0 and connection release is in ax25.c.
- */
-static int ax25_ds_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
-{
-	int queued = 0;
-
-	switch (frametype) {
-	case AX25_SABM:
-	case AX25_SABME:
-		if (frametype == AX25_SABM) {
-			ax25->modulus   = AX25_MODULUS;
-			ax25->window    = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
-		} else {
-			ax25->modulus   = AX25_EMODULUS;
-			ax25->window    = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
-		}
-		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
-		ax25_stop_t1timer(ax25);
-		ax25_start_t3timer(ax25);
-		ax25_start_idletimer(ax25);
-		ax25->condition = 0x00;
-		ax25->vs        = 0;
-		ax25->va        = 0;
-		ax25->vr        = 0;
-		ax25_requeue_frames(ax25);
-		ax25_dama_on(ax25);
-		break;
-
-	case AX25_DISC:
-		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
-		ax25_dama_off(ax25);
-		ax25_disconnect(ax25, 0);
-		break;
-
-	case AX25_DM:
-		ax25_dama_off(ax25);
-		ax25_disconnect(ax25, ECONNRESET);
-		break;
-
-	case AX25_RR:
-	case AX25_RNR:
-		if (frametype == AX25_RR)
-			ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
-		else
-			ax25->condition |= AX25_COND_PEER_RX_BUSY;
-
-		if (ax25_validate_nr(ax25, nr)) {
-			if (ax25_check_iframes_acked(ax25, nr))
-				ax25->n2count=0;
-			if (type == AX25_COMMAND && pf)
-				ax25_ds_enquiry_response(ax25);
-		} else {
-			ax25_ds_nr_error_recovery(ax25);
-			ax25->state = AX25_STATE_1;
-		}
-		break;
-
-	case AX25_REJ:
-		ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
-
-		if (ax25_validate_nr(ax25, nr)) {
-			if (ax25->va != nr)
-				ax25->n2count=0;
-
-			ax25_frames_acked(ax25, nr);
-			ax25_calculate_rtt(ax25);
-			ax25_stop_t1timer(ax25);
-			ax25_start_t3timer(ax25);
-			ax25_requeue_frames(ax25);
-
-			if (type == AX25_COMMAND && pf)
-				ax25_ds_enquiry_response(ax25);
-		} else {
-			ax25_ds_nr_error_recovery(ax25);
-			ax25->state = AX25_STATE_1;
-		}
-		break;
-
-	case AX25_I:
-		if (!ax25_validate_nr(ax25, nr)) {
-			ax25_ds_nr_error_recovery(ax25);
-			ax25->state = AX25_STATE_1;
-			break;
-		}
-		if (ax25->condition & AX25_COND_PEER_RX_BUSY) {
-			ax25_frames_acked(ax25, nr);
-			ax25->n2count = 0;
-		} else {
-			if (ax25_check_iframes_acked(ax25, nr))
-				ax25->n2count = 0;
-		}
-		if (ax25->condition & AX25_COND_OWN_RX_BUSY) {
-			if (pf) ax25_ds_enquiry_response(ax25);
-			break;
-		}
-		if (ns == ax25->vr) {
-			ax25->vr = (ax25->vr + 1) % ax25->modulus;
-			queued = ax25_rx_iframe(ax25, skb);
-			if (ax25->condition & AX25_COND_OWN_RX_BUSY)
-				ax25->vr = ns;	/* ax25->vr - 1 */
-			ax25->condition &= ~AX25_COND_REJECT;
-			if (pf) {
-				ax25_ds_enquiry_response(ax25);
-			} else {
-				if (!(ax25->condition & AX25_COND_ACK_PENDING)) {
-					ax25->condition |= AX25_COND_ACK_PENDING;
-					ax25_start_t2timer(ax25);
-				}
-			}
-		} else {
-			if (ax25->condition & AX25_COND_REJECT) {
-				if (pf) ax25_ds_enquiry_response(ax25);
-			} else {
-				ax25->condition |= AX25_COND_REJECT;
-				ax25_ds_enquiry_response(ax25);
-				ax25->condition &= ~AX25_COND_ACK_PENDING;
-			}
-		}
-		break;
-
-	case AX25_FRMR:
-	case AX25_ILLEGAL:
-		ax25_ds_establish_data_link(ax25);
-		ax25->state = AX25_STATE_1;
-		break;
-
-	default:
-		break;
-	}
-
-	return queued;
-}
-
-/*
- *	Higher level upcall for a LAPB frame
- */
-int ax25_ds_frame_in(ax25_cb *ax25, struct sk_buff *skb, int type)
-{
-	int queued = 0, frametype, ns, nr, pf;
-
-	frametype = ax25_decode(ax25, skb, &ns, &nr, &pf);
-
-	switch (ax25->state) {
-	case AX25_STATE_1:
-		queued = ax25_ds_state1_machine(ax25, skb, frametype, pf, type);
-		break;
-	case AX25_STATE_2:
-		queued = ax25_ds_state2_machine(ax25, skb, frametype, pf, type);
-		break;
-	case AX25_STATE_3:
-		queued = ax25_ds_state3_machine(ax25, skb, frametype, ns, nr, pf, type);
-		break;
-	}
-
-	return queued;
-}
diff --git a/net/ax25/ax25_ds_subr.c b/net/ax25/ax25_ds_subr.c
deleted file mode 100644
index f00e27df3c76..000000000000
--- a/net/ax25/ax25_ds_subr.c
+++ /dev/null
@@ -1,204 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/spinlock.h>
-#include <linux/net.h>
-#include <linux/gfp.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-void ax25_ds_nr_error_recovery(ax25_cb *ax25)
-{
-	ax25_ds_establish_data_link(ax25);
-}
-
-/*
- *	dl1bke 960114: transmit I frames on DAMA poll
- */
-void ax25_ds_enquiry_response(ax25_cb *ax25)
-{
-	ax25_cb *ax25o;
-
-	/* Please note that neither DK4EG's nor DG2FEF's
-	 * DAMA spec mention the following behaviour as seen
-	 * with TheFirmware:
-	 *
-	 * 	DB0ACH->DL1BKE <RR C P R0> [DAMA]
-	 *	DL1BKE->DB0ACH <I NR=0 NS=0>
-	 *	DL1BKE-7->DB0PRA-6 DB0ACH <I C S3 R5>
-	 *	DL1BKE->DB0ACH <RR R F R0>
-	 *
-	 * The Flexnet DAMA Master implementation apparently
-	 * insists on the "proper" AX.25 behaviour:
-	 *
-	 * 	DB0ACH->DL1BKE <RR C P R0> [DAMA]
-	 *	DL1BKE->DB0ACH <RR R F R0>
-	 *	DL1BKE->DB0ACH <I NR=0 NS=0>
-	 *	DL1BKE-7->DB0PRA-6 DB0ACH <I C S3 R5>
-	 *
-	 * Flexnet refuses to send us *any* I frame if we send
-	 * a REJ in case AX25_COND_REJECT is set. It is superfluous in
-	 * this mode anyway (a RR or RNR invokes the retransmission).
-	 * Is this a Flexnet bug?
-	 */
-
-	ax25_std_enquiry_response(ax25);
-
-	if (!(ax25->condition & AX25_COND_PEER_RX_BUSY)) {
-		ax25_requeue_frames(ax25);
-		ax25_kick(ax25);
-	}
-
-	if (ax25->state == AX25_STATE_1 || ax25->state == AX25_STATE_2 || skb_peek(&ax25->ack_queue) != NULL)
-		ax25_ds_t1_timeout(ax25);
-	else
-		ax25->n2count = 0;
-
-	ax25_start_t3timer(ax25);
-	ax25_ds_set_timer(ax25->ax25_dev);
-
-	spin_lock(&ax25_list_lock);
-	ax25_for_each(ax25o, &ax25_list) {
-		if (ax25o == ax25)
-			continue;
-
-		if (ax25o->ax25_dev != ax25->ax25_dev)
-			continue;
-
-		if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2) {
-			ax25_ds_t1_timeout(ax25o);
-			continue;
-		}
-
-		if (!(ax25o->condition & AX25_COND_PEER_RX_BUSY) && ax25o->state == AX25_STATE_3) {
-			ax25_requeue_frames(ax25o);
-			ax25_kick(ax25o);
-		}
-
-		if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2 || skb_peek(&ax25o->ack_queue) != NULL)
-			ax25_ds_t1_timeout(ax25o);
-
-		/* do not start T3 for listening sockets (tnx DD8NE) */
-
-		if (ax25o->state != AX25_STATE_0)
-			ax25_start_t3timer(ax25o);
-	}
-	spin_unlock(&ax25_list_lock);
-}
-
-void ax25_ds_establish_data_link(ax25_cb *ax25)
-{
-	ax25->condition &= AX25_COND_DAMA_MODE;
-	ax25->n2count    = 0;
-	ax25_calculate_t1(ax25);
-	ax25_start_t1timer(ax25);
-	ax25_stop_t2timer(ax25);
-	ax25_start_t3timer(ax25);
-}
-
-/*
- *	:::FIXME:::
- *	This is a kludge. Not all drivers recognize kiss commands.
- *	We need a driver level  request to switch duplex mode, that does
- *	either SCC changing, PI config or KISS as required. Currently
- *	this request isn't reliable.
- */
-static void ax25_kiss_cmd(ax25_dev *ax25_dev, unsigned char cmd, unsigned char param)
-{
-	struct sk_buff *skb;
-	unsigned char *p;
-
-	if (ax25_dev->dev == NULL)
-		return;
-
-	if ((skb = alloc_skb(2, GFP_ATOMIC)) == NULL)
-		return;
-
-	skb_reset_network_header(skb);
-	p = skb_put(skb, 2);
-
-	*p++ = cmd;
-	*p++ = param;
-
-	skb->protocol = ax25_type_trans(skb, ax25_dev->dev);
-
-	dev_queue_xmit(skb);
-}
-
-/*
- *	A nasty problem arises if we count the number of DAMA connections
- *	wrong, especially when connections on the device already existed
- *	and our network node (or the sysop) decides to turn on DAMA Master
- *	mode. We thus flag the 'real' slave connections with
- *	ax25->dama_slave=1 and look on every disconnect if still slave
- *	connections exist.
- */
-static int ax25_check_dama_slave(ax25_dev *ax25_dev)
-{
-	ax25_cb *ax25;
-	int res = 0;
-
-	spin_lock(&ax25_list_lock);
-	ax25_for_each(ax25, &ax25_list)
-		if (ax25->ax25_dev == ax25_dev && (ax25->condition & AX25_COND_DAMA_MODE) && ax25->state > AX25_STATE_1) {
-			res = 1;
-			break;
-		}
-	spin_unlock(&ax25_list_lock);
-
-	return res;
-}
-
-static void ax25_dev_dama_on(ax25_dev *ax25_dev)
-{
-	if (ax25_dev == NULL)
-		return;
-
-	if (ax25_dev->dama.slave == 0)
-		ax25_kiss_cmd(ax25_dev, 5, 1);
-
-	ax25_dev->dama.slave = 1;
-	ax25_ds_set_timer(ax25_dev);
-}
-
-void ax25_dev_dama_off(ax25_dev *ax25_dev)
-{
-	if (ax25_dev == NULL)
-		return;
-
-	if (ax25_dev->dama.slave && !ax25_check_dama_slave(ax25_dev)) {
-		ax25_kiss_cmd(ax25_dev, 5, 0);
-		ax25_dev->dama.slave = 0;
-		ax25_ds_del_timer(ax25_dev);
-	}
-}
-
-void ax25_dama_on(ax25_cb *ax25)
-{
-	ax25_dev_dama_on(ax25->ax25_dev);
-	ax25->condition |= AX25_COND_DAMA_MODE;
-}
-
-void ax25_dama_off(ax25_cb *ax25)
-{
-	ax25->condition &= ~AX25_COND_DAMA_MODE;
-	ax25_dev_dama_off(ax25->ax25_dev);
-}
diff --git a/net/ax25/ax25_ds_timer.c b/net/ax25/ax25_ds_timer.c
deleted file mode 100644
index 0c9e7775aa54..000000000000
--- a/net/ax25/ax25_ds_timer.c
+++ /dev/null
@@ -1,235 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/spinlock.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/jiffies.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <net/tcp_states.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-static void ax25_ds_timeout(struct timer_list *);
-
-/*
- *	Add DAMA slave timeout timer to timer list.
- *	Unlike the connection based timers the timeout function gets
- *	triggered every second. Please note that NET_AX25_DAMA_SLAVE_TIMEOUT
- *	(aka /proc/sys/net/ax25/{dev}/dama_slave_timeout) is still in
- *	1/10th of a second.
- */
-
-void ax25_ds_setup_timer(ax25_dev *ax25_dev)
-{
-	timer_setup(&ax25_dev->dama.slave_timer, ax25_ds_timeout, 0);
-}
-
-void ax25_ds_del_timer(ax25_dev *ax25_dev)
-{
-	if (ax25_dev)
-		timer_delete(&ax25_dev->dama.slave_timer);
-}
-
-void ax25_ds_set_timer(ax25_dev *ax25_dev)
-{
-	if (ax25_dev == NULL)		/* paranoia */
-		return;
-
-	ax25_dev->dama.slave_timeout =
-		msecs_to_jiffies(ax25_dev->values[AX25_VALUES_DS_TIMEOUT]) / 10;
-	mod_timer(&ax25_dev->dama.slave_timer, jiffies + HZ);
-}
-
-/*
- *	DAMA Slave Timeout
- *	Silently discard all (slave) connections in case our master forgot us...
- */
-
-static void ax25_ds_timeout(struct timer_list *t)
-{
-	ax25_dev *ax25_dev = timer_container_of(ax25_dev, t, dama.slave_timer);
-	ax25_cb *ax25;
-
-	if (ax25_dev == NULL || !ax25_dev->dama.slave)
-		return;			/* Yikes! */
-
-	if (!ax25_dev->dama.slave_timeout || --ax25_dev->dama.slave_timeout) {
-		ax25_ds_set_timer(ax25_dev);
-		return;
-	}
-
-	spin_lock(&ax25_list_lock);
-	ax25_for_each(ax25, &ax25_list) {
-		if (ax25->ax25_dev != ax25_dev || !(ax25->condition & AX25_COND_DAMA_MODE))
-			continue;
-
-		ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
-		ax25_disconnect(ax25, ETIMEDOUT);
-	}
-	spin_unlock(&ax25_list_lock);
-
-	ax25_dev_dama_off(ax25_dev);
-}
-
-void ax25_ds_heartbeat_expiry(ax25_cb *ax25)
-{
-	struct sock *sk=ax25->sk;
-
-	if (sk)
-		bh_lock_sock(sk);
-
-	switch (ax25->state) {
-
-	case AX25_STATE_0:
-	case AX25_STATE_2:
-		/* Magic here: If we listen() and a new link dies before it
-		   is accepted() it isn't 'dead' so doesn't get removed. */
-		if (!sk || sock_flag(sk, SOCK_DESTROY) ||
-		    (sk->sk_state == TCP_LISTEN &&
-		     sock_flag(sk, SOCK_DEAD))) {
-			if (sk) {
-				sock_hold(sk);
-				ax25_destroy_socket(ax25);
-				bh_unlock_sock(sk);
-				/* Ungrab socket and destroy it */
-				sock_put(sk);
-			} else
-				ax25_destroy_socket(ax25);
-			return;
-		}
-		break;
-
-	case AX25_STATE_3:
-		/*
-		 * Check the state of the receive buffer.
-		 */
-		if (sk != NULL) {
-			if (atomic_read(&sk->sk_rmem_alloc) <
-			    (sk->sk_rcvbuf >> 1) &&
-			    (ax25->condition & AX25_COND_OWN_RX_BUSY)) {
-				ax25->condition &= ~AX25_COND_OWN_RX_BUSY;
-				ax25->condition &= ~AX25_COND_ACK_PENDING;
-				break;
-			}
-		}
-		break;
-	}
-
-	if (sk)
-		bh_unlock_sock(sk);
-
-	ax25_start_heartbeat(ax25);
-}
-
-/* dl1bke 960114: T3 works much like the IDLE timeout, but
- *                gets reloaded with every frame for this
- *		  connection.
- */
-void ax25_ds_t3timer_expiry(ax25_cb *ax25)
-{
-	ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
-	ax25_dama_off(ax25);
-	ax25_disconnect(ax25, ETIMEDOUT);
-}
-
-/* dl1bke 960228: close the connection when IDLE expires.
- *		  unlike T3 this timer gets reloaded only on
- *		  I frames.
- */
-void ax25_ds_idletimer_expiry(ax25_cb *ax25)
-{
-	ax25_clear_queues(ax25);
-
-	ax25->n2count = 0;
-	ax25->state = AX25_STATE_2;
-
-	ax25_calculate_t1(ax25);
-	ax25_start_t1timer(ax25);
-	ax25_stop_t3timer(ax25);
-
-	if (ax25->sk != NULL) {
-		bh_lock_sock(ax25->sk);
-		ax25->sk->sk_state     = TCP_CLOSE;
-		ax25->sk->sk_err       = 0;
-		ax25->sk->sk_shutdown |= SEND_SHUTDOWN;
-		if (!sock_flag(ax25->sk, SOCK_DEAD)) {
-			ax25->sk->sk_state_change(ax25->sk);
-			sock_set_flag(ax25->sk, SOCK_DEAD);
-		}
-		bh_unlock_sock(ax25->sk);
-	}
-}
-
-/* dl1bke 960114: The DAMA protocol requires to send data and SABM/DISC
- *                within the poll of any connected channel. Remember
- *                that we are not allowed to send anything unless we
- *                get polled by the Master.
- *
- *                Thus we'll have to do parts of our T1 handling in
- *                ax25_enquiry_response().
- */
-void ax25_ds_t1_timeout(ax25_cb *ax25)
-{
-	switch (ax25->state) {
-	case AX25_STATE_1:
-		if (ax25->n2count == ax25->n2) {
-			if (ax25->modulus == AX25_MODULUS) {
-				ax25_disconnect(ax25, ETIMEDOUT);
-				return;
-			} else {
-				ax25->modulus = AX25_MODULUS;
-				ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
-				ax25->n2count = 0;
-				ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND);
-			}
-		} else {
-			ax25->n2count++;
-			if (ax25->modulus == AX25_MODULUS)
-				ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND);
-			else
-				ax25_send_control(ax25, AX25_SABME, AX25_POLLOFF, AX25_COMMAND);
-		}
-		break;
-
-	case AX25_STATE_2:
-		if (ax25->n2count == ax25->n2) {
-			ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
-			if (!sock_flag(ax25->sk, SOCK_DESTROY))
-				ax25_disconnect(ax25, ETIMEDOUT);
-			return;
-		} else {
-			ax25->n2count++;
-		}
-		break;
-
-	case AX25_STATE_3:
-		if (ax25->n2count == ax25->n2) {
-			ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
-			ax25_disconnect(ax25, ETIMEDOUT);
-			return;
-		} else {
-			ax25->n2count++;
-		}
-		break;
-	}
-
-	ax25_calculate_t1(ax25);
-	ax25_start_t1timer(ax25);
-}
diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c
deleted file mode 100644
index 3ad454416a5c..000000000000
--- a/net/ax25/ax25_iface.c
+++ /dev/null
@@ -1,214 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-static struct ax25_protocol *protocol_list;
-static DEFINE_RWLOCK(protocol_list_lock);
-
-static HLIST_HEAD(ax25_linkfail_list);
-static DEFINE_SPINLOCK(linkfail_lock);
-
-static struct listen_struct {
-	struct listen_struct *next;
-	ax25_address  callsign;
-	struct net_device *dev;
-} *listen_list = NULL;
-static DEFINE_SPINLOCK(listen_lock);
-
-/*
- * Do not register the internal protocols AX25_P_TEXT, AX25_P_SEGMENT,
- * AX25_P_IP or AX25_P_ARP ...
- */
-void ax25_register_pid(struct ax25_protocol *ap)
-{
-	write_lock_bh(&protocol_list_lock);
-	ap->next = protocol_list;
-	protocol_list = ap;
-	write_unlock_bh(&protocol_list_lock);
-}
-
-EXPORT_SYMBOL_GPL(ax25_register_pid);
-
-void ax25_protocol_release(unsigned int pid)
-{
-	struct ax25_protocol *protocol;
-
-	write_lock_bh(&protocol_list_lock);
-	protocol = protocol_list;
-	if (protocol == NULL)
-		goto out;
-
-	if (protocol->pid == pid) {
-		protocol_list = protocol->next;
-		goto out;
-	}
-
-	while (protocol != NULL && protocol->next != NULL) {
-		if (protocol->next->pid == pid) {
-			protocol->next = protocol->next->next;
-			goto out;
-		}
-
-		protocol = protocol->next;
-	}
-out:
-	write_unlock_bh(&protocol_list_lock);
-}
-
-EXPORT_SYMBOL(ax25_protocol_release);
-
-void ax25_linkfail_register(struct ax25_linkfail *lf)
-{
-	spin_lock_bh(&linkfail_lock);
-	hlist_add_head(&lf->lf_node, &ax25_linkfail_list);
-	spin_unlock_bh(&linkfail_lock);
-}
-
-EXPORT_SYMBOL(ax25_linkfail_register);
-
-void ax25_linkfail_release(struct ax25_linkfail *lf)
-{
-	spin_lock_bh(&linkfail_lock);
-	hlist_del_init(&lf->lf_node);
-	spin_unlock_bh(&linkfail_lock);
-}
-
-EXPORT_SYMBOL(ax25_linkfail_release);
-
-int ax25_listen_register(const ax25_address *callsign, struct net_device *dev)
-{
-	struct listen_struct *listen;
-
-	if (ax25_listen_mine(callsign, dev))
-		return 0;
-
-	if ((listen = kmalloc_obj(*listen, GFP_ATOMIC)) == NULL)
-		return -ENOMEM;
-
-	listen->callsign = *callsign;
-	listen->dev      = dev;
-
-	spin_lock_bh(&listen_lock);
-	listen->next = listen_list;
-	listen_list  = listen;
-	spin_unlock_bh(&listen_lock);
-
-	return 0;
-}
-
-EXPORT_SYMBOL(ax25_listen_register);
-
-void ax25_listen_release(const ax25_address *callsign, struct net_device *dev)
-{
-	struct listen_struct *s, *listen;
-
-	spin_lock_bh(&listen_lock);
-	listen = listen_list;
-	if (listen == NULL) {
-		spin_unlock_bh(&listen_lock);
-		return;
-	}
-
-	if (ax25cmp(&listen->callsign, callsign) == 0 && listen->dev == dev) {
-		listen_list = listen->next;
-		spin_unlock_bh(&listen_lock);
-		kfree(listen);
-		return;
-	}
-
-	while (listen != NULL && listen->next != NULL) {
-		if (ax25cmp(&listen->next->callsign, callsign) == 0 && listen->next->dev == dev) {
-			s = listen->next;
-			listen->next = listen->next->next;
-			spin_unlock_bh(&listen_lock);
-			kfree(s);
-			return;
-		}
-
-		listen = listen->next;
-	}
-	spin_unlock_bh(&listen_lock);
-}
-
-EXPORT_SYMBOL(ax25_listen_release);
-
-int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *)
-{
-	int (*res)(struct sk_buff *, ax25_cb *) = NULL;
-	struct ax25_protocol *protocol;
-
-	read_lock(&protocol_list_lock);
-	for (protocol = protocol_list; protocol != NULL; protocol = protocol->next)
-		if (protocol->pid == pid) {
-			res = protocol->func;
-			break;
-		}
-	read_unlock(&protocol_list_lock);
-
-	return res;
-}
-
-int ax25_listen_mine(const ax25_address *callsign, struct net_device *dev)
-{
-	struct listen_struct *listen;
-
-	spin_lock_bh(&listen_lock);
-	for (listen = listen_list; listen != NULL; listen = listen->next)
-		if (ax25cmp(&listen->callsign, callsign) == 0 &&
-		    (listen->dev == dev || listen->dev == NULL)) {
-			spin_unlock_bh(&listen_lock);
-			return 1;
-	}
-	spin_unlock_bh(&listen_lock);
-
-	return 0;
-}
-
-void ax25_link_failed(ax25_cb *ax25, int reason)
-{
-	struct ax25_linkfail *lf;
-
-	spin_lock_bh(&linkfail_lock);
-	hlist_for_each_entry(lf, &ax25_linkfail_list, lf_node)
-		lf->func(ax25, reason);
-	spin_unlock_bh(&linkfail_lock);
-}
-
-int ax25_protocol_is_registered(unsigned int pid)
-{
-	struct ax25_protocol *protocol;
-	int res = 0;
-
-	read_lock_bh(&protocol_list_lock);
-	for (protocol = protocol_list; protocol != NULL; protocol = protocol->next)
-		if (protocol->pid == pid) {
-			res = 1;
-			break;
-		}
-	read_unlock_bh(&protocol_list_lock);
-
-	return res;
-}
diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c
deleted file mode 100644
index d75b3e9ed93d..000000000000
--- a/net/ax25/ax25_in.c
+++ /dev/null
@@ -1,455 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
- * Copyright (C) Hans-Joachim Hetscher DD8NE (dd8ne@bnv-bamberg.de)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-/*
- *	Given a fragment, queue it on the fragment queue and if the fragment
- *	is complete, send it back to ax25_rx_iframe.
- */
-static int ax25_rx_fragment(ax25_cb *ax25, struct sk_buff *skb)
-{
-	struct sk_buff *skbn, *skbo;
-
-	if (ax25->fragno != 0) {
-		if (!(*skb->data & AX25_SEG_FIRST)) {
-			if ((ax25->fragno - 1) == (*skb->data & AX25_SEG_REM)) {
-				/* Enqueue fragment */
-				ax25->fragno = *skb->data & AX25_SEG_REM;
-				skb_pull(skb, 1);	/* skip fragno */
-				ax25->fraglen += skb->len;
-				skb_queue_tail(&ax25->frag_queue, skb);
-
-				/* Last fragment received ? */
-				if (ax25->fragno == 0) {
-					skbn = alloc_skb(AX25_MAX_HEADER_LEN +
-							 ax25->fraglen,
-							 GFP_ATOMIC);
-					if (!skbn) {
-						skb_queue_purge(&ax25->frag_queue);
-						return 1;
-					}
-
-					skb_reserve(skbn, AX25_MAX_HEADER_LEN);
-
-					skbn->dev   = ax25->ax25_dev->dev;
-					skb_reset_network_header(skbn);
-					skb_reset_transport_header(skbn);
-
-					/* Copy data from the fragments */
-					while ((skbo = skb_dequeue(&ax25->frag_queue)) != NULL) {
-						skb_copy_from_linear_data(skbo,
-							  skb_put(skbn, skbo->len),
-									  skbo->len);
-						kfree_skb(skbo);
-					}
-
-					ax25->fraglen = 0;
-
-					if (ax25_rx_iframe(ax25, skbn) == 0)
-						kfree_skb(skbn);
-				}
-
-				return 1;
-			}
-		}
-	} else {
-		/* First fragment received */
-		if (*skb->data & AX25_SEG_FIRST) {
-			skb_queue_purge(&ax25->frag_queue);
-			ax25->fragno = *skb->data & AX25_SEG_REM;
-			skb_pull(skb, 1);		/* skip fragno */
-			ax25->fraglen = skb->len;
-			skb_queue_tail(&ax25->frag_queue, skb);
-			return 1;
-		}
-	}
-
-	return 0;
-}
-
-/*
- *	This is where all valid I frames are sent to, to be dispatched to
- *	whichever protocol requires them.
- */
-int ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb)
-{
-	int (*func)(struct sk_buff *, ax25_cb *);
-	unsigned char pid;
-	int queued = 0;
-
-	if (skb == NULL) return 0;
-
-	ax25_start_idletimer(ax25);
-
-	pid = *skb->data;
-
-	if (pid == AX25_P_IP) {
-		/* working around a TCP bug to keep additional listeners
-		 * happy. TCP re-uses the buffer and destroys the original
-		 * content.
-		 */
-		struct sk_buff *skbn = skb_copy(skb, GFP_ATOMIC);
-		if (skbn != NULL) {
-			kfree_skb(skb);
-			skb = skbn;
-		}
-
-		skb_pull(skb, 1);	/* Remove PID */
-		skb->mac_header = skb->network_header;
-		skb_reset_network_header(skb);
-		skb->dev      = ax25->ax25_dev->dev;
-		skb->pkt_type = PACKET_HOST;
-		skb->protocol = htons(ETH_P_IP);
-		netif_rx(skb);
-		return 1;
-	}
-	if (pid == AX25_P_SEGMENT) {
-		skb_pull(skb, 1);	/* Remove PID */
-		return ax25_rx_fragment(ax25, skb);
-	}
-
-	if ((func = ax25_protocol_function(pid)) != NULL) {
-		skb_pull(skb, 1);	/* Remove PID */
-		return (*func)(skb, ax25);
-	}
-
-	if (ax25->sk != NULL && ax25->ax25_dev->values[AX25_VALUES_CONMODE] == 2) {
-		if ((!ax25->pidincl && ax25->sk->sk_protocol == pid) ||
-		    ax25->pidincl) {
-			if (sock_queue_rcv_skb(ax25->sk, skb) == 0)
-				queued = 1;
-			else
-				ax25->condition |= AX25_COND_OWN_RX_BUSY;
-		}
-	}
-
-	return queued;
-}
-
-/*
- *	Higher level upcall for a LAPB frame
- */
-static int ax25_process_rx_frame(ax25_cb *ax25, struct sk_buff *skb, int type, int dama)
-{
-	int queued = 0;
-
-	if (ax25->state == AX25_STATE_0)
-		return 0;
-
-	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
-	case AX25_PROTO_STD_SIMPLEX:
-	case AX25_PROTO_STD_DUPLEX:
-		queued = ax25_std_frame_in(ax25, skb, type);
-		break;
-
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	case AX25_PROTO_DAMA_SLAVE:
-		if (dama || ax25->ax25_dev->dama.slave)
-			queued = ax25_ds_frame_in(ax25, skb, type);
-		else
-			queued = ax25_std_frame_in(ax25, skb, type);
-		break;
-#endif
-	}
-
-	return queued;
-}
-
-static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
-		    const ax25_address *dev_addr, struct packet_type *ptype)
-{
-	ax25_address src, dest, *next_digi = NULL;
-	int type = 0, mine = 0, dama;
-	struct sock *make, *sk;
-	ax25_digi dp, reverse_dp;
-	ax25_cb *ax25;
-	ax25_dev *ax25_dev;
-
-	/*
-	 *	Process the AX.25/LAPB frame.
-	 */
-
-	skb_reset_transport_header(skb);
-
-	if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
-		goto free;
-
-	/*
-	 *	Parse the address header.
-	 */
-
-	if (ax25_addr_parse(skb->data, skb->len, &src, &dest, &dp, &type, &dama) == NULL)
-		goto free;
-
-	/*
-	 *	Ours perhaps ?
-	 */
-	if (dp.lastrepeat + 1 < dp.ndigi)		/* Not yet digipeated completely */
-		next_digi = &dp.calls[dp.lastrepeat + 1];
-
-	/*
-	 *	Pull of the AX.25 headers leaving the CTRL/PID bytes
-	 */
-	skb_pull(skb, ax25_addr_size(&dp));
-
-	/* For our port addresses ? */
-	if (ax25cmp(&dest, dev_addr) == 0 && dp.lastrepeat + 1 == dp.ndigi)
-		mine = 1;
-
-	/* Also match on any registered callsign from L3/4 */
-	if (!mine && ax25_listen_mine(&dest, dev) && dp.lastrepeat + 1 == dp.ndigi)
-		mine = 1;
-
-	/* UI frame - bypass LAPB processing */
-	if ((*skb->data & ~0x10) == AX25_UI && dp.lastrepeat + 1 == dp.ndigi) {
-		skb_set_transport_header(skb, 2); /* skip control and pid */
-
-		ax25_send_to_raw(&dest, skb, skb->data[1]);
-
-		if (!mine && ax25cmp(&dest, (ax25_address *)dev->broadcast) != 0)
-			goto free;
-
-		/* Now we are pointing at the pid byte */
-		switch (skb->data[1]) {
-		case AX25_P_IP:
-			skb_pull(skb,2);		/* drop PID/CTRL */
-			skb_reset_transport_header(skb);
-			skb_reset_network_header(skb);
-			skb->dev      = dev;
-			skb->pkt_type = PACKET_HOST;
-			skb->protocol = htons(ETH_P_IP);
-			netif_rx(skb);
-			break;
-
-		case AX25_P_ARP:
-			skb_pull(skb,2);
-			skb_reset_transport_header(skb);
-			skb_reset_network_header(skb);
-			skb->dev      = dev;
-			skb->pkt_type = PACKET_HOST;
-			skb->protocol = htons(ETH_P_ARP);
-			netif_rx(skb);
-			break;
-		case AX25_P_TEXT:
-			/* Now find a suitable dgram socket */
-			sk = ax25_get_socket(&dest, &src, SOCK_DGRAM);
-			if (sk != NULL) {
-				bh_lock_sock(sk);
-				if (atomic_read(&sk->sk_rmem_alloc) >=
-				    sk->sk_rcvbuf) {
-					kfree_skb(skb);
-				} else {
-					/*
-					 *	Remove the control and PID.
-					 */
-					skb_pull(skb, 2);
-					if (sock_queue_rcv_skb(sk, skb) != 0)
-						kfree_skb(skb);
-				}
-				bh_unlock_sock(sk);
-				sock_put(sk);
-			} else {
-				kfree_skb(skb);
-			}
-			break;
-
-		default:
-			kfree_skb(skb);	/* Will scan SOCK_AX25 RAW sockets */
-			break;
-		}
-
-		return 0;
-	}
-
-	/*
-	 *	Is connected mode supported on this device ?
-	 *	If not, should we DM the incoming frame (except DMs) or
-	 *	silently ignore them. For now we stay quiet.
-	 */
-	if (ax25_dev->values[AX25_VALUES_CONMODE] == 0)
-		goto free;
-
-	/* LAPB */
-
-	/* AX.25 state 1-4 */
-
-	ax25_digi_invert(&dp, &reverse_dp);
-
-	if ((ax25 = ax25_find_cb(&dest, &src, &reverse_dp, dev)) != NULL) {
-		/*
-		 *	Process the frame. If it is queued up internally it
-		 *	returns one otherwise we free it immediately. This
-		 *	routine itself wakes the user context layers so we do
-		 *	no further work
-		 */
-		if (ax25_process_rx_frame(ax25, skb, type, dama) == 0)
-			kfree_skb(skb);
-
-		ax25_cb_put(ax25);
-		return 0;
-	}
-
-	/* AX.25 state 0 (disconnected) */
-
-	/* a) received not a SABM(E) */
-
-	if ((*skb->data & ~AX25_PF) != AX25_SABM &&
-	    (*skb->data & ~AX25_PF) != AX25_SABME) {
-		/*
-		 *	Never reply to a DM. Also ignore any connects for
-		 *	addresses that are not our interfaces and not a socket.
-		 */
-		if ((*skb->data & ~AX25_PF) != AX25_DM && mine)
-			ax25_return_dm(dev, &src, &dest, &dp);
-
-		goto free;
-	}
-
-	/* b) received SABM(E) */
-
-	if (dp.lastrepeat + 1 == dp.ndigi)
-		sk = ax25_find_listener(&dest, 0, dev, SOCK_SEQPACKET);
-	else
-		sk = ax25_find_listener(next_digi, 1, dev, SOCK_SEQPACKET);
-
-	if (sk != NULL) {
-		bh_lock_sock(sk);
-		if (sk_acceptq_is_full(sk) ||
-		    (make = ax25_make_new(sk, ax25_dev)) == NULL) {
-			if (mine)
-				ax25_return_dm(dev, &src, &dest, &dp);
-			kfree_skb(skb);
-			bh_unlock_sock(sk);
-			sock_put(sk);
-
-			return 0;
-		}
-
-		ax25 = sk_to_ax25(make);
-		skb_set_owner_r(skb, make);
-		skb_queue_head(&sk->sk_receive_queue, skb);
-
-		make->sk_state = TCP_ESTABLISHED;
-
-		sk_acceptq_added(sk);
-		bh_unlock_sock(sk);
-	} else {
-		if (!mine)
-			goto free;
-
-		if ((ax25 = ax25_create_cb()) == NULL) {
-			ax25_return_dm(dev, &src, &dest, &dp);
-			goto free;
-		}
-
-		ax25_fillin_cb(ax25, ax25_dev);
-	}
-
-	ax25->source_addr = dest;
-	ax25->dest_addr   = src;
-
-	/*
-	 *	Sort out any digipeated paths.
-	 */
-	if (dp.ndigi && !ax25->digipeat &&
-	    (ax25->digipeat = kmalloc_obj(ax25_digi, GFP_ATOMIC)) == NULL) {
-		kfree_skb(skb);
-		ax25_destroy_socket(ax25);
-		if (sk)
-			sock_put(sk);
-		return 0;
-	}
-
-	if (dp.ndigi == 0) {
-		kfree(ax25->digipeat);
-		ax25->digipeat = NULL;
-	} else {
-		/* Reverse the source SABM's path */
-		memcpy(ax25->digipeat, &reverse_dp, sizeof(ax25_digi));
-	}
-
-	if ((*skb->data & ~AX25_PF) == AX25_SABME) {
-		ax25->modulus = AX25_EMODULUS;
-		ax25->window  = ax25_dev->values[AX25_VALUES_EWINDOW];
-	} else {
-		ax25->modulus = AX25_MODULUS;
-		ax25->window  = ax25_dev->values[AX25_VALUES_WINDOW];
-	}
-
-	ax25_send_control(ax25, AX25_UA, AX25_POLLON, AX25_RESPONSE);
-
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	if (dama && ax25->ax25_dev->values[AX25_VALUES_PROTOCOL] == AX25_PROTO_DAMA_SLAVE)
-		ax25_dama_on(ax25);
-#endif
-
-	ax25->state = AX25_STATE_3;
-
-	ax25_cb_add(ax25);
-
-	ax25_start_heartbeat(ax25);
-	ax25_start_t3timer(ax25);
-	ax25_start_idletimer(ax25);
-
-	if (sk) {
-		if (!sock_flag(sk, SOCK_DEAD))
-			sk->sk_data_ready(sk);
-		sock_put(sk);
-	} else {
-free:
-		kfree_skb(skb);
-	}
-	return 0;
-}
-
-/*
- *	Receive an AX.25 frame via a SLIP interface.
- */
-int ax25_kiss_rcv(struct sk_buff *skb, struct net_device *dev,
-		  struct packet_type *ptype, struct net_device *orig_dev)
-{
-	skb = skb_share_check(skb, GFP_ATOMIC);
-	if (!skb)
-		return NET_RX_DROP;
-
-	skb_orphan(skb);
-
-	if (!net_eq(dev_net(dev), &init_net)) {
-		kfree_skb(skb);
-		return 0;
-	}
-
-	if ((*skb->data & 0x0F) != 0) {
-		kfree_skb(skb);	/* Not a KISS data frame */
-		return 0;
-	}
-
-	skb_pull(skb, AX25_KISS_HEADER_LEN);	/* Remove the KISS byte */
-
-	return ax25_rcv(skb, dev, (const ax25_address *)dev->dev_addr, ptype);
-}
diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c
deleted file mode 100644
index 215d4ccf12b9..000000000000
--- a/net/ax25/ax25_ip.c
+++ /dev/null
@@ -1,247 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/termios.h>	/* For TIOCINQ/OUTQ */
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/notifier.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <linux/sysctl.h>
-#include <net/ip.h>
-#include <net/arp.h>
-
-/*
- *	IP over AX.25 encapsulation.
- */
-
-/*
- *	Shove an AX.25 UI header on an IP packet and handle ARP
- */
-
-#ifdef CONFIG_INET
-
-static int ax25_hard_header(struct sk_buff *skb, struct net_device *dev,
-			    unsigned short type, const void *daddr,
-			    const void *saddr, unsigned int len)
-{
-	unsigned char *buff;
-
-	/* they sometimes come back to us... */
-	if (type == ETH_P_AX25)
-		return 0;
-
-	/* header is an AX.25 UI frame from us to them */
-	buff = skb_push(skb, AX25_HEADER_LEN);
-	*buff++ = 0x00;	/* KISS DATA */
-
-	if (daddr != NULL)
-		memcpy(buff, daddr, dev->addr_len);	/* Address specified */
-
-	buff[6] &= ~AX25_CBIT;
-	buff[6] &= ~AX25_EBIT;
-	buff[6] |= AX25_SSSID_SPARE;
-	buff    += AX25_ADDR_LEN;
-
-	if (saddr != NULL)
-		memcpy(buff, saddr, dev->addr_len);
-	else
-		memcpy(buff, dev->dev_addr, dev->addr_len);
-
-	buff[6] &= ~AX25_CBIT;
-	buff[6] |= AX25_EBIT;
-	buff[6] |= AX25_SSSID_SPARE;
-	buff    += AX25_ADDR_LEN;
-
-	*buff++  = AX25_UI;	/* UI */
-
-	/* Append a suitable AX.25 PID */
-	switch (type) {
-	case ETH_P_IP:
-		*buff++ = AX25_P_IP;
-		break;
-	case ETH_P_ARP:
-		*buff++ = AX25_P_ARP;
-		break;
-	default:
-		printk(KERN_ERR "AX.25: ax25_hard_header - wrong protocol type 0x%2.2x\n", type);
-		*buff++ = 0;
-		break;
-	}
-
-	if (daddr != NULL)
-		return AX25_HEADER_LEN;
-
-	return -AX25_HEADER_LEN;	/* Unfinished header */
-}
-
-netdev_tx_t ax25_ip_xmit(struct sk_buff *skb)
-{
-	struct sk_buff *ourskb;
-	unsigned char *bp  = skb->data;
-	ax25_route *route;
-	struct net_device *dev = NULL;
-	ax25_address *src, *dst;
-	ax25_digi *digipeat = NULL;
-	ax25_dev *ax25_dev;
-	ax25_cb *ax25;
-	char ip_mode = ' ';
-
-	dst = (ax25_address *)(bp + 1);
-	src = (ax25_address *)(bp + 8);
-
-	ax25_route_lock_use();
-	route = ax25_get_route(dst, NULL);
-	if (route) {
-		digipeat = route->digipeat;
-		dev = route->dev;
-		ip_mode = route->ip_mode;
-	}
-
-	if (dev == NULL)
-		dev = skb->dev;
-
-	rcu_read_lock();
-	if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL) {
-		kfree_skb(skb);
-		goto put;
-	}
-
-	if (bp[16] == AX25_P_IP) {
-		if (ip_mode == 'V' || (ip_mode == ' ' && ax25_dev->values[AX25_VALUES_IPDEFMODE])) {
-			/*
-			 *	We copy the buffer and release the original thereby
-			 *	keeping it straight
-			 *
-			 *	Note: we report 1 back so the caller will
-			 *	not feed the frame direct to the physical device
-			 *	We don't want that to happen. (It won't be upset
-			 *	as we have pulled the frame from the queue by
-			 *	freeing it).
-			 *
-			 *	NB: TCP modifies buffers that are still
-			 *	on a device queue, thus we use skb_copy()
-			 *      instead of using skb_clone() unless this
-			 *	gets fixed.
-			 */
-
-			ax25_address src_c;
-			ax25_address dst_c;
-
-			if ((ourskb = skb_copy(skb, GFP_ATOMIC)) == NULL) {
-				kfree_skb(skb);
-				goto put;
-			}
-
-			if (skb->sk != NULL)
-				skb_set_owner_w(ourskb, skb->sk);
-
-			kfree_skb(skb);
-			/* dl9sau: bugfix
-			 * after kfree_skb(), dst and src which were pointer
-			 * to bp which is part of skb->data would not be valid
-			 * anymore hope that after skb_pull(ourskb, ..) our
-			 * dsc_c and src_c will not become invalid
-			 */
-			bp  = ourskb->data;
-			dst_c = *(ax25_address *)(bp + 1);
-			src_c = *(ax25_address *)(bp + 8);
-
-			skb_pull(ourskb, AX25_HEADER_LEN - 1);	/* Keep PID */
-			skb_reset_network_header(ourskb);
-
-			ax25=ax25_send_frame(
-			    ourskb,
-			    ax25_dev->values[AX25_VALUES_PACLEN],
-			    &src_c,
-			    &dst_c, digipeat, dev);
-			if (ax25) {
-				ax25_cb_put(ax25);
-			}
-			goto put;
-		}
-	}
-
-	bp[7]  &= ~AX25_CBIT;
-	bp[7]  &= ~AX25_EBIT;
-	bp[7]  |= AX25_SSSID_SPARE;
-
-	bp[14] &= ~AX25_CBIT;
-	bp[14] |= AX25_EBIT;
-	bp[14] |= AX25_SSSID_SPARE;
-
-	skb_pull(skb, AX25_KISS_HEADER_LEN);
-
-	if (digipeat != NULL) {
-		if ((ourskb = ax25_rt_build_path(skb, src, dst, route->digipeat)) == NULL)
-			goto put;
-
-		skb = ourskb;
-	}
-
-	ax25_queue_xmit(skb, dev);
-
-put:
-	rcu_read_unlock();
-	ax25_route_lock_unuse();
-	return NETDEV_TX_OK;
-}
-
-#else	/* INET */
-
-static int ax25_hard_header(struct sk_buff *skb, struct net_device *dev,
-			    unsigned short type, const void *daddr,
-			    const void *saddr, unsigned int len)
-{
-	return -AX25_HEADER_LEN;
-}
-
-netdev_tx_t ax25_ip_xmit(struct sk_buff *skb)
-{
-	kfree_skb(skb);
-	return NETDEV_TX_OK;
-}
-#endif
-
-static bool ax25_validate_header(const char *header, unsigned int len)
-{
-	ax25_digi digi;
-
-	if (!len)
-		return false;
-
-	if (header[0])
-		return true;
-
-	return ax25_addr_parse(header + 1, len - 1, NULL, NULL, &digi, NULL,
-			       NULL);
-}
-
-const struct header_ops ax25_header_ops = {
-	.create = ax25_hard_header,
-	.validate = ax25_validate_header,
-};
-
-EXPORT_SYMBOL(ax25_header_ops);
-EXPORT_SYMBOL(ax25_ip_xmit);
diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c
deleted file mode 100644
index 8bca2ace98e5..000000000000
--- a/net/ax25/ax25_out.c
+++ /dev/null
@@ -1,398 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/spinlock.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-static DEFINE_SPINLOCK(ax25_frag_lock);
-
-ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, const ax25_address *src, ax25_address *dest, ax25_digi *digi, struct net_device *dev)
-{
-	ax25_dev *ax25_dev;
-	ax25_cb *ax25;
-
-	/*
-	 * Take the default packet length for the device if zero is
-	 * specified.
-	 */
-	if (paclen == 0) {
-		rcu_read_lock();
-		ax25_dev = ax25_dev_ax25dev(dev);
-		if (!ax25_dev) {
-			rcu_read_unlock();
-			return NULL;
-		}
-		paclen = ax25_dev->values[AX25_VALUES_PACLEN];
-		rcu_read_unlock();
-	}
-
-	/*
-	 * Look for an existing connection.
-	 */
-	if ((ax25 = ax25_find_cb(src, dest, digi, dev)) != NULL) {
-		ax25_output(ax25, paclen, skb);
-		return ax25;		/* It already existed */
-	}
-
-	rcu_read_lock();
-	ax25_dev = ax25_dev_ax25dev(dev);
-	if (!ax25_dev) {
-		rcu_read_unlock();
-		return NULL;
-	}
-
-	if ((ax25 = ax25_create_cb()) == NULL) {
-		rcu_read_unlock();
-		return NULL;
-	}
-	ax25_fillin_cb(ax25, ax25_dev);
-	rcu_read_unlock();
-
-	ax25->source_addr = *src;
-	ax25->dest_addr   = *dest;
-
-	if (digi != NULL) {
-		ax25->digipeat = kmemdup(digi, sizeof(*digi), GFP_ATOMIC);
-		if (ax25->digipeat == NULL) {
-			ax25_cb_put(ax25);
-			return NULL;
-		}
-	}
-
-	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
-	case AX25_PROTO_STD_SIMPLEX:
-	case AX25_PROTO_STD_DUPLEX:
-		ax25_std_establish_data_link(ax25);
-		break;
-
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	case AX25_PROTO_DAMA_SLAVE:
-		if (ax25_dev->dama.slave)
-			ax25_ds_establish_data_link(ax25);
-		else
-			ax25_std_establish_data_link(ax25);
-		break;
-#endif
-	}
-
-	/*
-	 * There is one ref for the state machine; a caller needs
-	 * one more to put it back, just like with the existing one.
-	 */
-	ax25_cb_hold(ax25);
-
-	ax25_cb_add(ax25);
-
-	ax25->state = AX25_STATE_1;
-
-	ax25_start_heartbeat(ax25);
-
-	ax25_output(ax25, paclen, skb);
-
-	return ax25;			/* We had to create it */
-}
-
-EXPORT_SYMBOL(ax25_send_frame);
-
-/*
- *	All outgoing AX.25 I frames pass via this routine. Therefore this is
- *	where the fragmentation of frames takes place. If fragment is set to
- *	zero then we are not allowed to do fragmentation, even if the frame
- *	is too large.
- */
-void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb)
-{
-	struct sk_buff *skbn;
-	unsigned char *p;
-	int frontlen, len, fragno, ka9qfrag, first = 1;
-
-	if (paclen < 16) {
-		WARN_ON_ONCE(1);
-		kfree_skb(skb);
-		return;
-	}
-
-	if ((skb->len - 1) > paclen) {
-		if (*skb->data == AX25_P_TEXT) {
-			skb_pull(skb, 1); /* skip PID */
-			ka9qfrag = 0;
-		} else {
-			paclen -= 2;	/* Allow for fragment control info */
-			ka9qfrag = 1;
-		}
-
-		fragno = skb->len / paclen;
-		if (skb->len % paclen == 0) fragno--;
-
-		frontlen = skb_headroom(skb);	/* Address space + CTRL */
-
-		while (skb->len > 0) {
-			spin_lock_bh(&ax25_frag_lock);
-			if ((skbn = alloc_skb(paclen + 2 + frontlen, GFP_ATOMIC)) == NULL) {
-				spin_unlock_bh(&ax25_frag_lock);
-				printk(KERN_CRIT "AX.25: ax25_output - out of memory\n");
-				return;
-			}
-
-			if (skb->sk != NULL)
-				skb_set_owner_w(skbn, skb->sk);
-
-			spin_unlock_bh(&ax25_frag_lock);
-
-			len = (paclen > skb->len) ? skb->len : paclen;
-
-			if (ka9qfrag == 1) {
-				skb_reserve(skbn, frontlen + 2);
-				skb_set_network_header(skbn,
-						      skb_network_offset(skb));
-				skb_copy_from_linear_data(skb, skb_put(skbn, len), len);
-				p = skb_push(skbn, 2);
-
-				*p++ = AX25_P_SEGMENT;
-
-				*p = fragno--;
-				if (first) {
-					*p |= AX25_SEG_FIRST;
-					first = 0;
-				}
-			} else {
-				skb_reserve(skbn, frontlen + 1);
-				skb_set_network_header(skbn,
-						      skb_network_offset(skb));
-				skb_copy_from_linear_data(skb, skb_put(skbn, len), len);
-				p = skb_push(skbn, 1);
-				*p = AX25_P_TEXT;
-			}
-
-			skb_pull(skb, len);
-			skb_queue_tail(&ax25->write_queue, skbn); /* Throw it on the queue */
-		}
-
-		kfree_skb(skb);
-	} else {
-		skb_queue_tail(&ax25->write_queue, skb);	  /* Throw it on the queue */
-	}
-
-	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
-	case AX25_PROTO_STD_SIMPLEX:
-	case AX25_PROTO_STD_DUPLEX:
-		ax25_kick(ax25);
-		break;
-
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	/*
-	 * A DAMA slave is _required_ to work as normal AX.25L2V2
-	 * if no DAMA master is available.
-	 */
-	case AX25_PROTO_DAMA_SLAVE:
-		if (!ax25->ax25_dev->dama.slave) ax25_kick(ax25);
-		break;
-#endif
-	}
-}
-
-/*
- *  This procedure is passed a buffer descriptor for an iframe. It builds
- *  the rest of the control part of the frame and then writes it out.
- */
-static void ax25_send_iframe(ax25_cb *ax25, struct sk_buff *skb, int poll_bit)
-{
-	unsigned char *frame;
-
-	if (skb == NULL)
-		return;
-
-	skb_reset_network_header(skb);
-
-	if (ax25->modulus == AX25_MODULUS) {
-		frame = skb_push(skb, 1);
-
-		*frame = AX25_I;
-		*frame |= (poll_bit) ? AX25_PF : 0;
-		*frame |= (ax25->vr << 5);
-		*frame |= (ax25->vs << 1);
-	} else {
-		frame = skb_push(skb, 2);
-
-		frame[0] = AX25_I;
-		frame[0] |= (ax25->vs << 1);
-		frame[1] = (poll_bit) ? AX25_EPF : 0;
-		frame[1] |= (ax25->vr << 1);
-	}
-
-	ax25_start_idletimer(ax25);
-
-	ax25_transmit_buffer(ax25, skb, AX25_COMMAND);
-}
-
-void ax25_kick(ax25_cb *ax25)
-{
-	struct sk_buff *skb, *skbn;
-	int last = 1;
-	unsigned short start, end, next;
-
-	if (ax25->state != AX25_STATE_3 && ax25->state != AX25_STATE_4)
-		return;
-
-	if (ax25->condition & AX25_COND_PEER_RX_BUSY)
-		return;
-
-	if (skb_peek(&ax25->write_queue) == NULL)
-		return;
-
-	start = (skb_peek(&ax25->ack_queue) == NULL) ? ax25->va : ax25->vs;
-	end   = (ax25->va + ax25->window) % ax25->modulus;
-
-	if (start == end)
-		return;
-
-	/*
-	 * Transmit data until either we're out of data to send or
-	 * the window is full. Send a poll on the final I frame if
-	 * the window is filled.
-	 */
-
-	/*
-	 * Dequeue the frame and copy it.
-	 * Check for race with ax25_clear_queues().
-	 */
-	skb  = skb_dequeue(&ax25->write_queue);
-	if (!skb)
-		return;
-
-	ax25->vs = start;
-
-	do {
-		if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
-			skb_queue_head(&ax25->write_queue, skb);
-			break;
-		}
-
-		if (skb->sk != NULL)
-			skb_set_owner_w(skbn, skb->sk);
-
-		next = (ax25->vs + 1) % ax25->modulus;
-		last = (next == end);
-
-		/*
-		 * Transmit the frame copy.
-		 * bke 960114: do not set the Poll bit on the last frame
-		 * in DAMA mode.
-		 */
-		switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
-		case AX25_PROTO_STD_SIMPLEX:
-		case AX25_PROTO_STD_DUPLEX:
-			ax25_send_iframe(ax25, skbn, (last) ? AX25_POLLON : AX25_POLLOFF);
-			break;
-
-#ifdef CONFIG_AX25_DAMA_SLAVE
-		case AX25_PROTO_DAMA_SLAVE:
-			ax25_send_iframe(ax25, skbn, AX25_POLLOFF);
-			break;
-#endif
-		}
-
-		ax25->vs = next;
-
-		/*
-		 * Requeue the original data frame.
-		 */
-		skb_queue_tail(&ax25->ack_queue, skb);
-
-	} while (!last && (skb = skb_dequeue(&ax25->write_queue)) != NULL);
-
-	ax25->condition &= ~AX25_COND_ACK_PENDING;
-
-	if (!ax25_t1timer_running(ax25)) {
-		ax25_stop_t3timer(ax25);
-		ax25_calculate_t1(ax25);
-		ax25_start_t1timer(ax25);
-	}
-}
-
-void ax25_transmit_buffer(ax25_cb *ax25, struct sk_buff *skb, int type)
-{
-	unsigned char *ptr;
-	int headroom;
-
-	if (ax25->ax25_dev == NULL) {
-		ax25_disconnect(ax25, ENETUNREACH);
-		return;
-	}
-
-	headroom = ax25_addr_size(ax25->digipeat);
-
-	if (unlikely(skb_headroom(skb) < headroom)) {
-		skb = skb_expand_head(skb, headroom);
-		if (!skb) {
-			printk(KERN_CRIT "AX.25: ax25_transmit_buffer - out of memory\n");
-			return;
-		}
-	}
-
-	ptr = skb_push(skb, headroom);
-
-	ax25_addr_build(ptr, &ax25->source_addr, &ax25->dest_addr, ax25->digipeat, type, ax25->modulus);
-
-	ax25_queue_xmit(skb, ax25->ax25_dev->dev);
-}
-
-/*
- *	A small shim to dev_queue_xmit to add the KISS control byte, and do
- *	any packet forwarding in operation.
- */
-void ax25_queue_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	unsigned char *ptr;
-
-	rcu_read_lock();
-	skb->protocol = ax25_type_trans(skb, ax25_fwd_dev(dev));
-	rcu_read_unlock();
-
-	ptr  = skb_push(skb, 1);
-	*ptr = 0x00;			/* KISS */
-
-	dev_queue_xmit(skb);
-}
-
-int ax25_check_iframes_acked(ax25_cb *ax25, unsigned short nr)
-{
-	if (ax25->vs == nr) {
-		ax25_frames_acked(ax25, nr);
-		ax25_calculate_rtt(ax25);
-		ax25_stop_t1timer(ax25);
-		ax25_start_t3timer(ax25);
-		return 1;
-	} else {
-		if (ax25->va != nr) {
-			ax25_frames_acked(ax25, nr);
-			ax25_calculate_t1(ax25);
-			ax25_start_t1timer(ax25);
-			return 1;
-		}
-	}
-	return 0;
-}
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
deleted file mode 100644
index 1d5c59ccf142..000000000000
--- a/net/ax25/ax25_route.c
+++ /dev/null
@@ -1,416 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) Steven Whitehouse GW7RRM (stevew@acm.org)
- * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
- * Copyright (C) Hans-Joachim Hetscher DD8NE (dd8ne@bnv-bamberg.de)
- * Copyright (C) Frederic Rible F1OAT (frible@teaser.fr)
- */
-
-#include <linux/capability.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/timer.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/seq_file.h>
-#include <linux/export.h>
-
-static ax25_route *ax25_route_list;
-DEFINE_RWLOCK(ax25_route_lock);
-
-void ax25_rt_device_down(struct net_device *dev)
-{
-	ax25_route *s, *t, *ax25_rt;
-
-	write_lock_bh(&ax25_route_lock);
-	ax25_rt = ax25_route_list;
-	while (ax25_rt != NULL) {
-		s       = ax25_rt;
-		ax25_rt = ax25_rt->next;
-
-		if (s->dev == dev) {
-			if (ax25_route_list == s) {
-				ax25_route_list = s->next;
-				kfree(s->digipeat);
-				kfree(s);
-			} else {
-				for (t = ax25_route_list; t != NULL; t = t->next) {
-					if (t->next == s) {
-						t->next = s->next;
-						kfree(s->digipeat);
-						kfree(s);
-						break;
-					}
-				}
-			}
-		}
-	}
-	write_unlock_bh(&ax25_route_lock);
-}
-
-static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
-{
-	ax25_route *ax25_rt;
-	ax25_dev *ax25_dev;
-	int i;
-
-	if (route->digi_count > AX25_MAX_DIGIS)
-		return -EINVAL;
-
-	ax25_dev = ax25_addr_ax25dev(&route->port_addr);
-	if (!ax25_dev)
-		return -EINVAL;
-
-	write_lock_bh(&ax25_route_lock);
-
-	ax25_rt = ax25_route_list;
-	while (ax25_rt != NULL) {
-		if (ax25cmp(&ax25_rt->callsign, &route->dest_addr) == 0 &&
-			    ax25_rt->dev == ax25_dev->dev) {
-			kfree(ax25_rt->digipeat);
-			ax25_rt->digipeat = NULL;
-			if (route->digi_count != 0) {
-				if ((ax25_rt->digipeat = kmalloc_obj(ax25_digi, GFP_ATOMIC)) == NULL) {
-					write_unlock_bh(&ax25_route_lock);
-					ax25_dev_put(ax25_dev);
-					return -ENOMEM;
-				}
-				ax25_rt->digipeat->lastrepeat = -1;
-				ax25_rt->digipeat->ndigi      = route->digi_count;
-				for (i = 0; i < route->digi_count; i++) {
-					ax25_rt->digipeat->repeated[i] = 0;
-					ax25_rt->digipeat->calls[i]    = route->digi_addr[i];
-				}
-			}
-			write_unlock_bh(&ax25_route_lock);
-			ax25_dev_put(ax25_dev);
-			return 0;
-		}
-		ax25_rt = ax25_rt->next;
-	}
-
-	if ((ax25_rt = kmalloc_obj(ax25_route, GFP_ATOMIC)) == NULL) {
-		write_unlock_bh(&ax25_route_lock);
-		ax25_dev_put(ax25_dev);
-		return -ENOMEM;
-	}
-
-	ax25_rt->callsign     = route->dest_addr;
-	ax25_rt->dev          = ax25_dev->dev;
-	ax25_rt->digipeat     = NULL;
-	ax25_rt->ip_mode      = ' ';
-	if (route->digi_count != 0) {
-		if ((ax25_rt->digipeat = kmalloc_obj(ax25_digi, GFP_ATOMIC)) == NULL) {
-			write_unlock_bh(&ax25_route_lock);
-			kfree(ax25_rt);
-			ax25_dev_put(ax25_dev);
-			return -ENOMEM;
-		}
-		ax25_rt->digipeat->lastrepeat = -1;
-		ax25_rt->digipeat->ndigi      = route->digi_count;
-		for (i = 0; i < route->digi_count; i++) {
-			ax25_rt->digipeat->repeated[i] = 0;
-			ax25_rt->digipeat->calls[i]    = route->digi_addr[i];
-		}
-	}
-	ax25_rt->next   = ax25_route_list;
-	ax25_route_list = ax25_rt;
-	write_unlock_bh(&ax25_route_lock);
-	ax25_dev_put(ax25_dev);
-
-	return 0;
-}
-
-void __ax25_put_route(ax25_route *ax25_rt)
-{
-	kfree(ax25_rt->digipeat);
-	kfree(ax25_rt);
-}
-
-static int ax25_rt_del(struct ax25_routes_struct *route)
-{
-	ax25_route *s, *t, *ax25_rt;
-	ax25_dev *ax25_dev;
-
-	if ((ax25_dev = ax25_addr_ax25dev(&route->port_addr)) == NULL)
-		return -EINVAL;
-
-	write_lock_bh(&ax25_route_lock);
-
-	ax25_rt = ax25_route_list;
-	while (ax25_rt != NULL) {
-		s       = ax25_rt;
-		ax25_rt = ax25_rt->next;
-		if (s->dev == ax25_dev->dev &&
-		    ax25cmp(&route->dest_addr, &s->callsign) == 0) {
-			if (ax25_route_list == s) {
-				ax25_route_list = s->next;
-				__ax25_put_route(s);
-			} else {
-				for (t = ax25_route_list; t != NULL; t = t->next) {
-					if (t->next == s) {
-						t->next = s->next;
-						__ax25_put_route(s);
-						break;
-					}
-				}
-			}
-		}
-	}
-	write_unlock_bh(&ax25_route_lock);
-	ax25_dev_put(ax25_dev);
-
-	return 0;
-}
-
-static int ax25_rt_opt(struct ax25_route_opt_struct *rt_option)
-{
-	ax25_route *ax25_rt;
-	ax25_dev *ax25_dev;
-	int err = 0;
-
-	if ((ax25_dev = ax25_addr_ax25dev(&rt_option->port_addr)) == NULL)
-		return -EINVAL;
-
-	write_lock_bh(&ax25_route_lock);
-
-	ax25_rt = ax25_route_list;
-	while (ax25_rt != NULL) {
-		if (ax25_rt->dev == ax25_dev->dev &&
-		    ax25cmp(&rt_option->dest_addr, &ax25_rt->callsign) == 0) {
-			switch (rt_option->cmd) {
-			case AX25_SET_RT_IPMODE:
-				switch (rt_option->arg) {
-				case ' ':
-				case 'D':
-				case 'V':
-					ax25_rt->ip_mode = rt_option->arg;
-					break;
-				default:
-					err = -EINVAL;
-					goto out;
-				}
-				break;
-			default:
-				err = -EINVAL;
-				goto out;
-			}
-		}
-		ax25_rt = ax25_rt->next;
-	}
-
-out:
-	write_unlock_bh(&ax25_route_lock);
-	ax25_dev_put(ax25_dev);
-	return err;
-}
-
-int ax25_rt_ioctl(unsigned int cmd, void __user *arg)
-{
-	struct ax25_route_opt_struct rt_option;
-	struct ax25_routes_struct route;
-
-	switch (cmd) {
-	case SIOCADDRT:
-		if (copy_from_user(&route, arg, sizeof(route)))
-			return -EFAULT;
-		return ax25_rt_add(&route);
-
-	case SIOCDELRT:
-		if (copy_from_user(&route, arg, sizeof(route)))
-			return -EFAULT;
-		return ax25_rt_del(&route);
-
-	case SIOCAX25OPTRT:
-		if (copy_from_user(&rt_option, arg, sizeof(rt_option)))
-			return -EFAULT;
-		return ax25_rt_opt(&rt_option);
-
-	default:
-		return -EINVAL;
-	}
-}
-
-#ifdef CONFIG_PROC_FS
-
-static void *ax25_rt_seq_start(struct seq_file *seq, loff_t *pos)
-	__acquires(ax25_route_lock)
-{
-	struct ax25_route *ax25_rt;
-	int i = 1;
-
-	read_lock(&ax25_route_lock);
-	if (*pos == 0)
-		return SEQ_START_TOKEN;
-
-	for (ax25_rt = ax25_route_list; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
-		if (i == *pos)
-			return ax25_rt;
-		++i;
-	}
-
-	return NULL;
-}
-
-static void *ax25_rt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	++*pos;
-	return (v == SEQ_START_TOKEN) ? ax25_route_list :
-		((struct ax25_route *) v)->next;
-}
-
-static void ax25_rt_seq_stop(struct seq_file *seq, void *v)
-	__releases(ax25_route_lock)
-{
-	read_unlock(&ax25_route_lock);
-}
-
-static int ax25_rt_seq_show(struct seq_file *seq, void *v)
-{
-	char buf[11];
-
-	if (v == SEQ_START_TOKEN)
-		seq_puts(seq, "callsign  dev  mode digipeaters\n");
-	else {
-		struct ax25_route *ax25_rt = v;
-		const char *callsign;
-		int i;
-
-		if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0)
-			callsign = "default";
-		else
-			callsign = ax2asc(buf, &ax25_rt->callsign);
-
-		seq_printf(seq, "%-9s %-4s",
-			callsign,
-			ax25_rt->dev ? ax25_rt->dev->name : "???");
-
-		switch (ax25_rt->ip_mode) {
-		case 'V':
-			seq_puts(seq, "   vc");
-			break;
-		case 'D':
-			seq_puts(seq, "   dg");
-			break;
-		default:
-			seq_puts(seq, "    *");
-			break;
-		}
-
-		if (ax25_rt->digipeat != NULL)
-			for (i = 0; i < ax25_rt->digipeat->ndigi; i++)
-				seq_printf(seq, " %s",
-				     ax2asc(buf, &ax25_rt->digipeat->calls[i]));
-
-		seq_puts(seq, "\n");
-	}
-	return 0;
-}
-
-const struct seq_operations ax25_rt_seqops = {
-	.start = ax25_rt_seq_start,
-	.next = ax25_rt_seq_next,
-	.stop = ax25_rt_seq_stop,
-	.show = ax25_rt_seq_show,
-};
-#endif
-
-/*
- *	Find AX.25 route
- *
- *	Only routes with a reference count of zero can be destroyed.
- *	Must be called with ax25_route_lock read locked.
- */
-ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev)
-{
-	ax25_route *ax25_spe_rt = NULL;
-	ax25_route *ax25_def_rt = NULL;
-	ax25_route *ax25_rt;
-
-	/*
-	 *	Bind to the physical interface we heard them on, or the default
-	 *	route if none is found;
-	 */
-	for (ax25_rt = ax25_route_list; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
-		if (dev == NULL) {
-			if (ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->dev != NULL)
-				ax25_spe_rt = ax25_rt;
-			if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0 && ax25_rt->dev != NULL)
-				ax25_def_rt = ax25_rt;
-		} else {
-			if (ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->dev == dev)
-				ax25_spe_rt = ax25_rt;
-			if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0 && ax25_rt->dev == dev)
-				ax25_def_rt = ax25_rt;
-		}
-	}
-
-	ax25_rt = ax25_def_rt;
-	if (ax25_spe_rt != NULL)
-		ax25_rt = ax25_spe_rt;
-
-	return ax25_rt;
-}
-
-
-struct sk_buff *ax25_rt_build_path(struct sk_buff *skb, ax25_address *src,
-	ax25_address *dest, ax25_digi *digi)
-{
-	unsigned char *bp;
-	int len;
-
-	len = digi->ndigi * AX25_ADDR_LEN;
-
-	if (unlikely(skb_headroom(skb) < len)) {
-		skb = skb_expand_head(skb, len);
-		if (!skb) {
-			printk(KERN_CRIT "AX.25: ax25_dg_build_path - out of memory\n");
-			return NULL;
-		}
-	}
-
-	bp = skb_push(skb, len);
-
-	ax25_addr_build(bp, src, dest, digi, AX25_COMMAND, AX25_MODULUS);
-
-	return skb;
-}
-
-/*
- *	Free all memory associated with routing structures.
- */
-void __exit ax25_rt_free(void)
-{
-	ax25_route *s, *ax25_rt = ax25_route_list;
-
-	write_lock_bh(&ax25_route_lock);
-	while (ax25_rt != NULL) {
-		s       = ax25_rt;
-		ax25_rt = ax25_rt->next;
-
-		kfree(s->digipeat);
-		kfree(s);
-	}
-	write_unlock_bh(&ax25_route_lock);
-}
diff --git a/net/ax25/ax25_std_in.c b/net/ax25/ax25_std_in.c
deleted file mode 100644
index ba176196ae06..000000000000
--- a/net/ax25/ax25_std_in.c
+++ /dev/null
@@ -1,443 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
- * Copyright (C) Hans-Joachim Hetscher DD8NE (dd8ne@bnv-bamberg.de)
- *
- * Most of this code is based on the SDL diagrams published in the 7th ARRL
- * Computer Networking Conference papers. The diagrams have mistakes in them,
- * but are mostly correct. Before you modify the code could you read the SDL
- * diagrams as the code is not obvious and probably very easy to break.
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-/*
- *	State machine for state 1, Awaiting Connection State.
- *	The handling of the timer(s) is in file ax25_std_timer.c.
- *	Handling of state 0 and connection release is in ax25.c.
- */
-static int ax25_std_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
-{
-	switch (frametype) {
-	case AX25_SABM:
-		ax25->modulus = AX25_MODULUS;
-		ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
-		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
-		break;
-
-	case AX25_SABME:
-		ax25->modulus = AX25_EMODULUS;
-		ax25->window  = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
-		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
-		break;
-
-	case AX25_DISC:
-		ax25_send_control(ax25, AX25_DM, pf, AX25_RESPONSE);
-		break;
-
-	case AX25_UA:
-		if (pf) {
-			ax25_calculate_rtt(ax25);
-			ax25_stop_t1timer(ax25);
-			ax25_start_t3timer(ax25);
-			ax25_start_idletimer(ax25);
-			ax25->vs      = 0;
-			ax25->va      = 0;
-			ax25->vr      = 0;
-			ax25->state   = AX25_STATE_3;
-			ax25->n2count = 0;
-			if (ax25->sk != NULL) {
-				bh_lock_sock(ax25->sk);
-				ax25->sk->sk_state = TCP_ESTABLISHED;
-				/* For WAIT_SABM connections we will produce an accept ready socket here */
-				if (!sock_flag(ax25->sk, SOCK_DEAD))
-					ax25->sk->sk_state_change(ax25->sk);
-				bh_unlock_sock(ax25->sk);
-			}
-		}
-		break;
-
-	case AX25_DM:
-		if (pf) {
-			if (ax25->modulus == AX25_MODULUS) {
-				ax25_disconnect(ax25, ECONNREFUSED);
-			} else {
-				ax25->modulus = AX25_MODULUS;
-				ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
-			}
-		}
-		break;
-
-	default:
-		break;
-	}
-
-	return 0;
-}
-
-/*
- *	State machine for state 2, Awaiting Release State.
- *	The handling of the timer(s) is in file ax25_std_timer.c
- *	Handling of state 0 and connection release is in ax25.c.
- */
-static int ax25_std_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
-{
-	switch (frametype) {
-	case AX25_SABM:
-	case AX25_SABME:
-		ax25_send_control(ax25, AX25_DM, pf, AX25_RESPONSE);
-		break;
-
-	case AX25_DISC:
-		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
-		ax25_disconnect(ax25, 0);
-		break;
-
-	case AX25_DM:
-	case AX25_UA:
-		if (pf)
-			ax25_disconnect(ax25, 0);
-		break;
-
-	case AX25_I:
-	case AX25_REJ:
-	case AX25_RNR:
-	case AX25_RR:
-		if (pf) ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
-		break;
-
-	default:
-		break;
-	}
-
-	return 0;
-}
-
-/*
- *	State machine for state 3, Connected State.
- *	The handling of the timer(s) is in file ax25_std_timer.c
- *	Handling of state 0 and connection release is in ax25.c.
- */
-static int ax25_std_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
-{
-	int queued = 0;
-
-	switch (frametype) {
-	case AX25_SABM:
-	case AX25_SABME:
-		if (frametype == AX25_SABM) {
-			ax25->modulus = AX25_MODULUS;
-			ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
-		} else {
-			ax25->modulus = AX25_EMODULUS;
-			ax25->window  = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
-		}
-		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
-		ax25_stop_t1timer(ax25);
-		ax25_stop_t2timer(ax25);
-		ax25_start_t3timer(ax25);
-		ax25_start_idletimer(ax25);
-		ax25->condition = 0x00;
-		ax25->vs        = 0;
-		ax25->va        = 0;
-		ax25->vr        = 0;
-		ax25_requeue_frames(ax25);
-		break;
-
-	case AX25_DISC:
-		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
-		ax25_disconnect(ax25, 0);
-		break;
-
-	case AX25_DM:
-		ax25_disconnect(ax25, ECONNRESET);
-		break;
-
-	case AX25_RR:
-	case AX25_RNR:
-		if (frametype == AX25_RR)
-			ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
-		else
-			ax25->condition |= AX25_COND_PEER_RX_BUSY;
-		if (type == AX25_COMMAND && pf)
-			ax25_std_enquiry_response(ax25);
-		if (ax25_validate_nr(ax25, nr)) {
-			ax25_check_iframes_acked(ax25, nr);
-		} else {
-			ax25_std_nr_error_recovery(ax25);
-			ax25->state = AX25_STATE_1;
-		}
-		break;
-
-	case AX25_REJ:
-		ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
-		if (type == AX25_COMMAND && pf)
-			ax25_std_enquiry_response(ax25);
-		if (ax25_validate_nr(ax25, nr)) {
-			ax25_frames_acked(ax25, nr);
-			ax25_calculate_rtt(ax25);
-			ax25_stop_t1timer(ax25);
-			ax25_start_t3timer(ax25);
-			ax25_requeue_frames(ax25);
-		} else {
-			ax25_std_nr_error_recovery(ax25);
-			ax25->state = AX25_STATE_1;
-		}
-		break;
-
-	case AX25_I:
-		if (!ax25_validate_nr(ax25, nr)) {
-			ax25_std_nr_error_recovery(ax25);
-			ax25->state = AX25_STATE_1;
-			break;
-		}
-		if (ax25->condition & AX25_COND_PEER_RX_BUSY) {
-			ax25_frames_acked(ax25, nr);
-		} else {
-			ax25_check_iframes_acked(ax25, nr);
-		}
-		if (ax25->condition & AX25_COND_OWN_RX_BUSY) {
-			if (pf) ax25_std_enquiry_response(ax25);
-			break;
-		}
-		if (ns == ax25->vr) {
-			ax25->vr = (ax25->vr + 1) % ax25->modulus;
-			queued = ax25_rx_iframe(ax25, skb);
-			if (ax25->condition & AX25_COND_OWN_RX_BUSY)
-				ax25->vr = ns;	/* ax25->vr - 1 */
-			ax25->condition &= ~AX25_COND_REJECT;
-			if (pf) {
-				ax25_std_enquiry_response(ax25);
-			} else {
-				if (!(ax25->condition & AX25_COND_ACK_PENDING)) {
-					ax25->condition |= AX25_COND_ACK_PENDING;
-					ax25_start_t2timer(ax25);
-				}
-			}
-		} else {
-			if (ax25->condition & AX25_COND_REJECT) {
-				if (pf) ax25_std_enquiry_response(ax25);
-			} else {
-				ax25->condition |= AX25_COND_REJECT;
-				ax25_send_control(ax25, AX25_REJ, pf, AX25_RESPONSE);
-				ax25->condition &= ~AX25_COND_ACK_PENDING;
-			}
-		}
-		break;
-
-	case AX25_FRMR:
-	case AX25_ILLEGAL:
-		ax25_std_establish_data_link(ax25);
-		ax25->state = AX25_STATE_1;
-		break;
-
-	default:
-		break;
-	}
-
-	return queued;
-}
-
-/*
- *	State machine for state 4, Timer Recovery State.
- *	The handling of the timer(s) is in file ax25_std_timer.c
- *	Handling of state 0 and connection release is in ax25.c.
- */
-static int ax25_std_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
-{
-	int queued = 0;
-
-	switch (frametype) {
-	case AX25_SABM:
-	case AX25_SABME:
-		if (frametype == AX25_SABM) {
-			ax25->modulus = AX25_MODULUS;
-			ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
-		} else {
-			ax25->modulus = AX25_EMODULUS;
-			ax25->window  = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
-		}
-		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
-		ax25_stop_t1timer(ax25);
-		ax25_stop_t2timer(ax25);
-		ax25_start_t3timer(ax25);
-		ax25_start_idletimer(ax25);
-		ax25->condition = 0x00;
-		ax25->vs        = 0;
-		ax25->va        = 0;
-		ax25->vr        = 0;
-		ax25->state     = AX25_STATE_3;
-		ax25->n2count   = 0;
-		ax25_requeue_frames(ax25);
-		break;
-
-	case AX25_DISC:
-		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
-		ax25_disconnect(ax25, 0);
-		break;
-
-	case AX25_DM:
-		ax25_disconnect(ax25, ECONNRESET);
-		break;
-
-	case AX25_RR:
-	case AX25_RNR:
-		if (frametype == AX25_RR)
-			ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
-		else
-			ax25->condition |= AX25_COND_PEER_RX_BUSY;
-		if (type == AX25_RESPONSE && pf) {
-			ax25_stop_t1timer(ax25);
-			ax25->n2count = 0;
-			if (ax25_validate_nr(ax25, nr)) {
-				ax25_frames_acked(ax25, nr);
-				if (ax25->vs == ax25->va) {
-					ax25_start_t3timer(ax25);
-					ax25->state   = AX25_STATE_3;
-				} else {
-					ax25_requeue_frames(ax25);
-				}
-			} else {
-				ax25_std_nr_error_recovery(ax25);
-				ax25->state = AX25_STATE_1;
-			}
-			break;
-		}
-		if (type == AX25_COMMAND && pf)
-			ax25_std_enquiry_response(ax25);
-		if (ax25_validate_nr(ax25, nr)) {
-			ax25_frames_acked(ax25, nr);
-		} else {
-			ax25_std_nr_error_recovery(ax25);
-			ax25->state = AX25_STATE_1;
-		}
-		break;
-
-	case AX25_REJ:
-		ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
-		if (pf && type == AX25_RESPONSE) {
-			ax25_stop_t1timer(ax25);
-			ax25->n2count = 0;
-			if (ax25_validate_nr(ax25, nr)) {
-				ax25_frames_acked(ax25, nr);
-				if (ax25->vs == ax25->va) {
-					ax25_start_t3timer(ax25);
-					ax25->state   = AX25_STATE_3;
-				} else {
-					ax25_requeue_frames(ax25);
-				}
-			} else {
-				ax25_std_nr_error_recovery(ax25);
-				ax25->state = AX25_STATE_1;
-			}
-			break;
-		}
-		if (type == AX25_COMMAND && pf)
-			ax25_std_enquiry_response(ax25);
-		if (ax25_validate_nr(ax25, nr)) {
-			ax25_frames_acked(ax25, nr);
-			ax25_requeue_frames(ax25);
-		} else {
-			ax25_std_nr_error_recovery(ax25);
-			ax25->state = AX25_STATE_1;
-		}
-		break;
-
-	case AX25_I:
-		if (!ax25_validate_nr(ax25, nr)) {
-			ax25_std_nr_error_recovery(ax25);
-			ax25->state = AX25_STATE_1;
-			break;
-		}
-		ax25_frames_acked(ax25, nr);
-		if (ax25->condition & AX25_COND_OWN_RX_BUSY) {
-			if (pf)
-				ax25_std_enquiry_response(ax25);
-			break;
-		}
-		if (ns == ax25->vr) {
-			ax25->vr = (ax25->vr + 1) % ax25->modulus;
-			queued = ax25_rx_iframe(ax25, skb);
-			if (ax25->condition & AX25_COND_OWN_RX_BUSY)
-				ax25->vr = ns;	/* ax25->vr - 1 */
-			ax25->condition &= ~AX25_COND_REJECT;
-			if (pf) {
-				ax25_std_enquiry_response(ax25);
-			} else {
-				if (!(ax25->condition & AX25_COND_ACK_PENDING)) {
-					ax25->condition |= AX25_COND_ACK_PENDING;
-					ax25_start_t2timer(ax25);
-				}
-			}
-		} else {
-			if (ax25->condition & AX25_COND_REJECT) {
-				if (pf) ax25_std_enquiry_response(ax25);
-			} else {
-				ax25->condition |= AX25_COND_REJECT;
-				ax25_send_control(ax25, AX25_REJ, pf, AX25_RESPONSE);
-				ax25->condition &= ~AX25_COND_ACK_PENDING;
-			}
-		}
-		break;
-
-	case AX25_FRMR:
-	case AX25_ILLEGAL:
-		ax25_std_establish_data_link(ax25);
-		ax25->state = AX25_STATE_1;
-		break;
-
-	default:
-		break;
-	}
-
-	return queued;
-}
-
-/*
- *	Higher level upcall for a LAPB frame
- */
-int ax25_std_frame_in(ax25_cb *ax25, struct sk_buff *skb, int type)
-{
-	int queued = 0, frametype, ns, nr, pf;
-
-	frametype = ax25_decode(ax25, skb, &ns, &nr, &pf);
-
-	switch (ax25->state) {
-	case AX25_STATE_1:
-		queued = ax25_std_state1_machine(ax25, skb, frametype, pf, type);
-		break;
-	case AX25_STATE_2:
-		queued = ax25_std_state2_machine(ax25, skb, frametype, pf, type);
-		break;
-	case AX25_STATE_3:
-		queued = ax25_std_state3_machine(ax25, skb, frametype, ns, nr, pf, type);
-		break;
-	case AX25_STATE_4:
-		queued = ax25_std_state4_machine(ax25, skb, frametype, ns, nr, pf, type);
-		break;
-	}
-
-	ax25_kick(ax25);
-
-	return queued;
-}
diff --git a/net/ax25/ax25_std_subr.c b/net/ax25/ax25_std_subr.c
deleted file mode 100644
index 4c36f1342558..000000000000
--- a/net/ax25/ax25_std_subr.c
+++ /dev/null
@@ -1,83 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-/*
- * The following routines are taken from page 170 of the 7th ARRL Computer
- * Networking Conference paper, as is the whole state machine.
- */
-
-void ax25_std_nr_error_recovery(ax25_cb *ax25)
-{
-	ax25_std_establish_data_link(ax25);
-}
-
-void ax25_std_establish_data_link(ax25_cb *ax25)
-{
-	ax25->condition = 0x00;
-	ax25->n2count   = 0;
-
-	if (ax25->modulus == AX25_MODULUS)
-		ax25_send_control(ax25, AX25_SABM, AX25_POLLON, AX25_COMMAND);
-	else
-		ax25_send_control(ax25, AX25_SABME, AX25_POLLON, AX25_COMMAND);
-
-	ax25_calculate_t1(ax25);
-	ax25_stop_idletimer(ax25);
-	ax25_stop_t3timer(ax25);
-	ax25_stop_t2timer(ax25);
-	ax25_start_t1timer(ax25);
-}
-
-void ax25_std_transmit_enquiry(ax25_cb *ax25)
-{
-	if (ax25->condition & AX25_COND_OWN_RX_BUSY)
-		ax25_send_control(ax25, AX25_RNR, AX25_POLLON, AX25_COMMAND);
-	else
-		ax25_send_control(ax25, AX25_RR, AX25_POLLON, AX25_COMMAND);
-
-	ax25->condition &= ~AX25_COND_ACK_PENDING;
-
-	ax25_calculate_t1(ax25);
-	ax25_start_t1timer(ax25);
-}
-
-void ax25_std_enquiry_response(ax25_cb *ax25)
-{
-	if (ax25->condition & AX25_COND_OWN_RX_BUSY)
-		ax25_send_control(ax25, AX25_RNR, AX25_POLLON, AX25_RESPONSE);
-	else
-		ax25_send_control(ax25, AX25_RR, AX25_POLLON, AX25_RESPONSE);
-
-	ax25->condition &= ~AX25_COND_ACK_PENDING;
-}
-
-void ax25_std_timeout_response(ax25_cb *ax25)
-{
-	if (ax25->condition & AX25_COND_OWN_RX_BUSY)
-		ax25_send_control(ax25, AX25_RNR, AX25_POLLOFF, AX25_RESPONSE);
-	else
-		ax25_send_control(ax25, AX25_RR, AX25_POLLOFF, AX25_RESPONSE);
-
-	ax25->condition &= ~AX25_COND_ACK_PENDING;
-}
diff --git a/net/ax25/ax25_std_timer.c b/net/ax25/ax25_std_timer.c
deleted file mode 100644
index b17da41210cb..000000000000
--- a/net/ax25/ax25_std_timer.c
+++ /dev/null
@@ -1,175 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
- * Copyright (C) Frederic Rible F1OAT (frible@teaser.fr)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-void ax25_std_heartbeat_expiry(ax25_cb *ax25)
-{
-	struct sock *sk = ax25->sk;
-
-	if (sk)
-		bh_lock_sock(sk);
-
-	switch (ax25->state) {
-	case AX25_STATE_0:
-	case AX25_STATE_2:
-		/* Magic here: If we listen() and a new link dies before it
-		   is accepted() it isn't 'dead' so doesn't get removed. */
-		if (!sk || sock_flag(sk, SOCK_DESTROY) ||
-		    (sk->sk_state == TCP_LISTEN &&
-		     sock_flag(sk, SOCK_DEAD))) {
-			if (sk) {
-				sock_hold(sk);
-				ax25_destroy_socket(ax25);
-				bh_unlock_sock(sk);
-				/* Ungrab socket and destroy it */
-				sock_put(sk);
-			} else
-				ax25_destroy_socket(ax25);
-			return;
-		}
-		break;
-
-	case AX25_STATE_3:
-	case AX25_STATE_4:
-		/*
-		 * Check the state of the receive buffer.
-		 */
-		if (sk != NULL) {
-			if (atomic_read(&sk->sk_rmem_alloc) <
-			    (sk->sk_rcvbuf >> 1) &&
-			    (ax25->condition & AX25_COND_OWN_RX_BUSY)) {
-				ax25->condition &= ~AX25_COND_OWN_RX_BUSY;
-				ax25->condition &= ~AX25_COND_ACK_PENDING;
-				ax25_send_control(ax25, AX25_RR, AX25_POLLOFF, AX25_RESPONSE);
-				break;
-			}
-		}
-	}
-
-	if (sk)
-		bh_unlock_sock(sk);
-
-	ax25_start_heartbeat(ax25);
-}
-
-void ax25_std_t2timer_expiry(ax25_cb *ax25)
-{
-	if (ax25->condition & AX25_COND_ACK_PENDING) {
-		ax25->condition &= ~AX25_COND_ACK_PENDING;
-		ax25_std_timeout_response(ax25);
-	}
-}
-
-void ax25_std_t3timer_expiry(ax25_cb *ax25)
-{
-	ax25->n2count = 0;
-	ax25_std_transmit_enquiry(ax25);
-	ax25->state   = AX25_STATE_4;
-}
-
-void ax25_std_idletimer_expiry(ax25_cb *ax25)
-{
-	ax25_clear_queues(ax25);
-
-	ax25->n2count = 0;
-	ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
-	ax25->state   = AX25_STATE_2;
-
-	ax25_calculate_t1(ax25);
-	ax25_start_t1timer(ax25);
-	ax25_stop_t2timer(ax25);
-	ax25_stop_t3timer(ax25);
-
-	if (ax25->sk != NULL) {
-		bh_lock_sock(ax25->sk);
-		ax25->sk->sk_state     = TCP_CLOSE;
-		ax25->sk->sk_err       = 0;
-		ax25->sk->sk_shutdown |= SEND_SHUTDOWN;
-		if (!sock_flag(ax25->sk, SOCK_DEAD)) {
-			ax25->sk->sk_state_change(ax25->sk);
-			sock_set_flag(ax25->sk, SOCK_DEAD);
-		}
-		bh_unlock_sock(ax25->sk);
-	}
-}
-
-void ax25_std_t1timer_expiry(ax25_cb *ax25)
-{
-	switch (ax25->state) {
-	case AX25_STATE_1:
-		if (ax25->n2count == ax25->n2) {
-			if (ax25->modulus == AX25_MODULUS) {
-				ax25_disconnect(ax25, ETIMEDOUT);
-				return;
-			} else {
-				ax25->modulus = AX25_MODULUS;
-				ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
-				ax25->n2count = 0;
-				ax25_send_control(ax25, AX25_SABM, AX25_POLLON, AX25_COMMAND);
-			}
-		} else {
-			ax25->n2count++;
-			if (ax25->modulus == AX25_MODULUS)
-				ax25_send_control(ax25, AX25_SABM, AX25_POLLON, AX25_COMMAND);
-			else
-				ax25_send_control(ax25, AX25_SABME, AX25_POLLON, AX25_COMMAND);
-		}
-		break;
-
-	case AX25_STATE_2:
-		if (ax25->n2count == ax25->n2) {
-			ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
-			if (!sock_flag(ax25->sk, SOCK_DESTROY))
-				ax25_disconnect(ax25, ETIMEDOUT);
-			return;
-		} else {
-			ax25->n2count++;
-			ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
-		}
-		break;
-
-	case AX25_STATE_3:
-		ax25->n2count = 1;
-		ax25_std_transmit_enquiry(ax25);
-		ax25->state   = AX25_STATE_4;
-		break;
-
-	case AX25_STATE_4:
-		if (ax25->n2count == ax25->n2) {
-			ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
-			ax25_disconnect(ax25, ETIMEDOUT);
-			return;
-		} else {
-			ax25->n2count++;
-			ax25_std_transmit_enquiry(ax25);
-		}
-		break;
-	}
-
-	ax25_calculate_t1(ax25);
-	ax25_start_t1timer(ax25);
-}
diff --git a/net/ax25/ax25_subr.c b/net/ax25/ax25_subr.c
deleted file mode 100644
index bff4b203a893..000000000000
--- a/net/ax25/ax25_subr.c
+++ /dev/null
@@ -1,296 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
- * Copyright (C) Frederic Rible F1OAT (frible@teaser.fr)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-/*
- *	This routine purges all the queues of frames.
- */
-void ax25_clear_queues(ax25_cb *ax25)
-{
-	skb_queue_purge(&ax25->write_queue);
-	skb_queue_purge(&ax25->ack_queue);
-	skb_queue_purge(&ax25->reseq_queue);
-	skb_queue_purge(&ax25->frag_queue);
-}
-
-/*
- * This routine purges the input queue of those frames that have been
- * acknowledged. This replaces the boxes labelled "V(a) <- N(r)" on the
- * SDL diagram.
- */
-void ax25_frames_acked(ax25_cb *ax25, unsigned short nr)
-{
-	struct sk_buff *skb;
-
-	/*
-	 * Remove all the ack-ed frames from the ack queue.
-	 */
-	if (ax25->va != nr) {
-		while (skb_peek(&ax25->ack_queue) != NULL && ax25->va != nr) {
-			skb = skb_dequeue(&ax25->ack_queue);
-			kfree_skb(skb);
-			ax25->va = (ax25->va + 1) % ax25->modulus;
-		}
-	}
-}
-
-void ax25_requeue_frames(ax25_cb *ax25)
-{
-	struct sk_buff *skb;
-
-	/*
-	 * Requeue all the un-ack-ed frames on the output queue to be picked
-	 * up by ax25_kick called from the timer. This arrangement handles the
-	 * possibility of an empty output queue.
-	 */
-	while ((skb = skb_dequeue_tail(&ax25->ack_queue)) != NULL)
-		skb_queue_head(&ax25->write_queue, skb);
-}
-
-/*
- *	Validate that the value of nr is between va and vs. Return true or
- *	false for testing.
- */
-int ax25_validate_nr(ax25_cb *ax25, unsigned short nr)
-{
-	unsigned short vc = ax25->va;
-
-	while (vc != ax25->vs) {
-		if (nr == vc) return 1;
-		vc = (vc + 1) % ax25->modulus;
-	}
-
-	if (nr == ax25->vs) return 1;
-
-	return 0;
-}
-
-/*
- *	This routine is the centralised routine for parsing the control
- *	information for the different frame formats.
- */
-int ax25_decode(ax25_cb *ax25, struct sk_buff *skb, int *ns, int *nr, int *pf)
-{
-	unsigned char *frame;
-	int frametype = AX25_ILLEGAL;
-
-	frame = skb->data;
-	*ns = *nr = *pf = 0;
-
-	if (ax25->modulus == AX25_MODULUS) {
-		if ((frame[0] & AX25_S) == 0) {
-			frametype = AX25_I;			/* I frame - carries NR/NS/PF */
-			*ns = (frame[0] >> 1) & 0x07;
-			*nr = (frame[0] >> 5) & 0x07;
-			*pf = frame[0] & AX25_PF;
-		} else if ((frame[0] & AX25_U) == 1) { 	/* S frame - take out PF/NR */
-			frametype = frame[0] & 0x0F;
-			*nr = (frame[0] >> 5) & 0x07;
-			*pf = frame[0] & AX25_PF;
-		} else if ((frame[0] & AX25_U) == 3) { 	/* U frame - take out PF */
-			frametype = frame[0] & ~AX25_PF;
-			*pf = frame[0] & AX25_PF;
-		}
-		skb_pull(skb, 1);
-	} else {
-		if ((frame[0] & AX25_S) == 0) {
-			frametype = AX25_I;			/* I frame - carries NR/NS/PF */
-			*ns = (frame[0] >> 1) & 0x7F;
-			*nr = (frame[1] >> 1) & 0x7F;
-			*pf = frame[1] & AX25_EPF;
-			skb_pull(skb, 2);
-		} else if ((frame[0] & AX25_U) == 1) { 	/* S frame - take out PF/NR */
-			frametype = frame[0] & 0x0F;
-			*nr = (frame[1] >> 1) & 0x7F;
-			*pf = frame[1] & AX25_EPF;
-			skb_pull(skb, 2);
-		} else if ((frame[0] & AX25_U) == 3) { 	/* U frame - take out PF */
-			frametype = frame[0] & ~AX25_PF;
-			*pf = frame[0] & AX25_PF;
-			skb_pull(skb, 1);
-		}
-	}
-
-	return frametype;
-}
-
-/*
- *	This routine is called when the HDLC layer internally  generates a
- *	command or  response  for  the remote machine ( eg. RR, UA etc. ).
- *	Only supervisory or unnumbered frames are processed.
- */
-void ax25_send_control(ax25_cb *ax25, int frametype, int poll_bit, int type)
-{
-	struct sk_buff *skb;
-	unsigned char  *dptr;
-
-	if ((skb = alloc_skb(ax25->ax25_dev->dev->hard_header_len + 2, GFP_ATOMIC)) == NULL)
-		return;
-
-	skb_reserve(skb, ax25->ax25_dev->dev->hard_header_len);
-
-	skb_reset_network_header(skb);
-
-	/* Assume a response - address structure for DTE */
-	if (ax25->modulus == AX25_MODULUS) {
-		dptr = skb_put(skb, 1);
-		*dptr = frametype;
-		*dptr |= (poll_bit) ? AX25_PF : 0;
-		if ((frametype & AX25_U) == AX25_S)		/* S frames carry NR */
-			*dptr |= (ax25->vr << 5);
-	} else {
-		if ((frametype & AX25_U) == AX25_U) {
-			dptr = skb_put(skb, 1);
-			*dptr = frametype;
-			*dptr |= (poll_bit) ? AX25_PF : 0;
-		} else {
-			dptr = skb_put(skb, 2);
-			dptr[0] = frametype;
-			dptr[1] = (ax25->vr << 1);
-			dptr[1] |= (poll_bit) ? AX25_EPF : 0;
-		}
-	}
-
-	ax25_transmit_buffer(ax25, skb, type);
-}
-
-/*
- *	Send a 'DM' to an unknown connection attempt, or an invalid caller.
- *
- *	Note: src here is the sender, thus it's the target of the DM
- */
-void ax25_return_dm(struct net_device *dev, ax25_address *src, ax25_address *dest, ax25_digi *digi)
-{
-	struct sk_buff *skb;
-	char *dptr;
-	ax25_digi retdigi;
-
-	if (dev == NULL)
-		return;
-
-	if ((skb = alloc_skb(dev->hard_header_len + 1, GFP_ATOMIC)) == NULL)
-		return;	/* Next SABM will get DM'd */
-
-	skb_reserve(skb, dev->hard_header_len);
-	skb_reset_network_header(skb);
-
-	ax25_digi_invert(digi, &retdigi);
-
-	dptr = skb_put(skb, 1);
-
-	*dptr = AX25_DM | AX25_PF;
-
-	/*
-	 *	Do the address ourselves
-	 */
-	dptr  = skb_push(skb, ax25_addr_size(digi));
-	dptr += ax25_addr_build(dptr, dest, src, &retdigi, AX25_RESPONSE, AX25_MODULUS);
-
-	ax25_queue_xmit(skb, dev);
-}
-
-/*
- *	Exponential backoff for AX.25
- */
-void ax25_calculate_t1(ax25_cb *ax25)
-{
-	int n, t = 2;
-
-	switch (ax25->backoff) {
-	case 0:
-		break;
-
-	case 1:
-		t += 2 * ax25->n2count;
-		break;
-
-	case 2:
-		for (n = 0; n < ax25->n2count; n++)
-			t *= 2;
-		if (t > 8) t = 8;
-		break;
-	}
-
-	ax25->t1 = t * ax25->rtt;
-}
-
-/*
- *	Calculate the Round Trip Time
- */
-void ax25_calculate_rtt(ax25_cb *ax25)
-{
-	if (ax25->backoff == 0)
-		return;
-
-	if (ax25_t1timer_running(ax25) && ax25->n2count == 0)
-		ax25->rtt = (9 * ax25->rtt + ax25->t1 - ax25_display_timer(&ax25->t1timer)) / 10;
-
-	if (ax25->rtt < AX25_T1CLAMPLO)
-		ax25->rtt = AX25_T1CLAMPLO;
-
-	if (ax25->rtt > AX25_T1CLAMPHI)
-		ax25->rtt = AX25_T1CLAMPHI;
-}
-
-void ax25_disconnect(ax25_cb *ax25, int reason)
-{
-	ax25_clear_queues(ax25);
-
-	if (reason == ENETUNREACH) {
-		timer_delete_sync(&ax25->timer);
-		timer_delete_sync(&ax25->t1timer);
-		timer_delete_sync(&ax25->t2timer);
-		timer_delete_sync(&ax25->t3timer);
-		timer_delete_sync(&ax25->idletimer);
-	} else {
-		if (ax25->sk && !sock_flag(ax25->sk, SOCK_DESTROY))
-			ax25_stop_heartbeat(ax25);
-		ax25_stop_t1timer(ax25);
-		ax25_stop_t2timer(ax25);
-		ax25_stop_t3timer(ax25);
-		ax25_stop_idletimer(ax25);
-	}
-
-	ax25->state = AX25_STATE_0;
-
-	ax25_link_failed(ax25, reason);
-
-	if (ax25->sk != NULL) {
-		local_bh_disable();
-		bh_lock_sock(ax25->sk);
-		ax25->sk->sk_state     = TCP_CLOSE;
-		ax25->sk->sk_err       = reason;
-		ax25->sk->sk_shutdown |= SEND_SHUTDOWN;
-		if (!sock_flag(ax25->sk, SOCK_DEAD)) {
-			ax25->sk->sk_state_change(ax25->sk);
-			sock_set_flag(ax25->sk, SOCK_DEAD);
-		}
-		bh_unlock_sock(ax25->sk);
-		local_bh_enable();
-	}
-}
diff --git a/net/ax25/ax25_timer.c b/net/ax25/ax25_timer.c
deleted file mode 100644
index a69bfbc8b679..000000000000
--- a/net/ax25/ax25_timer.c
+++ /dev/null
@@ -1,224 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) Tomi Manninen OH2BNS (oh2bns@sral.fi)
- * Copyright (C) Darryl Miles G7LED (dlm@g7led.demon.co.uk)
- * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
- * Copyright (C) Frederic Rible F1OAT (frible@teaser.fr)
- * Copyright (C) 2002 Ralf Baechle DO1GRB (ralf@gnu.org)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/jiffies.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-static void ax25_heartbeat_expiry(struct timer_list *);
-static void ax25_t1timer_expiry(struct timer_list *);
-static void ax25_t2timer_expiry(struct timer_list *);
-static void ax25_t3timer_expiry(struct timer_list *);
-static void ax25_idletimer_expiry(struct timer_list *);
-
-void ax25_setup_timers(ax25_cb *ax25)
-{
-	timer_setup(&ax25->timer, ax25_heartbeat_expiry, 0);
-	timer_setup(&ax25->t1timer, ax25_t1timer_expiry, 0);
-	timer_setup(&ax25->t2timer, ax25_t2timer_expiry, 0);
-	timer_setup(&ax25->t3timer, ax25_t3timer_expiry, 0);
-	timer_setup(&ax25->idletimer, ax25_idletimer_expiry, 0);
-}
-
-void ax25_start_heartbeat(ax25_cb *ax25)
-{
-	mod_timer(&ax25->timer, jiffies + 5 * HZ);
-}
-
-void ax25_start_t1timer(ax25_cb *ax25)
-{
-	mod_timer(&ax25->t1timer, jiffies + ax25->t1);
-}
-
-void ax25_start_t2timer(ax25_cb *ax25)
-{
-	mod_timer(&ax25->t2timer, jiffies + ax25->t2);
-}
-
-void ax25_start_t3timer(ax25_cb *ax25)
-{
-	if (ax25->t3 > 0)
-		mod_timer(&ax25->t3timer, jiffies + ax25->t3);
-	else
-		timer_delete(&ax25->t3timer);
-}
-
-void ax25_start_idletimer(ax25_cb *ax25)
-{
-	if (ax25->idle > 0)
-		mod_timer(&ax25->idletimer, jiffies + ax25->idle);
-	else
-		timer_delete(&ax25->idletimer);
-}
-
-void ax25_stop_heartbeat(ax25_cb *ax25)
-{
-	timer_delete(&ax25->timer);
-}
-
-void ax25_stop_t1timer(ax25_cb *ax25)
-{
-	timer_delete(&ax25->t1timer);
-}
-
-void ax25_stop_t2timer(ax25_cb *ax25)
-{
-	timer_delete(&ax25->t2timer);
-}
-
-void ax25_stop_t3timer(ax25_cb *ax25)
-{
-	timer_delete(&ax25->t3timer);
-}
-
-void ax25_stop_idletimer(ax25_cb *ax25)
-{
-	timer_delete(&ax25->idletimer);
-}
-
-int ax25_t1timer_running(ax25_cb *ax25)
-{
-	return timer_pending(&ax25->t1timer);
-}
-
-unsigned long ax25_display_timer(struct timer_list *timer)
-{
-	long delta = timer->expires - jiffies;
-
-	if (!timer_pending(timer))
-		return 0;
-
-	return max(0L, delta);
-}
-
-EXPORT_SYMBOL(ax25_display_timer);
-
-static void ax25_heartbeat_expiry(struct timer_list *t)
-{
-	int proto = AX25_PROTO_STD_SIMPLEX;
-	ax25_cb *ax25 = timer_container_of(ax25, t, timer);
-
-	if (ax25->ax25_dev)
-		proto = ax25->ax25_dev->values[AX25_VALUES_PROTOCOL];
-
-	switch (proto) {
-	case AX25_PROTO_STD_SIMPLEX:
-	case AX25_PROTO_STD_DUPLEX:
-		ax25_std_heartbeat_expiry(ax25);
-		break;
-
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	case AX25_PROTO_DAMA_SLAVE:
-		if (ax25->ax25_dev->dama.slave)
-			ax25_ds_heartbeat_expiry(ax25);
-		else
-			ax25_std_heartbeat_expiry(ax25);
-		break;
-#endif
-	}
-}
-
-static void ax25_t1timer_expiry(struct timer_list *t)
-{
-	ax25_cb *ax25 = timer_container_of(ax25, t, t1timer);
-
-	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
-	case AX25_PROTO_STD_SIMPLEX:
-	case AX25_PROTO_STD_DUPLEX:
-		ax25_std_t1timer_expiry(ax25);
-		break;
-
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	case AX25_PROTO_DAMA_SLAVE:
-		if (!ax25->ax25_dev->dama.slave)
-			ax25_std_t1timer_expiry(ax25);
-		break;
-#endif
-	}
-}
-
-static void ax25_t2timer_expiry(struct timer_list *t)
-{
-	ax25_cb *ax25 = timer_container_of(ax25, t, t2timer);
-
-	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
-	case AX25_PROTO_STD_SIMPLEX:
-	case AX25_PROTO_STD_DUPLEX:
-		ax25_std_t2timer_expiry(ax25);
-		break;
-
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	case AX25_PROTO_DAMA_SLAVE:
-		if (!ax25->ax25_dev->dama.slave)
-			ax25_std_t2timer_expiry(ax25);
-		break;
-#endif
-	}
-}
-
-static void ax25_t3timer_expiry(struct timer_list *t)
-{
-	ax25_cb *ax25 = timer_container_of(ax25, t, t3timer);
-
-	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
-	case AX25_PROTO_STD_SIMPLEX:
-	case AX25_PROTO_STD_DUPLEX:
-		ax25_std_t3timer_expiry(ax25);
-		break;
-
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	case AX25_PROTO_DAMA_SLAVE:
-		if (ax25->ax25_dev->dama.slave)
-			ax25_ds_t3timer_expiry(ax25);
-		else
-			ax25_std_t3timer_expiry(ax25);
-		break;
-#endif
-	}
-}
-
-static void ax25_idletimer_expiry(struct timer_list *t)
-{
-	ax25_cb *ax25 = timer_container_of(ax25, t, idletimer);
-
-	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
-	case AX25_PROTO_STD_SIMPLEX:
-	case AX25_PROTO_STD_DUPLEX:
-		ax25_std_idletimer_expiry(ax25);
-		break;
-
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	case AX25_PROTO_DAMA_SLAVE:
-		if (ax25->ax25_dev->dama.slave)
-			ax25_ds_idletimer_expiry(ax25);
-		else
-			ax25_std_idletimer_expiry(ax25);
-		break;
-#endif
-	}
-}
diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c
deleted file mode 100644
index 159ce74273f0..000000000000
--- a/net/ax25/ax25_uid.c
+++ /dev/null
@@ -1,204 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- */
-
-#include <linux/capability.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/notifier.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/stat.h>
-#include <linux/sysctl.h>
-#include <linux/export.h>
-#include <net/ip.h>
-#include <net/arp.h>
-
-/*
- *	Callsign/UID mapper. This is in kernel space for security on multi-amateur machines.
- */
-
-static HLIST_HEAD(ax25_uid_list);
-static DEFINE_RWLOCK(ax25_uid_lock);
-
-int ax25_uid_policy;
-
-EXPORT_SYMBOL(ax25_uid_policy);
-
-ax25_uid_assoc *ax25_findbyuid(kuid_t uid)
-{
-	ax25_uid_assoc *ax25_uid, *res = NULL;
-
-	read_lock(&ax25_uid_lock);
-	ax25_uid_for_each(ax25_uid, &ax25_uid_list) {
-		if (uid_eq(ax25_uid->uid, uid)) {
-			ax25_uid_hold(ax25_uid);
-			res = ax25_uid;
-			break;
-		}
-	}
-	read_unlock(&ax25_uid_lock);
-
-	return res;
-}
-
-EXPORT_SYMBOL(ax25_findbyuid);
-
-int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)
-{
-	ax25_uid_assoc *ax25_uid;
-	ax25_uid_assoc *user;
-	unsigned long res;
-
-	switch (cmd) {
-	case SIOCAX25GETUID:
-		res = -ENOENT;
-		read_lock(&ax25_uid_lock);
-		ax25_uid_for_each(ax25_uid, &ax25_uid_list) {
-			if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) {
-				res = from_kuid_munged(current_user_ns(), ax25_uid->uid);
-				break;
-			}
-		}
-		read_unlock(&ax25_uid_lock);
-
-		return res;
-
-	case SIOCAX25ADDUID:
-	{
-		kuid_t sax25_kuid;
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		sax25_kuid = make_kuid(current_user_ns(), sax->sax25_uid);
-		if (!uid_valid(sax25_kuid))
-			return -EINVAL;
-		user = ax25_findbyuid(sax25_kuid);
-		if (user) {
-			ax25_uid_put(user);
-			return -EEXIST;
-		}
-		if (sax->sax25_uid == 0)
-			return -EINVAL;
-		if ((ax25_uid = kmalloc_obj(*ax25_uid)) == NULL)
-			return -ENOMEM;
-
-		refcount_set(&ax25_uid->refcount, 1);
-		ax25_uid->uid  = sax25_kuid;
-		ax25_uid->call = sax->sax25_call;
-
-		write_lock(&ax25_uid_lock);
-		hlist_add_head(&ax25_uid->uid_node, &ax25_uid_list);
-		write_unlock(&ax25_uid_lock);
-
-		return 0;
-	}
-	case SIOCAX25DELUID:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-
-		ax25_uid = NULL;
-		write_lock(&ax25_uid_lock);
-		ax25_uid_for_each(ax25_uid, &ax25_uid_list) {
-			if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0)
-				break;
-		}
-		if (ax25_uid == NULL) {
-			write_unlock(&ax25_uid_lock);
-			return -ENOENT;
-		}
-		hlist_del_init(&ax25_uid->uid_node);
-		ax25_uid_put(ax25_uid);
-		write_unlock(&ax25_uid_lock);
-
-		return 0;
-
-	default:
-		return -EINVAL;
-	}
-
-	return -EINVAL;	/*NOTREACHED */
-}
-
-#ifdef CONFIG_PROC_FS
-
-static void *ax25_uid_seq_start(struct seq_file *seq, loff_t *pos)
-	__acquires(ax25_uid_lock)
-{
-	read_lock(&ax25_uid_lock);
-	return seq_hlist_start_head(&ax25_uid_list, *pos);
-}
-
-static void *ax25_uid_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	return seq_hlist_next(v, &ax25_uid_list, pos);
-}
-
-static void ax25_uid_seq_stop(struct seq_file *seq, void *v)
-	__releases(ax25_uid_lock)
-{
-	read_unlock(&ax25_uid_lock);
-}
-
-static int ax25_uid_seq_show(struct seq_file *seq, void *v)
-{
-	char buf[11];
-
-	if (v == SEQ_START_TOKEN)
-		seq_printf(seq, "Policy: %d\n", ax25_uid_policy);
-	else {
-		struct ax25_uid_assoc *pt;
-
-		pt = hlist_entry(v, struct ax25_uid_assoc, uid_node);
-		seq_printf(seq, "%6d %s\n",
-			from_kuid_munged(seq_user_ns(seq), pt->uid),
-			ax2asc(buf, &pt->call));
-	}
-	return 0;
-}
-
-const struct seq_operations ax25_uid_seqops = {
-	.start = ax25_uid_seq_start,
-	.next = ax25_uid_seq_next,
-	.stop = ax25_uid_seq_stop,
-	.show = ax25_uid_seq_show,
-};
-#endif
-
-/*
- *	Free all memory associated with UID/Callsign structures.
- */
-void __exit ax25_uid_free(void)
-{
-	ax25_uid_assoc *ax25_uid;
-
-	write_lock(&ax25_uid_lock);
-again:
-	ax25_uid_for_each(ax25_uid, &ax25_uid_list) {
-		hlist_del_init(&ax25_uid->uid_node);
-		ax25_uid_put(ax25_uid);
-		goto again;
-	}
-	write_unlock(&ax25_uid_lock);
-}
diff --git a/net/ax25/sysctl_net_ax25.c b/net/ax25/sysctl_net_ax25.c
deleted file mode 100644
index 68753aa30334..000000000000
--- a/net/ax25/sysctl_net_ax25.c
+++ /dev/null
@@ -1,181 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) 1996 Mike Shaver (shaver@zeroknowledge.com)
- */
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/sysctl.h>
-#include <linux/spinlock.h>
-#include <net/ax25.h>
-
-static int min_ipdefmode[1],    	max_ipdefmode[] = {1};
-static int min_axdefmode[1],            max_axdefmode[] = {1};
-static int min_backoff[1],		max_backoff[] = {2};
-static int min_conmode[1],		max_conmode[] = {2};
-static int min_window[] = {1},		max_window[] = {7};
-static int min_ewindow[] = {1},		max_ewindow[] = {63};
-static int min_t1[] = {1},		max_t1[] = {30000};
-static int min_t2[] = {1},		max_t2[] = {20000};
-static int min_t3[1],			max_t3[] = {3600000};
-static int min_idle[1],			max_idle[] = {65535000};
-static int min_n2[] = {1},		max_n2[] = {31};
-static int min_paclen[] = {1},		max_paclen[] = {512};
-static int min_proto[1],		max_proto[] = { AX25_PROTO_MAX };
-#ifdef CONFIG_AX25_DAMA_SLAVE
-static int min_ds_timeout[1],		max_ds_timeout[] = {65535000};
-#endif
-
-static const struct ctl_table ax25_param_table[] = {
-	{
-		.procname	= "ip_default_mode",
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_ipdefmode,
-		.extra2		= &max_ipdefmode
-	},
-	{
-		.procname	= "ax25_default_mode",
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_axdefmode,
-		.extra2		= &max_axdefmode
-	},
-	{
-		.procname	= "backoff_type",
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_backoff,
-		.extra2		= &max_backoff
-	},
-	{
-		.procname	= "connect_mode",
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_conmode,
-		.extra2		= &max_conmode
-	},
-	{
-		.procname	= "standard_window_size",
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_window,
-		.extra2		= &max_window
-	},
-	{
-		.procname	= "extended_window_size",
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_ewindow,
-		.extra2		= &max_ewindow
-	},
-	{
-		.procname	= "t1_timeout",
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_t1,
-		.extra2		= &max_t1
-	},
-	{
-		.procname	= "t2_timeout",
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_t2,
-		.extra2		= &max_t2
-	},
-	{
-		.procname	= "t3_timeout",
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_t3,
-		.extra2		= &max_t3
-	},
-	{
-		.procname	= "idle_timeout",
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_idle,
-		.extra2		= &max_idle
-	},
-	{
-		.procname	= "maximum_retry_count",
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_n2,
-		.extra2		= &max_n2
-	},
-	{
-		.procname	= "maximum_packet_length",
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_paclen,
-		.extra2		= &max_paclen
-	},
-	{
-		.procname	= "protocol",
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_proto,
-		.extra2		= &max_proto
-	},
-#ifdef CONFIG_AX25_DAMA_SLAVE
-	{
-		.procname	= "dama_slave_timeout",
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_ds_timeout,
-		.extra2		= &max_ds_timeout
-	},
-#endif
-};
-
-int ax25_register_dev_sysctl(ax25_dev *ax25_dev)
-{
-	char path[sizeof("net/ax25/") + IFNAMSIZ];
-	int k;
-	struct ctl_table *table;
-
-	table = kmemdup(ax25_param_table, sizeof(ax25_param_table), GFP_KERNEL);
-	if (!table)
-		return -ENOMEM;
-
-	BUILD_BUG_ON(ARRAY_SIZE(ax25_param_table) != AX25_MAX_VALUES);
-	for (k = 0; k < AX25_MAX_VALUES; k++)
-		table[k].data = &ax25_dev->values[k];
-
-	snprintf(path, sizeof(path), "net/ax25/%s", ax25_dev->dev->name);
-	ax25_dev->sysheader = register_net_sysctl_sz(&init_net, path, table,
-						     ARRAY_SIZE(ax25_param_table));
-	if (!ax25_dev->sysheader) {
-		kfree(table);
-		return -ENOMEM;
-	}
-	return 0;
-}
-
-void ax25_unregister_dev_sysctl(ax25_dev *ax25_dev)
-{
-	struct ctl_table_header *header = ax25_dev->sysheader;
-	const struct ctl_table *table;
-
-	if (header) {
-		ax25_dev->sysheader = NULL;
-		table = header->ctl_table_arg;
-		unregister_net_sysctl_table(header);
-		kfree(table);
-	}
-}
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 51d70180e1cc..d409f606aec0 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -109,7 +109,6 @@
 #include <net/sock.h>
 #include <net/arp.h>
 #include <net/ax25.h>
-#include <net/netrom.h>
 #include <net/dst_metadata.h>
 #include <net/ip_tunnels.h>
 
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
deleted file mode 100644
index 5fc54836dfa8..000000000000
--- a/net/netrom/af_netrom.c
+++ /dev/null
@@ -1,1536 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
- * Copyright Darryl Miles G7LED (dlm@g7led.demon.co.uk)
- */
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/capability.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/sched/signal.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/stat.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <net/net_namespace.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/termios.h>	/* For TIOCINQ/OUTQ */
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/notifier.h>
-#include <net/netrom.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <net/ip.h>
-#include <net/tcp_states.h>
-#include <net/arp.h>
-#include <linux/init.h>
-
-static int nr_ndevs = 4;
-
-int sysctl_netrom_default_path_quality            = NR_DEFAULT_QUAL;
-int sysctl_netrom_obsolescence_count_initialiser  = NR_DEFAULT_OBS;
-int sysctl_netrom_network_ttl_initialiser         = NR_DEFAULT_TTL;
-int sysctl_netrom_transport_timeout               = NR_DEFAULT_T1;
-int sysctl_netrom_transport_maximum_tries         = NR_DEFAULT_N2;
-int sysctl_netrom_transport_acknowledge_delay     = NR_DEFAULT_T2;
-int sysctl_netrom_transport_busy_delay            = NR_DEFAULT_T4;
-int sysctl_netrom_transport_requested_window_size = NR_DEFAULT_WINDOW;
-int sysctl_netrom_transport_no_activity_timeout   = NR_DEFAULT_IDLE;
-int sysctl_netrom_routing_control                 = NR_DEFAULT_ROUTING;
-int sysctl_netrom_link_fails_count                = NR_DEFAULT_FAILS;
-int sysctl_netrom_reset_circuit                   = NR_DEFAULT_RESET;
-
-static unsigned short circuit = 0x101;
-
-static HLIST_HEAD(nr_list);
-static DEFINE_SPINLOCK(nr_list_lock);
-
-static const struct proto_ops nr_proto_ops;
-
-/*
- * NETROM network devices are virtual network devices encapsulating NETROM
- * frames into AX.25 which will be sent through an AX.25 device, so form a
- * special "super class" of normal net devices; split their locks off into a
- * separate class since they always nest.
- */
-static struct lock_class_key nr_netdev_xmit_lock_key;
-static struct lock_class_key nr_netdev_addr_lock_key;
-
-static void nr_set_lockdep_one(struct net_device *dev,
-			       struct netdev_queue *txq,
-			       void *_unused)
-{
-	lockdep_set_class(&txq->_xmit_lock, &nr_netdev_xmit_lock_key);
-}
-
-static void nr_set_lockdep_key(struct net_device *dev)
-{
-	lockdep_set_class(&dev->addr_list_lock, &nr_netdev_addr_lock_key);
-	netdev_for_each_tx_queue(dev, nr_set_lockdep_one, NULL);
-}
-
-/*
- *	Socket removal during an interrupt is now safe.
- */
-static void nr_remove_socket(struct sock *sk)
-{
-	spin_lock_bh(&nr_list_lock);
-	sk_del_node_init(sk);
-	spin_unlock_bh(&nr_list_lock);
-}
-
-/*
- *	Kill all bound sockets on a dropped device.
- */
-static void nr_kill_by_device(struct net_device *dev)
-{
-	struct sock *s;
-
-	spin_lock_bh(&nr_list_lock);
-	sk_for_each(s, &nr_list)
-		if (nr_sk(s)->device == dev)
-			nr_disconnect(s, ENETUNREACH);
-	spin_unlock_bh(&nr_list_lock);
-}
-
-/*
- *	Handle device status changes.
- */
-static int nr_device_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
-	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
-
-	if (!net_eq(dev_net(dev), &init_net))
-		return NOTIFY_DONE;
-
-	if (event != NETDEV_DOWN)
-		return NOTIFY_DONE;
-
-	nr_kill_by_device(dev);
-	nr_rt_device_down(dev);
-
-	return NOTIFY_DONE;
-}
-
-/*
- *	Add a socket to the bound sockets list.
- */
-static void nr_insert_socket(struct sock *sk)
-{
-	spin_lock_bh(&nr_list_lock);
-	sk_add_node(sk, &nr_list);
-	spin_unlock_bh(&nr_list_lock);
-}
-
-/*
- *	Find a socket that wants to accept the Connect Request we just
- *	received.
- */
-static struct sock *nr_find_listener(ax25_address *addr)
-{
-	struct sock *s;
-
-	spin_lock_bh(&nr_list_lock);
-	sk_for_each(s, &nr_list)
-		if (!ax25cmp(&nr_sk(s)->source_addr, addr) &&
-		    s->sk_state == TCP_LISTEN) {
-			sock_hold(s);
-			goto found;
-		}
-	s = NULL;
-found:
-	spin_unlock_bh(&nr_list_lock);
-	return s;
-}
-
-/*
- *	Find a connected NET/ROM socket given my circuit IDs.
- */
-static struct sock *nr_find_socket(unsigned char index, unsigned char id)
-{
-	struct sock *s;
-
-	spin_lock_bh(&nr_list_lock);
-	sk_for_each(s, &nr_list) {
-		struct nr_sock *nr = nr_sk(s);
-
-		if (nr->my_index == index && nr->my_id == id) {
-			sock_hold(s);
-			goto found;
-		}
-	}
-	s = NULL;
-found:
-	spin_unlock_bh(&nr_list_lock);
-	return s;
-}
-
-/*
- *	Find a connected NET/ROM socket given their circuit IDs.
- */
-static struct sock *nr_find_peer(unsigned char index, unsigned char id,
-	ax25_address *dest)
-{
-	struct sock *s;
-
-	spin_lock_bh(&nr_list_lock);
-	sk_for_each(s, &nr_list) {
-		struct nr_sock *nr = nr_sk(s);
-
-		if (nr->your_index == index && nr->your_id == id &&
-		    !ax25cmp(&nr->dest_addr, dest)) {
-			sock_hold(s);
-			goto found;
-		}
-	}
-	s = NULL;
-found:
-	spin_unlock_bh(&nr_list_lock);
-	return s;
-}
-
-/*
- *	Find next free circuit ID.
- */
-static unsigned short nr_find_next_circuit(void)
-{
-	unsigned short id = circuit;
-	unsigned char i, j;
-	struct sock *sk;
-
-	for (;;) {
-		i = id / 256;
-		j = id % 256;
-
-		if (i != 0 && j != 0) {
-			if ((sk=nr_find_socket(i, j)) == NULL)
-				break;
-			sock_put(sk);
-		}
-
-		id++;
-	}
-
-	return id;
-}
-
-/*
- *	Deferred destroy.
- */
-void nr_destroy_socket(struct sock *);
-
-/*
- *	Handler for deferred kills.
- */
-static void nr_destroy_timer(struct timer_list *t)
-{
-	struct sock *sk = timer_container_of(sk, t, sk_timer);
-	bh_lock_sock(sk);
-	sock_hold(sk);
-	nr_destroy_socket(sk);
-	bh_unlock_sock(sk);
-	sock_put(sk);
-}
-
-/*
- *	This is called from user mode and the timers. Thus it protects itself
- *	against interrupt users but doesn't worry about being called during
- *	work. Once it is removed from the queue no interrupt or bottom half
- *	will touch it and we are (fairly 8-) ) safe.
- */
-void nr_destroy_socket(struct sock *sk)
-{
-	struct sk_buff *skb;
-
-	nr_remove_socket(sk);
-
-	nr_stop_heartbeat(sk);
-	nr_stop_t1timer(sk);
-	nr_stop_t2timer(sk);
-	nr_stop_t4timer(sk);
-	nr_stop_idletimer(sk);
-
-	nr_clear_queues(sk);		/* Flush the queues */
-
-	while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
-		if (skb->sk != sk) { /* A pending connection */
-			/* Queue the unaccepted socket for death */
-			sock_set_flag(skb->sk, SOCK_DEAD);
-			nr_start_heartbeat(skb->sk);
-			nr_sk(skb->sk)->state = NR_STATE_0;
-		}
-
-		kfree_skb(skb);
-	}
-
-	if (sk_has_allocations(sk)) {
-		/* Defer: outstanding buffers */
-		sk->sk_timer.function = nr_destroy_timer;
-		sk->sk_timer.expires  = jiffies + 2 * HZ;
-		add_timer(&sk->sk_timer);
-	} else
-		sock_put(sk);
-}
-
-/*
- *	Handling for system calls applied via the various interfaces to a
- *	NET/ROM socket object.
- */
-
-static int nr_setsockopt(struct socket *sock, int level, int optname,
-		sockptr_t optval, unsigned int optlen)
-{
-	struct sock *sk = sock->sk;
-	struct nr_sock *nr = nr_sk(sk);
-	unsigned int opt;
-
-	if (level != SOL_NETROM)
-		return -ENOPROTOOPT;
-
-	if (optlen < sizeof(unsigned int))
-		return -EINVAL;
-
-	if (copy_from_sockptr(&opt, optval, sizeof(opt)))
-		return -EFAULT;
-
-	switch (optname) {
-	case NETROM_T1:
-		if (opt < 1 || opt > UINT_MAX / HZ)
-			return -EINVAL;
-		nr->t1 = opt * HZ;
-		return 0;
-
-	case NETROM_T2:
-		if (opt < 1 || opt > UINT_MAX / HZ)
-			return -EINVAL;
-		nr->t2 = opt * HZ;
-		return 0;
-
-	case NETROM_N2:
-		if (opt < 1 || opt > 31)
-			return -EINVAL;
-		nr->n2 = opt;
-		return 0;
-
-	case NETROM_T4:
-		if (opt < 1 || opt > UINT_MAX / HZ)
-			return -EINVAL;
-		nr->t4 = opt * HZ;
-		return 0;
-
-	case NETROM_IDLE:
-		if (opt > UINT_MAX / (60 * HZ))
-			return -EINVAL;
-		nr->idle = opt * 60 * HZ;
-		return 0;
-
-	default:
-		return -ENOPROTOOPT;
-	}
-}
-
-static int nr_getsockopt(struct socket *sock, int level, int optname,
-	char __user *optval, int __user *optlen)
-{
-	struct sock *sk = sock->sk;
-	struct nr_sock *nr = nr_sk(sk);
-	int val = 0;
-	int len;
-
-	if (level != SOL_NETROM)
-		return -ENOPROTOOPT;
-
-	if (get_user(len, optlen))
-		return -EFAULT;
-
-	if (len < 0)
-		return -EINVAL;
-
-	switch (optname) {
-	case NETROM_T1:
-		val = nr->t1 / HZ;
-		break;
-
-	case NETROM_T2:
-		val = nr->t2 / HZ;
-		break;
-
-	case NETROM_N2:
-		val = nr->n2;
-		break;
-
-	case NETROM_T4:
-		val = nr->t4 / HZ;
-		break;
-
-	case NETROM_IDLE:
-		val = nr->idle / (60 * HZ);
-		break;
-
-	default:
-		return -ENOPROTOOPT;
-	}
-
-	len = min_t(unsigned int, len, sizeof(int));
-
-	if (put_user(len, optlen))
-		return -EFAULT;
-
-	return copy_to_user(optval, &val, len) ? -EFAULT : 0;
-}
-
-static int nr_listen(struct socket *sock, int backlog)
-{
-	struct sock *sk = sock->sk;
-
-	lock_sock(sk);
-	if (sock->state != SS_UNCONNECTED) {
-		release_sock(sk);
-		return -EINVAL;
-	}
-
-	if (sk->sk_state != TCP_LISTEN) {
-		memset(&nr_sk(sk)->user_addr, 0, AX25_ADDR_LEN);
-		sk->sk_max_ack_backlog = backlog;
-		sk->sk_state           = TCP_LISTEN;
-		release_sock(sk);
-		return 0;
-	}
-	release_sock(sk);
-
-	return -EOPNOTSUPP;
-}
-
-static struct proto nr_proto = {
-	.name	  = "NETROM",
-	.owner	  = THIS_MODULE,
-	.obj_size = sizeof(struct nr_sock),
-};
-
-static int nr_create(struct net *net, struct socket *sock, int protocol,
-		     int kern)
-{
-	struct sock *sk;
-	struct nr_sock *nr;
-
-	if (!net_eq(net, &init_net))
-		return -EAFNOSUPPORT;
-
-	if (sock->type != SOCK_SEQPACKET || protocol != 0)
-		return -ESOCKTNOSUPPORT;
-
-	sk = sk_alloc(net, PF_NETROM, GFP_ATOMIC, &nr_proto, kern);
-	if (sk  == NULL)
-		return -ENOMEM;
-
-	nr = nr_sk(sk);
-
-	sock_init_data(sock, sk);
-
-	sock->ops    = &nr_proto_ops;
-	sk->sk_protocol = protocol;
-
-	skb_queue_head_init(&nr->ack_queue);
-	skb_queue_head_init(&nr->reseq_queue);
-	skb_queue_head_init(&nr->frag_queue);
-
-	nr_init_timers(sk);
-
-	nr->t1     =
-		msecs_to_jiffies(READ_ONCE(sysctl_netrom_transport_timeout));
-	nr->t2     =
-		msecs_to_jiffies(READ_ONCE(sysctl_netrom_transport_acknowledge_delay));
-	nr->n2     =
-		msecs_to_jiffies(READ_ONCE(sysctl_netrom_transport_maximum_tries));
-	nr->t4     =
-		msecs_to_jiffies(READ_ONCE(sysctl_netrom_transport_busy_delay));
-	nr->idle   =
-		msecs_to_jiffies(READ_ONCE(sysctl_netrom_transport_no_activity_timeout));
-	nr->window = READ_ONCE(sysctl_netrom_transport_requested_window_size);
-
-	nr->bpqext = 1;
-	nr->state  = NR_STATE_0;
-
-	return 0;
-}
-
-static struct sock *nr_make_new(struct sock *osk)
-{
-	struct sock *sk;
-	struct nr_sock *nr, *onr;
-
-	if (osk->sk_type != SOCK_SEQPACKET)
-		return NULL;
-
-	sk = sk_alloc(sock_net(osk), PF_NETROM, GFP_ATOMIC, osk->sk_prot, 0);
-	if (sk == NULL)
-		return NULL;
-
-	nr = nr_sk(sk);
-
-	sock_init_data(NULL, sk);
-
-	sk->sk_type     = osk->sk_type;
-	sk->sk_priority = READ_ONCE(osk->sk_priority);
-	sk->sk_protocol = osk->sk_protocol;
-	sk->sk_rcvbuf   = osk->sk_rcvbuf;
-	sk->sk_sndbuf   = osk->sk_sndbuf;
-	sk->sk_state    = TCP_ESTABLISHED;
-	sock_copy_flags(sk, osk);
-
-	skb_queue_head_init(&nr->ack_queue);
-	skb_queue_head_init(&nr->reseq_queue);
-	skb_queue_head_init(&nr->frag_queue);
-
-	nr_init_timers(sk);
-
-	onr = nr_sk(osk);
-
-	nr->t1      = onr->t1;
-	nr->t2      = onr->t2;
-	nr->n2      = onr->n2;
-	nr->t4      = onr->t4;
-	nr->idle    = onr->idle;
-	nr->window  = onr->window;
-
-	nr->device  = onr->device;
-	nr->bpqext  = onr->bpqext;
-
-	return sk;
-}
-
-static int nr_release(struct socket *sock)
-{
-	struct sock *sk = sock->sk;
-	struct nr_sock *nr;
-
-	if (sk == NULL) return 0;
-
-	sock_hold(sk);
-	sock_orphan(sk);
-	lock_sock(sk);
-	nr = nr_sk(sk);
-
-	switch (nr->state) {
-	case NR_STATE_0:
-	case NR_STATE_1:
-	case NR_STATE_2:
-		nr_disconnect(sk, 0);
-		nr_destroy_socket(sk);
-		break;
-
-	case NR_STATE_3:
-		nr_clear_queues(sk);
-		nr->n2count = 0;
-		nr_write_internal(sk, NR_DISCREQ);
-		nr_start_t1timer(sk);
-		nr_stop_t2timer(sk);
-		nr_stop_t4timer(sk);
-		nr_stop_idletimer(sk);
-		nr->state    = NR_STATE_2;
-		sk->sk_state    = TCP_CLOSE;
-		sk->sk_shutdown |= SEND_SHUTDOWN;
-		sk->sk_state_change(sk);
-		sock_set_flag(sk, SOCK_DESTROY);
-		break;
-
-	default:
-		break;
-	}
-
-	sock->sk   = NULL;
-	release_sock(sk);
-	sock_put(sk);
-
-	return 0;
-}
-
-static int nr_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int addr_len)
-{
-	struct sock *sk = sock->sk;
-	struct nr_sock *nr = nr_sk(sk);
-	struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr;
-	struct net_device *dev;
-	ax25_uid_assoc *user;
-	ax25_address *source;
-
-	lock_sock(sk);
-	if (!sock_flag(sk, SOCK_ZAPPED)) {
-		release_sock(sk);
-		return -EINVAL;
-	}
-	if (addr_len < sizeof(struct sockaddr_ax25) || addr_len > sizeof(struct full_sockaddr_ax25)) {
-		release_sock(sk);
-		return -EINVAL;
-	}
-	if (addr_len < (addr->fsa_ax25.sax25_ndigis * sizeof(ax25_address) + sizeof(struct sockaddr_ax25))) {
-		release_sock(sk);
-		return -EINVAL;
-	}
-	if (addr->fsa_ax25.sax25_family != AF_NETROM) {
-		release_sock(sk);
-		return -EINVAL;
-	}
-	if ((dev = nr_dev_get(&addr->fsa_ax25.sax25_call)) == NULL) {
-		release_sock(sk);
-		return -EADDRNOTAVAIL;
-	}
-
-	/*
-	 * Only the super user can set an arbitrary user callsign.
-	 */
-	if (addr->fsa_ax25.sax25_ndigis == 1) {
-		if (!capable(CAP_NET_BIND_SERVICE)) {
-			dev_put(dev);
-			release_sock(sk);
-			return -EPERM;
-		}
-		nr->user_addr   = addr->fsa_digipeater[0];
-		nr->source_addr = addr->fsa_ax25.sax25_call;
-	} else {
-		source = &addr->fsa_ax25.sax25_call;
-
-		user = ax25_findbyuid(current_euid());
-		if (user) {
-			nr->user_addr   = user->call;
-			ax25_uid_put(user);
-		} else {
-			if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) {
-				release_sock(sk);
-				dev_put(dev);
-				return -EPERM;
-			}
-			nr->user_addr   = *source;
-		}
-
-		nr->source_addr = *source;
-	}
-
-	nr->device = dev;
-	nr_insert_socket(sk);
-
-	sock_reset_flag(sk, SOCK_ZAPPED);
-	dev_put(dev);
-	release_sock(sk);
-
-	return 0;
-}
-
-static int nr_connect(struct socket *sock, struct sockaddr_unsized *uaddr,
-		      int addr_len, int flags)
-{
-	struct sock *sk = sock->sk;
-	struct nr_sock *nr = nr_sk(sk);
-	struct sockaddr_ax25 *addr = (struct sockaddr_ax25 *)uaddr;
-	const ax25_address *source = NULL;
-	ax25_uid_assoc *user;
-	struct net_device *dev;
-	int err = 0;
-
-	lock_sock(sk);
-	if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
-		sock->state = SS_CONNECTED;
-		goto out_release;	/* Connect completed during a ERESTARTSYS event */
-	}
-
-	if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) {
-		sock->state = SS_UNCONNECTED;
-		err = -ECONNREFUSED;
-		goto out_release;
-	}
-
-	if (sk->sk_state == TCP_ESTABLISHED) {
-		err = -EISCONN;	/* No reconnect on a seqpacket socket */
-		goto out_release;
-	}
-
-	if (sock->state == SS_CONNECTING) {
-		err = -EALREADY;
-		goto out_release;
-	}
-
-	sk->sk_state   = TCP_CLOSE;
-	sock->state = SS_UNCONNECTED;
-
-	if (addr_len != sizeof(struct sockaddr_ax25) && addr_len != sizeof(struct full_sockaddr_ax25)) {
-		err = -EINVAL;
-		goto out_release;
-	}
-	if (addr->sax25_family != AF_NETROM) {
-		err = -EINVAL;
-		goto out_release;
-	}
-	if (sock_flag(sk, SOCK_ZAPPED)) {	/* Must bind first - autobinding in this may or may not work */
-		sock_reset_flag(sk, SOCK_ZAPPED);
-
-		if ((dev = nr_dev_first()) == NULL) {
-			err = -ENETUNREACH;
-			goto out_release;
-		}
-		source = (const ax25_address *)dev->dev_addr;
-
-		user = ax25_findbyuid(current_euid());
-		if (user) {
-			nr->user_addr   = user->call;
-			ax25_uid_put(user);
-		} else {
-			if (ax25_uid_policy && !capable(CAP_NET_ADMIN)) {
-				dev_put(dev);
-				err = -EPERM;
-				goto out_release;
-			}
-			nr->user_addr   = *source;
-		}
-
-		nr->source_addr = *source;
-		nr->device      = dev;
-
-		dev_put(dev);
-		nr_insert_socket(sk);		/* Finish the bind */
-	}
-
-	nr->dest_addr = addr->sax25_call;
-
-	release_sock(sk);
-	circuit = nr_find_next_circuit();
-	lock_sock(sk);
-
-	nr->my_index = circuit / 256;
-	nr->my_id    = circuit % 256;
-
-	circuit++;
-
-	/* Move to connecting socket, start sending Connect Requests */
-	sock->state  = SS_CONNECTING;
-	sk->sk_state = TCP_SYN_SENT;
-
-	nr_establish_data_link(sk);
-
-	nr->state = NR_STATE_1;
-
-	nr_start_heartbeat(sk);
-
-	/* Now the loop */
-	if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) {
-		err = -EINPROGRESS;
-		goto out_release;
-	}
-
-	/*
-	 * A Connect Ack with Choke or timeout or failed routing will go to
-	 * closed.
-	 */
-	if (sk->sk_state == TCP_SYN_SENT) {
-		DEFINE_WAIT(wait);
-
-		for (;;) {
-			prepare_to_wait(sk_sleep(sk), &wait,
-					TASK_INTERRUPTIBLE);
-			if (sk->sk_state != TCP_SYN_SENT)
-				break;
-			if (!signal_pending(current)) {
-				release_sock(sk);
-				schedule();
-				lock_sock(sk);
-				continue;
-			}
-			err = -ERESTARTSYS;
-			break;
-		}
-		finish_wait(sk_sleep(sk), &wait);
-		if (err)
-			goto out_release;
-	}
-
-	if (sk->sk_state != TCP_ESTABLISHED) {
-		sock->state = SS_UNCONNECTED;
-		err = sock_error(sk);	/* Always set at this point */
-		goto out_release;
-	}
-
-	sock->state = SS_CONNECTED;
-
-out_release:
-	release_sock(sk);
-
-	return err;
-}
-
-static int nr_accept(struct socket *sock, struct socket *newsock,
-		     struct proto_accept_arg *arg)
-{
-	struct sk_buff *skb;
-	struct sock *newsk;
-	DEFINE_WAIT(wait);
-	struct sock *sk;
-	int err = 0;
-
-	if ((sk = sock->sk) == NULL)
-		return -EINVAL;
-
-	lock_sock(sk);
-	if (sk->sk_type != SOCK_SEQPACKET) {
-		err = -EOPNOTSUPP;
-		goto out_release;
-	}
-
-	if (sk->sk_state != TCP_LISTEN) {
-		err = -EINVAL;
-		goto out_release;
-	}
-
-	/*
-	 *	The write queue this time is holding sockets ready to use
-	 *	hooked into the SABM we saved
-	 */
-	for (;;) {
-		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
-		skb = skb_dequeue(&sk->sk_receive_queue);
-		if (skb)
-			break;
-
-		if (arg->flags & O_NONBLOCK) {
-			err = -EWOULDBLOCK;
-			break;
-		}
-		if (!signal_pending(current)) {
-			release_sock(sk);
-			schedule();
-			lock_sock(sk);
-			continue;
-		}
-		err = -ERESTARTSYS;
-		break;
-	}
-	finish_wait(sk_sleep(sk), &wait);
-	if (err)
-		goto out_release;
-
-	newsk = skb->sk;
-	sock_graft(newsk, newsock);
-
-	/* Now attach up the new socket */
-	kfree_skb(skb);
-	sk_acceptq_removed(sk);
-
-out_release:
-	release_sock(sk);
-
-	return err;
-}
-
-static int nr_getname(struct socket *sock, struct sockaddr *uaddr,
-	int peer)
-{
-	struct full_sockaddr_ax25 *sax = (struct full_sockaddr_ax25 *)uaddr;
-	struct sock *sk = sock->sk;
-	struct nr_sock *nr = nr_sk(sk);
-	int uaddr_len;
-
-	memset(&sax->fsa_ax25, 0, sizeof(struct sockaddr_ax25));
-
-	lock_sock(sk);
-	if (peer != 0) {
-		if (sk->sk_state != TCP_ESTABLISHED) {
-			release_sock(sk);
-			return -ENOTCONN;
-		}
-		sax->fsa_ax25.sax25_family = AF_NETROM;
-		sax->fsa_ax25.sax25_ndigis = 1;
-		sax->fsa_ax25.sax25_call   = nr->user_addr;
-		memset(sax->fsa_digipeater, 0, sizeof(sax->fsa_digipeater));
-		sax->fsa_digipeater[0]     = nr->dest_addr;
-		uaddr_len = sizeof(struct full_sockaddr_ax25);
-	} else {
-		sax->fsa_ax25.sax25_family = AF_NETROM;
-		sax->fsa_ax25.sax25_ndigis = 0;
-		sax->fsa_ax25.sax25_call   = nr->source_addr;
-		uaddr_len = sizeof(struct sockaddr_ax25);
-	}
-	release_sock(sk);
-
-	return uaddr_len;
-}
-
-int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
-{
-	struct sock *sk;
-	struct sock *make;
-	struct nr_sock *nr_make;
-	ax25_address *src, *dest, *user;
-	unsigned short circuit_index, circuit_id;
-	unsigned short peer_circuit_index, peer_circuit_id;
-	unsigned short frametype, flags, window, timeout;
-	int ret;
-
-	skb_orphan(skb);
-
-	/*
-	 *	skb->data points to the netrom frame start
-	 */
-
-	src  = (ax25_address *)(skb->data + 0);
-	dest = (ax25_address *)(skb->data + 7);
-
-	circuit_index      = skb->data[15];
-	circuit_id         = skb->data[16];
-	peer_circuit_index = skb->data[17];
-	peer_circuit_id    = skb->data[18];
-	frametype          = skb->data[19] & 0x0F;
-	flags              = skb->data[19] & 0xF0;
-
-	/*
-	 * Check for an incoming IP over NET/ROM frame.
-	 */
-	if (frametype == NR_PROTOEXT &&
-	    circuit_index == NR_PROTO_IP && circuit_id == NR_PROTO_IP) {
-		skb_pull(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
-		skb_reset_transport_header(skb);
-
-		return nr_rx_ip(skb, dev);
-	}
-
-	/*
-	 * Find an existing socket connection, based on circuit ID, if it's
-	 * a Connect Request base it on their circuit ID.
-	 *
-	 * Circuit ID 0/0 is not valid but it could still be a "reset" for a
-	 * circuit that no longer exists at the other end ...
-	 */
-
-	sk = NULL;
-
-	if (circuit_index == 0 && circuit_id == 0) {
-		if (frametype == NR_CONNACK && flags == NR_CHOKE_FLAG)
-			sk = nr_find_peer(peer_circuit_index, peer_circuit_id, src);
-	} else {
-		if (frametype == NR_CONNREQ)
-			sk = nr_find_peer(circuit_index, circuit_id, src);
-		else
-			sk = nr_find_socket(circuit_index, circuit_id);
-	}
-
-	if (sk != NULL) {
-		bh_lock_sock(sk);
-		skb_reset_transport_header(skb);
-
-		if (frametype == NR_CONNACK && skb->len == 22)
-			nr_sk(sk)->bpqext = 1;
-		else
-			nr_sk(sk)->bpqext = 0;
-
-		ret = nr_process_rx_frame(sk, skb);
-		bh_unlock_sock(sk);
-		sock_put(sk);
-		return ret;
-	}
-
-	/*
-	 * Now it should be a CONNREQ.
-	 */
-	if (frametype != NR_CONNREQ) {
-		/*
-		 * Here it would be nice to be able to send a reset but
-		 * NET/ROM doesn't have one.  We've tried to extend the protocol
-		 * by sending NR_CONNACK | NR_CHOKE_FLAGS replies but that
-		 * apparently kills BPQ boxes... :-(
-		 * So now we try to follow the established behaviour of
-		 * G8PZT's Xrouter which is sending packets with command type 7
-		 * as an extension of the protocol.
-		 */
-		if (READ_ONCE(sysctl_netrom_reset_circuit) &&
-		    (frametype != NR_RESET || flags != 0))
-			nr_transmit_reset(skb, 1);
-
-		return 0;
-	}
-
-	sk = nr_find_listener(dest);
-
-	user = (ax25_address *)(skb->data + 21);
-
-	if (sk == NULL || sk_acceptq_is_full(sk) ||
-	    (make = nr_make_new(sk)) == NULL) {
-		nr_transmit_refusal(skb, 0);
-		if (sk)
-			sock_put(sk);
-		return 0;
-	}
-
-	bh_lock_sock(sk);
-
-	window = skb->data[20];
-
-	sock_hold(make);
-	skb->sk             = make;
-	skb->destructor     = sock_efree;
-	make->sk_state	    = TCP_ESTABLISHED;
-
-	/* Fill in his circuit details */
-	nr_make = nr_sk(make);
-	nr_make->source_addr = *dest;
-	nr_make->dest_addr   = *src;
-	nr_make->user_addr   = *user;
-
-	nr_make->your_index  = circuit_index;
-	nr_make->your_id     = circuit_id;
-
-	bh_unlock_sock(sk);
-	circuit = nr_find_next_circuit();
-	bh_lock_sock(sk);
-
-	nr_make->my_index    = circuit / 256;
-	nr_make->my_id       = circuit % 256;
-
-	circuit++;
-
-	/* Window negotiation */
-	if (window < nr_make->window)
-		nr_make->window = window;
-
-	/* L4 timeout negotiation */
-	if (skb->len == 37) {
-		timeout = skb->data[36] * 256 + skb->data[35];
-		if (timeout * HZ < nr_make->t1)
-			nr_make->t1 = timeout * HZ;
-		nr_make->bpqext = 1;
-	} else {
-		nr_make->bpqext = 0;
-	}
-
-	nr_write_internal(make, NR_CONNACK);
-
-	nr_make->condition = 0x00;
-	nr_make->vs        = 0;
-	nr_make->va        = 0;
-	nr_make->vr        = 0;
-	nr_make->vl        = 0;
-	nr_make->state     = NR_STATE_3;
-	sk_acceptq_added(sk);
-	skb_queue_head(&sk->sk_receive_queue, skb);
-
-	if (!sock_flag(sk, SOCK_DEAD))
-		sk->sk_data_ready(sk);
-
-	bh_unlock_sock(sk);
-	sock_put(sk);
-
-	nr_insert_socket(make);
-
-	nr_start_heartbeat(make);
-	nr_start_idletimer(make);
-
-	return 1;
-}
-
-static int nr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
-{
-	struct sock *sk = sock->sk;
-	struct nr_sock *nr = nr_sk(sk);
-	DECLARE_SOCKADDR(struct sockaddr_ax25 *, usax, msg->msg_name);
-	int err;
-	struct sockaddr_ax25 sax;
-	struct sk_buff *skb;
-	unsigned char *asmptr;
-	int size;
-
-	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
-		return -EINVAL;
-
-	lock_sock(sk);
-	if (sock_flag(sk, SOCK_ZAPPED)) {
-		err = -EADDRNOTAVAIL;
-		goto out;
-	}
-
-	if (sk->sk_shutdown & SEND_SHUTDOWN) {
-		send_sig(SIGPIPE, current, 0);
-		err = -EPIPE;
-		goto out;
-	}
-
-	if (nr->device == NULL) {
-		err = -ENETUNREACH;
-		goto out;
-	}
-
-	if (usax) {
-		if (msg->msg_namelen < sizeof(sax)) {
-			err = -EINVAL;
-			goto out;
-		}
-		sax = *usax;
-		if (ax25cmp(&nr->dest_addr, &sax.sax25_call) != 0) {
-			err = -EISCONN;
-			goto out;
-		}
-		if (sax.sax25_family != AF_NETROM) {
-			err = -EINVAL;
-			goto out;
-		}
-	} else {
-		if (sk->sk_state != TCP_ESTABLISHED) {
-			err = -ENOTCONN;
-			goto out;
-		}
-		sax.sax25_family = AF_NETROM;
-		sax.sax25_call   = nr->dest_addr;
-	}
-
-	/* Build a packet - the conventional user limit is 236 bytes. We can
-	   do ludicrously large NetROM frames but must not overflow */
-	if (len > 65536) {
-		err = -EMSGSIZE;
-		goto out;
-	}
-
-	size = len + NR_NETWORK_LEN + NR_TRANSPORT_LEN;
-
-	if ((skb = sock_alloc_send_skb(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL)
-		goto out;
-
-	skb_reserve(skb, size - len);
-	skb_reset_transport_header(skb);
-
-	/*
-	 *	Push down the NET/ROM header
-	 */
-
-	asmptr = skb_push(skb, NR_TRANSPORT_LEN);
-
-	/* Build a NET/ROM Transport header */
-
-	*asmptr++ = nr->your_index;
-	*asmptr++ = nr->your_id;
-	*asmptr++ = 0;		/* To be filled in later */
-	*asmptr++ = 0;		/*      Ditto            */
-	*asmptr++ = NR_INFO;
-
-	/*
-	 *	Put the data on the end
-	 */
-	skb_put(skb, len);
-
-	/* User data follows immediately after the NET/ROM transport header */
-	if (memcpy_from_msg(skb_transport_header(skb), msg, len)) {
-		kfree_skb(skb);
-		err = -EFAULT;
-		goto out;
-	}
-
-	if (sk->sk_state != TCP_ESTABLISHED) {
-		kfree_skb(skb);
-		err = -ENOTCONN;
-		goto out;
-	}
-
-	nr_output(sk, skb);	/* Shove it onto the queue */
-
-	err = len;
-out:
-	release_sock(sk);
-	return err;
-}
-
-static int nr_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
-		      int flags)
-{
-	struct sock *sk = sock->sk;
-	DECLARE_SOCKADDR(struct sockaddr_ax25 *, sax, msg->msg_name);
-	size_t copied;
-	struct sk_buff *skb;
-	int er;
-
-	/*
-	 * This works for seqpacket too. The receiver has ordered the queue for
-	 * us! We do one quick check first though
-	 */
-
-	lock_sock(sk);
-	if (sk->sk_state != TCP_ESTABLISHED) {
-		release_sock(sk);
-		return -ENOTCONN;
-	}
-
-	/* Now we can treat all alike */
-	skb = skb_recv_datagram(sk, flags, &er);
-	if (!skb) {
-		release_sock(sk);
-		return er;
-	}
-
-	skb_reset_transport_header(skb);
-	copied     = skb->len;
-
-	if (copied > size) {
-		copied = size;
-		msg->msg_flags |= MSG_TRUNC;
-	}
-
-	er = skb_copy_datagram_msg(skb, 0, msg, copied);
-	if (er < 0) {
-		skb_free_datagram(sk, skb);
-		release_sock(sk);
-		return er;
-	}
-
-	if (sax != NULL) {
-		memset(sax, 0, sizeof(*sax));
-		sax->sax25_family = AF_NETROM;
-		skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call,
-			      AX25_ADDR_LEN);
-		msg->msg_namelen = sizeof(*sax);
-	}
-
-	skb_free_datagram(sk, skb);
-
-	release_sock(sk);
-	return copied;
-}
-
-
-static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
-	struct sock *sk = sock->sk;
-	void __user *argp = (void __user *)arg;
-
-	switch (cmd) {
-	case TIOCOUTQ: {
-		long amount;
-
-		lock_sock(sk);
-		amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
-		if (amount < 0)
-			amount = 0;
-		release_sock(sk);
-		return put_user(amount, (int __user *)argp);
-	}
-
-	case TIOCINQ: {
-		struct sk_buff *skb;
-		long amount = 0L;
-
-		lock_sock(sk);
-		/* These two are safe on a single CPU system as only user tasks fiddle here */
-		if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
-			amount = skb->len;
-		release_sock(sk);
-		return put_user(amount, (int __user *)argp);
-	}
-
-	case SIOCGIFADDR:
-	case SIOCSIFADDR:
-	case SIOCGIFDSTADDR:
-	case SIOCSIFDSTADDR:
-	case SIOCGIFBRDADDR:
-	case SIOCSIFBRDADDR:
-	case SIOCGIFNETMASK:
-	case SIOCSIFNETMASK:
-	case SIOCGIFMETRIC:
-	case SIOCSIFMETRIC:
-		return -EINVAL;
-
-	case SIOCADDRT:
-	case SIOCDELRT:
-	case SIOCNRDECOBS:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		return nr_rt_ioctl(cmd, argp);
-
-	default:
-		return -ENOIOCTLCMD;
-	}
-
-	return 0;
-}
-
-#ifdef CONFIG_PROC_FS
-
-static void *nr_info_start(struct seq_file *seq, loff_t *pos)
-	__acquires(&nr_list_lock)
-{
-	spin_lock_bh(&nr_list_lock);
-	return seq_hlist_start_head(&nr_list, *pos);
-}
-
-static void *nr_info_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	return seq_hlist_next(v, &nr_list, pos);
-}
-
-static void nr_info_stop(struct seq_file *seq, void *v)
-	__releases(&nr_list_lock)
-{
-	spin_unlock_bh(&nr_list_lock);
-}
-
-static int nr_info_show(struct seq_file *seq, void *v)
-{
-	struct sock *s = sk_entry(v);
-	struct net_device *dev;
-	struct nr_sock *nr;
-	const char *devname;
-	char buf[11];
-
-	if (v == SEQ_START_TOKEN)
-		seq_puts(seq,
-"user_addr dest_node src_node  dev    my  your  st  vs  vr  va    t1     t2     t4      idle   n2  wnd Snd-Q Rcv-Q inode\n");
-
-	else {
-
-		bh_lock_sock(s);
-		nr = nr_sk(s);
-
-		if ((dev = nr->device) == NULL)
-			devname = "???";
-		else
-			devname = dev->name;
-
-		seq_printf(seq, "%-9s ", ax2asc(buf, &nr->user_addr));
-		seq_printf(seq, "%-9s ", ax2asc(buf, &nr->dest_addr));
-		seq_printf(seq,
-"%-9s %-3s  %02X/%02X %02X/%02X %2d %3d %3d %3d %3lu/%03lu %2lu/%02lu %3lu/%03lu %3lu/%03lu %2d/%02d %3d %5d %5d %llu\n",
-			ax2asc(buf, &nr->source_addr),
-			devname,
-			nr->my_index,
-			nr->my_id,
-			nr->your_index,
-			nr->your_id,
-			nr->state,
-			nr->vs,
-			nr->vr,
-			nr->va,
-			ax25_display_timer(&nr->t1timer) / HZ,
-			nr->t1 / HZ,
-			ax25_display_timer(&nr->t2timer) / HZ,
-			nr->t2 / HZ,
-			ax25_display_timer(&nr->t4timer) / HZ,
-			nr->t4 / HZ,
-			ax25_display_timer(&nr->idletimer) / (60 * HZ),
-			nr->idle / (60 * HZ),
-			nr->n2count,
-			nr->n2,
-			nr->window,
-			sk_wmem_alloc_get(s),
-			sk_rmem_alloc_get(s),
-			s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : (u64)0);
-
-		bh_unlock_sock(s);
-	}
-	return 0;
-}
-
-static const struct seq_operations nr_info_seqops = {
-	.start = nr_info_start,
-	.next = nr_info_next,
-	.stop = nr_info_stop,
-	.show = nr_info_show,
-};
-#endif	/* CONFIG_PROC_FS */
-
-static const struct net_proto_family nr_family_ops = {
-	.family		=	PF_NETROM,
-	.create		=	nr_create,
-	.owner		=	THIS_MODULE,
-};
-
-static const struct proto_ops nr_proto_ops = {
-	.family		=	PF_NETROM,
-	.owner		=	THIS_MODULE,
-	.release	=	nr_release,
-	.bind		=	nr_bind,
-	.connect	=	nr_connect,
-	.socketpair	=	sock_no_socketpair,
-	.accept		=	nr_accept,
-	.getname	=	nr_getname,
-	.poll		=	datagram_poll,
-	.ioctl		=	nr_ioctl,
-	.gettstamp	=	sock_gettstamp,
-	.listen		=	nr_listen,
-	.shutdown	=	sock_no_shutdown,
-	.setsockopt	=	nr_setsockopt,
-	.getsockopt	=	nr_getsockopt,
-	.sendmsg	=	nr_sendmsg,
-	.recvmsg	=	nr_recvmsg,
-	.mmap		=	sock_no_mmap,
-};
-
-static struct notifier_block nr_dev_notifier = {
-	.notifier_call	=	nr_device_event,
-};
-
-static struct net_device **dev_nr;
-
-static struct ax25_protocol nr_pid = {
-	.pid	= AX25_P_NETROM,
-	.func	= nr_route_frame
-};
-
-static struct ax25_linkfail nr_linkfail_notifier = {
-	.func	= nr_link_failed,
-};
-
-static int __init nr_proto_init(void)
-{
-	int i;
-	int rc = proto_register(&nr_proto, 0);
-
-	if (rc)
-		return rc;
-
-	if (nr_ndevs > 0x7fffffff/sizeof(struct net_device *)) {
-		pr_err("NET/ROM: %s - nr_ndevs parameter too large\n",
-		       __func__);
-		rc = -EINVAL;
-		goto unregister_proto;
-	}
-
-	dev_nr = kzalloc_objs(struct net_device *, nr_ndevs);
-	if (!dev_nr) {
-		pr_err("NET/ROM: %s - unable to allocate device array\n",
-		       __func__);
-		rc = -ENOMEM;
-		goto unregister_proto;
-	}
-
-	for (i = 0; i < nr_ndevs; i++) {
-		char name[IFNAMSIZ];
-		struct net_device *dev;
-
-		sprintf(name, "nr%d", i);
-		dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, nr_setup);
-		if (!dev) {
-			rc = -ENOMEM;
-			goto fail;
-		}
-
-		dev->base_addr = i;
-		rc = register_netdev(dev);
-		if (rc) {
-			free_netdev(dev);
-			goto fail;
-		}
-		nr_set_lockdep_key(dev);
-		dev_nr[i] = dev;
-	}
-
-	rc = sock_register(&nr_family_ops);
-	if (rc)
-		goto fail;
-
-	rc = register_netdevice_notifier(&nr_dev_notifier);
-	if (rc)
-		goto out_sock;
-
-	ax25_register_pid(&nr_pid);
-	ax25_linkfail_register(&nr_linkfail_notifier);
-
-#ifdef CONFIG_SYSCTL
-	rc = nr_register_sysctl();
-	if (rc)
-		goto out_sysctl;
-#endif
-
-	nr_loopback_init();
-
-	rc = -ENOMEM;
-	if (!proc_create_seq("nr", 0444, init_net.proc_net, &nr_info_seqops))
-		goto proc_remove1;
-	if (!proc_create_seq("nr_neigh", 0444, init_net.proc_net,
-			     &nr_neigh_seqops))
-		goto proc_remove2;
-	if (!proc_create_seq("nr_nodes", 0444, init_net.proc_net,
-			     &nr_node_seqops))
-		goto proc_remove3;
-
-	return 0;
-
-proc_remove3:
-	remove_proc_entry("nr_neigh", init_net.proc_net);
-proc_remove2:
-	remove_proc_entry("nr", init_net.proc_net);
-proc_remove1:
-
-	nr_loopback_clear();
-	nr_rt_free();
-
-#ifdef CONFIG_SYSCTL
-	nr_unregister_sysctl();
-out_sysctl:
-#endif
-	ax25_linkfail_release(&nr_linkfail_notifier);
-	ax25_protocol_release(AX25_P_NETROM);
-	unregister_netdevice_notifier(&nr_dev_notifier);
-out_sock:
-	sock_unregister(PF_NETROM);
-fail:
-	while (--i >= 0) {
-		unregister_netdev(dev_nr[i]);
-		free_netdev(dev_nr[i]);
-	}
-	kfree(dev_nr);
-unregister_proto:
-	proto_unregister(&nr_proto);
-	return rc;
-}
-
-module_init(nr_proto_init);
-
-module_param(nr_ndevs, int, 0);
-MODULE_PARM_DESC(nr_ndevs, "number of NET/ROM devices");
-
-MODULE_AUTHOR("Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>");
-MODULE_DESCRIPTION("The amateur radio NET/ROM network and transport layer protocol");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_NETPROTO(PF_NETROM);
-
-static void __exit nr_exit(void)
-{
-	int i;
-
-	remove_proc_entry("nr", init_net.proc_net);
-	remove_proc_entry("nr_neigh", init_net.proc_net);
-	remove_proc_entry("nr_nodes", init_net.proc_net);
-	nr_loopback_clear();
-
-	nr_rt_free();
-
-#ifdef CONFIG_SYSCTL
-	nr_unregister_sysctl();
-#endif
-
-	ax25_linkfail_release(&nr_linkfail_notifier);
-	ax25_protocol_release(AX25_P_NETROM);
-
-	unregister_netdevice_notifier(&nr_dev_notifier);
-
-	sock_unregister(PF_NETROM);
-
-	for (i = 0; i < nr_ndevs; i++) {
-		struct net_device *dev = dev_nr[i];
-		if (dev) {
-			unregister_netdev(dev);
-			free_netdev(dev);
-		}
-	}
-
-	kfree(dev_nr);
-	proto_unregister(&nr_proto);
-}
-module_exit(nr_exit);
diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c
deleted file mode 100644
index 2c34389c3ce6..000000000000
--- a/net/netrom/nr_dev.c
+++ /dev/null
@@ -1,178 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- */
-#include <linux/module.h>
-#include <linux/proc_fs.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/fs.h>
-#include <linux/types.h>
-#include <linux/sysctl.h>
-#include <linux/string.h>
-#include <linux/socket.h>
-#include <linux/errno.h>
-#include <linux/fcntl.h>
-#include <linux/in.h>
-#include <linux/if_ether.h>	/* For the statistics structure. */
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-#include <asm/io.h>
-
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-
-#include <net/ip.h>
-#include <net/arp.h>
-
-#include <net/ax25.h>
-#include <net/netrom.h>
-
-/*
- *	Only allow IP over NET/ROM frames through if the netrom device is up.
- */
-
-int nr_rx_ip(struct sk_buff *skb, struct net_device *dev)
-{
-	struct net_device_stats *stats = &dev->stats;
-
-	if (!netif_running(dev)) {
-		stats->rx_dropped++;
-		return 0;
-	}
-
-	stats->rx_packets++;
-	stats->rx_bytes += skb->len;
-
-	skb->protocol = htons(ETH_P_IP);
-
-	/* Spoof incoming device */
-	skb->dev      = dev;
-	skb->mac_header = skb->network_header;
-	skb_reset_network_header(skb);
-	skb->pkt_type = PACKET_HOST;
-
-	netif_rx(skb);
-
-	return 1;
-}
-
-static int nr_header(struct sk_buff *skb, struct net_device *dev,
-		     unsigned short type,
-		     const void *daddr, const void *saddr, unsigned int len)
-{
-	unsigned char *buff = skb_push(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
-
-	memcpy(buff, (saddr != NULL) ? saddr : dev->dev_addr, dev->addr_len);
-	buff[6] &= ~AX25_CBIT;
-	buff[6] &= ~AX25_EBIT;
-	buff[6] |= AX25_SSSID_SPARE;
-	buff    += AX25_ADDR_LEN;
-
-	if (daddr != NULL)
-		memcpy(buff, daddr, dev->addr_len);
-	buff[6] &= ~AX25_CBIT;
-	buff[6] |= AX25_EBIT;
-	buff[6] |= AX25_SSSID_SPARE;
-	buff    += AX25_ADDR_LEN;
-
-	*buff++ = READ_ONCE(sysctl_netrom_network_ttl_initialiser);
-
-	*buff++ = NR_PROTO_IP;
-	*buff++ = NR_PROTO_IP;
-	*buff++ = 0;
-	*buff++ = 0;
-	*buff++ = NR_PROTOEXT;
-
-	if (daddr != NULL)
-		return 37;
-
-	return -37;
-}
-
-static int __must_check nr_set_mac_address(struct net_device *dev, void *addr)
-{
-	struct sockaddr *sa = addr;
-	int err;
-
-	if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len))
-		return 0;
-
-	if (dev->flags & IFF_UP) {
-		err = ax25_listen_register((ax25_address *)sa->sa_data, NULL);
-		if (err)
-			return err;
-
-		ax25_listen_release((const ax25_address *)dev->dev_addr, NULL);
-	}
-
-	dev_addr_set(dev, sa->sa_data);
-
-	return 0;
-}
-
-static int nr_open(struct net_device *dev)
-{
-	int err;
-
-	err = ax25_listen_register((const ax25_address *)dev->dev_addr, NULL);
-	if (err)
-		return err;
-
-	netif_start_queue(dev);
-
-	return 0;
-}
-
-static int nr_close(struct net_device *dev)
-{
-	ax25_listen_release((const ax25_address *)dev->dev_addr, NULL);
-	netif_stop_queue(dev);
-	return 0;
-}
-
-static netdev_tx_t nr_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct net_device_stats *stats = &dev->stats;
-	unsigned int len = skb->len;
-
-	if (!nr_route_frame(skb, NULL)) {
-		kfree_skb(skb);
-		stats->tx_errors++;
-		return NETDEV_TX_OK;
-	}
-
-	stats->tx_packets++;
-	stats->tx_bytes += len;
-
-	return NETDEV_TX_OK;
-}
-
-static const struct header_ops nr_header_ops = {
-	.create	= nr_header,
-};
-
-static const struct net_device_ops nr_netdev_ops = {
-	.ndo_open		= nr_open,
-	.ndo_stop		= nr_close,
-	.ndo_start_xmit		= nr_xmit,
-	.ndo_set_mac_address    = nr_set_mac_address,
-};
-
-void nr_setup(struct net_device *dev)
-{
-	dev->mtu		= NR_MAX_PACKET_SIZE;
-	dev->netdev_ops		= &nr_netdev_ops;
-	dev->header_ops		= &nr_header_ops;
-	dev->hard_header_len	= NR_NETWORK_LEN + NR_TRANSPORT_LEN;
-	dev->addr_len		= AX25_ADDR_LEN;
-	dev->type		= ARPHRD_NETROM;
-
-	/* New-style flags. */
-	dev->flags		= IFF_NOARP;
-}
diff --git a/net/netrom/nr_in.c b/net/netrom/nr_in.c
deleted file mode 100644
index 97944db6b5ac..000000000000
--- a/net/netrom/nr_in.c
+++ /dev/null
@@ -1,301 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright Darryl Miles G7LED (dlm@g7led.demon.co.uk)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <net/netrom.h>
-
-static int nr_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
-{
-	struct sk_buff *skbo, *skbn = skb;
-	struct nr_sock *nr = nr_sk(sk);
-
-	skb_pull(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
-
-	nr_start_idletimer(sk);
-
-	if (more) {
-		nr->fraglen += skb->len;
-		skb_queue_tail(&nr->frag_queue, skb);
-		return 0;
-	}
-
-	if (!more && nr->fraglen > 0) {	/* End of fragment */
-		nr->fraglen += skb->len;
-		skb_queue_tail(&nr->frag_queue, skb);
-
-		if ((skbn = alloc_skb(nr->fraglen, GFP_ATOMIC)) == NULL)
-			return 1;
-
-		skb_reset_transport_header(skbn);
-
-		while ((skbo = skb_dequeue(&nr->frag_queue)) != NULL) {
-			skb_copy_from_linear_data(skbo,
-						  skb_put(skbn, skbo->len),
-						  skbo->len);
-			kfree_skb(skbo);
-		}
-
-		nr->fraglen = 0;
-	}
-
-	return sock_queue_rcv_skb(sk, skbn);
-}
-
-/*
- * State machine for state 1, Awaiting Connection State.
- * The handling of the timer(s) is in file nr_timer.c.
- * Handling of state 0 and connection release is in netrom.c.
- */
-static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
-	int frametype)
-{
-	switch (frametype) {
-	case NR_CONNACK: {
-		struct nr_sock *nr = nr_sk(sk);
-
-		nr_stop_t1timer(sk);
-		nr_start_idletimer(sk);
-		nr->your_index = skb->data[17];
-		nr->your_id    = skb->data[18];
-		nr->vs	       = 0;
-		nr->va	       = 0;
-		nr->vr	       = 0;
-		nr->vl	       = 0;
-		nr->state      = NR_STATE_3;
-		nr->n2count    = 0;
-		nr->window     = skb->data[20];
-		sk->sk_state   = TCP_ESTABLISHED;
-		if (!sock_flag(sk, SOCK_DEAD))
-			sk->sk_state_change(sk);
-		break;
-	}
-
-	case NR_CONNACK | NR_CHOKE_FLAG:
-		nr_disconnect(sk, ECONNREFUSED);
-		break;
-
-	case NR_RESET:
-		if (READ_ONCE(sysctl_netrom_reset_circuit))
-			nr_disconnect(sk, ECONNRESET);
-		break;
-
-	default:
-		break;
-	}
-	return 0;
-}
-
-/*
- * State machine for state 2, Awaiting Release State.
- * The handling of the timer(s) is in file nr_timer.c
- * Handling of state 0 and connection release is in netrom.c.
- */
-static int nr_state2_machine(struct sock *sk, struct sk_buff *skb,
-	int frametype)
-{
-	switch (frametype) {
-	case NR_CONNACK | NR_CHOKE_FLAG:
-		nr_disconnect(sk, ECONNRESET);
-		break;
-
-	case NR_DISCREQ:
-		nr_write_internal(sk, NR_DISCACK);
-		fallthrough;
-	case NR_DISCACK:
-		nr_disconnect(sk, 0);
-		break;
-
-	case NR_RESET:
-		if (READ_ONCE(sysctl_netrom_reset_circuit))
-			nr_disconnect(sk, ECONNRESET);
-		break;
-
-	default:
-		break;
-	}
-	return 0;
-}
-
-/*
- * State machine for state 3, Connected State.
- * The handling of the timer(s) is in file nr_timer.c
- * Handling of state 0 and connection release is in netrom.c.
- */
-static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype)
-{
-	struct nr_sock *nrom = nr_sk(sk);
-	struct sk_buff_head temp_queue;
-	struct sk_buff *skbn;
-	unsigned short save_vr;
-	unsigned short nr, ns;
-	int queued = 0;
-
-	nr = skb->data[18];
-
-	switch (frametype) {
-	case NR_CONNREQ:
-		nr_write_internal(sk, NR_CONNACK);
-		break;
-
-	case NR_DISCREQ:
-		nr_write_internal(sk, NR_DISCACK);
-		nr_disconnect(sk, 0);
-		break;
-
-	case NR_CONNACK | NR_CHOKE_FLAG:
-	case NR_DISCACK:
-		nr_disconnect(sk, ECONNRESET);
-		break;
-
-	case NR_INFOACK:
-	case NR_INFOACK | NR_CHOKE_FLAG:
-	case NR_INFOACK | NR_NAK_FLAG:
-	case NR_INFOACK | NR_NAK_FLAG | NR_CHOKE_FLAG:
-		if (frametype & NR_CHOKE_FLAG) {
-			nrom->condition |= NR_COND_PEER_RX_BUSY;
-			nr_start_t4timer(sk);
-		} else {
-			nrom->condition &= ~NR_COND_PEER_RX_BUSY;
-			nr_stop_t4timer(sk);
-		}
-		if (!nr_validate_nr(sk, nr)) {
-			break;
-		}
-		if (frametype & NR_NAK_FLAG) {
-			nr_frames_acked(sk, nr);
-			nr_send_nak_frame(sk);
-		} else {
-			if (nrom->condition & NR_COND_PEER_RX_BUSY) {
-				nr_frames_acked(sk, nr);
-			} else {
-				nr_check_iframes_acked(sk, nr);
-			}
-		}
-		break;
-
-	case NR_INFO:
-	case NR_INFO | NR_NAK_FLAG:
-	case NR_INFO | NR_CHOKE_FLAG:
-	case NR_INFO | NR_MORE_FLAG:
-	case NR_INFO | NR_NAK_FLAG | NR_CHOKE_FLAG:
-	case NR_INFO | NR_CHOKE_FLAG | NR_MORE_FLAG:
-	case NR_INFO | NR_NAK_FLAG | NR_MORE_FLAG:
-	case NR_INFO | NR_NAK_FLAG | NR_CHOKE_FLAG | NR_MORE_FLAG:
-		if (frametype & NR_CHOKE_FLAG) {
-			nrom->condition |= NR_COND_PEER_RX_BUSY;
-			nr_start_t4timer(sk);
-		} else {
-			nrom->condition &= ~NR_COND_PEER_RX_BUSY;
-			nr_stop_t4timer(sk);
-		}
-		if (nr_validate_nr(sk, nr)) {
-			if (frametype & NR_NAK_FLAG) {
-				nr_frames_acked(sk, nr);
-				nr_send_nak_frame(sk);
-			} else {
-				if (nrom->condition & NR_COND_PEER_RX_BUSY) {
-					nr_frames_acked(sk, nr);
-				} else {
-					nr_check_iframes_acked(sk, nr);
-				}
-			}
-		}
-		queued = 1;
-		skb_queue_head(&nrom->reseq_queue, skb);
-		if (nrom->condition & NR_COND_OWN_RX_BUSY)
-			break;
-		skb_queue_head_init(&temp_queue);
-		do {
-			save_vr = nrom->vr;
-			while ((skbn = skb_dequeue(&nrom->reseq_queue)) != NULL) {
-				ns = skbn->data[17];
-				if (ns == nrom->vr) {
-					if (nr_queue_rx_frame(sk, skbn, frametype & NR_MORE_FLAG) == 0) {
-						nrom->vr = (nrom->vr + 1) % NR_MODULUS;
-					} else {
-						nrom->condition |= NR_COND_OWN_RX_BUSY;
-						skb_queue_tail(&temp_queue, skbn);
-					}
-				} else if (nr_in_rx_window(sk, ns)) {
-					skb_queue_tail(&temp_queue, skbn);
-				} else {
-					kfree_skb(skbn);
-				}
-			}
-			while ((skbn = skb_dequeue(&temp_queue)) != NULL) {
-				skb_queue_tail(&nrom->reseq_queue, skbn);
-			}
-		} while (save_vr != nrom->vr);
-		/*
-		 * Window is full, ack it immediately.
-		 */
-		if (((nrom->vl + nrom->window) % NR_MODULUS) == nrom->vr) {
-			nr_enquiry_response(sk);
-		} else {
-			if (!(nrom->condition & NR_COND_ACK_PENDING)) {
-				nrom->condition |= NR_COND_ACK_PENDING;
-				nr_start_t2timer(sk);
-			}
-		}
-		break;
-
-	case NR_RESET:
-		if (READ_ONCE(sysctl_netrom_reset_circuit))
-			nr_disconnect(sk, ECONNRESET);
-		break;
-
-	default:
-		break;
-	}
-	return queued;
-}
-
-/* Higher level upcall for a LAPB frame - called with sk locked */
-int nr_process_rx_frame(struct sock *sk, struct sk_buff *skb)
-{
-	struct nr_sock *nr = nr_sk(sk);
-	int queued = 0, frametype;
-
-	if (nr->state == NR_STATE_0)
-		return 0;
-
-	frametype = skb->data[19];
-
-	switch (nr->state) {
-	case NR_STATE_1:
-		queued = nr_state1_machine(sk, skb, frametype);
-		break;
-	case NR_STATE_2:
-		queued = nr_state2_machine(sk, skb, frametype);
-		break;
-	case NR_STATE_3:
-		queued = nr_state3_machine(sk, skb, frametype);
-		break;
-	}
-
-	nr_kick(sk);
-
-	return queued;
-}
diff --git a/net/netrom/nr_loopback.c b/net/netrom/nr_loopback.c
deleted file mode 100644
index 7a9d765b30c0..000000000000
--- a/net/netrom/nr_loopback.c
+++ /dev/null
@@ -1,73 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright Tomi Manninen OH2BNS (oh2bns@sral.fi)
- */
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/socket.h>
-#include <linux/timer.h>
-#include <net/ax25.h>
-#include <linux/skbuff.h>
-#include <net/netrom.h>
-#include <linux/init.h>
-
-static void nr_loopback_timer(struct timer_list *);
-
-static struct sk_buff_head loopback_queue;
-static DEFINE_TIMER(loopback_timer, nr_loopback_timer);
-
-void __init nr_loopback_init(void)
-{
-	skb_queue_head_init(&loopback_queue);
-}
-
-static inline int nr_loopback_running(void)
-{
-	return timer_pending(&loopback_timer);
-}
-
-int nr_loopback_queue(struct sk_buff *skb)
-{
-	struct sk_buff *skbn;
-
-	if ((skbn = alloc_skb(skb->len, GFP_ATOMIC)) != NULL) {
-		skb_copy_from_linear_data(skb, skb_put(skbn, skb->len), skb->len);
-		skb_reset_transport_header(skbn);
-
-		skb_queue_tail(&loopback_queue, skbn);
-
-		if (!nr_loopback_running())
-			mod_timer(&loopback_timer, jiffies + 10);
-	}
-
-	kfree_skb(skb);
-	return 1;
-}
-
-static void nr_loopback_timer(struct timer_list *unused)
-{
-	struct sk_buff *skb;
-	ax25_address *nr_dest;
-	struct net_device *dev;
-
-	if ((skb = skb_dequeue(&loopback_queue)) != NULL) {
-		nr_dest = (ax25_address *)(skb->data + 7);
-
-		dev = nr_dev_get(nr_dest);
-
-		if (dev == NULL || nr_rx_frame(skb, dev) == 0)
-			kfree_skb(skb);
-
-		dev_put(dev);
-
-		if (!skb_queue_empty(&loopback_queue) && !nr_loopback_running())
-			mod_timer(&loopback_timer, jiffies + 10);
-	}
-}
-
-void nr_loopback_clear(void)
-{
-	timer_delete_sync(&loopback_timer);
-	skb_queue_purge(&loopback_queue);
-}
diff --git a/net/netrom/nr_out.c b/net/netrom/nr_out.c
deleted file mode 100644
index 2b3cbceb0b52..000000000000
--- a/net/netrom/nr_out.c
+++ /dev/null
@@ -1,272 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright Darryl Miles G7LED (dlm@g7led.demon.co.uk)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <net/netrom.h>
-
-/*
- *	This is where all NET/ROM frames pass, except for IP-over-NET/ROM which
- *	cannot be fragmented in this manner.
- */
-void nr_output(struct sock *sk, struct sk_buff *skb)
-{
-	struct sk_buff *skbn;
-	unsigned char transport[NR_TRANSPORT_LEN];
-	int err, frontlen, len;
-
-	if (skb->len - NR_TRANSPORT_LEN > NR_MAX_PACKET_SIZE) {
-		/* Save a copy of the Transport Header */
-		skb_copy_from_linear_data(skb, transport, NR_TRANSPORT_LEN);
-		skb_pull(skb, NR_TRANSPORT_LEN);
-
-		frontlen = skb_headroom(skb);
-
-		while (skb->len > 0) {
-			if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL) {
-				kfree_skb(skb);
-				return;
-			}
-
-			skb_reserve(skbn, frontlen);
-
-			len = (NR_MAX_PACKET_SIZE > skb->len) ? skb->len : NR_MAX_PACKET_SIZE;
-
-			/* Copy the user data */
-			skb_copy_from_linear_data(skb, skb_put(skbn, len), len);
-			skb_pull(skb, len);
-
-			/* Duplicate the Transport Header */
-			skb_push(skbn, NR_TRANSPORT_LEN);
-			skb_copy_to_linear_data(skbn, transport,
-						NR_TRANSPORT_LEN);
-			if (skb->len > 0)
-				skbn->data[4] |= NR_MORE_FLAG;
-
-			skb_queue_tail(&sk->sk_write_queue, skbn); /* Throw it on the queue */
-		}
-
-		kfree_skb(skb);
-	} else {
-		skb_queue_tail(&sk->sk_write_queue, skb);		/* Throw it on the queue */
-	}
-
-	nr_kick(sk);
-}
-
-/*
- *	This procedure is passed a buffer descriptor for an iframe. It builds
- *	the rest of the control part of the frame and then writes it out.
- */
-static void nr_send_iframe(struct sock *sk, struct sk_buff *skb)
-{
-	struct nr_sock *nr = nr_sk(sk);
-
-	if (skb == NULL)
-		return;
-
-	skb->data[2] = nr->vs;
-	skb->data[3] = nr->vr;
-
-	if (nr->condition & NR_COND_OWN_RX_BUSY)
-		skb->data[4] |= NR_CHOKE_FLAG;
-
-	nr_start_idletimer(sk);
-
-	nr_transmit_buffer(sk, skb);
-}
-
-void nr_send_nak_frame(struct sock *sk)
-{
-	struct sk_buff *skb, *skbn;
-	struct nr_sock *nr = nr_sk(sk);
-
-	if ((skb = skb_peek(&nr->ack_queue)) == NULL)
-		return;
-
-	if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL)
-		return;
-
-	skbn->data[2] = nr->va;
-	skbn->data[3] = nr->vr;
-
-	if (nr->condition & NR_COND_OWN_RX_BUSY)
-		skbn->data[4] |= NR_CHOKE_FLAG;
-
-	nr_transmit_buffer(sk, skbn);
-
-	nr->condition &= ~NR_COND_ACK_PENDING;
-	nr->vl         = nr->vr;
-
-	nr_stop_t1timer(sk);
-}
-
-void nr_kick(struct sock *sk)
-{
-	struct nr_sock *nr = nr_sk(sk);
-	struct sk_buff *skb, *skbn;
-	unsigned short start, end;
-
-	if (nr->state != NR_STATE_3)
-		return;
-
-	if (nr->condition & NR_COND_PEER_RX_BUSY)
-		return;
-
-	if (!skb_peek(&sk->sk_write_queue))
-		return;
-
-	start = (skb_peek(&nr->ack_queue) == NULL) ? nr->va : nr->vs;
-	end   = (nr->va + nr->window) % NR_MODULUS;
-
-	if (start == end)
-		return;
-
-	nr->vs = start;
-
-	/*
-	 * Transmit data until either we're out of data to send or
-	 * the window is full.
-	 */
-
-	/*
-	 * Dequeue the frame and copy it.
-	 */
-	skb = skb_dequeue(&sk->sk_write_queue);
-
-	do {
-		if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
-			skb_queue_head(&sk->sk_write_queue, skb);
-			break;
-		}
-
-		skb_set_owner_w(skbn, sk);
-
-		/*
-		 * Transmit the frame copy.
-		 */
-		nr_send_iframe(sk, skbn);
-
-		nr->vs = (nr->vs + 1) % NR_MODULUS;
-
-		/*
-		 * Requeue the original data frame.
-		 */
-		skb_queue_tail(&nr->ack_queue, skb);
-
-	} while (nr->vs != end &&
-		 (skb = skb_dequeue(&sk->sk_write_queue)) != NULL);
-
-	nr->vl         = nr->vr;
-	nr->condition &= ~NR_COND_ACK_PENDING;
-
-	if (!nr_t1timer_running(sk))
-		nr_start_t1timer(sk);
-}
-
-void nr_transmit_buffer(struct sock *sk, struct sk_buff *skb)
-{
-	struct nr_sock *nr = nr_sk(sk);
-	unsigned char *dptr;
-
-	/*
-	 *	Add the protocol byte and network header.
-	 */
-	dptr = skb_push(skb, NR_NETWORK_LEN);
-
-	memcpy(dptr, &nr->source_addr, AX25_ADDR_LEN);
-	dptr[6] &= ~AX25_CBIT;
-	dptr[6] &= ~AX25_EBIT;
-	dptr[6] |= AX25_SSSID_SPARE;
-	dptr += AX25_ADDR_LEN;
-
-	memcpy(dptr, &nr->dest_addr, AX25_ADDR_LEN);
-	dptr[6] &= ~AX25_CBIT;
-	dptr[6] |= AX25_EBIT;
-	dptr[6] |= AX25_SSSID_SPARE;
-	dptr += AX25_ADDR_LEN;
-
-	*dptr++ = READ_ONCE(sysctl_netrom_network_ttl_initialiser);
-
-	if (!nr_route_frame(skb, NULL)) {
-		kfree_skb(skb);
-		nr_disconnect(sk, ENETUNREACH);
-	}
-}
-
-/*
- * The following routines are taken from page 170 of the 7th ARRL Computer
- * Networking Conference paper, as is the whole state machine.
- */
-
-void nr_establish_data_link(struct sock *sk)
-{
-	struct nr_sock *nr = nr_sk(sk);
-
-	nr->condition = 0x00;
-	nr->n2count   = 0;
-
-	nr_write_internal(sk, NR_CONNREQ);
-
-	nr_stop_t2timer(sk);
-	nr_stop_t4timer(sk);
-	nr_stop_idletimer(sk);
-	nr_start_t1timer(sk);
-}
-
-/*
- * Never send a NAK when we are CHOKEd.
- */
-void nr_enquiry_response(struct sock *sk)
-{
-	struct nr_sock *nr = nr_sk(sk);
-	int frametype = NR_INFOACK;
-
-	if (nr->condition & NR_COND_OWN_RX_BUSY) {
-		frametype |= NR_CHOKE_FLAG;
-	} else {
-		if (skb_peek(&nr->reseq_queue) != NULL)
-			frametype |= NR_NAK_FLAG;
-	}
-
-	nr_write_internal(sk, frametype);
-
-	nr->vl         = nr->vr;
-	nr->condition &= ~NR_COND_ACK_PENDING;
-}
-
-void nr_check_iframes_acked(struct sock *sk, unsigned short nr)
-{
-	struct nr_sock *nrom = nr_sk(sk);
-
-	if (nrom->vs == nr) {
-		nr_frames_acked(sk, nr);
-		nr_stop_t1timer(sk);
-		nrom->n2count = 0;
-	} else {
-		if (nrom->va != nr) {
-			nr_frames_acked(sk, nr);
-			nr_start_t1timer(sk);
-		}
-	}
-}
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
deleted file mode 100644
index 9cc29ae85b06..000000000000
--- a/net/netrom/nr_route.c
+++ /dev/null
@@ -1,989 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
- * Copyright Tomi Manninen OH2BNS (oh2bns@sral.fi)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <net/arp.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/termios.h>	/* For TIOCINQ/OUTQ */
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/notifier.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <net/netrom.h>
-#include <linux/seq_file.h>
-#include <linux/export.h>
-
-static unsigned int nr_neigh_no = 1;
-
-static HLIST_HEAD(nr_node_list);
-static DEFINE_SPINLOCK(nr_node_list_lock);
-static HLIST_HEAD(nr_neigh_list);
-static DEFINE_SPINLOCK(nr_neigh_list_lock);
-
-static struct nr_node *nr_node_get(ax25_address *callsign)
-{
-	struct nr_node *found = NULL;
-	struct nr_node *nr_node;
-
-	spin_lock_bh(&nr_node_list_lock);
-	nr_node_for_each(nr_node, &nr_node_list)
-		if (ax25cmp(callsign, &nr_node->callsign) == 0) {
-			nr_node_hold(nr_node);
-			found = nr_node;
-			break;
-		}
-	spin_unlock_bh(&nr_node_list_lock);
-	return found;
-}
-
-static struct nr_neigh *nr_neigh_get_dev(ax25_address *callsign,
-					 struct net_device *dev)
-{
-	struct nr_neigh *found = NULL;
-	struct nr_neigh *nr_neigh;
-
-	spin_lock_bh(&nr_neigh_list_lock);
-	nr_neigh_for_each(nr_neigh, &nr_neigh_list)
-		if (ax25cmp(callsign, &nr_neigh->callsign) == 0 &&
-		    nr_neigh->dev == dev) {
-			nr_neigh_hold(nr_neigh);
-			found = nr_neigh;
-			break;
-		}
-	spin_unlock_bh(&nr_neigh_list_lock);
-	return found;
-}
-
-static void nr_remove_neigh(struct nr_neigh *);
-
-/*      re-sort the routes in quality order.    */
-static void re_sort_routes(struct nr_node *nr_node, int x, int y)
-{
-	if (nr_node->routes[y].quality > nr_node->routes[x].quality) {
-		if (nr_node->which == x)
-			nr_node->which = y;
-		else if (nr_node->which == y)
-			nr_node->which = x;
-
-		swap(nr_node->routes[x], nr_node->routes[y]);
-	}
-}
-
-/*
- *	Add a new route to a node, and in the process add the node and the
- *	neighbour if it is new.
- */
-static int __must_check nr_add_node(ax25_address *nr, const char *mnemonic,
-	ax25_address *ax25, ax25_digi *ax25_digi, struct net_device *dev,
-	int quality, int obs_count)
-{
-	struct nr_node  *nr_node;
-	struct nr_neigh *nr_neigh;
-	int i, found;
-	struct net_device *odev;
-
-	if ((odev=nr_dev_get(nr)) != NULL) {	/* Can't add routes to ourself */
-		dev_put(odev);
-		return -EINVAL;
-	}
-
-	nr_node = nr_node_get(nr);
-
-	nr_neigh = nr_neigh_get_dev(ax25, dev);
-
-	/*
-	 * The L2 link to a neighbour has failed in the past
-	 * and now a frame comes from this neighbour. We assume
-	 * it was a temporary trouble with the link and reset the
-	 * routes now (and not wait for a node broadcast).
-	 */
-	if (nr_neigh != NULL && nr_neigh->failed != 0 && quality == 0) {
-		struct nr_node *nr_nodet;
-
-		spin_lock_bh(&nr_node_list_lock);
-		nr_node_for_each(nr_nodet, &nr_node_list) {
-			nr_node_lock(nr_nodet);
-			for (i = 0; i < nr_nodet->count; i++)
-				if (nr_nodet->routes[i].neighbour == nr_neigh)
-					if (i < nr_nodet->which)
-						nr_nodet->which = i;
-			nr_node_unlock(nr_nodet);
-		}
-		spin_unlock_bh(&nr_node_list_lock);
-	}
-
-	if (nr_neigh != NULL)
-		nr_neigh->failed = 0;
-
-	if (quality == 0 && nr_neigh != NULL && nr_node != NULL) {
-		nr_neigh_put(nr_neigh);
-		nr_node_put(nr_node);
-		return 0;
-	}
-
-	if (nr_neigh == NULL) {
-		if ((nr_neigh = kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL) {
-			if (nr_node)
-				nr_node_put(nr_node);
-			return -ENOMEM;
-		}
-
-		nr_neigh->callsign = *ax25;
-		nr_neigh->digipeat = NULL;
-		nr_neigh->ax25     = NULL;
-		nr_neigh->dev      = dev;
-		nr_neigh->quality  = READ_ONCE(sysctl_netrom_default_path_quality);
-		nr_neigh->locked   = 0;
-		nr_neigh->count    = 0;
-		nr_neigh->number   = nr_neigh_no++;
-		nr_neigh->failed   = 0;
-		refcount_set(&nr_neigh->refcount, 1);
-
-		if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
-			nr_neigh->digipeat = kmemdup(ax25_digi,
-						     sizeof(*ax25_digi),
-						     GFP_KERNEL);
-			if (nr_neigh->digipeat == NULL) {
-				kfree(nr_neigh);
-				if (nr_node)
-					nr_node_put(nr_node);
-				return -ENOMEM;
-			}
-		}
-
-		spin_lock_bh(&nr_neigh_list_lock);
-		hlist_add_head(&nr_neigh->neigh_node, &nr_neigh_list);
-		nr_neigh_hold(nr_neigh);
-		spin_unlock_bh(&nr_neigh_list_lock);
-	}
-
-	if (quality != 0 && ax25cmp(nr, ax25) == 0 && !nr_neigh->locked)
-		nr_neigh->quality = quality;
-
-	if (nr_node == NULL) {
-		if ((nr_node = kmalloc(sizeof(*nr_node), GFP_ATOMIC)) == NULL) {
-			if (nr_neigh)
-				nr_neigh_put(nr_neigh);
-			return -ENOMEM;
-		}
-
-		nr_node->callsign = *nr;
-		strscpy(nr_node->mnemonic, mnemonic);
-
-		nr_node->which = 0;
-		nr_node->count = 1;
-		refcount_set(&nr_node->refcount, 1);
-		spin_lock_init(&nr_node->node_lock);
-
-		nr_node->routes[0].quality   = quality;
-		nr_node->routes[0].obs_count = obs_count;
-		nr_node->routes[0].neighbour = nr_neigh;
-
-		nr_neigh_hold(nr_neigh);
-		nr_neigh->count++;
-
-		spin_lock_bh(&nr_node_list_lock);
-		hlist_add_head(&nr_node->node_node, &nr_node_list);
-		/* refcount initialized at 1 */
-		spin_unlock_bh(&nr_node_list_lock);
-
-		nr_neigh_put(nr_neigh);
-		return 0;
-	}
-	nr_node_lock(nr_node);
-
-	if (quality != 0)
-		strscpy(nr_node->mnemonic, mnemonic);
-
-	for (found = 0, i = 0; i < nr_node->count; i++) {
-		if (nr_node->routes[i].neighbour == nr_neigh) {
-			nr_node->routes[i].quality   = quality;
-			nr_node->routes[i].obs_count = obs_count;
-			found = 1;
-			break;
-		}
-	}
-
-	if (!found) {
-		/* We have space at the bottom, slot it in */
-		if (nr_node->count < 3) {
-			nr_node->routes[2] = nr_node->routes[1];
-			nr_node->routes[1] = nr_node->routes[0];
-
-			nr_node->routes[0].quality   = quality;
-			nr_node->routes[0].obs_count = obs_count;
-			nr_node->routes[0].neighbour = nr_neigh;
-
-			nr_node->which++;
-			nr_node->count++;
-			nr_neigh_hold(nr_neigh);
-			nr_neigh->count++;
-		} else {
-			/* It must be better than the worst */
-			if (quality > nr_node->routes[2].quality) {
-				nr_node->routes[2].neighbour->count--;
-				nr_neigh_put(nr_node->routes[2].neighbour);
-
-				if (nr_node->routes[2].neighbour->count == 0 && !nr_node->routes[2].neighbour->locked)
-					nr_remove_neigh(nr_node->routes[2].neighbour);
-
-				nr_node->routes[2].quality   = quality;
-				nr_node->routes[2].obs_count = obs_count;
-				nr_node->routes[2].neighbour = nr_neigh;
-
-				nr_neigh_hold(nr_neigh);
-				nr_neigh->count++;
-			}
-		}
-	}
-
-	/* Now re-sort the routes in quality order */
-	switch (nr_node->count) {
-	case 3:
-		re_sort_routes(nr_node, 0, 1);
-		re_sort_routes(nr_node, 1, 2);
-		fallthrough;
-	case 2:
-		re_sort_routes(nr_node, 0, 1);
-		break;
-	case 1:
-		break;
-	}
-
-	for (i = 0; i < nr_node->count; i++) {
-		if (nr_node->routes[i].neighbour == nr_neigh) {
-			if (i < nr_node->which)
-				nr_node->which = i;
-			break;
-		}
-	}
-
-	nr_neigh_put(nr_neigh);
-	nr_node_unlock(nr_node);
-	nr_node_put(nr_node);
-	return 0;
-}
-
-static void nr_remove_node_locked(struct nr_node *nr_node)
-{
-	lockdep_assert_held(&nr_node_list_lock);
-
-	hlist_del_init(&nr_node->node_node);
-	nr_node_put(nr_node);
-}
-
-static inline void __nr_remove_neigh(struct nr_neigh *nr_neigh)
-{
-	hlist_del_init(&nr_neigh->neigh_node);
-	nr_neigh_put(nr_neigh);
-}
-
-#define nr_remove_neigh_locked(__neigh) \
-	__nr_remove_neigh(__neigh)
-
-static void nr_remove_neigh(struct nr_neigh *nr_neigh)
-{
-	spin_lock_bh(&nr_neigh_list_lock);
-	__nr_remove_neigh(nr_neigh);
-	spin_unlock_bh(&nr_neigh_list_lock);
-}
-
-/*
- *	"Delete" a node. Strictly speaking remove a route to a node. The node
- *	is only deleted if no routes are left to it.
- */
-static int nr_del_node(ax25_address *callsign, ax25_address *neighbour, struct net_device *dev)
-{
-	struct nr_node  *nr_node;
-	struct nr_neigh *nr_neigh;
-	int i;
-
-	nr_node = nr_node_get(callsign);
-
-	if (nr_node == NULL)
-		return -EINVAL;
-
-	nr_neigh = nr_neigh_get_dev(neighbour, dev);
-
-	if (nr_neigh == NULL) {
-		nr_node_put(nr_node);
-		return -EINVAL;
-	}
-
-	spin_lock_bh(&nr_node_list_lock);
-	nr_node_lock(nr_node);
-	for (i = 0; i < nr_node->count; i++) {
-		if (nr_node->routes[i].neighbour == nr_neigh) {
-			nr_neigh->count--;
-			nr_neigh_put(nr_neigh);
-
-			if (nr_neigh->count == 0 && !nr_neigh->locked)
-				nr_remove_neigh(nr_neigh);
-			nr_neigh_put(nr_neigh);
-
-			nr_node->count--;
-
-			if (nr_node->count == 0) {
-				nr_remove_node_locked(nr_node);
-			} else {
-				switch (i) {
-				case 0:
-					nr_node->routes[0] = nr_node->routes[1];
-					fallthrough;
-				case 1:
-					nr_node->routes[1] = nr_node->routes[2];
-					fallthrough;
-				case 2:
-					break;
-				}
-				nr_node_put(nr_node);
-			}
-			nr_node_unlock(nr_node);
-			spin_unlock_bh(&nr_node_list_lock);
-
-			return 0;
-		}
-	}
-	nr_neigh_put(nr_neigh);
-	nr_node_unlock(nr_node);
-	spin_unlock_bh(&nr_node_list_lock);
-	nr_node_put(nr_node);
-
-	return -EINVAL;
-}
-
-/*
- *	Lock a neighbour with a quality.
- */
-static int __must_check nr_add_neigh(ax25_address *callsign,
-	ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality)
-{
-	struct nr_neigh *nr_neigh;
-
-	nr_neigh = nr_neigh_get_dev(callsign, dev);
-	if (nr_neigh) {
-		nr_neigh->quality = quality;
-		nr_neigh->locked  = 1;
-		nr_neigh_put(nr_neigh);
-		return 0;
-	}
-
-	if ((nr_neigh = kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL)
-		return -ENOMEM;
-
-	nr_neigh->callsign = *callsign;
-	nr_neigh->digipeat = NULL;
-	nr_neigh->ax25     = NULL;
-	nr_neigh->dev      = dev;
-	nr_neigh->quality  = quality;
-	nr_neigh->locked   = 1;
-	nr_neigh->count    = 0;
-	nr_neigh->number   = nr_neigh_no++;
-	nr_neigh->failed   = 0;
-	refcount_set(&nr_neigh->refcount, 1);
-
-	if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
-		nr_neigh->digipeat = kmemdup(ax25_digi, sizeof(*ax25_digi),
-					     GFP_KERNEL);
-		if (nr_neigh->digipeat == NULL) {
-			kfree(nr_neigh);
-			return -ENOMEM;
-		}
-	}
-
-	spin_lock_bh(&nr_neigh_list_lock);
-	hlist_add_head(&nr_neigh->neigh_node, &nr_neigh_list);
-	/* refcount is initialized at 1 */
-	spin_unlock_bh(&nr_neigh_list_lock);
-
-	return 0;
-}
-
-/*
- *	"Delete" a neighbour. The neighbour is only removed if the number
- *	of nodes that may use it is zero.
- */
-static int nr_del_neigh(ax25_address *callsign, struct net_device *dev, unsigned int quality)
-{
-	struct nr_neigh *nr_neigh;
-
-	nr_neigh = nr_neigh_get_dev(callsign, dev);
-
-	if (nr_neigh == NULL) return -EINVAL;
-
-	nr_neigh->quality = quality;
-	nr_neigh->locked  = 0;
-
-	if (nr_neigh->count == 0)
-		nr_remove_neigh(nr_neigh);
-	nr_neigh_put(nr_neigh);
-
-	return 0;
-}
-
-/*
- *	Decrement the obsolescence count by one. If a route is reduced to a
- *	count of zero, remove it. Also remove any unlocked neighbours with
- *	zero nodes routing via it.
- */
-static int nr_dec_obs(void)
-{
-	struct nr_neigh *nr_neigh;
-	struct nr_node  *s;
-	struct hlist_node *nodet;
-	int i;
-
-	spin_lock_bh(&nr_node_list_lock);
-	nr_node_for_each_safe(s, nodet, &nr_node_list) {
-		nr_node_lock(s);
-		for (i = 0; i < s->count; i++) {
-			switch (s->routes[i].obs_count) {
-			case 0:		/* A locked entry */
-				break;
-
-			case 1:		/* From 1 -> 0 */
-				nr_neigh = s->routes[i].neighbour;
-
-				nr_neigh->count--;
-				nr_neigh_put(nr_neigh);
-
-				if (nr_neigh->count == 0 && !nr_neigh->locked)
-					nr_remove_neigh(nr_neigh);
-
-				s->count--;
-
-				switch (i) {
-				case 0:
-					s->routes[0] = s->routes[1];
-					fallthrough;
-				case 1:
-					s->routes[1] = s->routes[2];
-					break;
-				case 2:
-					break;
-				}
-				break;
-
-			default:
-				s->routes[i].obs_count--;
-				break;
-
-			}
-		}
-
-		if (s->count <= 0)
-			nr_remove_node_locked(s);
-		nr_node_unlock(s);
-	}
-	spin_unlock_bh(&nr_node_list_lock);
-
-	return 0;
-}
-
-/*
- *	A device has been removed. Remove its routes and neighbours.
- */
-void nr_rt_device_down(struct net_device *dev)
-{
-	struct nr_neigh *s;
-	struct hlist_node *nodet, *node2t;
-	struct nr_node  *t;
-	int i;
-
-	spin_lock_bh(&nr_neigh_list_lock);
-	nr_neigh_for_each_safe(s, nodet, &nr_neigh_list) {
-		if (s->dev == dev) {
-			spin_lock_bh(&nr_node_list_lock);
-			nr_node_for_each_safe(t, node2t, &nr_node_list) {
-				nr_node_lock(t);
-				for (i = 0; i < t->count; i++) {
-					if (t->routes[i].neighbour == s) {
-						t->count--;
-
-						switch (i) {
-						case 0:
-							t->routes[0] = t->routes[1];
-							fallthrough;
-						case 1:
-							t->routes[1] = t->routes[2];
-							break;
-						case 2:
-							break;
-						}
-					}
-				}
-
-				if (t->count <= 0)
-					nr_remove_node_locked(t);
-				nr_node_unlock(t);
-			}
-			spin_unlock_bh(&nr_node_list_lock);
-
-			nr_remove_neigh_locked(s);
-		}
-	}
-	spin_unlock_bh(&nr_neigh_list_lock);
-}
-
-/*
- *	Check that the device given is a valid AX.25 interface that is "up".
- *	Or a valid ethernet interface with an AX.25 callsign binding.
- */
-static struct net_device *nr_ax25_dev_get(char *devname)
-{
-	struct net_device *dev;
-
-	if ((dev = dev_get_by_name(&init_net, devname)) == NULL)
-		return NULL;
-
-	if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
-		return dev;
-
-	dev_put(dev);
-	return NULL;
-}
-
-/*
- *	Find the first active NET/ROM device, usually "nr0".
- */
-struct net_device *nr_dev_first(void)
-{
-	struct net_device *dev, *first = NULL;
-
-	rcu_read_lock();
-	for_each_netdev_rcu(&init_net, dev) {
-		if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM)
-			if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
-				first = dev;
-	}
-	dev_hold(first);
-	rcu_read_unlock();
-
-	return first;
-}
-
-/*
- *	Find the NET/ROM device for the given callsign.
- */
-struct net_device *nr_dev_get(ax25_address *addr)
-{
-	struct net_device *dev;
-
-	rcu_read_lock();
-	for_each_netdev_rcu(&init_net, dev) {
-		if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM &&
-		    ax25cmp(addr, (const ax25_address *)dev->dev_addr) == 0) {
-			dev_hold(dev);
-			goto out;
-		}
-	}
-	dev = NULL;
-out:
-	rcu_read_unlock();
-	return dev;
-}
-
-static ax25_digi *nr_call_to_digi(ax25_digi *digi, int ndigis,
-	ax25_address *digipeaters)
-{
-	int i;
-
-	if (ndigis == 0)
-		return NULL;
-
-	for (i = 0; i < ndigis; i++) {
-		digi->calls[i]    = digipeaters[i];
-		digi->repeated[i] = 0;
-	}
-
-	digi->ndigi      = ndigis;
-	digi->lastrepeat = -1;
-
-	return digi;
-}
-
-/*
- *	Handle the ioctls that control the routing functions.
- */
-int nr_rt_ioctl(unsigned int cmd, void __user *arg)
-{
-	struct nr_route_struct nr_route;
-	struct net_device *dev;
-	ax25_digi digi;
-	int ret;
-
-	switch (cmd) {
-	case SIOCADDRT:
-		if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
-			return -EFAULT;
-		if (nr_route.ndigis > AX25_MAX_DIGIS)
-			return -EINVAL;
-		if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
-			return -EINVAL;
-		switch (nr_route.type) {
-		case NETROM_NODE:
-			if (strnlen(nr_route.mnemonic, 7) == 7) {
-				ret = -EINVAL;
-				break;
-			}
-
-			ret = nr_add_node(&nr_route.callsign,
-				nr_route.mnemonic,
-				&nr_route.neighbour,
-				nr_call_to_digi(&digi, nr_route.ndigis,
-						nr_route.digipeaters),
-				dev, nr_route.quality,
-				nr_route.obs_count);
-			break;
-		case NETROM_NEIGH:
-			ret = nr_add_neigh(&nr_route.callsign,
-				nr_call_to_digi(&digi, nr_route.ndigis,
-						nr_route.digipeaters),
-				dev, nr_route.quality);
-			break;
-		default:
-			ret = -EINVAL;
-		}
-		dev_put(dev);
-		return ret;
-
-	case SIOCDELRT:
-		if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
-			return -EFAULT;
-		if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
-			return -EINVAL;
-		switch (nr_route.type) {
-		case NETROM_NODE:
-			ret = nr_del_node(&nr_route.callsign,
-				&nr_route.neighbour, dev);
-			break;
-		case NETROM_NEIGH:
-			ret = nr_del_neigh(&nr_route.callsign,
-				dev, nr_route.quality);
-			break;
-		default:
-			ret = -EINVAL;
-		}
-		dev_put(dev);
-		return ret;
-
-	case SIOCNRDECOBS:
-		return nr_dec_obs();
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/*
- * 	A level 2 link has timed out, therefore it appears to be a poor link,
- *	then don't use that neighbour until it is reset.
- */
-void nr_link_failed(ax25_cb *ax25, int reason)
-{
-	struct nr_neigh *s, *nr_neigh = NULL;
-	struct nr_node  *nr_node = NULL;
-
-	spin_lock_bh(&nr_neigh_list_lock);
-	nr_neigh_for_each(s, &nr_neigh_list) {
-		if (s->ax25 == ax25) {
-			nr_neigh_hold(s);
-			nr_neigh = s;
-			break;
-		}
-	}
-	spin_unlock_bh(&nr_neigh_list_lock);
-
-	if (nr_neigh == NULL)
-		return;
-
-	nr_neigh->ax25 = NULL;
-	ax25_cb_put(ax25);
-
-	if (++nr_neigh->failed < READ_ONCE(sysctl_netrom_link_fails_count)) {
-		nr_neigh_put(nr_neigh);
-		return;
-	}
-	spin_lock_bh(&nr_node_list_lock);
-	nr_node_for_each(nr_node, &nr_node_list) {
-		nr_node_lock(nr_node);
-		if (nr_node->which < nr_node->count &&
-		    nr_node->routes[nr_node->which].neighbour == nr_neigh)
-			nr_node->which++;
-		nr_node_unlock(nr_node);
-	}
-	spin_unlock_bh(&nr_node_list_lock);
-	nr_neigh_put(nr_neigh);
-}
-
-/*
- *	Route a frame to an appropriate AX.25 connection. A NULL ax25_cb
- *	indicates an internally generated frame.
- */
-int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
-{
-	ax25_address *nr_src, *nr_dest;
-	struct nr_neigh *nr_neigh;
-	struct nr_node  *nr_node;
-	struct net_device *dev;
-	unsigned char *dptr;
-	ax25_cb *ax25s;
-	int ret;
-	struct sk_buff *nskb, *oskb;
-
-	/*
-	 * Reject malformed packets early. Check that it contains at least 2
-	 * addresses and 1 byte more for Time-To-Live
-	 */
-	if (skb->len < 2 * sizeof(ax25_address) + 1)
-		return 0;
-
-	nr_src  = (ax25_address *)(skb->data + 0);
-	nr_dest = (ax25_address *)(skb->data + 7);
-
-	if (ax25 != NULL) {
-		ret = nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
-				  ax25->ax25_dev->dev, 0,
-				  READ_ONCE(sysctl_netrom_obsolescence_count_initialiser));
-		if (ret)
-			return ret;
-	}
-
-	if ((dev = nr_dev_get(nr_dest)) != NULL) {	/* Its for me */
-		if (ax25 == NULL)			/* Its from me */
-			ret = nr_loopback_queue(skb);
-		else
-			ret = nr_rx_frame(skb, dev);
-		dev_put(dev);
-		return ret;
-	}
-
-	if (!READ_ONCE(sysctl_netrom_routing_control) && ax25 != NULL)
-		return 0;
-
-	/* Its Time-To-Live has expired */
-	if (skb->data[14] == 1) {
-		return 0;
-	}
-
-	nr_node = nr_node_get(nr_dest);
-	if (nr_node == NULL)
-		return 0;
-	nr_node_lock(nr_node);
-
-	if (nr_node->which >= nr_node->count) {
-		nr_node_unlock(nr_node);
-		nr_node_put(nr_node);
-		return 0;
-	}
-
-	nr_neigh = nr_node->routes[nr_node->which].neighbour;
-
-	if ((dev = nr_dev_first()) == NULL) {
-		nr_node_unlock(nr_node);
-		nr_node_put(nr_node);
-		return 0;
-	}
-
-	/* We are going to change the netrom headers so we should get our
-	   own skb, we also did not know until now how much header space
-	   we had to reserve... - RXQ */
-	nskb = skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC);
-
-	if (!nskb) {
-		nr_node_unlock(nr_node);
-		nr_node_put(nr_node);
-		dev_put(dev);
-		return 0;
-	}
-	oskb = skb;
-	skb = nskb;
-	skb->data[14]--;
-
-	dptr  = skb_push(skb, 1);
-	*dptr = AX25_P_NETROM;
-
-	ax25s = nr_neigh->ax25;
-	nr_neigh->ax25 = ax25_send_frame(skb, 256,
-					 (const ax25_address *)dev->dev_addr,
-					 &nr_neigh->callsign,
-					 nr_neigh->digipeat, nr_neigh->dev);
-	if (ax25s)
-		ax25_cb_put(ax25s);
-
-	dev_put(dev);
-	ret = (nr_neigh->ax25 != NULL);
-	nr_node_unlock(nr_node);
-	nr_node_put(nr_node);
-
-	if (ret)
-		kfree_skb(oskb);
-
-	return ret;
-}
-
-#ifdef CONFIG_PROC_FS
-
-static void *nr_node_start(struct seq_file *seq, loff_t *pos)
-	__acquires(&nr_node_list_lock)
-{
-	spin_lock_bh(&nr_node_list_lock);
-	return seq_hlist_start_head(&nr_node_list, *pos);
-}
-
-static void *nr_node_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	return seq_hlist_next(v, &nr_node_list, pos);
-}
-
-static void nr_node_stop(struct seq_file *seq, void *v)
-	__releases(&nr_node_list_lock)
-{
-	spin_unlock_bh(&nr_node_list_lock);
-}
-
-static int nr_node_show(struct seq_file *seq, void *v)
-{
-	char buf[11];
-	int i;
-
-	if (v == SEQ_START_TOKEN)
-		seq_puts(seq,
-			 "callsign  mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n");
-	else {
-		struct nr_node *nr_node = hlist_entry(v, struct nr_node,
-						      node_node);
-
-		nr_node_lock(nr_node);
-		seq_printf(seq, "%-9s %-7s  %d %d",
-			ax2asc(buf, &nr_node->callsign),
-			(nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic,
-			nr_node->which + 1,
-			nr_node->count);
-
-		for (i = 0; i < nr_node->count; i++) {
-			seq_printf(seq, "  %3d   %d %05d",
-				nr_node->routes[i].quality,
-				nr_node->routes[i].obs_count,
-				nr_node->routes[i].neighbour->number);
-		}
-		nr_node_unlock(nr_node);
-
-		seq_puts(seq, "\n");
-	}
-	return 0;
-}
-
-const struct seq_operations nr_node_seqops = {
-	.start = nr_node_start,
-	.next = nr_node_next,
-	.stop = nr_node_stop,
-	.show = nr_node_show,
-};
-
-static void *nr_neigh_start(struct seq_file *seq, loff_t *pos)
-	__acquires(&nr_neigh_list_lock)
-{
-	spin_lock_bh(&nr_neigh_list_lock);
-	return seq_hlist_start_head(&nr_neigh_list, *pos);
-}
-
-static void *nr_neigh_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	return seq_hlist_next(v, &nr_neigh_list, pos);
-}
-
-static void nr_neigh_stop(struct seq_file *seq, void *v)
-	__releases(&nr_neigh_list_lock)
-{
-	spin_unlock_bh(&nr_neigh_list_lock);
-}
-
-static int nr_neigh_show(struct seq_file *seq, void *v)
-{
-	char buf[11];
-	int i;
-
-	if (v == SEQ_START_TOKEN)
-		seq_puts(seq, "addr  callsign  dev  qual lock count failed digipeaters\n");
-	else {
-		struct nr_neigh *nr_neigh;
-
-		nr_neigh = hlist_entry(v, struct nr_neigh, neigh_node);
-		seq_printf(seq, "%05d %-9s %-4s  %3d    %d   %3d    %3d",
-			nr_neigh->number,
-			ax2asc(buf, &nr_neigh->callsign),
-			nr_neigh->dev ? nr_neigh->dev->name : "???",
-			nr_neigh->quality,
-			nr_neigh->locked,
-			nr_neigh->count,
-			nr_neigh->failed);
-
-		if (nr_neigh->digipeat != NULL) {
-			for (i = 0; i < nr_neigh->digipeat->ndigi; i++)
-				seq_printf(seq, " %s",
-					   ax2asc(buf, &nr_neigh->digipeat->calls[i]));
-		}
-
-		seq_puts(seq, "\n");
-	}
-	return 0;
-}
-
-const struct seq_operations nr_neigh_seqops = {
-	.start = nr_neigh_start,
-	.next = nr_neigh_next,
-	.stop = nr_neigh_stop,
-	.show = nr_neigh_show,
-};
-#endif
-
-/*
- *	Free all memory associated with the nodes and routes lists.
- */
-void nr_rt_free(void)
-{
-	struct nr_neigh *s = NULL;
-	struct nr_node  *t = NULL;
-	struct hlist_node *nodet;
-
-	spin_lock_bh(&nr_neigh_list_lock);
-	spin_lock_bh(&nr_node_list_lock);
-	nr_node_for_each_safe(t, nodet, &nr_node_list) {
-		nr_node_lock(t);
-		nr_remove_node_locked(t);
-		nr_node_unlock(t);
-	}
-	nr_neigh_for_each_safe(s, nodet, &nr_neigh_list) {
-		while(s->count) {
-			s->count--;
-			nr_neigh_put(s);
-		}
-		nr_remove_neigh_locked(s);
-	}
-	spin_unlock_bh(&nr_node_list_lock);
-	spin_unlock_bh(&nr_neigh_list_lock);
-}
diff --git a/net/netrom/nr_subr.c b/net/netrom/nr_subr.c
deleted file mode 100644
index c3bbd5880850..000000000000
--- a/net/netrom/nr_subr.c
+++ /dev/null
@@ -1,280 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <net/netrom.h>
-
-/*
- *	This routine purges all of the queues of frames.
- */
-void nr_clear_queues(struct sock *sk)
-{
-	struct nr_sock *nr = nr_sk(sk);
-
-	skb_queue_purge(&sk->sk_write_queue);
-	skb_queue_purge(&nr->ack_queue);
-	skb_queue_purge(&nr->reseq_queue);
-	skb_queue_purge(&nr->frag_queue);
-}
-
-/*
- * This routine purges the input queue of those frames that have been
- * acknowledged. This replaces the boxes labelled "V(a) <- N(r)" on the
- * SDL diagram.
- */
-void nr_frames_acked(struct sock *sk, unsigned short nr)
-{
-	struct nr_sock *nrom = nr_sk(sk);
-	struct sk_buff *skb;
-
-	/*
-	 * Remove all the ack-ed frames from the ack queue.
-	 */
-	if (nrom->va != nr) {
-		while (skb_peek(&nrom->ack_queue) != NULL && nrom->va != nr) {
-			skb = skb_dequeue(&nrom->ack_queue);
-			kfree_skb(skb);
-			nrom->va = (nrom->va + 1) % NR_MODULUS;
-		}
-	}
-}
-
-/*
- * Requeue all the un-ack-ed frames on the output queue to be picked
- * up by nr_kick called from the timer. This arrangement handles the
- * possibility of an empty output queue.
- */
-void nr_requeue_frames(struct sock *sk)
-{
-	struct sk_buff *skb, *skb_prev = NULL;
-
-	while ((skb = skb_dequeue(&nr_sk(sk)->ack_queue)) != NULL) {
-		if (skb_prev == NULL)
-			skb_queue_head(&sk->sk_write_queue, skb);
-		else
-			skb_append(skb_prev, skb, &sk->sk_write_queue);
-		skb_prev = skb;
-	}
-}
-
-/*
- *	Validate that the value of nr is between va and vs. Return true or
- *	false for testing.
- */
-int nr_validate_nr(struct sock *sk, unsigned short nr)
-{
-	struct nr_sock *nrom = nr_sk(sk);
-	unsigned short vc = nrom->va;
-
-	while (vc != nrom->vs) {
-		if (nr == vc) return 1;
-		vc = (vc + 1) % NR_MODULUS;
-	}
-
-	return nr == nrom->vs;
-}
-
-/*
- *	Check that ns is within the receive window.
- */
-int nr_in_rx_window(struct sock *sk, unsigned short ns)
-{
-	struct nr_sock *nr = nr_sk(sk);
-	unsigned short vc = nr->vr;
-	unsigned short vt = (nr->vl + nr->window) % NR_MODULUS;
-
-	while (vc != vt) {
-		if (ns == vc) return 1;
-		vc = (vc + 1) % NR_MODULUS;
-	}
-
-	return 0;
-}
-
-/*
- *  This routine is called when the HDLC layer internally generates a
- *  control frame.
- */
-void nr_write_internal(struct sock *sk, int frametype)
-{
-	struct nr_sock *nr = nr_sk(sk);
-	struct sk_buff *skb;
-	unsigned char  *dptr;
-	int len, timeout;
-
-	len = NR_TRANSPORT_LEN;
-
-	switch (frametype & 0x0F) {
-	case NR_CONNREQ:
-		len += 17;
-		break;
-	case NR_CONNACK:
-		len += (nr->bpqext) ? 2 : 1;
-		break;
-	case NR_DISCREQ:
-	case NR_DISCACK:
-	case NR_INFOACK:
-		break;
-	default:
-		printk(KERN_ERR "NET/ROM: nr_write_internal - invalid frame type %d\n", frametype);
-		return;
-	}
-
-	skb = alloc_skb(NR_NETWORK_LEN + len, GFP_ATOMIC);
-	if (!skb)
-		return;
-
-	/*
-	 *	Space for AX.25 and NET/ROM network header
-	 */
-	skb_reserve(skb, NR_NETWORK_LEN);
-
-	dptr = skb_put(skb, len);
-
-	switch (frametype & 0x0F) {
-	case NR_CONNREQ:
-		timeout  = nr->t1 / HZ;
-		*dptr++  = nr->my_index;
-		*dptr++  = nr->my_id;
-		*dptr++  = 0;
-		*dptr++  = 0;
-		*dptr++  = frametype;
-		*dptr++  = nr->window;
-		memcpy(dptr, &nr->user_addr, AX25_ADDR_LEN);
-		dptr[6] &= ~AX25_CBIT;
-		dptr[6] &= ~AX25_EBIT;
-		dptr[6] |= AX25_SSSID_SPARE;
-		dptr    += AX25_ADDR_LEN;
-		memcpy(dptr, &nr->source_addr, AX25_ADDR_LEN);
-		dptr[6] &= ~AX25_CBIT;
-		dptr[6] &= ~AX25_EBIT;
-		dptr[6] |= AX25_SSSID_SPARE;
-		dptr    += AX25_ADDR_LEN;
-		*dptr++  = timeout % 256;
-		*dptr++  = timeout / 256;
-		break;
-
-	case NR_CONNACK:
-		*dptr++ = nr->your_index;
-		*dptr++ = nr->your_id;
-		*dptr++ = nr->my_index;
-		*dptr++ = nr->my_id;
-		*dptr++ = frametype;
-		*dptr++ = nr->window;
-		if (nr->bpqext)
-			*dptr++ = READ_ONCE(sysctl_netrom_network_ttl_initialiser);
-		break;
-
-	case NR_DISCREQ:
-	case NR_DISCACK:
-		*dptr++ = nr->your_index;
-		*dptr++ = nr->your_id;
-		*dptr++ = 0;
-		*dptr++ = 0;
-		*dptr++ = frametype;
-		break;
-
-	case NR_INFOACK:
-		*dptr++ = nr->your_index;
-		*dptr++ = nr->your_id;
-		*dptr++ = 0;
-		*dptr++ = nr->vr;
-		*dptr++ = frametype;
-		break;
-	}
-
-	nr_transmit_buffer(sk, skb);
-}
-
-/*
- * This routine is called to send an error reply.
- */
-void __nr_transmit_reply(struct sk_buff *skb, int mine, unsigned char cmdflags)
-{
-	struct sk_buff *skbn;
-	unsigned char *dptr;
-	int len;
-
-	len = NR_NETWORK_LEN + NR_TRANSPORT_LEN + 1;
-
-	if ((skbn = alloc_skb(len, GFP_ATOMIC)) == NULL)
-		return;
-
-	skb_reserve(skbn, 0);
-
-	dptr = skb_put(skbn, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
-
-	skb_copy_from_linear_data_offset(skb, 7, dptr, AX25_ADDR_LEN);
-	dptr[6] &= ~AX25_CBIT;
-	dptr[6] &= ~AX25_EBIT;
-	dptr[6] |= AX25_SSSID_SPARE;
-	dptr += AX25_ADDR_LEN;
-
-	skb_copy_from_linear_data(skb, dptr, AX25_ADDR_LEN);
-	dptr[6] &= ~AX25_CBIT;
-	dptr[6] |= AX25_EBIT;
-	dptr[6] |= AX25_SSSID_SPARE;
-	dptr += AX25_ADDR_LEN;
-
-	*dptr++ = READ_ONCE(sysctl_netrom_network_ttl_initialiser);
-
-	if (mine) {
-		*dptr++ = 0;
-		*dptr++ = 0;
-		*dptr++ = skb->data[15];
-		*dptr++ = skb->data[16];
-	} else {
-		*dptr++ = skb->data[15];
-		*dptr++ = skb->data[16];
-		*dptr++ = 0;
-		*dptr++ = 0;
-	}
-
-	*dptr++ = cmdflags;
-	*dptr++ = 0;
-
-	if (!nr_route_frame(skbn, NULL))
-		kfree_skb(skbn);
-}
-
-void nr_disconnect(struct sock *sk, int reason)
-{
-	nr_stop_t1timer(sk);
-	nr_stop_t2timer(sk);
-	nr_stop_t4timer(sk);
-	nr_stop_idletimer(sk);
-
-	nr_clear_queues(sk);
-
-	nr_sk(sk)->state = NR_STATE_0;
-
-	sk->sk_state     = TCP_CLOSE;
-	sk->sk_err       = reason;
-	sk->sk_shutdown |= SEND_SHUTDOWN;
-
-	if (!sock_flag(sk, SOCK_DEAD)) {
-		sk->sk_state_change(sk);
-		sock_set_flag(sk, SOCK_DEAD);
-	}
-}
diff --git a/net/netrom/nr_timer.c b/net/netrom/nr_timer.c
deleted file mode 100644
index b3a62b1f3a09..000000000000
--- a/net/netrom/nr_timer.c
+++ /dev/null
@@ -1,249 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) 2002 Ralf Baechle DO1GRB (ralf@gnu.org)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/jiffies.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <net/netrom.h>
-
-static void nr_heartbeat_expiry(struct timer_list *);
-static void nr_t1timer_expiry(struct timer_list *);
-static void nr_t2timer_expiry(struct timer_list *);
-static void nr_t4timer_expiry(struct timer_list *);
-static void nr_idletimer_expiry(struct timer_list *);
-
-void nr_init_timers(struct sock *sk)
-{
-	struct nr_sock *nr = nr_sk(sk);
-
-	timer_setup(&nr->t1timer, nr_t1timer_expiry, 0);
-	timer_setup(&nr->t2timer, nr_t2timer_expiry, 0);
-	timer_setup(&nr->t4timer, nr_t4timer_expiry, 0);
-	timer_setup(&nr->idletimer, nr_idletimer_expiry, 0);
-
-	/* initialized by sock_init_data */
-	sk->sk_timer.function = nr_heartbeat_expiry;
-}
-
-void nr_start_t1timer(struct sock *sk)
-{
-	struct nr_sock *nr = nr_sk(sk);
-
-	sk_reset_timer(sk, &nr->t1timer, jiffies + nr->t1);
-}
-
-void nr_start_t2timer(struct sock *sk)
-{
-	struct nr_sock *nr = nr_sk(sk);
-
-	sk_reset_timer(sk, &nr->t2timer, jiffies + nr->t2);
-}
-
-void nr_start_t4timer(struct sock *sk)
-{
-	struct nr_sock *nr = nr_sk(sk);
-
-	sk_reset_timer(sk, &nr->t4timer, jiffies + nr->t4);
-}
-
-void nr_start_idletimer(struct sock *sk)
-{
-	struct nr_sock *nr = nr_sk(sk);
-
-	if (nr->idle > 0)
-		sk_reset_timer(sk, &nr->idletimer, jiffies + nr->idle);
-}
-
-void nr_start_heartbeat(struct sock *sk)
-{
-	sk_reset_timer(sk, &sk->sk_timer, jiffies + 5 * HZ);
-}
-
-void nr_stop_t1timer(struct sock *sk)
-{
-	sk_stop_timer(sk, &nr_sk(sk)->t1timer);
-}
-
-void nr_stop_t2timer(struct sock *sk)
-{
-	sk_stop_timer(sk, &nr_sk(sk)->t2timer);
-}
-
-void nr_stop_t4timer(struct sock *sk)
-{
-	sk_stop_timer(sk, &nr_sk(sk)->t4timer);
-}
-
-void nr_stop_idletimer(struct sock *sk)
-{
-	sk_stop_timer(sk, &nr_sk(sk)->idletimer);
-}
-
-void nr_stop_heartbeat(struct sock *sk)
-{
-	sk_stop_timer(sk, &sk->sk_timer);
-}
-
-int nr_t1timer_running(struct sock *sk)
-{
-	return timer_pending(&nr_sk(sk)->t1timer);
-}
-
-static void nr_heartbeat_expiry(struct timer_list *t)
-{
-	struct sock *sk = timer_container_of(sk, t, sk_timer);
-	struct nr_sock *nr = nr_sk(sk);
-
-	bh_lock_sock(sk);
-	switch (nr->state) {
-	case NR_STATE_0:
-		/* Magic here: If we listen() and a new link dies before it
-		   is accepted() it isn't 'dead' so doesn't get removed. */
-		if (sock_flag(sk, SOCK_DESTROY) ||
-		    (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) {
-			if (sk->sk_state == TCP_LISTEN)
-				sock_hold(sk);
-			bh_unlock_sock(sk);
-			nr_destroy_socket(sk);
-			goto out;
-		}
-		break;
-
-	case NR_STATE_3:
-		/*
-		 * Check for the state of the receive buffer.
-		 */
-		if (atomic_read(&sk->sk_rmem_alloc) < (sk->sk_rcvbuf / 2) &&
-		    (nr->condition & NR_COND_OWN_RX_BUSY)) {
-			nr->condition &= ~NR_COND_OWN_RX_BUSY;
-			nr->condition &= ~NR_COND_ACK_PENDING;
-			nr->vl         = nr->vr;
-			nr_write_internal(sk, NR_INFOACK);
-			break;
-		}
-		break;
-	}
-
-	nr_start_heartbeat(sk);
-	bh_unlock_sock(sk);
-out:
-	sock_put(sk);
-}
-
-static void nr_t2timer_expiry(struct timer_list *t)
-{
-	struct nr_sock *nr = timer_container_of(nr, t, t2timer);
-	struct sock *sk = &nr->sock;
-
-	bh_lock_sock(sk);
-	if (nr->condition & NR_COND_ACK_PENDING) {
-		nr->condition &= ~NR_COND_ACK_PENDING;
-		nr_enquiry_response(sk);
-	}
-	bh_unlock_sock(sk);
-	sock_put(sk);
-}
-
-static void nr_t4timer_expiry(struct timer_list *t)
-{
-	struct nr_sock *nr = timer_container_of(nr, t, t4timer);
-	struct sock *sk = &nr->sock;
-
-	bh_lock_sock(sk);
-	nr_sk(sk)->condition &= ~NR_COND_PEER_RX_BUSY;
-	bh_unlock_sock(sk);
-	sock_put(sk);
-}
-
-static void nr_idletimer_expiry(struct timer_list *t)
-{
-	struct nr_sock *nr = timer_container_of(nr, t, idletimer);
-	struct sock *sk = &nr->sock;
-
-	bh_lock_sock(sk);
-
-	nr_clear_queues(sk);
-
-	nr->n2count = 0;
-	nr_write_internal(sk, NR_DISCREQ);
-	nr->state = NR_STATE_2;
-
-	nr_start_t1timer(sk);
-	nr_stop_t2timer(sk);
-	nr_stop_t4timer(sk);
-
-	sk->sk_state     = TCP_CLOSE;
-	sk->sk_err       = 0;
-	sk->sk_shutdown |= SEND_SHUTDOWN;
-
-	if (!sock_flag(sk, SOCK_DEAD)) {
-		sk->sk_state_change(sk);
-		sock_set_flag(sk, SOCK_DEAD);
-	}
-	bh_unlock_sock(sk);
-	sock_put(sk);
-}
-
-static void nr_t1timer_expiry(struct timer_list *t)
-{
-	struct nr_sock *nr = timer_container_of(nr, t, t1timer);
-	struct sock *sk = &nr->sock;
-
-	bh_lock_sock(sk);
-	switch (nr->state) {
-	case NR_STATE_1:
-		if (nr->n2count == nr->n2) {
-			nr_disconnect(sk, ETIMEDOUT);
-			goto out;
-		} else {
-			nr->n2count++;
-			nr_write_internal(sk, NR_CONNREQ);
-		}
-		break;
-
-	case NR_STATE_2:
-		if (nr->n2count == nr->n2) {
-			nr_disconnect(sk, ETIMEDOUT);
-			goto out;
-		} else {
-			nr->n2count++;
-			nr_write_internal(sk, NR_DISCREQ);
-		}
-		break;
-
-	case NR_STATE_3:
-		if (nr->n2count == nr->n2) {
-			nr_disconnect(sk, ETIMEDOUT);
-			goto out;
-		} else {
-			nr->n2count++;
-			nr_requeue_frames(sk);
-		}
-		break;
-	}
-
-	nr_start_t1timer(sk);
-out:
-	bh_unlock_sock(sk);
-	sock_put(sk);
-}
diff --git a/net/netrom/sysctl_net_netrom.c b/net/netrom/sysctl_net_netrom.c
deleted file mode 100644
index 7dc0fa628f2e..000000000000
--- a/net/netrom/sysctl_net_netrom.c
+++ /dev/null
@@ -1,156 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) 1996 Mike Shaver (shaver@zeroknowledge.com)
- */
-#include <linux/mm.h>
-#include <linux/sysctl.h>
-#include <linux/init.h>
-#include <net/ax25.h>
-#include <net/netrom.h>
-
-/*
- *	Values taken from NET/ROM documentation.
- */
-static int min_quality[] = {0}, max_quality[] = {255};
-static int min_obs[]     = {0}, max_obs[]     = {255};
-static int min_ttl[]     = {0}, max_ttl[]     = {255};
-static int min_t1[]      = {5 * HZ};
-static int max_t1[]      = {600 * HZ};
-static int min_n2[]      = {2}, max_n2[]      = {127};
-static int min_t2[]      = {1 * HZ};
-static int max_t2[]      = {60 * HZ};
-static int min_t4[]      = {1 * HZ};
-static int max_t4[]      = {1000 * HZ};
-static int min_window[]  = {1}, max_window[]  = {127};
-static int min_idle[]    = {0 * HZ};
-static int max_idle[]    = {65535 * HZ};
-static int min_route[]   = {0}, max_route[]   = {1};
-static int min_fails[]   = {1}, max_fails[]   = {10};
-static int min_reset[]   = {0}, max_reset[]   = {1};
-
-static struct ctl_table_header *nr_table_header;
-
-static struct ctl_table nr_table[] = {
-	{
-		.procname	= "default_path_quality",
-		.data		= &sysctl_netrom_default_path_quality,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_quality,
-		.extra2		= &max_quality
-	},
-	{
-		.procname	= "obsolescence_count_initialiser",
-		.data		= &sysctl_netrom_obsolescence_count_initialiser,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_obs,
-		.extra2		= &max_obs
-	},
-	{
-		.procname	= "network_ttl_initialiser",
-		.data		= &sysctl_netrom_network_ttl_initialiser,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_ttl,
-		.extra2		= &max_ttl
-	},
-	{
-		.procname	= "transport_timeout",
-		.data		= &sysctl_netrom_transport_timeout,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_t1,
-		.extra2		= &max_t1
-	},
-	{
-		.procname	= "transport_maximum_tries",
-		.data		= &sysctl_netrom_transport_maximum_tries,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_n2,
-		.extra2		= &max_n2
-	},
-	{
-		.procname	= "transport_acknowledge_delay",
-		.data		= &sysctl_netrom_transport_acknowledge_delay,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_t2,
-		.extra2		= &max_t2
-	},
-	{
-		.procname	= "transport_busy_delay",
-		.data		= &sysctl_netrom_transport_busy_delay,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_t4,
-		.extra2		= &max_t4
-	},
-	{
-		.procname	= "transport_requested_window_size",
-		.data		= &sysctl_netrom_transport_requested_window_size,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_window,
-		.extra2		= &max_window
-	},
-	{
-		.procname	= "transport_no_activity_timeout",
-		.data		= &sysctl_netrom_transport_no_activity_timeout,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_idle,
-		.extra2		= &max_idle
-	},
-	{
-		.procname	= "routing_control",
-		.data		= &sysctl_netrom_routing_control,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_route,
-		.extra2		= &max_route
-	},
-	{
-		.procname	= "link_fails_count",
-		.data		= &sysctl_netrom_link_fails_count,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_fails,
-		.extra2		= &max_fails
-	},
-	{
-		.procname	= "reset",
-		.data		= &sysctl_netrom_reset_circuit,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_reset,
-		.extra2		= &max_reset
-	},
-};
-
-int __init nr_register_sysctl(void)
-{
-	nr_table_header = register_net_sysctl(&init_net, "net/netrom", nr_table);
-	if (!nr_table_header)
-		return -ENOMEM;
-	return 0;
-}
-
-void nr_unregister_sysctl(void)
-{
-	unregister_net_sysctl_table(nr_table_header);
-}
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
deleted file mode 100644
index d5032840ee48..000000000000
--- a/net/rose/af_rose.c
+++ /dev/null
@@ -1,1687 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
- * Copyright (C) Terry Dawson VK2KTJ (terry@animats.net)
- * Copyright (C) Tomi Manninen OH2BNS (oh2bns@sral.fi)
- */
-
-#include <linux/capability.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/sched/signal.h>
-#include <linux/spinlock.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/stat.h>
-#include <net/net_namespace.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/termios.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/notifier.h>
-#include <net/rose.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <net/tcp_states.h>
-#include <net/ip.h>
-#include <net/arp.h>
-
-static int rose_ndevs = 10;
-
-int sysctl_rose_restart_request_timeout = ROSE_DEFAULT_T0;
-int sysctl_rose_call_request_timeout    = ROSE_DEFAULT_T1;
-int sysctl_rose_reset_request_timeout   = ROSE_DEFAULT_T2;
-int sysctl_rose_clear_request_timeout   = ROSE_DEFAULT_T3;
-int sysctl_rose_no_activity_timeout     = ROSE_DEFAULT_IDLE;
-int sysctl_rose_ack_hold_back_timeout   = ROSE_DEFAULT_HB;
-int sysctl_rose_routing_control         = ROSE_DEFAULT_ROUTING;
-int sysctl_rose_link_fail_timeout       = ROSE_DEFAULT_FAIL_TIMEOUT;
-int sysctl_rose_maximum_vcs             = ROSE_DEFAULT_MAXVC;
-int sysctl_rose_window_size             = ROSE_DEFAULT_WINDOW_SIZE;
-
-static HLIST_HEAD(rose_list);
-static DEFINE_SPINLOCK(rose_list_lock);
-
-static const struct proto_ops rose_proto_ops;
-
-ax25_address rose_callsign;
-
-/*
- * ROSE network devices are virtual network devices encapsulating ROSE
- * frames into AX.25 which will be sent through an AX.25 device, so form a
- * special "super class" of normal net devices; split their locks off into a
- * separate class since they always nest.
- */
-static struct lock_class_key rose_netdev_xmit_lock_key;
-static struct lock_class_key rose_netdev_addr_lock_key;
-
-static void rose_set_lockdep_one(struct net_device *dev,
-				 struct netdev_queue *txq,
-				 void *_unused)
-{
-	lockdep_set_class(&txq->_xmit_lock, &rose_netdev_xmit_lock_key);
-}
-
-static void rose_set_lockdep_key(struct net_device *dev)
-{
-	lockdep_set_class(&dev->addr_list_lock, &rose_netdev_addr_lock_key);
-	netdev_for_each_tx_queue(dev, rose_set_lockdep_one, NULL);
-}
-
-/*
- *	Convert a ROSE address into text.
- */
-char *rose2asc(char *buf, const rose_address *addr)
-{
-	if (addr->rose_addr[0] == 0x00 && addr->rose_addr[1] == 0x00 &&
-	    addr->rose_addr[2] == 0x00 && addr->rose_addr[3] == 0x00 &&
-	    addr->rose_addr[4] == 0x00) {
-		strcpy(buf, "*");
-	} else {
-		sprintf(buf, "%02X%02X%02X%02X%02X", addr->rose_addr[0] & 0xFF,
-						addr->rose_addr[1] & 0xFF,
-						addr->rose_addr[2] & 0xFF,
-						addr->rose_addr[3] & 0xFF,
-						addr->rose_addr[4] & 0xFF);
-	}
-
-	return buf;
-}
-
-/*
- *	Compare two ROSE addresses, 0 == equal.
- */
-int rosecmp(const rose_address *addr1, const rose_address *addr2)
-{
-	int i;
-
-	for (i = 0; i < 5; i++)
-		if (addr1->rose_addr[i] != addr2->rose_addr[i])
-			return 1;
-
-	return 0;
-}
-
-/*
- *	Compare two ROSE addresses for only mask digits, 0 == equal.
- */
-int rosecmpm(const rose_address *addr1, const rose_address *addr2,
-	     unsigned short mask)
-{
-	unsigned int i, j;
-
-	if (mask > 10)
-		return 1;
-
-	for (i = 0; i < mask; i++) {
-		j = i / 2;
-
-		if ((i % 2) != 0) {
-			if ((addr1->rose_addr[j] & 0x0F) != (addr2->rose_addr[j] & 0x0F))
-				return 1;
-		} else {
-			if ((addr1->rose_addr[j] & 0xF0) != (addr2->rose_addr[j] & 0xF0))
-				return 1;
-		}
-	}
-
-	return 0;
-}
-
-/*
- *	Socket removal during an interrupt is now safe.
- */
-static void rose_remove_socket(struct sock *sk)
-{
-	spin_lock_bh(&rose_list_lock);
-	sk_del_node_init(sk);
-	spin_unlock_bh(&rose_list_lock);
-}
-
-/*
- *	Kill all bound sockets on a broken link layer connection to a
- *	particular neighbour.
- */
-void rose_kill_by_neigh(struct rose_neigh *neigh)
-{
-	struct sock *s;
-
-	spin_lock_bh(&rose_list_lock);
-	sk_for_each(s, &rose_list) {
-		struct rose_sock *rose = rose_sk(s);
-
-		if (rose->neighbour == neigh) {
-			rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
-			rose_neigh_put(rose->neighbour);
-			rose->neighbour = NULL;
-		}
-	}
-	spin_unlock_bh(&rose_list_lock);
-}
-
-/*
- *	Kill all bound sockets on a dropped device.
- */
-static void rose_kill_by_device(struct net_device *dev)
-{
-	struct sock *sk, *array[16];
-	struct rose_sock *rose;
-	bool rescan;
-	int i, cnt;
-
-start:
-	rescan = false;
-	cnt = 0;
-	spin_lock_bh(&rose_list_lock);
-	sk_for_each(sk, &rose_list) {
-		rose = rose_sk(sk);
-		if (rose->device == dev) {
-			if (cnt == ARRAY_SIZE(array)) {
-				rescan = true;
-				break;
-			}
-			sock_hold(sk);
-			array[cnt++] = sk;
-		}
-	}
-	spin_unlock_bh(&rose_list_lock);
-
-	for (i = 0; i < cnt; i++) {
-		sk = array[i];
-		rose = rose_sk(sk);
-		lock_sock(sk);
-		spin_lock_bh(&rose_list_lock);
-		if (rose->device == dev) {
-			rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
-			if (rose->neighbour)
-				rose_neigh_put(rose->neighbour);
-			netdev_put(rose->device, &rose->dev_tracker);
-			rose->device = NULL;
-		}
-		spin_unlock_bh(&rose_list_lock);
-		release_sock(sk);
-		sock_put(sk);
-		cond_resched();
-	}
-	if (rescan)
-		goto start;
-}
-
-/*
- *	Handle device status changes.
- */
-static int rose_device_event(struct notifier_block *this,
-			     unsigned long event, void *ptr)
-{
-	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
-
-	if (!net_eq(dev_net(dev), &init_net))
-		return NOTIFY_DONE;
-
-	if (event != NETDEV_DOWN)
-		return NOTIFY_DONE;
-
-	switch (dev->type) {
-	case ARPHRD_ROSE:
-		rose_kill_by_device(dev);
-		break;
-	case ARPHRD_AX25:
-		rose_link_device_down(dev);
-		rose_rt_device_down(dev);
-		break;
-	}
-
-	return NOTIFY_DONE;
-}
-
-/*
- *	Add a socket to the bound sockets list.
- */
-static void rose_insert_socket(struct sock *sk)
-{
-
-	spin_lock_bh(&rose_list_lock);
-	sk_add_node(sk, &rose_list);
-	spin_unlock_bh(&rose_list_lock);
-}
-
-/*
- *	Find a socket that wants to accept the Call Request we just
- *	received.
- */
-static struct sock *rose_find_listener(rose_address *addr, ax25_address *call)
-{
-	struct sock *s;
-
-	spin_lock_bh(&rose_list_lock);
-	sk_for_each(s, &rose_list) {
-		struct rose_sock *rose = rose_sk(s);
-
-		if (!rosecmp(&rose->source_addr, addr) &&
-		    !ax25cmp(&rose->source_call, call) &&
-		    !rose->source_ndigis && s->sk_state == TCP_LISTEN)
-			goto found;
-	}
-
-	sk_for_each(s, &rose_list) {
-		struct rose_sock *rose = rose_sk(s);
-
-		if (!rosecmp(&rose->source_addr, addr) &&
-		    !ax25cmp(&rose->source_call, &null_ax25_address) &&
-		    s->sk_state == TCP_LISTEN)
-			goto found;
-	}
-	s = NULL;
-found:
-	spin_unlock_bh(&rose_list_lock);
-	return s;
-}
-
-/*
- *	Find a connected ROSE socket given my LCI and device.
- */
-struct sock *rose_find_socket(unsigned int lci, struct rose_neigh *neigh)
-{
-	struct sock *s;
-
-	spin_lock_bh(&rose_list_lock);
-	sk_for_each(s, &rose_list) {
-		struct rose_sock *rose = rose_sk(s);
-
-		if (rose->lci == lci && rose->neighbour == neigh)
-			goto found;
-	}
-	s = NULL;
-found:
-	spin_unlock_bh(&rose_list_lock);
-	return s;
-}
-
-/*
- *	Find a unique LCI for a given device.
- */
-unsigned int rose_new_lci(struct rose_neigh *neigh)
-{
-	int lci;
-
-	if (neigh->dce_mode) {
-		for (lci = 1; lci <= sysctl_rose_maximum_vcs; lci++)
-			if (rose_find_socket(lci, neigh) == NULL && rose_route_free_lci(lci, neigh) == NULL)
-				return lci;
-	} else {
-		for (lci = sysctl_rose_maximum_vcs; lci > 0; lci--)
-			if (rose_find_socket(lci, neigh) == NULL && rose_route_free_lci(lci, neigh) == NULL)
-				return lci;
-	}
-
-	return 0;
-}
-
-/*
- *	Deferred destroy.
- */
-void rose_destroy_socket(struct sock *);
-
-/*
- *	Handler for deferred kills.
- */
-static void rose_destroy_timer(struct timer_list *t)
-{
-	struct sock *sk = timer_container_of(sk, t, sk_timer);
-
-	rose_destroy_socket(sk);
-}
-
-/*
- *	This is called from user mode and the timers. Thus it protects itself
- *	against interrupt users but doesn't worry about being called during
- *	work.  Once it is removed from the queue no interrupt or bottom half
- *	will touch it and we are (fairly 8-) ) safe.
- */
-void rose_destroy_socket(struct sock *sk)
-{
-	struct sk_buff *skb;
-
-	rose_remove_socket(sk);
-	rose_stop_heartbeat(sk);
-	rose_stop_idletimer(sk);
-	rose_stop_timer(sk);
-
-	rose_clear_queues(sk);		/* Flush the queues */
-
-	while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
-		if (skb->sk != sk) {	/* A pending connection */
-			/* Queue the unaccepted socket for death */
-			sock_set_flag(skb->sk, SOCK_DEAD);
-			rose_start_heartbeat(skb->sk);
-			rose_sk(skb->sk)->state = ROSE_STATE_0;
-		}
-
-		kfree_skb(skb);
-	}
-
-	if (sk_has_allocations(sk)) {
-		/* Defer: outstanding buffers */
-		timer_setup(&sk->sk_timer, rose_destroy_timer, 0);
-		sk->sk_timer.expires  = jiffies + 10 * HZ;
-		add_timer(&sk->sk_timer);
-	} else
-		sock_put(sk);
-}
-
-/*
- *	Handling for system calls applied via the various interfaces to a
- *	ROSE socket object.
- */
-
-static int rose_setsockopt(struct socket *sock, int level, int optname,
-		sockptr_t optval, unsigned int optlen)
-{
-	struct sock *sk = sock->sk;
-	struct rose_sock *rose = rose_sk(sk);
-	unsigned int opt;
-
-	if (level != SOL_ROSE)
-		return -ENOPROTOOPT;
-
-	if (optlen < sizeof(unsigned int))
-		return -EINVAL;
-
-	if (copy_from_sockptr(&opt, optval, sizeof(unsigned int)))
-		return -EFAULT;
-
-	switch (optname) {
-	case ROSE_DEFER:
-		rose->defer = opt ? 1 : 0;
-		return 0;
-
-	case ROSE_T1:
-		if (opt < 1 || opt > UINT_MAX / HZ)
-			return -EINVAL;
-		rose->t1 = opt * HZ;
-		return 0;
-
-	case ROSE_T2:
-		if (opt < 1 || opt > UINT_MAX / HZ)
-			return -EINVAL;
-		rose->t2 = opt * HZ;
-		return 0;
-
-	case ROSE_T3:
-		if (opt < 1 || opt > UINT_MAX / HZ)
-			return -EINVAL;
-		rose->t3 = opt * HZ;
-		return 0;
-
-	case ROSE_HOLDBACK:
-		if (opt < 1 || opt > UINT_MAX / HZ)
-			return -EINVAL;
-		rose->hb = opt * HZ;
-		return 0;
-
-	case ROSE_IDLE:
-		if (opt > UINT_MAX / (60 * HZ))
-			return -EINVAL;
-		rose->idle = opt * 60 * HZ;
-		return 0;
-
-	case ROSE_QBITINCL:
-		rose->qbitincl = opt ? 1 : 0;
-		return 0;
-
-	default:
-		return -ENOPROTOOPT;
-	}
-}
-
-static int rose_getsockopt(struct socket *sock, int level, int optname,
-	char __user *optval, int __user *optlen)
-{
-	struct sock *sk = sock->sk;
-	struct rose_sock *rose = rose_sk(sk);
-	int val = 0;
-	int len;
-
-	if (level != SOL_ROSE)
-		return -ENOPROTOOPT;
-
-	if (get_user(len, optlen))
-		return -EFAULT;
-
-	if (len < 0)
-		return -EINVAL;
-
-	switch (optname) {
-	case ROSE_DEFER:
-		val = rose->defer;
-		break;
-
-	case ROSE_T1:
-		val = rose->t1 / HZ;
-		break;
-
-	case ROSE_T2:
-		val = rose->t2 / HZ;
-		break;
-
-	case ROSE_T3:
-		val = rose->t3 / HZ;
-		break;
-
-	case ROSE_HOLDBACK:
-		val = rose->hb / HZ;
-		break;
-
-	case ROSE_IDLE:
-		val = rose->idle / (60 * HZ);
-		break;
-
-	case ROSE_QBITINCL:
-		val = rose->qbitincl;
-		break;
-
-	default:
-		return -ENOPROTOOPT;
-	}
-
-	len = min_t(unsigned int, len, sizeof(int));
-
-	if (put_user(len, optlen))
-		return -EFAULT;
-
-	return copy_to_user(optval, &val, len) ? -EFAULT : 0;
-}
-
-static int rose_listen(struct socket *sock, int backlog)
-{
-	struct sock *sk = sock->sk;
-
-	lock_sock(sk);
-	if (sock->state != SS_UNCONNECTED) {
-		release_sock(sk);
-		return -EINVAL;
-	}
-
-	if (sk->sk_state != TCP_LISTEN) {
-		struct rose_sock *rose = rose_sk(sk);
-
-		rose->dest_ndigis = 0;
-		memset(&rose->dest_addr, 0, ROSE_ADDR_LEN);
-		memset(&rose->dest_call, 0, AX25_ADDR_LEN);
-		memset(rose->dest_digis, 0, AX25_ADDR_LEN * ROSE_MAX_DIGIS);
-		sk->sk_max_ack_backlog = backlog;
-		sk->sk_state           = TCP_LISTEN;
-		release_sock(sk);
-		return 0;
-	}
-	release_sock(sk);
-
-	return -EOPNOTSUPP;
-}
-
-static struct proto rose_proto = {
-	.name	  = "ROSE",
-	.owner	  = THIS_MODULE,
-	.obj_size = sizeof(struct rose_sock),
-};
-
-static int rose_create(struct net *net, struct socket *sock, int protocol,
-		       int kern)
-{
-	struct sock *sk;
-	struct rose_sock *rose;
-
-	if (!net_eq(net, &init_net))
-		return -EAFNOSUPPORT;
-
-	if (sock->type != SOCK_SEQPACKET || protocol != 0)
-		return -ESOCKTNOSUPPORT;
-
-	sk = sk_alloc(net, PF_ROSE, GFP_ATOMIC, &rose_proto, kern);
-	if (sk == NULL)
-		return -ENOMEM;
-
-	rose = rose_sk(sk);
-
-	sock_init_data(sock, sk);
-
-	skb_queue_head_init(&rose->ack_queue);
-#ifdef M_BIT
-	skb_queue_head_init(&rose->frag_queue);
-	rose->fraglen    = 0;
-#endif
-
-	sock->ops    = &rose_proto_ops;
-	sk->sk_protocol = protocol;
-
-	timer_setup(&rose->timer, NULL, 0);
-	timer_setup(&rose->idletimer, NULL, 0);
-
-	rose->t1   = msecs_to_jiffies(sysctl_rose_call_request_timeout);
-	rose->t2   = msecs_to_jiffies(sysctl_rose_reset_request_timeout);
-	rose->t3   = msecs_to_jiffies(sysctl_rose_clear_request_timeout);
-	rose->hb   = msecs_to_jiffies(sysctl_rose_ack_hold_back_timeout);
-	rose->idle = msecs_to_jiffies(sysctl_rose_no_activity_timeout);
-
-	rose->state = ROSE_STATE_0;
-
-	return 0;
-}
-
-static struct sock *rose_make_new(struct sock *osk)
-{
-	struct sock *sk;
-	struct rose_sock *rose, *orose;
-
-	if (osk->sk_type != SOCK_SEQPACKET)
-		return NULL;
-
-	sk = sk_alloc(sock_net(osk), PF_ROSE, GFP_ATOMIC, &rose_proto, 0);
-	if (sk == NULL)
-		return NULL;
-
-	rose = rose_sk(sk);
-
-	sock_init_data(NULL, sk);
-
-	skb_queue_head_init(&rose->ack_queue);
-#ifdef M_BIT
-	skb_queue_head_init(&rose->frag_queue);
-	rose->fraglen  = 0;
-#endif
-
-	sk->sk_type     = osk->sk_type;
-	sk->sk_priority = READ_ONCE(osk->sk_priority);
-	sk->sk_protocol = osk->sk_protocol;
-	sk->sk_rcvbuf   = osk->sk_rcvbuf;
-	sk->sk_sndbuf   = osk->sk_sndbuf;
-	sk->sk_state    = TCP_ESTABLISHED;
-	sock_copy_flags(sk, osk);
-
-	timer_setup(&rose->timer, NULL, 0);
-	timer_setup(&rose->idletimer, NULL, 0);
-
-	orose		= rose_sk(osk);
-	rose->t1	= orose->t1;
-	rose->t2	= orose->t2;
-	rose->t3	= orose->t3;
-	rose->hb	= orose->hb;
-	rose->idle	= orose->idle;
-	rose->defer	= orose->defer;
-	rose->device	= orose->device;
-	if (rose->device)
-		netdev_hold(rose->device, &rose->dev_tracker, GFP_ATOMIC);
-	rose->qbitincl	= orose->qbitincl;
-
-	return sk;
-}
-
-static int rose_release(struct socket *sock)
-{
-	struct sock *sk = sock->sk;
-	struct rose_sock *rose;
-
-	if (sk == NULL) return 0;
-
-	sock_hold(sk);
-	sock_orphan(sk);
-	lock_sock(sk);
-	rose = rose_sk(sk);
-
-	switch (rose->state) {
-	case ROSE_STATE_0:
-		release_sock(sk);
-		rose_disconnect(sk, 0, -1, -1);
-		lock_sock(sk);
-		rose_destroy_socket(sk);
-		break;
-
-	case ROSE_STATE_2:
-		rose_neigh_put(rose->neighbour);
-		release_sock(sk);
-		rose_disconnect(sk, 0, -1, -1);
-		lock_sock(sk);
-		rose_destroy_socket(sk);
-		break;
-
-	case ROSE_STATE_1:
-	case ROSE_STATE_3:
-	case ROSE_STATE_4:
-	case ROSE_STATE_5:
-		rose_clear_queues(sk);
-		rose_stop_idletimer(sk);
-		rose_write_internal(sk, ROSE_CLEAR_REQUEST);
-		rose_start_t3timer(sk);
-		rose->state  = ROSE_STATE_2;
-		sk->sk_state    = TCP_CLOSE;
-		sk->sk_shutdown |= SEND_SHUTDOWN;
-		sk->sk_state_change(sk);
-		sock_set_flag(sk, SOCK_DEAD);
-		sock_set_flag(sk, SOCK_DESTROY);
-		break;
-
-	default:
-		break;
-	}
-
-	spin_lock_bh(&rose_list_lock);
-	netdev_put(rose->device, &rose->dev_tracker);
-	rose->device = NULL;
-	spin_unlock_bh(&rose_list_lock);
-	sock->sk = NULL;
-	release_sock(sk);
-	sock_put(sk);
-
-	return 0;
-}
-
-static int rose_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int addr_len)
-{
-	struct sock *sk = sock->sk;
-	struct rose_sock *rose = rose_sk(sk);
-	struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr;
-	struct net_device *dev;
-	ax25_address *source;
-	ax25_uid_assoc *user;
-	int err = -EINVAL;
-	int n;
-
-	if (addr_len != sizeof(struct sockaddr_rose) && addr_len != sizeof(struct full_sockaddr_rose))
-		return -EINVAL;
-
-	if (addr->srose_family != AF_ROSE)
-		return -EINVAL;
-
-	if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1)
-		return -EINVAL;
-
-	if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS)
-		return -EINVAL;
-
-	lock_sock(sk);
-
-	if (!sock_flag(sk, SOCK_ZAPPED))
-		goto out_release;
-
-	err = -EADDRNOTAVAIL;
-	dev = rose_dev_get(&addr->srose_addr);
-	if (!dev)
-		goto out_release;
-
-	source = &addr->srose_call;
-
-	user = ax25_findbyuid(current_euid());
-	if (user) {
-		rose->source_call = user->call;
-		ax25_uid_put(user);
-	} else {
-		if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) {
-			dev_put(dev);
-			err = -EACCES;
-			goto out_release;
-		}
-		rose->source_call   = *source;
-	}
-
-	rose->source_addr   = addr->srose_addr;
-	rose->device        = dev;
-	netdev_tracker_alloc(rose->device, &rose->dev_tracker, GFP_KERNEL);
-	rose->source_ndigis = addr->srose_ndigis;
-
-	if (addr_len == sizeof(struct full_sockaddr_rose)) {
-		struct full_sockaddr_rose *full_addr = (struct full_sockaddr_rose *)uaddr;
-		for (n = 0 ; n < addr->srose_ndigis ; n++)
-			rose->source_digis[n] = full_addr->srose_digis[n];
-	} else {
-		if (rose->source_ndigis == 1) {
-			rose->source_digis[0] = addr->srose_digi;
-		}
-	}
-
-	rose_insert_socket(sk);
-
-	sock_reset_flag(sk, SOCK_ZAPPED);
-	err = 0;
-out_release:
-	release_sock(sk);
-	return err;
-}
-
-static int rose_connect(struct socket *sock, struct sockaddr_unsized *uaddr, int addr_len,
-			int flags)
-{
-	struct sock *sk = sock->sk;
-	struct rose_sock *rose = rose_sk(sk);
-	struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr;
-	unsigned char cause, diagnostic;
-	ax25_uid_assoc *user;
-	int n, err = 0;
-
-	if (addr_len != sizeof(struct sockaddr_rose) && addr_len != sizeof(struct full_sockaddr_rose))
-		return -EINVAL;
-
-	if (addr->srose_family != AF_ROSE)
-		return -EINVAL;
-
-	if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1)
-		return -EINVAL;
-
-	if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS)
-		return -EINVAL;
-
-	/* Source + Destination digis should not exceed ROSE_MAX_DIGIS */
-	if ((rose->source_ndigis + addr->srose_ndigis) > ROSE_MAX_DIGIS)
-		return -EINVAL;
-
-	lock_sock(sk);
-
-	if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
-		/* Connect completed during a ERESTARTSYS event */
-		sock->state = SS_CONNECTED;
-		goto out_release;
-	}
-
-	if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) {
-		sock->state = SS_UNCONNECTED;
-		err = -ECONNREFUSED;
-		goto out_release;
-	}
-
-	if (sk->sk_state == TCP_ESTABLISHED) {
-		/* No reconnect on a seqpacket socket */
-		err = -EISCONN;
-		goto out_release;
-	}
-
-	if (sk->sk_state == TCP_SYN_SENT) {
-		err = -EALREADY;
-		goto out_release;
-	}
-
-	sk->sk_state   = TCP_CLOSE;
-	sock->state = SS_UNCONNECTED;
-
-	rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause,
-					 &diagnostic, 0);
-	if (!rose->neighbour) {
-		err = -ENETUNREACH;
-		goto out_release;
-	}
-
-	rose->lci = rose_new_lci(rose->neighbour);
-	if (!rose->lci) {
-		err = -ENETUNREACH;
-		rose_neigh_put(rose->neighbour);
-		goto out_release;
-	}
-
-	if (sock_flag(sk, SOCK_ZAPPED)) {	/* Must bind first - autobinding in this may or may not work */
-		struct net_device *dev;
-
-		sock_reset_flag(sk, SOCK_ZAPPED);
-
-		dev = rose_dev_first();
-		if (!dev) {
-			err = -ENETUNREACH;
-			rose_neigh_put(rose->neighbour);
-			goto out_release;
-		}
-
-		user = ax25_findbyuid(current_euid());
-		if (!user) {
-			err = -EINVAL;
-			rose_neigh_put(rose->neighbour);
-			dev_put(dev);
-			goto out_release;
-		}
-
-		memcpy(&rose->source_addr, dev->dev_addr, ROSE_ADDR_LEN);
-		rose->source_call = user->call;
-		rose->device      = dev;
-		netdev_tracker_alloc(rose->device, &rose->dev_tracker,
-				     GFP_KERNEL);
-		ax25_uid_put(user);
-
-		rose_insert_socket(sk);		/* Finish the bind */
-	}
-	rose->dest_addr   = addr->srose_addr;
-	rose->dest_call   = addr->srose_call;
-	rose->rand        = ((long)rose & 0xFFFF) + rose->lci;
-	rose->dest_ndigis = addr->srose_ndigis;
-
-	if (addr_len == sizeof(struct full_sockaddr_rose)) {
-		struct full_sockaddr_rose *full_addr = (struct full_sockaddr_rose *)uaddr;
-		for (n = 0 ; n < addr->srose_ndigis ; n++)
-			rose->dest_digis[n] = full_addr->srose_digis[n];
-	} else {
-		if (rose->dest_ndigis == 1) {
-			rose->dest_digis[0] = addr->srose_digi;
-		}
-	}
-
-	/* Move to connecting socket, start sending Connect Requests */
-	sock->state   = SS_CONNECTING;
-	sk->sk_state     = TCP_SYN_SENT;
-
-	rose->state = ROSE_STATE_1;
-
-	rose_write_internal(sk, ROSE_CALL_REQUEST);
-	rose_start_heartbeat(sk);
-	rose_start_t1timer(sk);
-
-	/* Now the loop */
-	if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) {
-		err = -EINPROGRESS;
-		goto out_release;
-	}
-
-	/*
-	 * A Connect Ack with Choke or timeout or failed routing will go to
-	 * closed.
-	 */
-	if (sk->sk_state == TCP_SYN_SENT) {
-		DEFINE_WAIT(wait);
-
-		for (;;) {
-			prepare_to_wait(sk_sleep(sk), &wait,
-					TASK_INTERRUPTIBLE);
-			if (sk->sk_state != TCP_SYN_SENT)
-				break;
-			if (!signal_pending(current)) {
-				release_sock(sk);
-				schedule();
-				lock_sock(sk);
-				continue;
-			}
-			err = -ERESTARTSYS;
-			break;
-		}
-		finish_wait(sk_sleep(sk), &wait);
-
-		if (err)
-			goto out_release;
-	}
-
-	if (sk->sk_state != TCP_ESTABLISHED) {
-		sock->state = SS_UNCONNECTED;
-		err = sock_error(sk);	/* Always set at this point */
-		goto out_release;
-	}
-
-	sock->state = SS_CONNECTED;
-
-out_release:
-	release_sock(sk);
-
-	return err;
-}
-
-static int rose_accept(struct socket *sock, struct socket *newsock,
-		       struct proto_accept_arg *arg)
-{
-	struct sk_buff *skb;
-	struct sock *newsk;
-	DEFINE_WAIT(wait);
-	struct sock *sk;
-	int err = 0;
-
-	if ((sk = sock->sk) == NULL)
-		return -EINVAL;
-
-	lock_sock(sk);
-	if (sk->sk_type != SOCK_SEQPACKET) {
-		err = -EOPNOTSUPP;
-		goto out_release;
-	}
-
-	if (sk->sk_state != TCP_LISTEN) {
-		err = -EINVAL;
-		goto out_release;
-	}
-
-	/*
-	 *	The write queue this time is holding sockets ready to use
-	 *	hooked into the SABM we saved
-	 */
-	for (;;) {
-		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
-
-		skb = skb_dequeue(&sk->sk_receive_queue);
-		if (skb)
-			break;
-
-		if (arg->flags & O_NONBLOCK) {
-			err = -EWOULDBLOCK;
-			break;
-		}
-		if (!signal_pending(current)) {
-			release_sock(sk);
-			schedule();
-			lock_sock(sk);
-			continue;
-		}
-		err = -ERESTARTSYS;
-		break;
-	}
-	finish_wait(sk_sleep(sk), &wait);
-	if (err)
-		goto out_release;
-
-	newsk = skb->sk;
-	sock_graft(newsk, newsock);
-
-	/* Now attach up the new socket */
-	skb->sk = NULL;
-	kfree_skb(skb);
-	sk_acceptq_removed(sk);
-
-out_release:
-	release_sock(sk);
-
-	return err;
-}
-
-static int rose_getname(struct socket *sock, struct sockaddr *uaddr,
-	int peer)
-{
-	struct full_sockaddr_rose *srose = (struct full_sockaddr_rose *)uaddr;
-	struct sock *sk = sock->sk;
-	struct rose_sock *rose = rose_sk(sk);
-	int n;
-
-	memset(srose, 0, sizeof(*srose));
-	if (peer != 0) {
-		if (sk->sk_state != TCP_ESTABLISHED)
-			return -ENOTCONN;
-		srose->srose_family = AF_ROSE;
-		srose->srose_addr   = rose->dest_addr;
-		srose->srose_call   = rose->dest_call;
-		srose->srose_ndigis = rose->dest_ndigis;
-		for (n = 0; n < rose->dest_ndigis; n++)
-			srose->srose_digis[n] = rose->dest_digis[n];
-	} else {
-		srose->srose_family = AF_ROSE;
-		srose->srose_addr   = rose->source_addr;
-		srose->srose_call   = rose->source_call;
-		srose->srose_ndigis = rose->source_ndigis;
-		for (n = 0; n < rose->source_ndigis; n++)
-			srose->srose_digis[n] = rose->source_digis[n];
-	}
-
-	return sizeof(struct full_sockaddr_rose);
-}
-
-int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct rose_neigh *neigh, unsigned int lci)
-{
-	struct sock *sk;
-	struct sock *make;
-	struct rose_sock *make_rose;
-	struct rose_facilities_struct facilities;
-	int n;
-
-	skb->sk = NULL;		/* Initially we don't know who it's for */
-
-	/*
-	 *	skb->data points to the rose frame start
-	 */
-	memset(&facilities, 0x00, sizeof(struct rose_facilities_struct));
-
-	if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF,
-				   skb->len - ROSE_CALL_REQ_FACILITIES_OFF,
-				   &facilities)) {
-		rose_transmit_clear_request(neigh, lci, ROSE_INVALID_FACILITY, 76);
-		return 0;
-	}
-
-	sk = rose_find_listener(&facilities.source_addr, &facilities.source_call);
-
-	/*
-	 * We can't accept the Call Request.
-	 */
-	if (sk == NULL || sk_acceptq_is_full(sk) ||
-	    (make = rose_make_new(sk)) == NULL) {
-		rose_transmit_clear_request(neigh, lci, ROSE_NETWORK_CONGESTION, 120);
-		return 0;
-	}
-
-	skb->sk     = make;
-	make->sk_state = TCP_ESTABLISHED;
-	make_rose = rose_sk(make);
-
-	make_rose->lci           = lci;
-	make_rose->dest_addr     = facilities.dest_addr;
-	make_rose->dest_call     = facilities.dest_call;
-	make_rose->dest_ndigis   = facilities.dest_ndigis;
-	for (n = 0 ; n < facilities.dest_ndigis ; n++)
-		make_rose->dest_digis[n] = facilities.dest_digis[n];
-	make_rose->source_addr   = facilities.source_addr;
-	make_rose->source_call   = facilities.source_call;
-	make_rose->source_ndigis = facilities.source_ndigis;
-	for (n = 0 ; n < facilities.source_ndigis ; n++)
-		make_rose->source_digis[n] = facilities.source_digis[n];
-	make_rose->neighbour     = neigh;
-	make_rose->device        = dev;
-	/* Caller got a reference for us. */
-	netdev_tracker_alloc(make_rose->device, &make_rose->dev_tracker,
-			     GFP_ATOMIC);
-	make_rose->facilities    = facilities;
-
-	rose_neigh_hold(make_rose->neighbour);
-
-	if (rose_sk(sk)->defer) {
-		make_rose->state = ROSE_STATE_5;
-	} else {
-		rose_write_internal(make, ROSE_CALL_ACCEPTED);
-		make_rose->state = ROSE_STATE_3;
-		rose_start_idletimer(make);
-	}
-
-	make_rose->condition = 0x00;
-	make_rose->vs        = 0;
-	make_rose->va        = 0;
-	make_rose->vr        = 0;
-	make_rose->vl        = 0;
-	sk_acceptq_added(sk);
-
-	rose_insert_socket(make);
-
-	skb_queue_head(&sk->sk_receive_queue, skb);
-
-	rose_start_heartbeat(make);
-
-	if (!sock_flag(sk, SOCK_DEAD))
-		sk->sk_data_ready(sk);
-
-	return 1;
-}
-
-static int rose_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
-{
-	struct sock *sk = sock->sk;
-	struct rose_sock *rose = rose_sk(sk);
-	DECLARE_SOCKADDR(struct sockaddr_rose *, usrose, msg->msg_name);
-	int err;
-	struct full_sockaddr_rose srose;
-	struct sk_buff *skb;
-	unsigned char *asmptr;
-	int n, size, qbit = 0;
-
-	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
-		return -EINVAL;
-
-	if (sock_flag(sk, SOCK_ZAPPED))
-		return -EADDRNOTAVAIL;
-
-	if (sk->sk_shutdown & SEND_SHUTDOWN) {
-		send_sig(SIGPIPE, current, 0);
-		return -EPIPE;
-	}
-
-	if (rose->neighbour == NULL || rose->device == NULL)
-		return -ENETUNREACH;
-
-	if (usrose != NULL) {
-		if (msg->msg_namelen != sizeof(struct sockaddr_rose) && msg->msg_namelen != sizeof(struct full_sockaddr_rose))
-			return -EINVAL;
-		memset(&srose, 0, sizeof(struct full_sockaddr_rose));
-		memcpy(&srose, usrose, msg->msg_namelen);
-		if (rosecmp(&rose->dest_addr, &srose.srose_addr) != 0 ||
-		    ax25cmp(&rose->dest_call, &srose.srose_call) != 0)
-			return -EISCONN;
-		if (srose.srose_ndigis != rose->dest_ndigis)
-			return -EISCONN;
-		if (srose.srose_ndigis == rose->dest_ndigis) {
-			for (n = 0 ; n < srose.srose_ndigis ; n++)
-				if (ax25cmp(&rose->dest_digis[n],
-					    &srose.srose_digis[n]))
-					return -EISCONN;
-		}
-		if (srose.srose_family != AF_ROSE)
-			return -EINVAL;
-	} else {
-		if (sk->sk_state != TCP_ESTABLISHED)
-			return -ENOTCONN;
-
-		srose.srose_family = AF_ROSE;
-		srose.srose_addr   = rose->dest_addr;
-		srose.srose_call   = rose->dest_call;
-		srose.srose_ndigis = rose->dest_ndigis;
-		for (n = 0 ; n < rose->dest_ndigis ; n++)
-			srose.srose_digis[n] = rose->dest_digis[n];
-	}
-
-	/* Build a packet */
-	/* Sanity check the packet size */
-	if (len > 65535)
-		return -EMSGSIZE;
-
-	size = len + AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN;
-
-	if ((skb = sock_alloc_send_skb(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL)
-		return err;
-
-	skb_reserve(skb, AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN);
-
-	/*
-	 *	Put the data on the end
-	 */
-
-	skb_reset_transport_header(skb);
-	skb_put(skb, len);
-
-	err = memcpy_from_msg(skb_transport_header(skb), msg, len);
-	if (err) {
-		kfree_skb(skb);
-		return err;
-	}
-
-	/*
-	 *	If the Q BIT Include socket option is in force, the first
-	 *	byte of the user data is the logical value of the Q Bit.
-	 */
-	if (rose->qbitincl) {
-		qbit = skb->data[0];
-		skb_pull(skb, 1);
-	}
-
-	/*
-	 *	Push down the ROSE header
-	 */
-	asmptr = skb_push(skb, ROSE_MIN_LEN);
-
-	/* Build a ROSE Network header */
-	asmptr[0] = ((rose->lci >> 8) & 0x0F) | ROSE_GFI;
-	asmptr[1] = (rose->lci >> 0) & 0xFF;
-	asmptr[2] = ROSE_DATA;
-
-	if (qbit)
-		asmptr[0] |= ROSE_Q_BIT;
-
-	if (sk->sk_state != TCP_ESTABLISHED) {
-		kfree_skb(skb);
-		return -ENOTCONN;
-	}
-
-#ifdef M_BIT
-#define ROSE_PACLEN (256-ROSE_MIN_LEN)
-	if (skb->len - ROSE_MIN_LEN > ROSE_PACLEN) {
-		unsigned char header[ROSE_MIN_LEN];
-		struct sk_buff *skbn;
-		int frontlen;
-		int lg;
-
-		/* Save a copy of the Header */
-		skb_copy_from_linear_data(skb, header, ROSE_MIN_LEN);
-		skb_pull(skb, ROSE_MIN_LEN);
-
-		frontlen = skb_headroom(skb);
-
-		while (skb->len > 0) {
-			if ((skbn = sock_alloc_send_skb(sk, frontlen + ROSE_PACLEN, 0, &err)) == NULL) {
-				kfree_skb(skb);
-				return err;
-			}
-
-			skbn->sk   = sk;
-			skbn->free = 1;
-			skbn->arp  = 1;
-
-			skb_reserve(skbn, frontlen);
-
-			lg = (ROSE_PACLEN > skb->len) ? skb->len : ROSE_PACLEN;
-
-			/* Copy the user data */
-			skb_copy_from_linear_data(skb, skb_put(skbn, lg), lg);
-			skb_pull(skb, lg);
-
-			/* Duplicate the Header */
-			skb_push(skbn, ROSE_MIN_LEN);
-			skb_copy_to_linear_data(skbn, header, ROSE_MIN_LEN);
-
-			if (skb->len > 0)
-				skbn->data[2] |= M_BIT;
-
-			skb_queue_tail(&sk->sk_write_queue, skbn); /* Throw it on the queue */
-		}
-
-		skb->free = 1;
-		kfree_skb(skb);
-	} else {
-		skb_queue_tail(&sk->sk_write_queue, skb);		/* Throw it on the queue */
-	}
-#else
-	skb_queue_tail(&sk->sk_write_queue, skb);	/* Shove it onto the queue */
-#endif
-
-	rose_kick(sk);
-
-	return len;
-}
-
-
-static int rose_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
-			int flags)
-{
-	struct sock *sk = sock->sk;
-	struct rose_sock *rose = rose_sk(sk);
-	size_t copied;
-	unsigned char *asmptr;
-	struct sk_buff *skb;
-	int n, er, qbit;
-
-	/*
-	 * This works for seqpacket too. The receiver has ordered the queue for
-	 * us! We do one quick check first though
-	 */
-	if (sk->sk_state != TCP_ESTABLISHED)
-		return -ENOTCONN;
-
-	/* Now we can treat all alike */
-	skb = skb_recv_datagram(sk, flags, &er);
-	if (!skb)
-		return er;
-
-	qbit = (skb->data[0] & ROSE_Q_BIT) == ROSE_Q_BIT;
-
-	skb_pull(skb, ROSE_MIN_LEN);
-
-	if (rose->qbitincl) {
-		asmptr  = skb_push(skb, 1);
-		*asmptr = qbit;
-	}
-
-	skb_reset_transport_header(skb);
-	copied     = skb->len;
-
-	if (copied > size) {
-		copied = size;
-		msg->msg_flags |= MSG_TRUNC;
-	}
-
-	skb_copy_datagram_msg(skb, 0, msg, copied);
-
-	if (msg->msg_name) {
-		struct sockaddr_rose *srose;
-		DECLARE_SOCKADDR(struct full_sockaddr_rose *, full_srose,
-				 msg->msg_name);
-
-		memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose));
-		srose = msg->msg_name;
-		srose->srose_family = AF_ROSE;
-		srose->srose_addr   = rose->dest_addr;
-		srose->srose_call   = rose->dest_call;
-		srose->srose_ndigis = rose->dest_ndigis;
-		for (n = 0 ; n < rose->dest_ndigis ; n++)
-			full_srose->srose_digis[n] = rose->dest_digis[n];
-		msg->msg_namelen = sizeof(struct full_sockaddr_rose);
-	}
-
-	skb_free_datagram(sk, skb);
-
-	return copied;
-}
-
-
-static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
-	struct sock *sk = sock->sk;
-	struct rose_sock *rose = rose_sk(sk);
-	void __user *argp = (void __user *)arg;
-
-	switch (cmd) {
-	case TIOCOUTQ: {
-		long amount;
-
-		amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
-		if (amount < 0)
-			amount = 0;
-		return put_user(amount, (unsigned int __user *) argp);
-	}
-
-	case TIOCINQ: {
-		struct sk_buff *skb;
-		long amount = 0L;
-
-		spin_lock_irq(&sk->sk_receive_queue.lock);
-		if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
-			amount = skb->len;
-		spin_unlock_irq(&sk->sk_receive_queue.lock);
-		return put_user(amount, (unsigned int __user *) argp);
-	}
-
-	case SIOCGIFADDR:
-	case SIOCSIFADDR:
-	case SIOCGIFDSTADDR:
-	case SIOCSIFDSTADDR:
-	case SIOCGIFBRDADDR:
-	case SIOCSIFBRDADDR:
-	case SIOCGIFNETMASK:
-	case SIOCSIFNETMASK:
-	case SIOCGIFMETRIC:
-	case SIOCSIFMETRIC:
-		return -EINVAL;
-
-	case SIOCADDRT:
-	case SIOCDELRT:
-	case SIOCRSCLRRT:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		return rose_rt_ioctl(cmd, argp);
-
-	case SIOCRSGCAUSE: {
-		struct rose_cause_struct rose_cause;
-		rose_cause.cause      = rose->cause;
-		rose_cause.diagnostic = rose->diagnostic;
-		return copy_to_user(argp, &rose_cause, sizeof(struct rose_cause_struct)) ? -EFAULT : 0;
-	}
-
-	case SIOCRSSCAUSE: {
-		struct rose_cause_struct rose_cause;
-		if (copy_from_user(&rose_cause, argp, sizeof(struct rose_cause_struct)))
-			return -EFAULT;
-		rose->cause      = rose_cause.cause;
-		rose->diagnostic = rose_cause.diagnostic;
-		return 0;
-	}
-
-	case SIOCRSSL2CALL:
-		if (!capable(CAP_NET_ADMIN)) return -EPERM;
-		if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
-			ax25_listen_release(&rose_callsign, NULL);
-		if (copy_from_user(&rose_callsign, argp, sizeof(ax25_address)))
-			return -EFAULT;
-		if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
-			return ax25_listen_register(&rose_callsign, NULL);
-
-		return 0;
-
-	case SIOCRSGL2CALL:
-		return copy_to_user(argp, &rose_callsign, sizeof(ax25_address)) ? -EFAULT : 0;
-
-	case SIOCRSACCEPT:
-		if (rose->state == ROSE_STATE_5) {
-			rose_write_internal(sk, ROSE_CALL_ACCEPTED);
-			rose_start_idletimer(sk);
-			rose->condition = 0x00;
-			rose->vs        = 0;
-			rose->va        = 0;
-			rose->vr        = 0;
-			rose->vl        = 0;
-			rose->state     = ROSE_STATE_3;
-		}
-		return 0;
-
-	default:
-		return -ENOIOCTLCMD;
-	}
-
-	return 0;
-}
-
-#ifdef CONFIG_PROC_FS
-static void *rose_info_start(struct seq_file *seq, loff_t *pos)
-	__acquires(rose_list_lock)
-{
-	spin_lock_bh(&rose_list_lock);
-	return seq_hlist_start_head(&rose_list, *pos);
-}
-
-static void *rose_info_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	return seq_hlist_next(v, &rose_list, pos);
-}
-
-static void rose_info_stop(struct seq_file *seq, void *v)
-	__releases(rose_list_lock)
-{
-	spin_unlock_bh(&rose_list_lock);
-}
-
-static int rose_info_show(struct seq_file *seq, void *v)
-{
-	char buf[11], rsbuf[11];
-
-	if (v == SEQ_START_TOKEN)
-		seq_puts(seq,
-			 "dest_addr  dest_call src_addr   src_call  dev   lci neigh st vs vr va   t  t1  t2  t3  hb    idle Snd-Q Rcv-Q inode\n");
-
-	else {
-		struct sock *s = sk_entry(v);
-		struct rose_sock *rose = rose_sk(s);
-		const char *devname, *callsign;
-		const struct net_device *dev = rose->device;
-
-		if (!dev)
-			devname = "???";
-		else
-			devname = dev->name;
-
-		seq_printf(seq, "%-10s %-9s ",
-			   rose2asc(rsbuf, &rose->dest_addr),
-			   ax2asc(buf, &rose->dest_call));
-
-		if (ax25cmp(&rose->source_call, &null_ax25_address) == 0)
-			callsign = "??????-?";
-		else
-			callsign = ax2asc(buf, &rose->source_call);
-
-		seq_printf(seq,
-			   "%-10s %-9s %-5s %3.3X %05d  %d  %d  %d  %d %3lu %3lu %3lu %3lu %3lu %3lu/%03lu %5d %5d %llu\n",
-			rose2asc(rsbuf, &rose->source_addr),
-			callsign,
-			devname,
-			rose->lci & 0x0FFF,
-			(rose->neighbour) ? rose->neighbour->number : 0,
-			rose->state,
-			rose->vs,
-			rose->vr,
-			rose->va,
-			ax25_display_timer(&rose->timer) / HZ,
-			rose->t1 / HZ,
-			rose->t2 / HZ,
-			rose->t3 / HZ,
-			rose->hb / HZ,
-			ax25_display_timer(&rose->idletimer) / (60 * HZ),
-			rose->idle / (60 * HZ),
-			sk_wmem_alloc_get(s),
-			sk_rmem_alloc_get(s),
-			s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : (u64)0);
-	}
-
-	return 0;
-}
-
-static const struct seq_operations rose_info_seqops = {
-	.start = rose_info_start,
-	.next = rose_info_next,
-	.stop = rose_info_stop,
-	.show = rose_info_show,
-};
-#endif	/* CONFIG_PROC_FS */
-
-static const struct net_proto_family rose_family_ops = {
-	.family		=	PF_ROSE,
-	.create		=	rose_create,
-	.owner		=	THIS_MODULE,
-};
-
-static const struct proto_ops rose_proto_ops = {
-	.family		=	PF_ROSE,
-	.owner		=	THIS_MODULE,
-	.release	=	rose_release,
-	.bind		=	rose_bind,
-	.connect	=	rose_connect,
-	.socketpair	=	sock_no_socketpair,
-	.accept		=	rose_accept,
-	.getname	=	rose_getname,
-	.poll		=	datagram_poll,
-	.ioctl		=	rose_ioctl,
-	.gettstamp	=	sock_gettstamp,
-	.listen		=	rose_listen,
-	.shutdown	=	sock_no_shutdown,
-	.setsockopt	=	rose_setsockopt,
-	.getsockopt	=	rose_getsockopt,
-	.sendmsg	=	rose_sendmsg,
-	.recvmsg	=	rose_recvmsg,
-	.mmap		=	sock_no_mmap,
-};
-
-static struct notifier_block rose_dev_notifier = {
-	.notifier_call	=	rose_device_event,
-};
-
-static struct net_device **dev_rose;
-
-static struct ax25_protocol rose_pid = {
-	.pid	= AX25_P_ROSE,
-	.func	= rose_route_frame
-};
-
-static struct ax25_linkfail rose_linkfail_notifier = {
-	.func	= rose_link_failed
-};
-
-static int __init rose_proto_init(void)
-{
-	int i;
-	int rc;
-
-	if (rose_ndevs > 0x7FFFFFFF/sizeof(struct net_device *)) {
-		printk(KERN_ERR "ROSE: rose_proto_init - rose_ndevs parameter too large\n");
-		rc = -EINVAL;
-		goto out;
-	}
-
-	rc = proto_register(&rose_proto, 0);
-	if (rc != 0)
-		goto out;
-
-	rose_callsign = null_ax25_address;
-
-	dev_rose = kzalloc_objs(struct net_device *, rose_ndevs);
-	if (dev_rose == NULL) {
-		printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate device structure\n");
-		rc = -ENOMEM;
-		goto out_proto_unregister;
-	}
-
-	for (i = 0; i < rose_ndevs; i++) {
-		struct net_device *dev;
-		char name[IFNAMSIZ];
-
-		sprintf(name, "rose%d", i);
-		dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, rose_setup);
-		if (!dev) {
-			printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate memory\n");
-			rc = -ENOMEM;
-			goto fail;
-		}
-		rc = register_netdev(dev);
-		if (rc) {
-			printk(KERN_ERR "ROSE: netdevice registration failed\n");
-			free_netdev(dev);
-			goto fail;
-		}
-		rose_set_lockdep_key(dev);
-		dev_rose[i] = dev;
-	}
-
-	sock_register(&rose_family_ops);
-	register_netdevice_notifier(&rose_dev_notifier);
-
-	ax25_register_pid(&rose_pid);
-	ax25_linkfail_register(&rose_linkfail_notifier);
-
-#ifdef CONFIG_SYSCTL
-	rose_register_sysctl();
-#endif
-	rose_loopback_init();
-
-	rose_add_loopback_neigh();
-
-	proc_create_seq("rose", 0444, init_net.proc_net, &rose_info_seqops);
-	proc_create_seq("rose_neigh", 0444, init_net.proc_net,
-		    &rose_neigh_seqops);
-	proc_create_seq("rose_nodes", 0444, init_net.proc_net,
-		    &rose_node_seqops);
-	proc_create_seq("rose_routes", 0444, init_net.proc_net,
-		    &rose_route_seqops);
-out:
-	return rc;
-fail:
-	while (--i >= 0) {
-		unregister_netdev(dev_rose[i]);
-		free_netdev(dev_rose[i]);
-	}
-	kfree(dev_rose);
-out_proto_unregister:
-	proto_unregister(&rose_proto);
-	goto out;
-}
-module_init(rose_proto_init);
-
-module_param(rose_ndevs, int, 0);
-MODULE_PARM_DESC(rose_ndevs, "number of ROSE devices");
-
-MODULE_AUTHOR("Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>");
-MODULE_DESCRIPTION("The amateur radio ROSE network layer protocol");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_NETPROTO(PF_ROSE);
-
-static void __exit rose_exit(void)
-{
-	int i;
-
-	remove_proc_entry("rose", init_net.proc_net);
-	remove_proc_entry("rose_neigh", init_net.proc_net);
-	remove_proc_entry("rose_nodes", init_net.proc_net);
-	remove_proc_entry("rose_routes", init_net.proc_net);
-	rose_loopback_clear();
-
-	rose_rt_free();
-
-	ax25_protocol_release(AX25_P_ROSE);
-	ax25_linkfail_release(&rose_linkfail_notifier);
-
-	if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
-		ax25_listen_release(&rose_callsign, NULL);
-
-#ifdef CONFIG_SYSCTL
-	rose_unregister_sysctl();
-#endif
-	unregister_netdevice_notifier(&rose_dev_notifier);
-
-	sock_unregister(PF_ROSE);
-
-	for (i = 0; i < rose_ndevs; i++) {
-		struct net_device *dev = dev_rose[i];
-
-		if (dev) {
-			unregister_netdev(dev);
-			free_netdev(dev);
-		}
-	}
-
-	kfree(dev_rose);
-	proto_unregister(&rose_proto);
-}
-
-module_exit(rose_exit);
diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c
deleted file mode 100644
index f1a76a5820f1..000000000000
--- a/net/rose/rose_dev.c
+++ /dev/null
@@ -1,141 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- */
-#include <linux/module.h>
-#include <linux/proc_fs.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/fs.h>
-#include <linux/types.h>
-#include <linux/sysctl.h>
-#include <linux/string.h>
-#include <linux/socket.h>
-#include <linux/errno.h>
-#include <linux/fcntl.h>
-#include <linux/in.h>
-#include <linux/if_ether.h>
-#include <linux/slab.h>
-
-#include <asm/io.h>
-
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-
-#include <net/ip.h>
-#include <net/arp.h>
-
-#include <net/ax25.h>
-#include <net/rose.h>
-
-static int rose_header(struct sk_buff *skb, struct net_device *dev,
-		       unsigned short type,
-		       const void *daddr, const void *saddr, unsigned int len)
-{
-	unsigned char *buff = skb_push(skb, ROSE_MIN_LEN + 2);
-
-	if (daddr)
-		memcpy(buff + 7, daddr, dev->addr_len);
-
-	*buff++ = ROSE_GFI | ROSE_Q_BIT;
-	*buff++ = 0x00;
-	*buff++ = ROSE_DATA;
-	*buff++ = 0x7F;
-	*buff++ = AX25_P_IP;
-
-	if (daddr != NULL)
-		return 37;
-
-	return -37;
-}
-
-static int rose_set_mac_address(struct net_device *dev, void *addr)
-{
-	struct sockaddr *sa = addr;
-	int err;
-
-	if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len))
-		return 0;
-
-	if (dev->flags & IFF_UP) {
-		err = rose_add_loopback_node((rose_address *)sa->sa_data);
-		if (err)
-			return err;
-
-		rose_del_loopback_node((const rose_address *)dev->dev_addr);
-	}
-
-	dev_addr_set(dev, sa->sa_data);
-
-	return 0;
-}
-
-static int rose_open(struct net_device *dev)
-{
-	int err;
-
-	err = rose_add_loopback_node((const rose_address *)dev->dev_addr);
-	if (err)
-		return err;
-
-	netif_start_queue(dev);
-
-	return 0;
-}
-
-static int rose_close(struct net_device *dev)
-{
-	netif_stop_queue(dev);
-	rose_del_loopback_node((const rose_address *)dev->dev_addr);
-	return 0;
-}
-
-static netdev_tx_t rose_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct net_device_stats *stats = &dev->stats;
-	unsigned int len = skb->len;
-
-	if (!netif_running(dev)) {
-		printk(KERN_ERR "ROSE: rose_xmit - called when iface is down\n");
-		return NETDEV_TX_BUSY;
-	}
-
-	if (!rose_route_frame(skb, NULL)) {
-		dev_kfree_skb(skb);
-		stats->tx_errors++;
-		return NETDEV_TX_OK;
-	}
-
-	stats->tx_packets++;
-	stats->tx_bytes += len;
-	return NETDEV_TX_OK;
-}
-
-static const struct header_ops rose_header_ops = {
-	.create	= rose_header,
-};
-
-static const struct net_device_ops rose_netdev_ops = {
-	.ndo_open		= rose_open,
-	.ndo_stop		= rose_close,
-	.ndo_start_xmit		= rose_xmit,
-	.ndo_set_mac_address    = rose_set_mac_address,
-};
-
-void rose_setup(struct net_device *dev)
-{
-	dev->mtu		= ROSE_MAX_PACKET_SIZE - 2;
-	dev->netdev_ops		= &rose_netdev_ops;
-
-	dev->header_ops		= &rose_header_ops;
-	dev->hard_header_len	= AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN;
-	dev->addr_len		= ROSE_ADDR_LEN;
-	dev->type		= ARPHRD_ROSE;
-
-	/* New-style flags. */
-	dev->flags		= IFF_NOARP;
-}
diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
deleted file mode 100644
index ca4f217ef3d3..000000000000
--- a/net/rose/rose_in.c
+++ /dev/null
@@ -1,301 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- *
- * Most of this code is based on the SDL diagrams published in the 7th ARRL
- * Computer Networking Conference papers. The diagrams have mistakes in them,
- * but are mostly correct. Before you modify the code could you read the SDL
- * diagrams as the code is not obvious and probably very easy to break.
- */
-#include <linux/errno.h>
-#include <linux/filter.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <net/rose.h>
-
-/*
- * State machine for state 1, Awaiting Call Accepted State.
- * The handling of the timer(s) is in file rose_timer.c.
- * Handling of state 0 and connection release is in af_rose.c.
- */
-static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype)
-{
-	struct rose_sock *rose = rose_sk(sk);
-
-	switch (frametype) {
-	case ROSE_CALL_ACCEPTED:
-		rose_stop_timer(sk);
-		rose_start_idletimer(sk);
-		rose->condition = 0x00;
-		rose->vs        = 0;
-		rose->va        = 0;
-		rose->vr        = 0;
-		rose->vl        = 0;
-		rose->state     = ROSE_STATE_3;
-		sk->sk_state	= TCP_ESTABLISHED;
-		if (!sock_flag(sk, SOCK_DEAD))
-			sk->sk_state_change(sk);
-		break;
-
-	case ROSE_CLEAR_REQUEST:
-		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
-		rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
-		rose_neigh_put(rose->neighbour);
-		break;
-
-	default:
-		break;
-	}
-
-	return 0;
-}
-
-/*
- * State machine for state 2, Awaiting Clear Confirmation State.
- * The handling of the timer(s) is in file rose_timer.c
- * Handling of state 0 and connection release is in af_rose.c.
- */
-static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int frametype)
-{
-	struct rose_sock *rose = rose_sk(sk);
-
-	switch (frametype) {
-	case ROSE_CLEAR_REQUEST:
-		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
-		rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
-		rose_neigh_put(rose->neighbour);
-		break;
-
-	case ROSE_CLEAR_CONFIRMATION:
-		rose_disconnect(sk, 0, -1, -1);
-		rose_neigh_put(rose->neighbour);
-		break;
-
-	default:
-		break;
-	}
-
-	return 0;
-}
-
-/*
- * State machine for state 3, Connected State.
- * The handling of the timer(s) is in file rose_timer.c
- * Handling of state 0 and connection release is in af_rose.c.
- */
-static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype, int ns, int nr, int q, int d, int m)
-{
-	struct rose_sock *rose = rose_sk(sk);
-	int queued = 0;
-
-	switch (frametype) {
-	case ROSE_RESET_REQUEST:
-		rose_stop_timer(sk);
-		rose_start_idletimer(sk);
-		rose_write_internal(sk, ROSE_RESET_CONFIRMATION);
-		rose->condition = 0x00;
-		rose->vs        = 0;
-		rose->vr        = 0;
-		rose->va        = 0;
-		rose->vl        = 0;
-		rose_requeue_frames(sk);
-		break;
-
-	case ROSE_CLEAR_REQUEST:
-		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
-		rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
-		rose_neigh_put(rose->neighbour);
-		break;
-
-	case ROSE_RR:
-	case ROSE_RNR:
-		if (!rose_validate_nr(sk, nr)) {
-			rose_write_internal(sk, ROSE_RESET_REQUEST);
-			rose->condition = 0x00;
-			rose->vs        = 0;
-			rose->vr        = 0;
-			rose->va        = 0;
-			rose->vl        = 0;
-			rose->state     = ROSE_STATE_4;
-			rose_start_t2timer(sk);
-			rose_stop_idletimer(sk);
-		} else {
-			rose_frames_acked(sk, nr);
-			if (frametype == ROSE_RNR) {
-				rose->condition |= ROSE_COND_PEER_RX_BUSY;
-			} else {
-				rose->condition &= ~ROSE_COND_PEER_RX_BUSY;
-			}
-		}
-		break;
-
-	case ROSE_DATA:	/* XXX */
-		rose->condition &= ~ROSE_COND_PEER_RX_BUSY;
-		if (!rose_validate_nr(sk, nr)) {
-			rose_write_internal(sk, ROSE_RESET_REQUEST);
-			rose->condition = 0x00;
-			rose->vs        = 0;
-			rose->vr        = 0;
-			rose->va        = 0;
-			rose->vl        = 0;
-			rose->state     = ROSE_STATE_4;
-			rose_start_t2timer(sk);
-			rose_stop_idletimer(sk);
-			break;
-		}
-		rose_frames_acked(sk, nr);
-		if (ns == rose->vr) {
-			rose_start_idletimer(sk);
-			if (!sk_filter_trim_cap(sk, skb, ROSE_MIN_LEN) &&
-			    __sock_queue_rcv_skb(sk, skb) == 0) {
-				rose->vr = (rose->vr + 1) % ROSE_MODULUS;
-				queued = 1;
-			} else {
-				/* Should never happen ! */
-				rose_write_internal(sk, ROSE_RESET_REQUEST);
-				rose->condition = 0x00;
-				rose->vs        = 0;
-				rose->vr        = 0;
-				rose->va        = 0;
-				rose->vl        = 0;
-				rose->state     = ROSE_STATE_4;
-				rose_start_t2timer(sk);
-				rose_stop_idletimer(sk);
-				break;
-			}
-			if (atomic_read(&sk->sk_rmem_alloc) >
-			    (sk->sk_rcvbuf >> 1))
-				rose->condition |= ROSE_COND_OWN_RX_BUSY;
-		}
-		/*
-		 * If the window is full, ack the frame, else start the
-		 * acknowledge hold back timer.
-		 */
-		if (((rose->vl + sysctl_rose_window_size) % ROSE_MODULUS) == rose->vr) {
-			rose->condition &= ~ROSE_COND_ACK_PENDING;
-			rose_stop_timer(sk);
-			rose_enquiry_response(sk);
-		} else {
-			rose->condition |= ROSE_COND_ACK_PENDING;
-			rose_start_hbtimer(sk);
-		}
-		break;
-
-	default:
-		printk(KERN_WARNING "ROSE: unknown %02X in state 3\n", frametype);
-		break;
-	}
-
-	return queued;
-}
-
-/*
- * State machine for state 4, Awaiting Reset Confirmation State.
- * The handling of the timer(s) is in file rose_timer.c
- * Handling of state 0 and connection release is in af_rose.c.
- */
-static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int frametype)
-{
-	struct rose_sock *rose = rose_sk(sk);
-
-	switch (frametype) {
-	case ROSE_RESET_REQUEST:
-		rose_write_internal(sk, ROSE_RESET_CONFIRMATION);
-		fallthrough;
-	case ROSE_RESET_CONFIRMATION:
-		rose_stop_timer(sk);
-		rose_start_idletimer(sk);
-		rose->condition = 0x00;
-		rose->va        = 0;
-		rose->vr        = 0;
-		rose->vs        = 0;
-		rose->vl        = 0;
-		rose->state     = ROSE_STATE_3;
-		rose_requeue_frames(sk);
-		break;
-
-	case ROSE_CLEAR_REQUEST:
-		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
-		rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
-		rose_neigh_put(rose->neighbour);
-		break;
-
-	default:
-		break;
-	}
-
-	return 0;
-}
-
-/*
- * State machine for state 5, Awaiting Call Acceptance State.
- * The handling of the timer(s) is in file rose_timer.c
- * Handling of state 0 and connection release is in af_rose.c.
- */
-static int rose_state5_machine(struct sock *sk, struct sk_buff *skb, int frametype)
-{
-	if (frametype == ROSE_CLEAR_REQUEST) {
-		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
-		rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
-		rose_neigh_put(rose_sk(sk)->neighbour);
-	}
-
-	return 0;
-}
-
-/* Higher level upcall for a LAPB frame */
-int rose_process_rx_frame(struct sock *sk, struct sk_buff *skb)
-{
-	struct rose_sock *rose = rose_sk(sk);
-	int queued = 0, frametype, ns, nr, q, d, m;
-
-	if (rose->state == ROSE_STATE_0)
-		return 0;
-
-	frametype = rose_decode(skb, &ns, &nr, &q, &d, &m);
-
-	/*
-	 * ROSE_CLEAR_REQUEST carries cause and diagnostic in bytes 3..4.
-	 * Reject a malformed frame that is too short to contain them.
-	 */
-	if (frametype == ROSE_CLEAR_REQUEST && skb->len < 5)
-		return 0;
-
-	switch (rose->state) {
-	case ROSE_STATE_1:
-		queued = rose_state1_machine(sk, skb, frametype);
-		break;
-	case ROSE_STATE_2:
-		queued = rose_state2_machine(sk, skb, frametype);
-		break;
-	case ROSE_STATE_3:
-		queued = rose_state3_machine(sk, skb, frametype, ns, nr, q, d, m);
-		break;
-	case ROSE_STATE_4:
-		queued = rose_state4_machine(sk, skb, frametype);
-		break;
-	case ROSE_STATE_5:
-		queued = rose_state5_machine(sk, skb, frametype);
-		break;
-	}
-
-	rose_kick(sk);
-
-	return queued;
-}
diff --git a/net/rose/rose_link.c b/net/rose/rose_link.c
deleted file mode 100644
index 7746229fdc8c..000000000000
--- a/net/rose/rose_link.c
+++ /dev/null
@@ -1,289 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/jiffies.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <net/rose.h>
-
-static void rose_ftimer_expiry(struct timer_list *);
-static void rose_t0timer_expiry(struct timer_list *);
-
-static void rose_transmit_restart_confirmation(struct rose_neigh *neigh);
-static void rose_transmit_restart_request(struct rose_neigh *neigh);
-
-void rose_start_ftimer(struct rose_neigh *neigh)
-{
-	timer_delete(&neigh->ftimer);
-
-	neigh->ftimer.function = rose_ftimer_expiry;
-	neigh->ftimer.expires  =
-		jiffies + msecs_to_jiffies(sysctl_rose_link_fail_timeout);
-
-	add_timer(&neigh->ftimer);
-}
-
-static void rose_start_t0timer(struct rose_neigh *neigh)
-{
-	timer_delete(&neigh->t0timer);
-
-	neigh->t0timer.function = rose_t0timer_expiry;
-	neigh->t0timer.expires  =
-		jiffies + msecs_to_jiffies(sysctl_rose_restart_request_timeout);
-
-	add_timer(&neigh->t0timer);
-}
-
-void rose_stop_ftimer(struct rose_neigh *neigh)
-{
-	timer_delete(&neigh->ftimer);
-}
-
-void rose_stop_t0timer(struct rose_neigh *neigh)
-{
-	timer_delete(&neigh->t0timer);
-}
-
-int rose_ftimer_running(struct rose_neigh *neigh)
-{
-	return timer_pending(&neigh->ftimer);
-}
-
-static int rose_t0timer_running(struct rose_neigh *neigh)
-{
-	return timer_pending(&neigh->t0timer);
-}
-
-static void rose_ftimer_expiry(struct timer_list *t)
-{
-}
-
-static void rose_t0timer_expiry(struct timer_list *t)
-{
-	struct rose_neigh *neigh = timer_container_of(neigh, t, t0timer);
-
-	rose_transmit_restart_request(neigh);
-
-	neigh->dce_mode = 0;
-
-	rose_start_t0timer(neigh);
-}
-
-/*
- *	Interface to ax25_send_frame. Changes my level 2 callsign depending
- *	on whether we have a global ROSE callsign or use the default port
- *	callsign.
- */
-static int rose_send_frame(struct sk_buff *skb, struct rose_neigh *neigh)
-{
-	const ax25_address *rose_call;
-	ax25_cb *ax25s;
-
-	if (ax25cmp(&rose_callsign, &null_ax25_address) == 0)
-		rose_call = (const ax25_address *)neigh->dev->dev_addr;
-	else
-		rose_call = &rose_callsign;
-
-	ax25s = neigh->ax25;
-	neigh->ax25 = ax25_send_frame(skb, 260, rose_call, &neigh->callsign, neigh->digipeat, neigh->dev);
-	if (ax25s)
-		ax25_cb_put(ax25s);
-
-	return neigh->ax25 != NULL;
-}
-
-/*
- *	Interface to ax25_link_up. Changes my level 2 callsign depending
- *	on whether we have a global ROSE callsign or use the default port
- *	callsign.
- */
-static int rose_link_up(struct rose_neigh *neigh)
-{
-	const ax25_address *rose_call;
-	ax25_cb *ax25s;
-
-	if (ax25cmp(&rose_callsign, &null_ax25_address) == 0)
-		rose_call = (const ax25_address *)neigh->dev->dev_addr;
-	else
-		rose_call = &rose_callsign;
-
-	ax25s = neigh->ax25;
-	neigh->ax25 = ax25_find_cb(rose_call, &neigh->callsign, neigh->digipeat, neigh->dev);
-	if (ax25s)
-		ax25_cb_put(ax25s);
-
-	return neigh->ax25 != NULL;
-}
-
-/*
- *	This handles all restart and diagnostic frames.
- */
-void rose_link_rx_restart(struct sk_buff *skb, struct rose_neigh *neigh, unsigned short frametype)
-{
-	struct sk_buff *skbn;
-
-	switch (frametype) {
-	case ROSE_RESTART_REQUEST:
-		rose_stop_t0timer(neigh);
-		neigh->restarted = 1;
-		neigh->dce_mode  = (skb->data[3] == ROSE_DTE_ORIGINATED);
-		rose_transmit_restart_confirmation(neigh);
-		break;
-
-	case ROSE_RESTART_CONFIRMATION:
-		rose_stop_t0timer(neigh);
-		neigh->restarted = 1;
-		break;
-
-	case ROSE_DIAGNOSTIC:
-		pr_warn("ROSE: received diagnostic #%d - %3ph\n", skb->data[3],
-			skb->data + 4);
-		break;
-
-	default:
-		printk(KERN_WARNING "ROSE: received unknown %02X with LCI 000\n", frametype);
-		break;
-	}
-
-	if (neigh->restarted) {
-		while ((skbn = skb_dequeue(&neigh->queue)) != NULL)
-			if (!rose_send_frame(skbn, neigh))
-				kfree_skb(skbn);
-	}
-}
-
-/*
- *	This routine is called when a Restart Request is needed
- */
-static void rose_transmit_restart_request(struct rose_neigh *neigh)
-{
-	struct sk_buff *skb;
-	unsigned char *dptr;
-	int len;
-
-	len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN + 3;
-
-	if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
-		return;
-
-	skb_reserve(skb, AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN);
-
-	dptr = skb_put(skb, ROSE_MIN_LEN + 3);
-
-	*dptr++ = AX25_P_ROSE;
-	*dptr++ = ROSE_GFI;
-	*dptr++ = 0x00;
-	*dptr++ = ROSE_RESTART_REQUEST;
-	*dptr++ = ROSE_DTE_ORIGINATED;
-	*dptr++ = 0;
-
-	if (!rose_send_frame(skb, neigh))
-		kfree_skb(skb);
-}
-
-/*
- * This routine is called when a Restart Confirmation is needed
- */
-static void rose_transmit_restart_confirmation(struct rose_neigh *neigh)
-{
-	struct sk_buff *skb;
-	unsigned char *dptr;
-	int len;
-
-	len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN + 1;
-
-	if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
-		return;
-
-	skb_reserve(skb, AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN);
-
-	dptr = skb_put(skb, ROSE_MIN_LEN + 1);
-
-	*dptr++ = AX25_P_ROSE;
-	*dptr++ = ROSE_GFI;
-	*dptr++ = 0x00;
-	*dptr++ = ROSE_RESTART_CONFIRMATION;
-
-	if (!rose_send_frame(skb, neigh))
-		kfree_skb(skb);
-}
-
-/*
- * This routine is called when a Clear Request is needed outside of the context
- * of a connected socket.
- */
-void rose_transmit_clear_request(struct rose_neigh *neigh, unsigned int lci, unsigned char cause, unsigned char diagnostic)
-{
-	struct sk_buff *skb;
-	unsigned char *dptr;
-	int len;
-
-	if (!neigh->dev)
-		return;
-
-	len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN + 3;
-
-	if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
-		return;
-
-	skb_reserve(skb, AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN);
-
-	dptr = skb_put(skb, ROSE_MIN_LEN + 3);
-
-	*dptr++ = AX25_P_ROSE;
-	*dptr++ = ((lci >> 8) & 0x0F) | ROSE_GFI;
-	*dptr++ = ((lci >> 0) & 0xFF);
-	*dptr++ = ROSE_CLEAR_REQUEST;
-	*dptr++ = cause;
-	*dptr++ = diagnostic;
-
-	if (!rose_send_frame(skb, neigh))
-		kfree_skb(skb);
-}
-
-void rose_transmit_link(struct sk_buff *skb, struct rose_neigh *neigh)
-{
-	unsigned char *dptr;
-
-	if (neigh->loopback) {
-		rose_loopback_queue(skb, neigh);
-		return;
-	}
-
-	if (!rose_link_up(neigh))
-		neigh->restarted = 0;
-
-	dptr = skb_push(skb, 1);
-	*dptr++ = AX25_P_ROSE;
-
-	if (neigh->restarted) {
-		if (!rose_send_frame(skb, neigh))
-			kfree_skb(skb);
-	} else {
-		skb_queue_tail(&neigh->queue, skb);
-
-		if (!rose_t0timer_running(neigh)) {
-			rose_transmit_restart_request(neigh);
-			neigh->dce_mode = 0;
-			rose_start_t0timer(neigh);
-		}
-	}
-}
diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c
deleted file mode 100644
index b538e39b3df5..000000000000
--- a/net/rose/rose_loopback.c
+++ /dev/null
@@ -1,133 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- */
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/socket.h>
-#include <linux/timer.h>
-#include <net/ax25.h>
-#include <linux/skbuff.h>
-#include <net/rose.h>
-#include <linux/init.h>
-
-static struct sk_buff_head loopback_queue;
-#define ROSE_LOOPBACK_LIMIT 1000
-static struct timer_list loopback_timer;
-
-static void rose_set_loopback_timer(void);
-static void rose_loopback_timer(struct timer_list *unused);
-
-void rose_loopback_init(void)
-{
-	skb_queue_head_init(&loopback_queue);
-
-	timer_setup(&loopback_timer, rose_loopback_timer, 0);
-}
-
-static int rose_loopback_running(void)
-{
-	return timer_pending(&loopback_timer);
-}
-
-int rose_loopback_queue(struct sk_buff *skb, struct rose_neigh *neigh)
-{
-	struct sk_buff *skbn = NULL;
-
-	if (skb_queue_len(&loopback_queue) < ROSE_LOOPBACK_LIMIT)
-		skbn = skb_clone(skb, GFP_ATOMIC);
-
-	if (skbn) {
-		consume_skb(skb);
-		skb_queue_tail(&loopback_queue, skbn);
-
-		if (!rose_loopback_running())
-			rose_set_loopback_timer();
-	} else {
-		kfree_skb(skb);
-	}
-
-	return 1;
-}
-
-static void rose_set_loopback_timer(void)
-{
-	mod_timer(&loopback_timer, jiffies + 10);
-}
-
-static void rose_loopback_timer(struct timer_list *unused)
-{
-	struct sk_buff *skb;
-	struct net_device *dev;
-	rose_address *dest;
-	struct sock *sk;
-	unsigned short frametype;
-	unsigned int lci_i, lci_o;
-	int count;
-
-	for (count = 0; count < ROSE_LOOPBACK_LIMIT; count++) {
-		skb = skb_dequeue(&loopback_queue);
-		if (!skb)
-			return;
-		if (skb->len < ROSE_MIN_LEN) {
-			kfree_skb(skb);
-			continue;
-		}
-		lci_i     = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
-		frametype = skb->data[2];
-		if (frametype == ROSE_CALL_REQUEST &&
-		    (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF ||
-		     skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] !=
-		     ROSE_CALL_REQ_ADDR_LEN_VAL)) {
-			kfree_skb(skb);
-			continue;
-		}
-		dest      = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF);
-		lci_o     = ROSE_DEFAULT_MAXVC + 1 - lci_i;
-
-		skb_reset_transport_header(skb);
-
-		sk = rose_find_socket(lci_o, rose_loopback_neigh);
-		if (sk) {
-			if (rose_process_rx_frame(sk, skb) == 0)
-				kfree_skb(skb);
-			continue;
-		}
-
-		if (frametype == ROSE_CALL_REQUEST) {
-			if (!rose_loopback_neigh->dev &&
-			    !rose_loopback_neigh->loopback) {
-				kfree_skb(skb);
-				continue;
-			}
-
-			dev = rose_dev_get(dest);
-			if (!dev) {
-				kfree_skb(skb);
-				continue;
-			}
-
-			if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0) {
-				dev_put(dev);
-				kfree_skb(skb);
-			}
-		} else {
-			kfree_skb(skb);
-		}
-	}
-	if (!skb_queue_empty(&loopback_queue))
-		mod_timer(&loopback_timer, jiffies + 1);
-}
-
-void __exit rose_loopback_clear(void)
-{
-	struct sk_buff *skb;
-
-	timer_delete(&loopback_timer);
-
-	while ((skb = skb_dequeue(&loopback_queue)) != NULL) {
-		skb->sk = NULL;
-		kfree_skb(skb);
-	}
-}
diff --git a/net/rose/rose_out.c b/net/rose/rose_out.c
deleted file mode 100644
index 9050e33c9604..000000000000
--- a/net/rose/rose_out.c
+++ /dev/null
@@ -1,122 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/gfp.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <net/rose.h>
-
-/*
- *	This procedure is passed a buffer descriptor for an iframe. It builds
- *	the rest of the control part of the frame and then writes it out.
- */
-static void rose_send_iframe(struct sock *sk, struct sk_buff *skb)
-{
-	struct rose_sock *rose = rose_sk(sk);
-
-	if (skb == NULL)
-		return;
-
-	skb->data[2] |= (rose->vr << 5) & 0xE0;
-	skb->data[2] |= (rose->vs << 1) & 0x0E;
-
-	rose_start_idletimer(sk);
-
-	rose_transmit_link(skb, rose->neighbour);
-}
-
-void rose_kick(struct sock *sk)
-{
-	struct rose_sock *rose = rose_sk(sk);
-	struct sk_buff *skb, *skbn;
-	unsigned short start, end;
-
-	if (rose->state != ROSE_STATE_3)
-		return;
-
-	if (rose->condition & ROSE_COND_PEER_RX_BUSY)
-		return;
-
-	if (!skb_peek(&sk->sk_write_queue))
-		return;
-
-	start = (skb_peek(&rose->ack_queue) == NULL) ? rose->va : rose->vs;
-	end   = (rose->va + sysctl_rose_window_size) % ROSE_MODULUS;
-
-	if (start == end)
-		return;
-
-	rose->vs = start;
-
-	/*
-	 * Transmit data until either we're out of data to send or
-	 * the window is full.
-	 */
-
-	skb  = skb_dequeue(&sk->sk_write_queue);
-
-	do {
-		if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
-			skb_queue_head(&sk->sk_write_queue, skb);
-			break;
-		}
-
-		skb_set_owner_w(skbn, sk);
-
-		/*
-		 * Transmit the frame copy.
-		 */
-		rose_send_iframe(sk, skbn);
-
-		rose->vs = (rose->vs + 1) % ROSE_MODULUS;
-
-		/*
-		 * Requeue the original data frame.
-		 */
-		skb_queue_tail(&rose->ack_queue, skb);
-
-	} while (rose->vs != end &&
-		 (skb = skb_dequeue(&sk->sk_write_queue)) != NULL);
-
-	rose->vl         = rose->vr;
-	rose->condition &= ~ROSE_COND_ACK_PENDING;
-
-	rose_stop_timer(sk);
-}
-
-/*
- * The following routines are taken from page 170 of the 7th ARRL Computer
- * Networking Conference paper, as is the whole state machine.
- */
-
-void rose_enquiry_response(struct sock *sk)
-{
-	struct rose_sock *rose = rose_sk(sk);
-
-	if (rose->condition & ROSE_COND_OWN_RX_BUSY)
-		rose_write_internal(sk, ROSE_RNR);
-	else
-		rose_write_internal(sk, ROSE_RR);
-
-	rose->vl         = rose->vr;
-	rose->condition &= ~ROSE_COND_ACK_PENDING;
-
-	rose_stop_timer(sk);
-}
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
deleted file mode 100644
index e31842e6b3c8..000000000000
--- a/net/rose/rose_route.c
+++ /dev/null
@@ -1,1333 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) Terry Dawson VK2KTJ (terry@animats.net)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <net/arp.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <linux/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/termios.h>	/* For TIOCINQ/OUTQ */
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/notifier.h>
-#include <linux/init.h>
-#include <net/rose.h>
-#include <linux/seq_file.h>
-#include <linux/export.h>
-
-static unsigned int rose_neigh_no = 1;
-
-static struct rose_node  *rose_node_list;
-static DEFINE_SPINLOCK(rose_node_list_lock);
-static struct rose_neigh *rose_neigh_list;
-static DEFINE_SPINLOCK(rose_neigh_list_lock);
-static struct rose_route *rose_route_list;
-static DEFINE_SPINLOCK(rose_route_list_lock);
-
-struct rose_neigh *rose_loopback_neigh;
-
-/*
- *	Add a new route to a node, and in the process add the node and the
- *	neighbour if it is new.
- */
-static int __must_check rose_add_node(struct rose_route_struct *rose_route,
-	struct net_device *dev)
-{
-	struct rose_node  *rose_node, *rose_tmpn, *rose_tmpp;
-	struct rose_neigh *rose_neigh;
-	int i, res = 0;
-
-	spin_lock_bh(&rose_node_list_lock);
-	spin_lock_bh(&rose_neigh_list_lock);
-
-	rose_node = rose_node_list;
-	while (rose_node != NULL) {
-		if ((rose_node->mask == rose_route->mask) &&
-		    (rosecmpm(&rose_route->address, &rose_node->address,
-			      rose_route->mask) == 0))
-			break;
-		rose_node = rose_node->next;
-	}
-
-	if (rose_node != NULL && rose_node->loopback) {
-		res = -EINVAL;
-		goto out;
-	}
-
-	rose_neigh = rose_neigh_list;
-	while (rose_neigh != NULL) {
-		if (ax25cmp(&rose_route->neighbour,
-			    &rose_neigh->callsign) == 0 &&
-		    rose_neigh->dev == dev)
-			break;
-		rose_neigh = rose_neigh->next;
-	}
-
-	if (rose_neigh == NULL) {
-		rose_neigh = kmalloc_obj(*rose_neigh, GFP_ATOMIC);
-		if (rose_neigh == NULL) {
-			res = -ENOMEM;
-			goto out;
-		}
-
-		rose_neigh->callsign  = rose_route->neighbour;
-		rose_neigh->digipeat  = NULL;
-		rose_neigh->ax25      = NULL;
-		rose_neigh->dev       = dev;
-		rose_neigh->count     = 0;
-		rose_neigh->dce_mode  = 0;
-		rose_neigh->loopback  = 0;
-		rose_neigh->number    = rose_neigh_no++;
-		rose_neigh->restarted = 0;
-		refcount_set(&rose_neigh->use, 1);
-
-		skb_queue_head_init(&rose_neigh->queue);
-
-		timer_setup(&rose_neigh->ftimer, NULL, 0);
-		timer_setup(&rose_neigh->t0timer, NULL, 0);
-
-		if (rose_route->ndigis != 0) {
-			rose_neigh->digipeat =
-				kmalloc_obj(ax25_digi, GFP_ATOMIC);
-			if (rose_neigh->digipeat == NULL) {
-				kfree(rose_neigh);
-				res = -ENOMEM;
-				goto out;
-			}
-
-			rose_neigh->digipeat->ndigi      = rose_route->ndigis;
-			rose_neigh->digipeat->lastrepeat = -1;
-
-			for (i = 0; i < rose_route->ndigis; i++) {
-				rose_neigh->digipeat->calls[i]    =
-					rose_route->digipeaters[i];
-				rose_neigh->digipeat->repeated[i] = 0;
-			}
-		}
-
-		rose_neigh->next = rose_neigh_list;
-		rose_neigh_list  = rose_neigh;
-	}
-
-	/*
-	 * This is a new node to be inserted into the list. Find where it needs
-	 * to be inserted into the list, and insert it. We want to be sure
-	 * to order the list in descending order of mask size to ensure that
-	 * later when we are searching this list the first match will be the
-	 * best match.
-	 */
-	if (rose_node == NULL) {
-		rose_tmpn = rose_node_list;
-		rose_tmpp = NULL;
-
-		while (rose_tmpn != NULL) {
-			if (rose_tmpn->mask > rose_route->mask) {
-				rose_tmpp = rose_tmpn;
-				rose_tmpn = rose_tmpn->next;
-			} else {
-				break;
-			}
-		}
-
-		/* create new node */
-		rose_node = kmalloc_obj(*rose_node, GFP_ATOMIC);
-		if (rose_node == NULL) {
-			res = -ENOMEM;
-			goto out;
-		}
-
-		rose_node->address      = rose_route->address;
-		rose_node->mask         = rose_route->mask;
-		rose_node->count        = 1;
-		rose_node->loopback     = 0;
-		rose_node->neighbour[0] = rose_neigh;
-
-		if (rose_tmpn == NULL) {
-			if (rose_tmpp == NULL) {	/* Empty list */
-				rose_node_list  = rose_node;
-				rose_node->next = NULL;
-			} else {
-				rose_tmpp->next = rose_node;
-				rose_node->next = NULL;
-			}
-		} else {
-			if (rose_tmpp == NULL) {	/* 1st node */
-				rose_node->next = rose_node_list;
-				rose_node_list  = rose_node;
-			} else {
-				rose_tmpp->next = rose_node;
-				rose_node->next = rose_tmpn;
-			}
-		}
-		rose_neigh->count++;
-		rose_neigh_hold(rose_neigh);
-
-		goto out;
-	}
-
-	/* We have space, slot it in */
-	if (rose_node->count < 3) {
-		rose_node->neighbour[rose_node->count] = rose_neigh;
-		rose_node->count++;
-		rose_neigh->count++;
-		rose_neigh_hold(rose_neigh);
-	}
-
-out:
-	spin_unlock_bh(&rose_neigh_list_lock);
-	spin_unlock_bh(&rose_node_list_lock);
-
-	return res;
-}
-
-/*
- * Caller is holding rose_node_list_lock.
- */
-static void rose_remove_node(struct rose_node *rose_node)
-{
-	struct rose_node *s;
-
-	if ((s = rose_node_list) == rose_node) {
-		rose_node_list = rose_node->next;
-		kfree(rose_node);
-		return;
-	}
-
-	while (s != NULL && s->next != NULL) {
-		if (s->next == rose_node) {
-			s->next = rose_node->next;
-			kfree(rose_node);
-			return;
-		}
-
-		s = s->next;
-	}
-}
-
-/*
- * Caller is holding rose_neigh_list_lock.
- */
-static void rose_remove_neigh(struct rose_neigh *rose_neigh)
-{
-	struct rose_neigh *s;
-
-	timer_delete_sync(&rose_neigh->ftimer);
-	timer_delete_sync(&rose_neigh->t0timer);
-
-	skb_queue_purge(&rose_neigh->queue);
-
-	if ((s = rose_neigh_list) == rose_neigh) {
-		rose_neigh_list = rose_neigh->next;
-		return;
-	}
-
-	while (s != NULL && s->next != NULL) {
-		if (s->next == rose_neigh) {
-			s->next = rose_neigh->next;
-			return;
-		}
-
-		s = s->next;
-	}
-}
-
-/*
- * Caller is holding rose_route_list_lock.
- */
-static void rose_remove_route(struct rose_route *rose_route)
-{
-	struct rose_route *s;
-
-	if (rose_route->neigh1 != NULL)
-		rose_neigh_put(rose_route->neigh1);
-
-	if (rose_route->neigh2 != NULL)
-		rose_neigh_put(rose_route->neigh2);
-
-	if ((s = rose_route_list) == rose_route) {
-		rose_route_list = rose_route->next;
-		kfree(rose_route);
-		return;
-	}
-
-	while (s != NULL && s->next != NULL) {
-		if (s->next == rose_route) {
-			s->next = rose_route->next;
-			kfree(rose_route);
-			return;
-		}
-
-		s = s->next;
-	}
-}
-
-/*
- *	"Delete" a node. Strictly speaking remove a route to a node. The node
- *	is only deleted if no routes are left to it.
- */
-static int rose_del_node(struct rose_route_struct *rose_route,
-	struct net_device *dev)
-{
-	struct rose_node  *rose_node;
-	struct rose_neigh *rose_neigh;
-	int i, err = 0;
-
-	spin_lock_bh(&rose_node_list_lock);
-	spin_lock_bh(&rose_neigh_list_lock);
-
-	rose_node = rose_node_list;
-	while (rose_node != NULL) {
-		if ((rose_node->mask == rose_route->mask) &&
-		    (rosecmpm(&rose_route->address, &rose_node->address,
-			      rose_route->mask) == 0))
-			break;
-		rose_node = rose_node->next;
-	}
-
-	if (rose_node == NULL || rose_node->loopback) {
-		err = -EINVAL;
-		goto out;
-	}
-
-	rose_neigh = rose_neigh_list;
-	while (rose_neigh != NULL) {
-		if (ax25cmp(&rose_route->neighbour,
-			    &rose_neigh->callsign) == 0 &&
-		    rose_neigh->dev == dev)
-			break;
-		rose_neigh = rose_neigh->next;
-	}
-
-	if (rose_neigh == NULL) {
-		err = -EINVAL;
-		goto out;
-	}
-
-	for (i = 0; i < rose_node->count; i++) {
-		if (rose_node->neighbour[i] == rose_neigh) {
-			rose_neigh->count--;
-			rose_neigh_put(rose_neigh);
-
-			if (rose_neigh->count == 0) {
-				rose_remove_neigh(rose_neigh);
-				rose_neigh_put(rose_neigh);
-			}
-
-			rose_node->count--;
-
-			if (rose_node->count == 0) {
-				rose_remove_node(rose_node);
-			} else {
-				switch (i) {
-				case 0:
-					rose_node->neighbour[0] =
-						rose_node->neighbour[1];
-					fallthrough;
-				case 1:
-					rose_node->neighbour[1] =
-						rose_node->neighbour[2];
-					break;
-				case 2:
-					break;
-				}
-			}
-			goto out;
-		}
-	}
-	err = -EINVAL;
-
-out:
-	spin_unlock_bh(&rose_neigh_list_lock);
-	spin_unlock_bh(&rose_node_list_lock);
-
-	return err;
-}
-
-/*
- *	Add the loopback neighbour.
- */
-void rose_add_loopback_neigh(void)
-{
-	struct rose_neigh *sn;
-
-	rose_loopback_neigh = kmalloc_obj(struct rose_neigh);
-	if (!rose_loopback_neigh)
-		return;
-	sn = rose_loopback_neigh;
-
-	sn->callsign  = null_ax25_address;
-	sn->digipeat  = NULL;
-	sn->ax25      = NULL;
-	sn->dev       = NULL;
-	sn->count     = 0;
-	sn->dce_mode  = 1;
-	sn->loopback  = 1;
-	sn->number    = rose_neigh_no++;
-	sn->restarted = 1;
-	refcount_set(&sn->use, 1);
-
-	skb_queue_head_init(&sn->queue);
-
-	timer_setup(&sn->ftimer, NULL, 0);
-	timer_setup(&sn->t0timer, NULL, 0);
-
-	spin_lock_bh(&rose_neigh_list_lock);
-	sn->next = rose_neigh_list;
-	rose_neigh_list           = sn;
-	spin_unlock_bh(&rose_neigh_list_lock);
-}
-
-/*
- *	Add a loopback node.
- */
-int rose_add_loopback_node(const rose_address *address)
-{
-	struct rose_node *rose_node;
-	int err = 0;
-
-	spin_lock_bh(&rose_node_list_lock);
-
-	rose_node = rose_node_list;
-	while (rose_node != NULL) {
-		if ((rose_node->mask == 10) &&
-		     (rosecmpm(address, &rose_node->address, 10) == 0) &&
-		     rose_node->loopback)
-			break;
-		rose_node = rose_node->next;
-	}
-
-	if (rose_node != NULL)
-		goto out;
-
-	if ((rose_node = kmalloc_obj(*rose_node, GFP_ATOMIC)) == NULL) {
-		err = -ENOMEM;
-		goto out;
-	}
-
-	rose_node->address      = *address;
-	rose_node->mask         = 10;
-	rose_node->count        = 1;
-	rose_node->loopback     = 1;
-	rose_node->neighbour[0] = rose_loopback_neigh;
-
-	/* Insert at the head of list. Address is always mask=10 */
-	rose_node->next = rose_node_list;
-	rose_node_list  = rose_node;
-
-	rose_loopback_neigh->count++;
-	rose_neigh_hold(rose_loopback_neigh);
-
-out:
-	spin_unlock_bh(&rose_node_list_lock);
-
-	return err;
-}
-
-/*
- *	Delete a loopback node.
- */
-void rose_del_loopback_node(const rose_address *address)
-{
-	struct rose_node *rose_node;
-
-	spin_lock_bh(&rose_node_list_lock);
-
-	rose_node = rose_node_list;
-	while (rose_node != NULL) {
-		if ((rose_node->mask == 10) &&
-		    (rosecmpm(address, &rose_node->address, 10) == 0) &&
-		    rose_node->loopback)
-			break;
-		rose_node = rose_node->next;
-	}
-
-	if (rose_node == NULL)
-		goto out;
-
-	rose_remove_node(rose_node);
-
-	rose_loopback_neigh->count--;
-	rose_neigh_put(rose_loopback_neigh);
-
-out:
-	spin_unlock_bh(&rose_node_list_lock);
-}
-
-/*
- *	A device has been removed. Remove its routes and neighbours.
- */
-void rose_rt_device_down(struct net_device *dev)
-{
-	struct rose_neigh *s, *rose_neigh;
-	struct rose_node  *t, *rose_node;
-	int i;
-
-	spin_lock_bh(&rose_node_list_lock);
-	spin_lock_bh(&rose_neigh_list_lock);
-	rose_neigh = rose_neigh_list;
-	while (rose_neigh != NULL) {
-		s          = rose_neigh;
-		rose_neigh = rose_neigh->next;
-
-		if (s->dev != dev)
-			continue;
-
-		rose_node = rose_node_list;
-
-		while (rose_node != NULL) {
-			t         = rose_node;
-			rose_node = rose_node->next;
-
-			for (i = t->count - 1; i >= 0; i--) {
-				if (t->neighbour[i] != s)
-					continue;
-
-				t->count--;
-
-				memmove(&t->neighbour[i], &t->neighbour[i + 1],
-					sizeof(t->neighbour[0]) *
-						(t->count - i));
-				rose_neigh_put(s);
-			}
-
-			if (t->count <= 0)
-				rose_remove_node(t);
-		}
-
-		rose_remove_neigh(s);
-		rose_neigh_put(s);
-	}
-	spin_unlock_bh(&rose_neigh_list_lock);
-	spin_unlock_bh(&rose_node_list_lock);
-}
-
-#if 0 /* Currently unused */
-/*
- *	A device has been removed. Remove its links.
- */
-void rose_route_device_down(struct net_device *dev)
-{
-	struct rose_route *s, *rose_route;
-
-	spin_lock_bh(&rose_route_list_lock);
-	rose_route = rose_route_list;
-	while (rose_route != NULL) {
-		s          = rose_route;
-		rose_route = rose_route->next;
-
-		if (s->neigh1->dev == dev || s->neigh2->dev == dev)
-			rose_remove_route(s);
-	}
-	spin_unlock_bh(&rose_route_list_lock);
-}
-#endif
-
-/*
- *	Clear all nodes and neighbours out, except for neighbours with
- *	active connections going through them.
- *  Do not clear loopback neighbour and nodes.
- */
-static int rose_clear_routes(void)
-{
-	struct rose_neigh *s, *rose_neigh;
-	struct rose_node  *t, *rose_node;
-	int i;
-
-	spin_lock_bh(&rose_node_list_lock);
-	spin_lock_bh(&rose_neigh_list_lock);
-
-	rose_neigh = rose_neigh_list;
-	rose_node  = rose_node_list;
-
-	while (rose_node != NULL) {
-		t         = rose_node;
-		rose_node = rose_node->next;
-
-		if (!t->loopback) {
-			for (i = 0; i < t->count; i++)
-				rose_neigh_put(t->neighbour[i]);
-			rose_remove_node(t);
-		}
-	}
-
-	while (rose_neigh != NULL) {
-		s          = rose_neigh;
-		rose_neigh = rose_neigh->next;
-
-		if (!s->loopback) {
-			rose_remove_neigh(s);
-			rose_neigh_put(s);
-		}
-	}
-
-	spin_unlock_bh(&rose_neigh_list_lock);
-	spin_unlock_bh(&rose_node_list_lock);
-
-	return 0;
-}
-
-/*
- *	Check that the device given is a valid AX.25 interface that is "up".
- * 	called with RTNL
- */
-static struct net_device *rose_ax25_dev_find(char *devname)
-{
-	struct net_device *dev;
-
-	if ((dev = __dev_get_by_name(&init_net, devname)) == NULL)
-		return NULL;
-
-	if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
-		return dev;
-
-	return NULL;
-}
-
-/*
- *	Find the first active ROSE device, usually "rose0".
- */
-struct net_device *rose_dev_first(void)
-{
-	struct net_device *dev, *first = NULL;
-
-	rcu_read_lock();
-	for_each_netdev_rcu(&init_net, dev) {
-		if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE)
-			if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
-				first = dev;
-	}
-	if (first)
-		dev_hold(first);
-	rcu_read_unlock();
-
-	return first;
-}
-
-/*
- *	Find the ROSE device for the given address.
- */
-struct net_device *rose_dev_get(rose_address *addr)
-{
-	struct net_device *dev;
-
-	rcu_read_lock();
-	for_each_netdev_rcu(&init_net, dev) {
-		if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE &&
-		    rosecmp(addr, (const rose_address *)dev->dev_addr) == 0) {
-			dev_hold(dev);
-			goto out;
-		}
-	}
-	dev = NULL;
-out:
-	rcu_read_unlock();
-	return dev;
-}
-
-static int rose_dev_exists(rose_address *addr)
-{
-	struct net_device *dev;
-
-	rcu_read_lock();
-	for_each_netdev_rcu(&init_net, dev) {
-		if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE &&
-		    rosecmp(addr, (const rose_address *)dev->dev_addr) == 0)
-			goto out;
-	}
-	dev = NULL;
-out:
-	rcu_read_unlock();
-	return dev != NULL;
-}
-
-
-
-
-struct rose_route *rose_route_free_lci(unsigned int lci, struct rose_neigh *neigh)
-{
-	struct rose_route *rose_route;
-
-	for (rose_route = rose_route_list; rose_route != NULL; rose_route = rose_route->next)
-		if ((rose_route->neigh1 == neigh && rose_route->lci1 == lci) ||
-		    (rose_route->neigh2 == neigh && rose_route->lci2 == lci))
-			return rose_route;
-
-	return NULL;
-}
-
-/*
- *	Find a neighbour or a route given a ROSE address.
- */
-struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
-	unsigned char *diagnostic, int route_frame)
-{
-	struct rose_neigh *res = NULL;
-	struct rose_node *node;
-	int failed = 0;
-	int i;
-
-	if (!route_frame) spin_lock_bh(&rose_node_list_lock);
-	for (node = rose_node_list; node != NULL; node = node->next) {
-		if (rosecmpm(addr, &node->address, node->mask) == 0) {
-			for (i = 0; i < node->count; i++) {
-				if (node->neighbour[i]->restarted) {
-					res = node->neighbour[i];
-					rose_neigh_hold(node->neighbour[i]);
-					goto out;
-				}
-			}
-		}
-	}
-	if (!route_frame) { /* connect request */
-		for (node = rose_node_list; node != NULL; node = node->next) {
-			if (rosecmpm(addr, &node->address, node->mask) == 0) {
-				for (i = 0; i < node->count; i++) {
-					if (!rose_ftimer_running(node->neighbour[i])) {
-						res = node->neighbour[i];
-						rose_neigh_hold(node->neighbour[i]);
-						goto out;
-					}
-					failed = 1;
-				}
-			}
-		}
-	}
-
-	if (failed) {
-		*cause      = ROSE_OUT_OF_ORDER;
-		*diagnostic = 0;
-	} else {
-		*cause      = ROSE_NOT_OBTAINABLE;
-		*diagnostic = 0;
-	}
-
-out:
-	if (!route_frame) spin_unlock_bh(&rose_node_list_lock);
-	return res;
-}
-
-/*
- *	Handle the ioctls that control the routing functions.
- */
-int rose_rt_ioctl(unsigned int cmd, void __user *arg)
-{
-	struct rose_route_struct rose_route;
-	struct net_device *dev;
-	int err;
-
-	switch (cmd) {
-	case SIOCADDRT:
-		if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
-			return -EFAULT;
-		if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL)
-			return -EINVAL;
-		if (rose_dev_exists(&rose_route.address)) /* Can't add routes to ourself */
-			return -EINVAL;
-		if (rose_route.mask > 10) /* Mask can't be more than 10 digits */
-			return -EINVAL;
-		if (rose_route.ndigis > AX25_MAX_DIGIS)
-			return -EINVAL;
-		err = rose_add_node(&rose_route, dev);
-		return err;
-
-	case SIOCDELRT:
-		if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
-			return -EFAULT;
-		if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL)
-			return -EINVAL;
-		err = rose_del_node(&rose_route, dev);
-		return err;
-
-	case SIOCRSCLRRT:
-		return rose_clear_routes();
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh)
-{
-	struct rose_route *rose_route, *s;
-
-	rose_neigh->restarted = 0;
-
-	rose_stop_t0timer(rose_neigh);
-	rose_start_ftimer(rose_neigh);
-
-	skb_queue_purge(&rose_neigh->queue);
-
-	spin_lock_bh(&rose_route_list_lock);
-
-	rose_route = rose_route_list;
-
-	while (rose_route != NULL) {
-		if ((rose_route->neigh1 == rose_neigh && rose_route->neigh2 == rose_neigh) ||
-		    (rose_route->neigh1 == rose_neigh && rose_route->neigh2 == NULL)       ||
-		    (rose_route->neigh2 == rose_neigh && rose_route->neigh1 == NULL)) {
-			s = rose_route->next;
-			rose_remove_route(rose_route);
-			rose_route = s;
-			continue;
-		}
-
-		if (rose_route->neigh1 == rose_neigh) {
-			rose_neigh_put(rose_route->neigh1);
-			rose_route->neigh1 = NULL;
-			rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0);
-		}
-
-		if (rose_route->neigh2 == rose_neigh) {
-			rose_neigh_put(rose_route->neigh2);
-			rose_route->neigh2 = NULL;
-			rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0);
-		}
-
-		rose_route = rose_route->next;
-	}
-	spin_unlock_bh(&rose_route_list_lock);
-}
-
-/*
- * 	A level 2 link has timed out, therefore it appears to be a poor link,
- *	then don't use that neighbour until it is reset. Blow away all through
- *	routes and connections using this route.
- */
-void rose_link_failed(ax25_cb *ax25, int reason)
-{
-	struct rose_neigh *rose_neigh;
-
-	spin_lock_bh(&rose_neigh_list_lock);
-	rose_neigh = rose_neigh_list;
-	while (rose_neigh != NULL) {
-		if (rose_neigh->ax25 == ax25)
-			break;
-		rose_neigh = rose_neigh->next;
-	}
-
-	if (rose_neigh != NULL) {
-		rose_neigh->ax25 = NULL;
-		ax25_cb_put(ax25);
-
-		rose_del_route_by_neigh(rose_neigh);
-		rose_kill_by_neigh(rose_neigh);
-	}
-	spin_unlock_bh(&rose_neigh_list_lock);
-}
-
-/*
- * 	A device has been "downed" remove its link status. Blow away all
- *	through routes and connections that use this device.
- */
-void rose_link_device_down(struct net_device *dev)
-{
-	struct rose_neigh *rose_neigh;
-
-	for (rose_neigh = rose_neigh_list; rose_neigh != NULL; rose_neigh = rose_neigh->next) {
-		if (rose_neigh->dev == dev) {
-			rose_del_route_by_neigh(rose_neigh);
-			rose_kill_by_neigh(rose_neigh);
-		}
-	}
-}
-
-/*
- *	Route a frame to an appropriate AX.25 connection.
- *	A NULL ax25_cb indicates an internally generated frame.
- */
-int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
-{
-	struct rose_neigh *rose_neigh, *new_neigh;
-	struct rose_route *rose_route;
-	struct rose_facilities_struct facilities;
-	rose_address *src_addr, *dest_addr;
-	struct sock *sk;
-	unsigned short frametype;
-	unsigned int lci, new_lci;
-	unsigned char cause, diagnostic;
-	struct net_device *dev;
-	int res = 0;
-	char buf[11];
-
-	if (skb->len < ROSE_MIN_LEN)
-		return res;
-
-	if (!ax25)
-		return rose_loopback_queue(skb, NULL);
-
-	frametype = skb->data[2];
-	lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
-	if (frametype == ROSE_CALL_REQUEST &&
-	    (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF ||
-	     skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] !=
-	     ROSE_CALL_REQ_ADDR_LEN_VAL))
-		return res;
-	src_addr  = (rose_address *)(skb->data + ROSE_CALL_REQ_SRC_ADDR_OFF);
-	dest_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF);
-
-	spin_lock_bh(&rose_neigh_list_lock);
-	spin_lock_bh(&rose_route_list_lock);
-
-	rose_neigh = rose_neigh_list;
-	while (rose_neigh != NULL) {
-		if (ax25cmp(&ax25->dest_addr, &rose_neigh->callsign) == 0 &&
-		    ax25->ax25_dev->dev == rose_neigh->dev)
-			break;
-		rose_neigh = rose_neigh->next;
-	}
-
-	if (rose_neigh == NULL) {
-		printk("rose_route : unknown neighbour or device %s\n",
-		       ax2asc(buf, &ax25->dest_addr));
-		goto out;
-	}
-
-	/*
-	 *	Obviously the link is working, halt the ftimer.
-	 */
-	rose_stop_ftimer(rose_neigh);
-
-	/*
-	 *	LCI of zero is always for us, and its always a restart
-	 * 	frame.
-	 */
-	if (lci == 0) {
-		rose_link_rx_restart(skb, rose_neigh, frametype);
-		goto out;
-	}
-
-	/*
-	 *	Find an existing socket.
-	 */
-	if ((sk = rose_find_socket(lci, rose_neigh)) != NULL) {
-		if (frametype == ROSE_CALL_REQUEST) {
-			struct rose_sock *rose = rose_sk(sk);
-
-			/* Remove an existing unused socket */
-			rose_clear_queues(sk);
-			rose->cause	 = ROSE_NETWORK_CONGESTION;
-			rose->diagnostic = 0;
-			rose_neigh_put(rose->neighbour);
-			rose->neighbour	 = NULL;
-			rose->lci	 = 0;
-			rose->state	 = ROSE_STATE_0;
-			sk->sk_state	 = TCP_CLOSE;
-			sk->sk_err	 = 0;
-			sk->sk_shutdown	 |= SEND_SHUTDOWN;
-			if (!sock_flag(sk, SOCK_DEAD)) {
-				sk->sk_state_change(sk);
-				sock_set_flag(sk, SOCK_DEAD);
-			}
-		}
-		else {
-			skb_reset_transport_header(skb);
-			res = rose_process_rx_frame(sk, skb);
-			goto out;
-		}
-	}
-
-	/*
-	 *	Is is a Call Request and is it for us ?
-	 */
-	if (frametype == ROSE_CALL_REQUEST)
-		if ((dev = rose_dev_get(dest_addr)) != NULL) {
-			res = rose_rx_call_request(skb, dev, rose_neigh, lci);
-			dev_put(dev);
-			goto out;
-		}
-
-	if (!sysctl_rose_routing_control) {
-		rose_transmit_clear_request(rose_neigh, lci, ROSE_NOT_OBTAINABLE, 0);
-		goto out;
-	}
-
-	/*
-	 *	Route it to the next in line if we have an entry for it.
-	 */
-	rose_route = rose_route_list;
-	while (rose_route != NULL) {
-		if (rose_route->lci1 == lci &&
-		    rose_route->neigh1 == rose_neigh) {
-			if (frametype == ROSE_CALL_REQUEST) {
-				/* F6FBB - Remove an existing unused route */
-				rose_remove_route(rose_route);
-				break;
-			} else if (rose_route->neigh2 != NULL) {
-				skb->data[0] &= 0xF0;
-				skb->data[0] |= (rose_route->lci2 >> 8) & 0x0F;
-				skb->data[1]  = (rose_route->lci2 >> 0) & 0xFF;
-				rose_transmit_link(skb, rose_route->neigh2);
-				if (frametype == ROSE_CLEAR_CONFIRMATION)
-					rose_remove_route(rose_route);
-				res = 1;
-				goto out;
-			} else {
-				if (frametype == ROSE_CLEAR_CONFIRMATION)
-					rose_remove_route(rose_route);
-				goto out;
-			}
-		}
-		if (rose_route->lci2 == lci &&
-		    rose_route->neigh2 == rose_neigh) {
-			if (frametype == ROSE_CALL_REQUEST) {
-				/* F6FBB - Remove an existing unused route */
-				rose_remove_route(rose_route);
-				break;
-			} else if (rose_route->neigh1 != NULL) {
-				skb->data[0] &= 0xF0;
-				skb->data[0] |= (rose_route->lci1 >> 8) & 0x0F;
-				skb->data[1]  = (rose_route->lci1 >> 0) & 0xFF;
-				rose_transmit_link(skb, rose_route->neigh1);
-				if (frametype == ROSE_CLEAR_CONFIRMATION)
-					rose_remove_route(rose_route);
-				res = 1;
-				goto out;
-			} else {
-				if (frametype == ROSE_CLEAR_CONFIRMATION)
-					rose_remove_route(rose_route);
-				goto out;
-			}
-		}
-		rose_route = rose_route->next;
-	}
-
-	/*
-	 *	We know that:
-	 *	1. The frame isn't for us,
-	 *	2. It isn't "owned" by any existing route.
-	 */
-	if (frametype != ROSE_CALL_REQUEST) {	/* XXX */
-		res = 0;
-		goto out;
-	}
-
-	memset(&facilities, 0x00, sizeof(struct rose_facilities_struct));
-
-	if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF,
-				   skb->len - ROSE_CALL_REQ_FACILITIES_OFF,
-				   &facilities)) {
-		rose_transmit_clear_request(rose_neigh, lci, ROSE_INVALID_FACILITY, 76);
-		goto out;
-	}
-
-	/*
-	 *	Check for routing loops.
-	 */
-	rose_route = rose_route_list;
-	while (rose_route != NULL) {
-		if (rose_route->rand == facilities.rand &&
-		    rosecmp(src_addr, &rose_route->src_addr) == 0 &&
-		    ax25cmp(&facilities.dest_call, &rose_route->src_call) == 0 &&
-		    ax25cmp(&facilities.source_call, &rose_route->dest_call) == 0) {
-			rose_transmit_clear_request(rose_neigh, lci, ROSE_NOT_OBTAINABLE, 120);
-			goto out;
-		}
-		rose_route = rose_route->next;
-	}
-
-	if ((new_neigh = rose_get_neigh(dest_addr, &cause, &diagnostic, 1)) == NULL) {
-		rose_transmit_clear_request(rose_neigh, lci, cause, diagnostic);
-		goto out;
-	}
-
-	if ((new_lci = rose_new_lci(new_neigh)) == 0) {
-		rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 71);
-		goto put_neigh;
-	}
-
-	if ((rose_route = kmalloc_obj(*rose_route, GFP_ATOMIC)) == NULL) {
-		rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 120);
-		goto put_neigh;
-	}
-
-	rose_route->lci1      = lci;
-	rose_route->src_addr  = *src_addr;
-	rose_route->dest_addr = *dest_addr;
-	rose_route->src_call  = facilities.dest_call;
-	rose_route->dest_call = facilities.source_call;
-	rose_route->rand      = facilities.rand;
-	rose_route->neigh1    = rose_neigh;
-	rose_route->lci2      = new_lci;
-	rose_route->neigh2    = new_neigh;
-
-	rose_neigh_hold(rose_route->neigh1);
-	rose_neigh_hold(rose_route->neigh2);
-
-	rose_route->next = rose_route_list;
-	rose_route_list  = rose_route;
-
-	skb->data[0] &= 0xF0;
-	skb->data[0] |= (rose_route->lci2 >> 8) & 0x0F;
-	skb->data[1]  = (rose_route->lci2 >> 0) & 0xFF;
-
-	rose_transmit_link(skb, rose_route->neigh2);
-	res = 1;
-
-put_neigh:
-	rose_neigh_put(new_neigh);
-out:
-	spin_unlock_bh(&rose_route_list_lock);
-	spin_unlock_bh(&rose_neigh_list_lock);
-
-	return res;
-}
-
-#ifdef CONFIG_PROC_FS
-
-static void *rose_node_start(struct seq_file *seq, loff_t *pos)
-	__acquires(rose_node_list_lock)
-{
-	struct rose_node *rose_node;
-	int i = 1;
-
-	spin_lock_bh(&rose_node_list_lock);
-	if (*pos == 0)
-		return SEQ_START_TOKEN;
-
-	for (rose_node = rose_node_list; rose_node && i < *pos;
-	     rose_node = rose_node->next, ++i);
-
-	return (i == *pos) ? rose_node : NULL;
-}
-
-static void *rose_node_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	++*pos;
-
-	return (v == SEQ_START_TOKEN) ? rose_node_list
-		: ((struct rose_node *)v)->next;
-}
-
-static void rose_node_stop(struct seq_file *seq, void *v)
-	__releases(rose_node_list_lock)
-{
-	spin_unlock_bh(&rose_node_list_lock);
-}
-
-static int rose_node_show(struct seq_file *seq, void *v)
-{
-	char rsbuf[11];
-	int i;
-
-	if (v == SEQ_START_TOKEN)
-		seq_puts(seq, "address    mask n neigh neigh neigh\n");
-	else {
-		const struct rose_node *rose_node = v;
-		seq_printf(seq, "%-10s %04d %d",
-			   rose2asc(rsbuf, &rose_node->address),
-			   rose_node->mask,
-			   rose_node->count);
-
-		for (i = 0; i < rose_node->count; i++)
-			seq_printf(seq, " %05d", rose_node->neighbour[i]->number);
-
-		seq_puts(seq, "\n");
-	}
-	return 0;
-}
-
-const struct seq_operations rose_node_seqops = {
-	.start = rose_node_start,
-	.next = rose_node_next,
-	.stop = rose_node_stop,
-	.show = rose_node_show,
-};
-
-static void *rose_neigh_start(struct seq_file *seq, loff_t *pos)
-	__acquires(rose_neigh_list_lock)
-{
-	struct rose_neigh *rose_neigh;
-	int i = 1;
-
-	spin_lock_bh(&rose_neigh_list_lock);
-	if (*pos == 0)
-		return SEQ_START_TOKEN;
-
-	for (rose_neigh = rose_neigh_list; rose_neigh && i < *pos;
-	     rose_neigh = rose_neigh->next, ++i);
-
-	return (i == *pos) ? rose_neigh : NULL;
-}
-
-static void *rose_neigh_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	++*pos;
-
-	return (v == SEQ_START_TOKEN) ? rose_neigh_list
-		: ((struct rose_neigh *)v)->next;
-}
-
-static void rose_neigh_stop(struct seq_file *seq, void *v)
-	__releases(rose_neigh_list_lock)
-{
-	spin_unlock_bh(&rose_neigh_list_lock);
-}
-
-static int rose_neigh_show(struct seq_file *seq, void *v)
-{
-	char buf[11];
-	int i;
-
-	if (v == SEQ_START_TOKEN)
-		seq_puts(seq,
-			 "addr  callsign  dev  count use mode restart  t0  tf digipeaters\n");
-	else {
-		struct rose_neigh *rose_neigh = v;
-
-		/* if (!rose_neigh->loopback) { */
-		seq_printf(seq, "%05d %-9s %-4s   %3d %3d  %3s     %3s %3lu %3lu",
-			   rose_neigh->number,
-			   (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
-			   rose_neigh->dev ? rose_neigh->dev->name : "???",
-			   rose_neigh->count,
-			   refcount_read(&rose_neigh->use) - rose_neigh->count - 1,
-			   (rose_neigh->dce_mode) ? "DCE" : "DTE",
-			   (rose_neigh->restarted) ? "yes" : "no",
-			   ax25_display_timer(&rose_neigh->t0timer) / HZ,
-			   ax25_display_timer(&rose_neigh->ftimer)  / HZ);
-
-		if (rose_neigh->digipeat != NULL) {
-			for (i = 0; i < rose_neigh->digipeat->ndigi; i++)
-				seq_printf(seq, " %s", ax2asc(buf, &rose_neigh->digipeat->calls[i]));
-		}
-
-		seq_puts(seq, "\n");
-	}
-	return 0;
-}
-
-
-const struct seq_operations rose_neigh_seqops = {
-	.start = rose_neigh_start,
-	.next = rose_neigh_next,
-	.stop = rose_neigh_stop,
-	.show = rose_neigh_show,
-};
-
-static void *rose_route_start(struct seq_file *seq, loff_t *pos)
-	__acquires(rose_route_list_lock)
-{
-	struct rose_route *rose_route;
-	int i = 1;
-
-	spin_lock_bh(&rose_route_list_lock);
-	if (*pos == 0)
-		return SEQ_START_TOKEN;
-
-	for (rose_route = rose_route_list; rose_route && i < *pos;
-	     rose_route = rose_route->next, ++i);
-
-	return (i == *pos) ? rose_route : NULL;
-}
-
-static void *rose_route_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	++*pos;
-
-	return (v == SEQ_START_TOKEN) ? rose_route_list
-		: ((struct rose_route *)v)->next;
-}
-
-static void rose_route_stop(struct seq_file *seq, void *v)
-	__releases(rose_route_list_lock)
-{
-	spin_unlock_bh(&rose_route_list_lock);
-}
-
-static int rose_route_show(struct seq_file *seq, void *v)
-{
-	char buf[11], rsbuf[11];
-
-	if (v == SEQ_START_TOKEN)
-		seq_puts(seq,
-			 "lci  address     callsign   neigh  <-> lci  address     callsign   neigh\n");
-	else {
-		struct rose_route *rose_route = v;
-
-		if (rose_route->neigh1)
-			seq_printf(seq,
-				   "%3.3X  %-10s  %-9s  %05d      ",
-				   rose_route->lci1,
-				   rose2asc(rsbuf, &rose_route->src_addr),
-				   ax2asc(buf, &rose_route->src_call),
-				   rose_route->neigh1->number);
-		else
-			seq_puts(seq,
-				 "000  *           *          00000      ");
-
-		if (rose_route->neigh2)
-			seq_printf(seq,
-				   "%3.3X  %-10s  %-9s  %05d\n",
-				   rose_route->lci2,
-				   rose2asc(rsbuf, &rose_route->dest_addr),
-				   ax2asc(buf, &rose_route->dest_call),
-				   rose_route->neigh2->number);
-		 else
-			 seq_puts(seq,
-				  "000  *           *          00000\n");
-		}
-	return 0;
-}
-
-struct seq_operations rose_route_seqops = {
-	.start = rose_route_start,
-	.next = rose_route_next,
-	.stop = rose_route_stop,
-	.show = rose_route_show,
-};
-#endif /* CONFIG_PROC_FS */
-
-/*
- *	Release all memory associated with ROSE routing structures.
- */
-void __exit rose_rt_free(void)
-{
-	struct rose_neigh *s, *rose_neigh = rose_neigh_list;
-	struct rose_node  *t, *rose_node  = rose_node_list;
-	struct rose_route *u, *rose_route = rose_route_list;
-	int i;
-
-	while (rose_neigh != NULL) {
-		s          = rose_neigh;
-		rose_neigh = rose_neigh->next;
-
-		rose_remove_neigh(s);
-		rose_neigh_put(s);
-	}
-
-	while (rose_node != NULL) {
-		t         = rose_node;
-		rose_node = rose_node->next;
-
-		for (i = 0; i < t->count; i++)
-			rose_neigh_put(t->neighbour[i]);
-		rose_remove_node(t);
-	}
-
-	while (rose_route != NULL) {
-		u          = rose_route;
-		rose_route = rose_route->next;
-
-		rose_remove_route(u);
-	}
-}
diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c
deleted file mode 100644
index 4dbc437a9e22..000000000000
--- a/net/rose/rose_subr.c
+++ /dev/null
@@ -1,556 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <net/rose.h>
-
-static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose);
-
-/*
- *	This routine purges all of the queues of frames.
- */
-void rose_clear_queues(struct sock *sk)
-{
-	skb_queue_purge(&sk->sk_write_queue);
-	skb_queue_purge(&rose_sk(sk)->ack_queue);
-}
-
-/*
- * This routine purges the input queue of those frames that have been
- * acknowledged. This replaces the boxes labelled "V(a) <- N(r)" on the
- * SDL diagram.
- */
-void rose_frames_acked(struct sock *sk, unsigned short nr)
-{
-	struct sk_buff *skb;
-	struct rose_sock *rose = rose_sk(sk);
-
-	/*
-	 * Remove all the ack-ed frames from the ack queue.
-	 */
-	if (rose->va != nr) {
-		while (skb_peek(&rose->ack_queue) != NULL && rose->va != nr) {
-			skb = skb_dequeue(&rose->ack_queue);
-			kfree_skb(skb);
-			rose->va = (rose->va + 1) % ROSE_MODULUS;
-		}
-	}
-}
-
-void rose_requeue_frames(struct sock *sk)
-{
-	struct sk_buff *skb, *skb_prev = NULL;
-
-	/*
-	 * Requeue all the un-ack-ed frames on the output queue to be picked
-	 * up by rose_kick. This arrangement handles the possibility of an
-	 * empty output queue.
-	 */
-	while ((skb = skb_dequeue(&rose_sk(sk)->ack_queue)) != NULL) {
-		if (skb_prev == NULL)
-			skb_queue_head(&sk->sk_write_queue, skb);
-		else
-			skb_append(skb_prev, skb, &sk->sk_write_queue);
-		skb_prev = skb;
-	}
-}
-
-/*
- *	Validate that the value of nr is between va and vs. Return true or
- *	false for testing.
- */
-int rose_validate_nr(struct sock *sk, unsigned short nr)
-{
-	struct rose_sock *rose = rose_sk(sk);
-	unsigned short vc = rose->va;
-
-	while (vc != rose->vs) {
-		if (nr == vc) return 1;
-		vc = (vc + 1) % ROSE_MODULUS;
-	}
-
-	return nr == rose->vs;
-}
-
-/*
- *  This routine is called when the packet layer internally generates a
- *  control frame.
- */
-void rose_write_internal(struct sock *sk, int frametype)
-{
-	struct rose_sock *rose = rose_sk(sk);
-	struct sk_buff *skb;
-	unsigned char  *dptr;
-	unsigned char  lci1, lci2;
-	int maxfaclen = 0;
-	int len, faclen;
-	int reserve;
-
-	reserve = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + 1;
-	len = ROSE_MIN_LEN;
-
-	switch (frametype) {
-	case ROSE_CALL_REQUEST:
-		len   += 1 + ROSE_ADDR_LEN + ROSE_ADDR_LEN;
-		maxfaclen = 256;
-		break;
-	case ROSE_CALL_ACCEPTED:
-	case ROSE_CLEAR_REQUEST:
-	case ROSE_RESET_REQUEST:
-		len   += 2;
-		break;
-	}
-
-	skb = alloc_skb(reserve + len + maxfaclen, GFP_ATOMIC);
-	if (!skb)
-		return;
-
-	/*
-	 *	Space for AX.25 header and PID.
-	 */
-	skb_reserve(skb, reserve);
-
-	dptr = skb_put(skb, len);
-
-	lci1 = (rose->lci >> 8) & 0x0F;
-	lci2 = (rose->lci >> 0) & 0xFF;
-
-	switch (frametype) {
-	case ROSE_CALL_REQUEST:
-		*dptr++ = ROSE_GFI | lci1;
-		*dptr++ = lci2;
-		*dptr++ = frametype;
-		*dptr++ = ROSE_CALL_REQ_ADDR_LEN_VAL;
-		memcpy(dptr, &rose->dest_addr,  ROSE_ADDR_LEN);
-		dptr   += ROSE_ADDR_LEN;
-		memcpy(dptr, &rose->source_addr, ROSE_ADDR_LEN);
-		dptr   += ROSE_ADDR_LEN;
-		faclen = rose_create_facilities(dptr, rose);
-		skb_put(skb, faclen);
-		dptr   += faclen;
-		break;
-
-	case ROSE_CALL_ACCEPTED:
-		*dptr++ = ROSE_GFI | lci1;
-		*dptr++ = lci2;
-		*dptr++ = frametype;
-		*dptr++ = 0x00;		/* Address length */
-		*dptr++ = 0;		/* Facilities length */
-		break;
-
-	case ROSE_CLEAR_REQUEST:
-		*dptr++ = ROSE_GFI | lci1;
-		*dptr++ = lci2;
-		*dptr++ = frametype;
-		*dptr++ = rose->cause;
-		*dptr++ = rose->diagnostic;
-		break;
-
-	case ROSE_RESET_REQUEST:
-		*dptr++ = ROSE_GFI | lci1;
-		*dptr++ = lci2;
-		*dptr++ = frametype;
-		*dptr++ = ROSE_DTE_ORIGINATED;
-		*dptr++ = 0;
-		break;
-
-	case ROSE_RR:
-	case ROSE_RNR:
-		*dptr++ = ROSE_GFI | lci1;
-		*dptr++ = lci2;
-		*dptr   = frametype;
-		*dptr++ |= (rose->vr << 5) & 0xE0;
-		break;
-
-	case ROSE_CLEAR_CONFIRMATION:
-	case ROSE_RESET_CONFIRMATION:
-		*dptr++ = ROSE_GFI | lci1;
-		*dptr++ = lci2;
-		*dptr++  = frametype;
-		break;
-
-	default:
-		printk(KERN_ERR "ROSE: rose_write_internal - invalid frametype %02X\n", frametype);
-		kfree_skb(skb);
-		return;
-	}
-
-	rose_transmit_link(skb, rose->neighbour);
-}
-
-int rose_decode(struct sk_buff *skb, int *ns, int *nr, int *q, int *d, int *m)
-{
-	unsigned char *frame;
-
-	frame = skb->data;
-
-	*ns = *nr = *q = *d = *m = 0;
-
-	switch (frame[2]) {
-	case ROSE_CALL_REQUEST:
-	case ROSE_CALL_ACCEPTED:
-	case ROSE_CLEAR_REQUEST:
-	case ROSE_CLEAR_CONFIRMATION:
-	case ROSE_RESET_REQUEST:
-	case ROSE_RESET_CONFIRMATION:
-		return frame[2];
-	default:
-		break;
-	}
-
-	if ((frame[2] & 0x1F) == ROSE_RR  ||
-	    (frame[2] & 0x1F) == ROSE_RNR) {
-		*nr = (frame[2] >> 5) & 0x07;
-		return frame[2] & 0x1F;
-	}
-
-	if ((frame[2] & 0x01) == ROSE_DATA) {
-		*q  = (frame[0] & ROSE_Q_BIT) == ROSE_Q_BIT;
-		*d  = (frame[0] & ROSE_D_BIT) == ROSE_D_BIT;
-		*m  = (frame[2] & ROSE_M_BIT) == ROSE_M_BIT;
-		*nr = (frame[2] >> 5) & 0x07;
-		*ns = (frame[2] >> 1) & 0x07;
-		return ROSE_DATA;
-	}
-
-	return ROSE_ILLEGAL;
-}
-
-static int rose_parse_national(unsigned char *p, struct rose_facilities_struct *facilities, int len)
-{
-	unsigned char *pt;
-	unsigned char l, lg, n = 0;
-	int fac_national_digis_received = 0;
-
-	do {
-		switch (*p & 0xC0) {
-		case 0x00:
-			if (len < 2)
-				return -1;
-			p   += 2;
-			n   += 2;
-			len -= 2;
-			break;
-
-		case 0x40:
-			if (len < 3)
-				return -1;
-			if (*p == FAC_NATIONAL_RAND)
-				facilities->rand = ((p[1] << 8) & 0xFF00) + ((p[2] << 0) & 0x00FF);
-			p   += 3;
-			n   += 3;
-			len -= 3;
-			break;
-
-		case 0x80:
-			if (len < 4)
-				return -1;
-			p   += 4;
-			n   += 4;
-			len -= 4;
-			break;
-
-		case 0xC0:
-			if (len < 2)
-				return -1;
-			l = p[1];
-			if (len < 2 + l)
-				return -1;
-			if (*p == FAC_NATIONAL_DEST_DIGI) {
-				if (!fac_national_digis_received) {
-					if (l < AX25_ADDR_LEN)
-						return -1;
-					memcpy(&facilities->source_digis[0], p + 2, AX25_ADDR_LEN);
-					facilities->source_ndigis = 1;
-				}
-			}
-			else if (*p == FAC_NATIONAL_SRC_DIGI) {
-				if (!fac_national_digis_received) {
-					if (l < AX25_ADDR_LEN)
-						return -1;
-					memcpy(&facilities->dest_digis[0], p + 2, AX25_ADDR_LEN);
-					facilities->dest_ndigis = 1;
-				}
-			}
-			else if (*p == FAC_NATIONAL_FAIL_CALL) {
-				if (l < AX25_ADDR_LEN)
-					return -1;
-				memcpy(&facilities->fail_call, p + 2, AX25_ADDR_LEN);
-			}
-			else if (*p == FAC_NATIONAL_FAIL_ADD) {
-				if (l < 1 + ROSE_ADDR_LEN)
-					return -1;
-				memcpy(&facilities->fail_addr, p + 3, ROSE_ADDR_LEN);
-			}
-			else if (*p == FAC_NATIONAL_DIGIS) {
-				if (l % AX25_ADDR_LEN)
-					return -1;
-				fac_national_digis_received = 1;
-				facilities->source_ndigis = 0;
-				facilities->dest_ndigis   = 0;
-				for (pt = p + 2, lg = 0 ; lg < l ; pt += AX25_ADDR_LEN, lg += AX25_ADDR_LEN) {
-					if (pt[6] & AX25_HBIT) {
-						if (facilities->dest_ndigis >= ROSE_MAX_DIGIS)
-							return -1;
-						memcpy(&facilities->dest_digis[facilities->dest_ndigis++], pt, AX25_ADDR_LEN);
-					} else {
-						if (facilities->source_ndigis >= ROSE_MAX_DIGIS)
-							return -1;
-						memcpy(&facilities->source_digis[facilities->source_ndigis++], pt, AX25_ADDR_LEN);
-					}
-				}
-			}
-			p   += l + 2;
-			n   += l + 2;
-			len -= l + 2;
-			break;
-		}
-	} while (*p != 0x00 && len > 0);
-
-	return n;
-}
-
-static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *facilities, int len)
-{
-	unsigned char l, n = 0;
-	char callsign[11];
-
-	do {
-		switch (*p & 0xC0) {
-		case 0x00:
-			if (len < 2)
-				return -1;
-			p   += 2;
-			n   += 2;
-			len -= 2;
-			break;
-
-		case 0x40:
-			if (len < 3)
-				return -1;
-			p   += 3;
-			n   += 3;
-			len -= 3;
-			break;
-
-		case 0x80:
-			if (len < 4)
-				return -1;
-			p   += 4;
-			n   += 4;
-			len -= 4;
-			break;
-
-		case 0xC0:
-			if (len < 2)
-				return -1;
-			l = p[1];
-
-			/* Prevent overflows*/
-			if (l < 10 || l > 20)
-				return -1;
-
-			if (*p == FAC_CCITT_DEST_NSAP) {
-				memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN);
-				memcpy(callsign, p + 12,   l - 10);
-				callsign[l - 10] = '\0';
-				asc2ax(&facilities->source_call, callsign);
-			}
-			if (*p == FAC_CCITT_SRC_NSAP) {
-				memcpy(&facilities->dest_addr, p + 7, ROSE_ADDR_LEN);
-				memcpy(callsign, p + 12, l - 10);
-				callsign[l - 10] = '\0';
-				asc2ax(&facilities->dest_call, callsign);
-			}
-			p   += l + 2;
-			n   += l + 2;
-			len -= l + 2;
-			break;
-		}
-	} while (*p != 0x00 && len > 0);
-
-	return n;
-}
-
-int rose_parse_facilities(unsigned char *p, unsigned packet_len,
-	struct rose_facilities_struct *facilities)
-{
-	int facilities_len, len;
-
-	facilities_len = *p++;
-
-	if (facilities_len == 0 || (unsigned int)facilities_len > packet_len)
-		return 0;
-
-	while (facilities_len >= 3 && *p == 0x00) {
-		facilities_len--;
-		p++;
-
-		switch (*p) {
-		case FAC_NATIONAL:		/* National */
-			len = rose_parse_national(p + 1, facilities, facilities_len - 1);
-			break;
-
-		case FAC_CCITT:		/* CCITT */
-			len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1);
-			break;
-
-		default:
-			printk(KERN_DEBUG "ROSE: rose_parse_facilities - unknown facilities family %02X\n", *p);
-			len = 1;
-			break;
-		}
-
-		if (len < 0)
-			return 0;
-		if (WARN_ON(len >= facilities_len))
-			return 0;
-		facilities_len -= len + 1;
-		p += len + 1;
-	}
-
-	return facilities_len == 0;
-}
-
-static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose)
-{
-	unsigned char *p = buffer + 1;
-	char *callsign;
-	char buf[11];
-	int len, nb;
-
-	/* National Facilities */
-	if (rose->rand != 0 || rose->source_ndigis == 1 || rose->dest_ndigis == 1) {
-		*p++ = 0x00;
-		*p++ = FAC_NATIONAL;
-
-		if (rose->rand != 0) {
-			*p++ = FAC_NATIONAL_RAND;
-			*p++ = (rose->rand >> 8) & 0xFF;
-			*p++ = (rose->rand >> 0) & 0xFF;
-		}
-
-		/* Sent before older facilities */
-		if ((rose->source_ndigis > 0) || (rose->dest_ndigis > 0)) {
-			int maxdigi = 0;
-			*p++ = FAC_NATIONAL_DIGIS;
-			*p++ = AX25_ADDR_LEN * (rose->source_ndigis + rose->dest_ndigis);
-			for (nb = 0 ; nb < rose->source_ndigis ; nb++) {
-				if (++maxdigi >= ROSE_MAX_DIGIS)
-					break;
-				memcpy(p, &rose->source_digis[nb], AX25_ADDR_LEN);
-				p[6] |= AX25_HBIT;
-				p += AX25_ADDR_LEN;
-			}
-			for (nb = 0 ; nb < rose->dest_ndigis ; nb++) {
-				if (++maxdigi >= ROSE_MAX_DIGIS)
-					break;
-				memcpy(p, &rose->dest_digis[nb], AX25_ADDR_LEN);
-				p[6] &= ~AX25_HBIT;
-				p += AX25_ADDR_LEN;
-			}
-		}
-
-		/* For compatibility */
-		if (rose->source_ndigis > 0) {
-			*p++ = FAC_NATIONAL_SRC_DIGI;
-			*p++ = AX25_ADDR_LEN;
-			memcpy(p, &rose->source_digis[0], AX25_ADDR_LEN);
-			p   += AX25_ADDR_LEN;
-		}
-
-		/* For compatibility */
-		if (rose->dest_ndigis > 0) {
-			*p++ = FAC_NATIONAL_DEST_DIGI;
-			*p++ = AX25_ADDR_LEN;
-			memcpy(p, &rose->dest_digis[0], AX25_ADDR_LEN);
-			p   += AX25_ADDR_LEN;
-		}
-	}
-
-	*p++ = 0x00;
-	*p++ = FAC_CCITT;
-
-	*p++ = FAC_CCITT_DEST_NSAP;
-
-	callsign = ax2asc(buf, &rose->dest_call);
-
-	*p++ = strlen(callsign) + 10;
-	*p++ = (strlen(callsign) + 9) * 2;		/* ??? */
-
-	*p++ = 0x47; *p++ = 0x00; *p++ = 0x11;
-	*p++ = ROSE_ADDR_LEN * 2;
-	memcpy(p, &rose->dest_addr, ROSE_ADDR_LEN);
-	p   += ROSE_ADDR_LEN;
-
-	memcpy(p, callsign, strlen(callsign));
-	p   += strlen(callsign);
-
-	*p++ = FAC_CCITT_SRC_NSAP;
-
-	callsign = ax2asc(buf, &rose->source_call);
-
-	*p++ = strlen(callsign) + 10;
-	*p++ = (strlen(callsign) + 9) * 2;		/* ??? */
-
-	*p++ = 0x47; *p++ = 0x00; *p++ = 0x11;
-	*p++ = ROSE_ADDR_LEN * 2;
-	memcpy(p, &rose->source_addr, ROSE_ADDR_LEN);
-	p   += ROSE_ADDR_LEN;
-
-	memcpy(p, callsign, strlen(callsign));
-	p   += strlen(callsign);
-
-	len       = p - buffer;
-	buffer[0] = len - 1;
-
-	return len;
-}
-
-void rose_disconnect(struct sock *sk, int reason, int cause, int diagnostic)
-{
-	struct rose_sock *rose = rose_sk(sk);
-
-	rose_stop_timer(sk);
-	rose_stop_idletimer(sk);
-
-	rose_clear_queues(sk);
-
-	rose->lci   = 0;
-	rose->state = ROSE_STATE_0;
-
-	if (cause != -1)
-		rose->cause = cause;
-
-	if (diagnostic != -1)
-		rose->diagnostic = diagnostic;
-
-	sk->sk_state     = TCP_CLOSE;
-	sk->sk_err       = reason;
-	sk->sk_shutdown |= SEND_SHUTDOWN;
-
-	if (!sock_flag(sk, SOCK_DEAD)) {
-		sk->sk_state_change(sk);
-		sock_set_flag(sk, SOCK_DEAD);
-	}
-}
diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c
deleted file mode 100644
index bb60a1654d61..000000000000
--- a/net/rose/rose_timer.c
+++ /dev/null
@@ -1,227 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) 2002 Ralf Baechle DO1GRB (ralf@gnu.org)
- */
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/jiffies.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <net/ax25.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <net/rose.h>
-
-static void rose_heartbeat_expiry(struct timer_list *t);
-static void rose_timer_expiry(struct timer_list *);
-static void rose_idletimer_expiry(struct timer_list *);
-
-void rose_start_heartbeat(struct sock *sk)
-{
-	sk_stop_timer(sk, &sk->sk_timer);
-
-	sk->sk_timer.function = rose_heartbeat_expiry;
-	sk->sk_timer.expires  = jiffies + 5 * HZ;
-
-	sk_reset_timer(sk, &sk->sk_timer, sk->sk_timer.expires);
-}
-
-void rose_start_t1timer(struct sock *sk)
-{
-	struct rose_sock *rose = rose_sk(sk);
-
-	sk_stop_timer(sk, &rose->timer);
-
-	rose->timer.function = rose_timer_expiry;
-	rose->timer.expires  = jiffies + rose->t1;
-
-	sk_reset_timer(sk, &rose->timer, rose->timer.expires);
-}
-
-void rose_start_t2timer(struct sock *sk)
-{
-	struct rose_sock *rose = rose_sk(sk);
-
-	sk_stop_timer(sk, &rose->timer);
-
-	rose->timer.function = rose_timer_expiry;
-	rose->timer.expires  = jiffies + rose->t2;
-
-	sk_reset_timer(sk, &rose->timer, rose->timer.expires);
-}
-
-void rose_start_t3timer(struct sock *sk)
-{
-	struct rose_sock *rose = rose_sk(sk);
-
-	sk_stop_timer(sk, &rose->timer);
-
-	rose->timer.function = rose_timer_expiry;
-	rose->timer.expires  = jiffies + rose->t3;
-
-	sk_reset_timer(sk, &rose->timer, rose->timer.expires);
-}
-
-void rose_start_hbtimer(struct sock *sk)
-{
-	struct rose_sock *rose = rose_sk(sk);
-
-	sk_stop_timer(sk, &rose->timer);
-
-	rose->timer.function = rose_timer_expiry;
-	rose->timer.expires  = jiffies + rose->hb;
-
-	sk_reset_timer(sk, &rose->timer, rose->timer.expires);
-}
-
-void rose_start_idletimer(struct sock *sk)
-{
-	struct rose_sock *rose = rose_sk(sk);
-
-	sk_stop_timer(sk, &rose->idletimer);
-
-	if (rose->idle > 0) {
-		rose->idletimer.function = rose_idletimer_expiry;
-		rose->idletimer.expires  = jiffies + rose->idle;
-
-		sk_reset_timer(sk, &rose->idletimer, rose->idletimer.expires);
-	}
-}
-
-void rose_stop_heartbeat(struct sock *sk)
-{
-	sk_stop_timer(sk, &sk->sk_timer);
-}
-
-void rose_stop_timer(struct sock *sk)
-{
-	sk_stop_timer(sk, &rose_sk(sk)->timer);
-}
-
-void rose_stop_idletimer(struct sock *sk)
-{
-	sk_stop_timer(sk, &rose_sk(sk)->idletimer);
-}
-
-static void rose_heartbeat_expiry(struct timer_list *t)
-{
-	struct sock *sk = timer_container_of(sk, t, sk_timer);
-	struct rose_sock *rose = rose_sk(sk);
-
-	bh_lock_sock(sk);
-	if (sock_owned_by_user(sk)) {
-		sk_reset_timer(sk, &sk->sk_timer, jiffies + HZ/20);
-		goto out;
-	}
-	switch (rose->state) {
-	case ROSE_STATE_0:
-		/* Magic here: If we listen() and a new link dies before it
-		   is accepted() it isn't 'dead' so doesn't get removed. */
-		if (sock_flag(sk, SOCK_DESTROY) ||
-		    (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) {
-			bh_unlock_sock(sk);
-			rose_destroy_socket(sk);
-			sock_put(sk);
-			return;
-		}
-		break;
-
-	case ROSE_STATE_3:
-		/*
-		 * Check for the state of the receive buffer.
-		 */
-		if (atomic_read(&sk->sk_rmem_alloc) < (sk->sk_rcvbuf / 2) &&
-		    (rose->condition & ROSE_COND_OWN_RX_BUSY)) {
-			rose->condition &= ~ROSE_COND_OWN_RX_BUSY;
-			rose->condition &= ~ROSE_COND_ACK_PENDING;
-			rose->vl         = rose->vr;
-			rose_write_internal(sk, ROSE_RR);
-			rose_stop_timer(sk);	/* HB */
-			break;
-		}
-		break;
-	}
-
-	rose_start_heartbeat(sk);
-out:
-	bh_unlock_sock(sk);
-	sock_put(sk);
-}
-
-static void rose_timer_expiry(struct timer_list *t)
-{
-	struct rose_sock *rose = timer_container_of(rose, t, timer);
-	struct sock *sk = &rose->sock;
-
-	bh_lock_sock(sk);
-	if (sock_owned_by_user(sk)) {
-		sk_reset_timer(sk, &rose->timer, jiffies + HZ/20);
-		goto out;
-	}
-	switch (rose->state) {
-	case ROSE_STATE_1:	/* T1 */
-	case ROSE_STATE_4:	/* T2 */
-		rose_write_internal(sk, ROSE_CLEAR_REQUEST);
-		rose->state = ROSE_STATE_2;
-		rose_start_t3timer(sk);
-		break;
-
-	case ROSE_STATE_2:	/* T3 */
-		rose_neigh_put(rose->neighbour);
-		rose_disconnect(sk, ETIMEDOUT, -1, -1);
-		break;
-
-	case ROSE_STATE_3:	/* HB */
-		if (rose->condition & ROSE_COND_ACK_PENDING) {
-			rose->condition &= ~ROSE_COND_ACK_PENDING;
-			rose_enquiry_response(sk);
-		}
-		break;
-	}
-out:
-	bh_unlock_sock(sk);
-	sock_put(sk);
-}
-
-static void rose_idletimer_expiry(struct timer_list *t)
-{
-	struct rose_sock *rose = timer_container_of(rose, t, idletimer);
-	struct sock *sk = &rose->sock;
-
-	bh_lock_sock(sk);
-	if (sock_owned_by_user(sk)) {
-		sk_reset_timer(sk, &rose->idletimer, jiffies + HZ/20);
-		goto out;
-	}
-	rose_clear_queues(sk);
-
-	rose_write_internal(sk, ROSE_CLEAR_REQUEST);
-	rose_sk(sk)->state = ROSE_STATE_2;
-
-	rose_start_t3timer(sk);
-
-	sk->sk_state     = TCP_CLOSE;
-	sk->sk_err       = 0;
-	sk->sk_shutdown |= SEND_SHUTDOWN;
-
-	if (!sock_flag(sk, SOCK_DEAD)) {
-		sk->sk_state_change(sk);
-		sock_set_flag(sk, SOCK_DEAD);
-	}
-out:
-	bh_unlock_sock(sk);
-	sock_put(sk);
-}
diff --git a/net/rose/sysctl_net_rose.c b/net/rose/sysctl_net_rose.c
deleted file mode 100644
index d801315b7083..000000000000
--- a/net/rose/sysctl_net_rose.c
+++ /dev/null
@@ -1,125 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (C) 1996 Mike Shaver (shaver@zeroknowledge.com)
- */
-#include <linux/mm.h>
-#include <linux/sysctl.h>
-#include <linux/init.h>
-#include <net/ax25.h>
-#include <net/rose.h>
-
-static int min_timer[]  = {1 * HZ};
-static int max_timer[]  = {300 * HZ};
-static int min_idle[]   = {0 * HZ};
-static int max_idle[]   = {65535 * HZ};
-static int min_route[1],       max_route[] = {1};
-static int min_ftimer[] = {60 * HZ};
-static int max_ftimer[] = {600 * HZ};
-static int min_maxvcs[] = {1}, max_maxvcs[] = {254};
-static int min_window[] = {1}, max_window[] = {7};
-
-static struct ctl_table_header *rose_table_header;
-
-static struct ctl_table rose_table[] = {
-	{
-		.procname	= "restart_request_timeout",
-		.data		= &sysctl_rose_restart_request_timeout,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_timer,
-		.extra2		= &max_timer
-	},
-	{
-		.procname	= "call_request_timeout",
-		.data		= &sysctl_rose_call_request_timeout,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_timer,
-		.extra2		= &max_timer
-	},
-	{
-		.procname	= "reset_request_timeout",
-		.data		= &sysctl_rose_reset_request_timeout,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_timer,
-		.extra2		= &max_timer
-	},
-	{
-		.procname	= "clear_request_timeout",
-		.data		= &sysctl_rose_clear_request_timeout,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_timer,
-		.extra2		= &max_timer
-	},
-	{
-		.procname	= "no_activity_timeout",
-		.data		= &sysctl_rose_no_activity_timeout,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_idle,
-		.extra2		= &max_idle
-	},
-	{
-		.procname	= "acknowledge_hold_back_timeout",
-		.data		= &sysctl_rose_ack_hold_back_timeout,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_timer,
-		.extra2		= &max_timer
-	},
-	{
-		.procname	= "routing_control",
-		.data		= &sysctl_rose_routing_control,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_route,
-		.extra2		= &max_route
-	},
-	{
-		.procname	= "link_fail_timeout",
-		.data		= &sysctl_rose_link_fail_timeout,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_ftimer,
-		.extra2		= &max_ftimer
-	},
-	{
-		.procname	= "maximum_virtual_circuits",
-		.data		= &sysctl_rose_maximum_vcs,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_maxvcs,
-		.extra2		= &max_maxvcs
-	},
-	{
-		.procname	= "window_size",
-		.data		= &sysctl_rose_window_size,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &min_window,
-		.extra2		= &max_window
-	},
-};
-
-void __init rose_register_sysctl(void)
-{
-	rose_table_header = register_net_sysctl(&init_net, "net/rose", rose_table);
-}
-
-void rose_unregister_sysctl(void)
-{
-	unregister_net_sysctl_table(rose_table_header);
-}
diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig
index d10b3d4adbd1..acbab8dae53f 100644
--- a/arch/mips/configs/bcm47xx_defconfig
+++ b/arch/mips/configs/bcm47xx_defconfig
@@ -28,7 +28,6 @@ CONFIG_NETFILTER=y
 CONFIG_VLAN_8021Q=y
 CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_FQ_CODEL=y
-CONFIG_HAMRADIO=y
 CONFIG_CFG80211=y
 CONFIG_MAC80211=y
 CONFIG_MTD=y
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index 3b64e151e187..aa63ada62e28 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -84,16 +84,6 @@ CONFIG_IP_VS_FTP=m
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
 CONFIG_VLAN_8021Q_GVRP=y
-CONFIG_HAMRADIO=y
-CONFIG_AX25=m
-CONFIG_NETROM=m
-CONFIG_ROSE=m
-CONFIG_MKISS=m
-CONFIG_6PACK=m
-CONFIG_BPQETHER=m
-CONFIG_BAYCOM_SER_FDX=m
-CONFIG_BAYCOM_SER_HDX=m
-CONFIG_YAM=m
 CONFIG_FW_LOADER=m
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_NBD=m
diff --git a/arch/mips/configs/gpr_defconfig b/arch/mips/configs/gpr_defconfig
index 8097974489e3..ad80ad2eae6b 100644
--- a/arch/mips/configs/gpr_defconfig
+++ b/arch/mips/configs/gpr_defconfig
@@ -126,17 +126,6 @@ CONFIG_NET_EMATCH_TEXT=m
 CONFIG_NET_CLS_ACT=y
 CONFIG_NET_ACT_POLICE=y
 CONFIG_NET_PKTGEN=m
-CONFIG_HAMRADIO=y
-CONFIG_AX25=m
-# CONFIG_AX25_DAMA_SLAVE is not set
-CONFIG_NETROM=m
-CONFIG_ROSE=m
-CONFIG_MKISS=m
-CONFIG_6PACK=m
-CONFIG_BPQETHER=m
-CONFIG_BAYCOM_SER_FDX=m
-CONFIG_BAYCOM_SER_HDX=m
-CONFIG_YAM=m
 CONFIG_CFG80211=y
 CONFIG_MAC80211=y
 CONFIG_MTD=y
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig
index 63787b8b733e..1295164af08e 100644
--- a/arch/mips/configs/mtx1_defconfig
+++ b/arch/mips/configs/mtx1_defconfig
@@ -172,17 +172,6 @@ CONFIG_NET_EMATCH_TEXT=m
 CONFIG_NET_CLS_ACT=y
 CONFIG_NET_ACT_POLICE=y
 CONFIG_NET_PKTGEN=m
-CONFIG_HAMRADIO=y
-CONFIG_AX25=m
-# CONFIG_AX25_DAMA_SLAVE is not set
-CONFIG_NETROM=m
-CONFIG_ROSE=m
-CONFIG_MKISS=m
-CONFIG_6PACK=m
-CONFIG_BPQETHER=m
-CONFIG_BAYCOM_SER_FDX=m
-CONFIG_BAYCOM_SER_HDX=m
-CONFIG_YAM=m
 CONFIG_BT=m
 CONFIG_BT_RFCOMM=m
 CONFIG_BT_RFCOMM_TTY=y
diff --git a/arch/mips/configs/rb532_defconfig b/arch/mips/configs/rb532_defconfig
index 30d18b084cda..a88322fe3935 100644
--- a/arch/mips/configs/rb532_defconfig
+++ b/arch/mips/configs/rb532_defconfig
@@ -95,7 +95,6 @@ CONFIG_NET_ACT_GACT=m
 CONFIG_GACT_PROB=y
 CONFIG_NET_ACT_MIRRED=m
 CONFIG_NET_ACT_PEDIT=m
-CONFIG_HAMRADIO=y
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_BLOCK2MTD=y
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index b1e67ff0c4f0..ad9fbd0cbb38 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -147,13 +147,6 @@ CONFIG_NET_CLS_FW=m
 CONFIG_NET_CLS_U32=m
 CONFIG_NET_CLS_RSVP=m
 CONFIG_NET_CLS_RSVP6=m
-CONFIG_HAMRADIO=y
-CONFIG_AX25=m
-CONFIG_NETROM=m
-CONFIG_ROSE=m
-CONFIG_MKISS=m
-CONFIG_6PACK=m
-CONFIG_BPQETHER=m
 CONFIG_CONNECTOR=m
 CONFIG_PARPORT=m
 CONFIG_PARPORT_PC=m
diff --git a/arch/mips/configs/rt305x_defconfig b/arch/mips/configs/rt305x_defconfig
index 8f9701efef19..c920976bedd0 100644
--- a/arch/mips/configs/rt305x_defconfig
+++ b/arch/mips/configs/rt305x_defconfig
@@ -64,7 +64,6 @@ CONFIG_BRIDGE=y
 # CONFIG_BRIDGE_IGMP_SNOOPING is not set
 CONFIG_VLAN_8021Q=y
 CONFIG_NET_SCHED=y
-CONFIG_HAMRADIO=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_BLOCK=y
diff --git a/arch/mips/configs/xway_defconfig b/arch/mips/configs/xway_defconfig
index aae8497b6872..f1c53bbb72e9 100644
--- a/arch/mips/configs/xway_defconfig
+++ b/arch/mips/configs/xway_defconfig
@@ -66,7 +66,6 @@ CONFIG_BRIDGE=y
 # CONFIG_BRIDGE_IGMP_SNOOPING is not set
 CONFIG_VLAN_8021Q=y
 CONFIG_NET_SCHED=y
-CONFIG_HAMRADIO=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_BLOCK=y
-- 
2.53.0


^ permalink raw reply related

* [PATCH net-deletions] net: remove unused ATM protocols and legacy ATM device drivers
From: Jakub Kicinski @ 2026-04-21  2:19 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, Jakub Kicinski,
	corbet, skhan, linux, tsbogend, maddy, mpe, npiggin, chleroy,
	3chas3, razor, idosch, jani.nikula, mchehab+huawei, tytso,
	herbert, geert, ebiggers, johannes.berg, jonathan.cameron, kees,
	kuniyu, fourier.thomas, andriy.shevchenko, rdunlap, akpm,
	linux-doc, linux-mips, linuxppc-dev, bridge

Remove the ATM protocol modules and PCI/SBUS ATM device drivers
that are no longer in active use.

The ATM core protocol stack, PPPoATM, and USB DSL modem drivers
(drivers/usb/atm/) are retained in-tree to maintain PPP over ATM
(PPPoA) support for DSL connections.

Removed ATM protocol modules:
 - net/atm/clip.c - Classical IP over ATM (RFC 2225)
 - net/atm/br2684.c - RFC 2684 bridged protocols
 - net/atm/lec.c - LAN Emulation Client (LANE)
 - net/atm/mpc.c, mpoa_caches.c, mpoa_proc.c - Multi-Protocol Over ATM

Removed PCI/SBUS ATM device drivers (drivers/atm/):
 - adummy, atmtcp - software/testing ATM devices
 - eni - Efficient Networks ENI155P (OC-3, ~1995)
 - fore200e - FORE Systems 200E PCI/SBUS (OC-3, ~1999)
 - he - ForeRunner HE (OC-3/OC-12, ~2000)
 - idt77105 - IDT 77105 25 Mbps ATM PHY
 - idt77252 - IDT 77252 NICStAR II (OC-3, ~2000)
 - iphase - Interphase ATM PCI (OC-3/DS3/E3)
 - lanai - Efficient Networks Speedstream 3010
 - nicstar - IDT 77201 NICStAR (155/25 Mbps, ~1999)
 - solos-pci - Traverse Technologies ADSL2+ PCI (defunct vendor)
 - suni - PMC S/UNI SONET PHY library

Also clean up references in:
 - net/bridge/ - remove ATM LANE hook (br_fdb_test_addr_hook,
   br_fdb_test_addr)
 - net/core/dev.c - remove br_fdb_test_addr_hook export
 - defconfig files - remove ATM driver config options

The removed code is moved to an out-of-tree module package (mod-orphan).

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
CC: corbet@lwn.net
CC: skhan@linuxfoundation.org
CC: linux@armlinux.org.uk
CC: tsbogend@alpha.franken.de
CC: maddy@linux.ibm.com
CC: mpe@ellerman.id.au
CC: npiggin@gmail.com
CC: chleroy@kernel.org
CC: 3chas3@gmail.com
CC: razor@blackwall.org
CC: idosch@nvidia.com
CC: jani.nikula@intel.com
CC: mchehab+huawei@kernel.org
CC: tytso@mit.edu
CC: herbert@gondor.apana.org.au
CC: geert@linux-m68k.org
CC: ebiggers@kernel.org
CC: johannes.berg@intel.com
CC: jonathan.cameron@huawei.com
CC: kees@kernel.org
CC: kuniyu@google.com
CC: fourier.thomas@gmail.com
CC: andriy.shevchenko@intel.com
CC: rdunlap@infradead.org
CC: akpm@linux-foundation.org
CC: linux-doc@vger.kernel.org
CC: linux-mips@vger.kernel.org
CC: linuxppc-dev@lists.ozlabs.org
CC: bridge@lists.linux.dev
---
 MAINTAINERS                                   |    3 +-
 Documentation/.renames.txt                    |    2 -
 .../device_drivers/atm/fore200e.rst           |   66 -
 .../networking/device_drivers/atm/index.rst   |    2 -
 .../networking/device_drivers/atm/iphase.rst  |  193 -
 drivers/atm/Kconfig                           |  325 --
 drivers/net/Kconfig                           |    2 -
 net/atm/Kconfig                               |   58 -
 drivers/Makefile                              |    1 -
 drivers/atm/Makefile                          |   32 -
 net/atm/Makefile                              |    8 +-
 drivers/atm/eni.h                             |  136 -
 drivers/atm/fore200e.h                        |  973 -----
 drivers/atm/he.h                              |  845 ----
 drivers/atm/idt77105.h                        |   92 -
 drivers/atm/idt77252.h                        |  816 ----
 drivers/atm/idt77252_tables.h                 |  781 ----
 drivers/atm/iphase.h                          | 1452 -------
 drivers/atm/midway.h                          |  266 --
 drivers/atm/nicstar.h                         |  759 ----
 drivers/atm/suni.h                            |  242 --
 drivers/atm/tonga.h                           |   21 -
 drivers/atm/zeprom.h                          |   35 -
 net/atm/lec.h                                 |  155 -
 net/atm/lec_arpc.h                            |   97 -
 net/atm/mpc.h                                 |   65 -
 net/atm/mpoa_caches.h                         |   99 -
 net/bridge/br_private.h                       |    4 -
 drivers/atm/adummy.c                          |  202 -
 drivers/atm/atmtcp.c                          |  513 ---
 drivers/atm/eni.c                             | 2321 ----------
 drivers/atm/fore200e.c                        | 3012 -------------
 drivers/atm/he.c                              | 2861 -------------
 drivers/atm/idt77105.c                        |  376 --
 drivers/atm/idt77252.c                        | 3797 -----------------
 drivers/atm/iphase.c                          | 3283 --------------
 drivers/atm/lanai.c                           | 2603 -----------
 drivers/atm/nicstar.c                         | 2759 ------------
 drivers/atm/nicstarmac.c                      |  244 --
 drivers/atm/solos-attrlist.c                  |   83 -
 drivers/atm/solos-pci.c                       | 1496 -------
 drivers/atm/suni.c                            |  391 --
 net/atm/br2684.c                              |  872 ----
 net/atm/clip.c                                |  960 -----
 net/atm/lec.c                                 | 2274 ----------
 net/atm/mpc.c                                 | 1538 -------
 net/atm/mpoa_caches.c                         |  565 ---
 net/atm/mpoa_proc.c                           |  307 --
 net/bridge/br.c                               |    7 -
 net/bridge/br_fdb.c                           |   29 -
 net/core/dev.c                                |    7 -
 arch/arm/configs/ixp4xx_defconfig             |    5 -
 arch/mips/configs/gpr_defconfig               |   13 -
 arch/mips/configs/mtx1_defconfig              |   13 -
 arch/powerpc/configs/ppc6xx_defconfig         |    9 -
 drivers/atm/.gitignore                        |    5 -
 drivers/atm/nicstarmac.copyright              |   61 -
 57 files changed, 3 insertions(+), 38133 deletions(-)
 delete mode 100644 Documentation/networking/device_drivers/atm/fore200e.rst
 delete mode 100644 Documentation/networking/device_drivers/atm/iphase.rst
 delete mode 100644 drivers/atm/Kconfig
 delete mode 100644 drivers/atm/Makefile
 delete mode 100644 drivers/atm/eni.h
 delete mode 100644 drivers/atm/fore200e.h
 delete mode 100644 drivers/atm/he.h
 delete mode 100644 drivers/atm/idt77105.h
 delete mode 100644 drivers/atm/idt77252.h
 delete mode 100644 drivers/atm/idt77252_tables.h
 delete mode 100644 drivers/atm/iphase.h
 delete mode 100644 drivers/atm/midway.h
 delete mode 100644 drivers/atm/nicstar.h
 delete mode 100644 drivers/atm/suni.h
 delete mode 100644 drivers/atm/tonga.h
 delete mode 100644 drivers/atm/zeprom.h
 delete mode 100644 net/atm/lec.h
 delete mode 100644 net/atm/lec_arpc.h
 delete mode 100644 net/atm/mpc.h
 delete mode 100644 net/atm/mpoa_caches.h
 delete mode 100644 drivers/atm/adummy.c
 delete mode 100644 drivers/atm/atmtcp.c
 delete mode 100644 drivers/atm/eni.c
 delete mode 100644 drivers/atm/fore200e.c
 delete mode 100644 drivers/atm/he.c
 delete mode 100644 drivers/atm/idt77105.c
 delete mode 100644 drivers/atm/idt77252.c
 delete mode 100644 drivers/atm/iphase.c
 delete mode 100644 drivers/atm/lanai.c
 delete mode 100644 drivers/atm/nicstar.c
 delete mode 100644 drivers/atm/nicstarmac.c
 delete mode 100644 drivers/atm/solos-attrlist.c
 delete mode 100644 drivers/atm/solos-pci.c
 delete mode 100644 drivers/atm/suni.c
 delete mode 100644 net/atm/br2684.c
 delete mode 100644 net/atm/clip.c
 delete mode 100644 net/atm/lec.c
 delete mode 100644 net/atm/mpc.c
 delete mode 100644 net/atm/mpoa_caches.c
 delete mode 100644 net/atm/mpoa_proc.c
 delete mode 100644 drivers/atm/.gitignore
 delete mode 100644 drivers/atm/nicstarmac.copyright

diff --git a/MAINTAINERS b/MAINTAINERS
index 867ca44422d8..cfcf422dd40a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4150,11 +4150,12 @@ L:	linux-atm-general@lists.sourceforge.net (moderated for non-subscribers)
 L:	netdev@vger.kernel.org
 S:	Maintained
 W:	http://linux-atm.sourceforge.net
-F:	drivers/atm/
+F:	drivers/usb/atm/
 F:	include/linux/atm*
 F:	include/linux/sonet.h
 F:	include/uapi/linux/atm*
 F:	include/uapi/linux/sonet.h
+F:	net/atm/
 
 ATMEL MACB ETHERNET DRIVER
 M:	Nicolas Ferre <nicolas.ferre@microchip.com>
diff --git a/Documentation/.renames.txt b/Documentation/.renames.txt
index e5f2f7447914..df4db1121995 100644
--- a/Documentation/.renames.txt
+++ b/Documentation/.renames.txt
@@ -835,14 +835,12 @@ networking/e100 networking/device_drivers/ethernet/intel/e100
 networking/e1000 networking/device_drivers/ethernet/intel/e1000
 networking/e1000e networking/device_drivers/ethernet/intel/e1000e
 networking/fm10k networking/device_drivers/ethernet/intel/fm10k
-networking/fore200e networking/device_drivers/atm/fore200e
 networking/hinic networking/device_drivers/ethernet/huawei/hinic
 networking/i40e networking/device_drivers/ethernet/intel/i40e
 networking/iavf networking/device_drivers/ethernet/intel/iavf
 networking/ice networking/device_drivers/ethernet/intel/ice
 networking/igb networking/device_drivers/ethernet/intel/igb
 networking/igbvf networking/device_drivers/ethernet/intel/igbvf
-networking/iphase networking/device_drivers/atm/iphase
 networking/ixgbe networking/device_drivers/ethernet/intel/ixgbe
 networking/ixgbevf networking/device_drivers/ethernet/intel/ixgbevf
 networking/netdev-FAQ process/maintainer-netdev
diff --git a/Documentation/networking/device_drivers/atm/fore200e.rst b/Documentation/networking/device_drivers/atm/fore200e.rst
deleted file mode 100644
index 55df9ec09ac8..000000000000
--- a/Documentation/networking/device_drivers/atm/fore200e.rst
+++ /dev/null
@@ -1,66 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=============================================
-FORE Systems PCA-200E/SBA-200E ATM NIC driver
-=============================================
-
-This driver adds support for the FORE Systems 200E-series ATM adapters
-to the Linux operating system. It is based on the earlier PCA-200E driver
-written by Uwe Dannowski.
-
-The driver simultaneously supports PCA-200E and SBA-200E adapters on
-i386, alpha (untested), powerpc, sparc and sparc64 archs.
-
-The intent is to enable the use of different models of FORE adapters at the
-same time, by hosts that have several bus interfaces (such as PCI+SBUS,
-or PCI+EISA).
-
-Only PCI and SBUS devices are currently supported by the driver, but support
-for other bus interfaces such as EISA should not be too hard to add.
-
-
-Firmware Copyright Notice
--------------------------
-
-Please read the fore200e_firmware_copyright file present
-in the linux/drivers/atm directory for details and restrictions.
-
-
-Firmware Updates
-----------------
-
-The FORE Systems 200E-series driver is shipped with firmware data being
-uploaded to the ATM adapters at system boot time or at module loading time.
-The supplied firmware images should work with all adapters.
-
-However, if you encounter problems (the firmware doesn't start or the driver
-is unable to read the PROM data), you may consider trying another firmware
-version. Alternative binary firmware images can be found somewhere on the
-ForeThought CD-ROM supplied with your adapter by FORE Systems.
-
-You can also get the latest firmware images from FORE Systems at
-https://en.wikipedia.org/wiki/FORE_Systems. Register TACTics Online and go to
-the 'software updates' pages. The firmware binaries are part of
-the various ForeThought software distributions.
-
-Notice that different versions of the PCA-200E firmware exist, depending
-on the endianness of the host architecture. The driver is shipped with
-both little and big endian PCA firmware images.
-
-Name and location of the new firmware images can be set at kernel
-configuration time:
-
-1. Copy the new firmware binary files (with .bin, .bin1 or .bin2 suffix)
-   to some directory, such as linux/drivers/atm.
-
-2. Reconfigure your kernel to set the new firmware name and location.
-   Expected pathnames are absolute or relative to the drivers/atm directory.
-
-3. Rebuild and re-install your kernel or your module.
-
-
-Feedback
---------
-
-Feedback is welcome. Please send success stories/bug reports/
-patches/improvement/comments/flames to <lizzi@cnam.fr>.
diff --git a/Documentation/networking/device_drivers/atm/index.rst b/Documentation/networking/device_drivers/atm/index.rst
index 724552ca0be4..9392c86f48bc 100644
--- a/Documentation/networking/device_drivers/atm/index.rst
+++ b/Documentation/networking/device_drivers/atm/index.rst
@@ -9,5 +9,3 @@ Asynchronous Transfer Mode (ATM) Device Drivers
    :maxdepth: 2
 
    cxacru
-   fore200e
-   iphase
diff --git a/Documentation/networking/device_drivers/atm/iphase.rst b/Documentation/networking/device_drivers/atm/iphase.rst
deleted file mode 100644
index 388c7101e2cb..000000000000
--- a/Documentation/networking/device_drivers/atm/iphase.rst
+++ /dev/null
@@ -1,193 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==================================
-ATM (i)Chip IA Linux Driver Source
-==================================
-
-			      READ ME FIRST
-
---------------------------------------------------------------------------------
-
-		     Read This Before You Begin!
-
---------------------------------------------------------------------------------
-
-Description
-===========
-
-This is the README file for the Interphase PCI ATM (i)Chip IA Linux driver
-source release.
-
-The features and limitations of this driver are as follows:
-
-    - A single VPI (VPI value of 0) is supported.
-    - Supports 4K VCs for the server board (with 512K control memory) and 1K
-      VCs for the client board (with 128K control memory).
-    - UBR, ABR and CBR service categories are supported.
-    - Only AAL5 is supported.
-    - Supports setting of PCR on the VCs.
-    - Multiple adapters in a system are supported.
-    - All variants of Interphase ATM PCI (i)Chip adapter cards are supported,
-      including x575 (OC3, control memory 128K , 512K and packet memory 128K,
-      512K and 1M), x525 (UTP25) and x531 (DS3 and E3). See
-      http://www.iphase.com/
-      for details.
-    - Only x86 platforms are supported.
-    - SMP is supported.
-
-
-Before You Start
-================
-
-
-Installation
-------------
-
-1. Installing the adapters in the system
-
-   To install the ATM adapters in the system, follow the steps below.
-
-       a. Login as root.
-       b. Shut down the system and power off the system.
-       c. Install one or more ATM adapters in the system.
-       d. Connect each adapter to a port on an ATM switch. The green 'Link'
-	  LED on the front panel of the adapter will be on if the adapter is
-	  connected to the switch properly when the system is powered up.
-       e. Power on and boot the system.
-
-2. [ Removed ]
-
-3. Rebuild kernel with ABR support
-
-   [ a. and b. removed ]
-
-    c. Reconfigure the kernel, choose the Interphase ia driver through "make
-       menuconfig" or "make xconfig".
-    d. Rebuild the kernel, loadable modules and the atm tools.
-    e. Install the new built kernel and modules and reboot.
-
-4. Load the adapter hardware driver (ia driver) if it is built as a module
-
-       a. Login as root.
-       b. Change directory to /lib/modules/<kernel-version>/atm.
-       c. Run "insmod suni.o;insmod iphase.o"
-	  The yellow 'status' LED on the front panel of the adapter will blink
-	  while the driver is loaded in the system.
-       d. To verify that the 'ia' driver is loaded successfully, run the
-	  following command::
-
-	      cat /proc/atm/devices
-
-	  If the driver is loaded successfully, the output of the command will
-	  be similar to the following lines::
-
-	      Itf Type    ESI/"MAC"addr AAL(TX,err,RX,err,drop) ...
-	      0   ia      xxxxxxxxx  0 ( 0 0 0 0 0 )  5 ( 0 0 0 0 0 )
-
-	  You can also check the system log file /var/log/messages for messages
-	  related to the ATM driver.
-
-5. Ia Driver Configuration
-
-5.1 Configuration of adapter buffers
-    The (i)Chip boards have 3 different packet RAM size variants: 128K, 512K and
-    1M. The RAM size decides the number of buffers and buffer size. The default
-    size and number of buffers are set as following:
-
-	=========  =======  ======   ======   ======   ======   ======
-	 Total     Rx RAM   Tx RAM   Rx Buf   Tx Buf   Rx buf   Tx buf
-	 RAM size  size     size     size     size     cnt      cnt
-	=========  =======  ======   ======   ======   ======   ======
-	   128K      64K      64K      10K      10K       6        6
-	   512K     256K     256K      10K      10K      25       25
-	     1M     512K     512K      10K      10K      51       51
-	=========  =======  ======   ======   ======   ======   ======
-
-       These setting should work well in most environments, but can be
-       changed by typing the following command::
-
-	   insmod <IA_DIR>/ia.o IA_RX_BUF=<RX_CNT> IA_RX_BUF_SZ=<RX_SIZE> \
-		   IA_TX_BUF=<TX_CNT> IA_TX_BUF_SZ=<TX_SIZE>
-
-       Where:
-
-	    - RX_CNT = number of receive buffers in the range (1-128)
-	    - RX_SIZE = size of receive buffers in the range (48-64K)
-	    - TX_CNT = number of transmit buffers in the range (1-128)
-	    - TX_SIZE = size of transmit buffers in the range (48-64K)
-
-	    1. Transmit and receive buffer size must be a multiple of 4.
-	    2. Care should be taken so that the memory required for the
-	       transmit and receive buffers is less than or equal to the
-	       total adapter packet memory.
-
-5.2 Turn on ia debug trace
-
-    When the ia driver is built with the CONFIG_ATM_IA_DEBUG flag, the driver
-    can provide more debug trace if needed. There is a bit mask variable,
-    IADebugFlag, which controls the output of the traces. You can find the bit
-    map of the IADebugFlag in iphase.h.
-    The debug trace can be turn on through the insmod command line option, for
-    example, "insmod iphase.o IADebugFlag=0xffffffff" can turn on all the debug
-    traces together with loading the driver.
-
-6. Ia Driver Test Using ttcp_atm and PVC
-
-   For the PVC setup, the test machines can either be connected back-to-back or
-   through a switch. If connected through the switch, the switch must be
-   configured for the PVC(s).
-
-   a. For UBR test:
-
-      At the test machine intended to receive data, type::
-
-	 ttcp_atm -r -a -s 0.100
-
-      At the other test machine, type::
-
-	 ttcp_atm -t -a -s 0.100 -n 10000
-
-      Run "ttcp_atm -h" to display more options of the ttcp_atm tool.
-   b. For ABR test:
-
-      It is the same as the UBR testing, but with an extra command option::
-
-	 -Pabr:max_pcr=<xxx>
-
-      where:
-
-	     xxx = the maximum peak cell rate, from 170 - 353207.
-
-      This option must be set on both the machines.
-
-   c. For CBR test:
-
-      It is the same as the UBR testing, but with an extra command option::
-
-	 -Pcbr:max_pcr=<xxx>
-
-      where:
-
-	     xxx = the maximum peak cell rate, from 170 - 353207.
-
-      This option may only be set on the transmit machine.
-
-
-Outstanding Issues
-==================
-
-
-
-Contact Information
--------------------
-
-::
-
-     Customer Support:
-	 United States:	Telephone:	(214) 654-5555
-			Fax:		(214) 654-5500
-			E-Mail:		intouch@iphase.com
-	 Europe:	Telephone:	33 (0)1 41 15 44 00
-			Fax:		33 (0)1 41 15 12 13
-     World Wide Web:	http://www.iphase.com
-     Anonymous FTP:	ftp.iphase.com
diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig
deleted file mode 100644
index 63cdb46a3439..000000000000
--- a/drivers/atm/Kconfig
+++ /dev/null
@@ -1,325 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# ATM device configuration
-#
-
-menuconfig ATM_DRIVERS
-	bool "ATM drivers"
-	depends on NETDEVICES && ATM
-	default y
-	help
-	  Say Y here to get to see options for Asynchronous Transfer Mode
-	  device drivers. This option alone does not add any kernel code.
-
-	  If you say N, all options in this submenu will be skipped and disabled.
-
-if ATM_DRIVERS && NETDEVICES && ATM
-
-config ATM_DUMMY
-	tristate "Dummy ATM driver"
-	help
-	  Dummy ATM driver. Useful for proxy signalling, testing,
-	  and development.  If unsure, say N.
-
-config ATM_TCP
-	tristate "ATM over TCP"
-	depends on INET
-	help
-	  ATM over TCP driver. Useful mainly for development and for
-	  experiments. If unsure, say N.
-
-config ATM_LANAI
-	tristate "Efficient Networks Speedstream 3010"
-	depends on PCI && ATM
-	help
-	  Supports ATM cards based on the Efficient Networks "Lanai"
-	  chipset such as the Speedstream 3010 and the ENI-25p.  The
-	  Speedstream 3060 is currently not supported since we don't
-	  have the code to drive the on-board Alcatel DSL chipset (yet).
-
-config ATM_ENI
-	tristate "Efficient Networks ENI155P"
-	depends on PCI
-	help
-	  Driver for the Efficient Networks ENI155p series and SMC ATM
-	  Power155 155 Mbps ATM adapters. Both, the versions with 512KB and
-	  2MB on-board RAM (Efficient calls them "C" and "S", respectively),
-	  and the FPGA and the ASIC Tonga versions of the board are supported.
-	  The driver works with MMF (-MF or ...F) and UTP-5 (-U5 or ...D)
-	  adapters.
-
-	  To compile this driver as a module, choose M here: the module will
-	  be called eni.
-
-config ATM_ENI_DEBUG
-	bool "Enable extended debugging"
-	depends on ATM_ENI
-	help
-	  Extended debugging records various events and displays that list
-	  when an inconsistency is detected. This mechanism is faster than
-	  generally using printks, but still has some impact on performance.
-	  Note that extended debugging may create certain race conditions
-	  itself. Enable this ONLY if you suspect problems with the driver.
-
-config ATM_ENI_TUNE_BURST
-	bool "Fine-tune burst settings"
-	depends on ATM_ENI
-	help
-	  In order to obtain good throughput, the ENI NIC can transfer
-	  multiple words of data per PCI bus access cycle. Such a multi-word
-	  transfer is called a burst.
-
-	  The default settings for the burst sizes are suitable for most PCI
-	  chipsets. However, in some cases, large bursts may overrun buffers
-	  in the PCI chipset and cause data corruption. In such cases, large
-	  bursts must be disabled and only (slower) small bursts can be used.
-	  The burst sizes can be set independently in the send (TX) and
-	  receive (RX) direction.
-
-	  Note that enabling many different burst sizes in the same direction
-	  may increase the cost of setting up a transfer such that the
-	  resulting throughput is lower than when using only the largest
-	  available burst size.
-
-	  Also, sometimes larger bursts lead to lower throughput, e.g. on an
-	  Intel 440FX board, a drop from 135 Mbps to 103 Mbps was observed
-	  when going from 8W to 16W bursts.
-
-config ATM_ENI_BURST_TX_16W
-	bool "Enable 16W TX bursts (discouraged)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst sixteen words at once in the send direction. This may work
-	  with recent PCI chipsets, but is known to fail with older chipsets.
-
-config ATM_ENI_BURST_TX_8W
-	bool "Enable 8W TX bursts (recommended)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst eight words at once in the send direction. This is the default
-	  setting.
-
-config ATM_ENI_BURST_TX_4W
-	bool "Enable 4W TX bursts (optional)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst four words at once in the send direction. You may want to try
-	  this if you have disabled 8W bursts. Enabling 4W if 8W is also set
-	  may or may not improve throughput.
-
-config ATM_ENI_BURST_TX_2W
-	bool "Enable 2W TX bursts (optional)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst two words at once in the send direction. You may want to try
-	  this if you have disabled 4W and 8W bursts. Enabling 2W if 4W or 8W
-	  are also set may or may not improve throughput.
-
-config ATM_ENI_BURST_RX_16W
-	bool "Enable 16W RX bursts (discouraged)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst sixteen words at once in the receive direction. This may work
-	  with recent PCI chipsets, but is known to fail with older chipsets.
-
-config ATM_ENI_BURST_RX_8W
-	bool "Enable 8W RX bursts (discouraged)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst eight words at once in the receive direction. This may work
-	  with recent PCI chipsets, but is known to fail with older chipsets,
-	  such as the Intel Neptune series.
-
-config ATM_ENI_BURST_RX_4W
-	bool "Enable 4W RX bursts (recommended)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst four words at once in the receive direction. This is the
-	  default setting. Enabling 4W if 8W is also set may or may not
-	  improve throughput.
-
-config ATM_ENI_BURST_RX_2W
-	bool "Enable 2W RX bursts (optional)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst two words at once in the receive direction. You may want to
-	  try this if you have disabled 4W and 8W bursts. Enabling 2W if 4W or
-	  8W are also set may or may not improve throughput.
-
-config ATM_NICSTAR
-	tristate "IDT 77201 (NICStAR) (ForeRunnerLE)"
-	depends on PCI
-	help
-	  The NICStAR chipset family is used in a large number of ATM NICs for
-	  25 and for 155 Mbps, including IDT cards and the Fore ForeRunnerLE
-	  series. Say Y if you have one of those.
-
-	  To compile this driver as a module, choose M here: the module will
-	  be called nicstar.
-
-config ATM_NICSTAR_USE_SUNI
-	bool "Use suni PHY driver (155Mbps)"
-	depends on ATM_NICSTAR
-	help
-	  Support for the S-UNI and compatible PHYsical layer chips. These are
-	  found in most 155Mbps NICStAR based ATM cards, namely in the
-	  ForeRunner LE155 cards. This driver provides detection of cable~
-	  removal and reinsertion and provides some statistics. This driver
-	  doesn't have removal capability when compiled as a module, so if you
-	  need that capability don't include S-UNI support (it's not needed to
-	  make the card work).
-
-config ATM_NICSTAR_USE_IDT77105
-	bool "Use IDT77105 PHY driver (25Mbps)"
-	depends on ATM_NICSTAR
-	help
-	  Support for the PHYsical layer chip in ForeRunner LE25 cards. In
-	  addition to cable removal/reinsertion detection, this driver allows
-	  you to control the loopback mode of the chip via a dedicated IOCTL.
-	  This driver is required for proper handling of temporary carrier
-	  loss, so if you have a 25Mbps NICStAR based ATM card you must say Y.
-
-config ATM_IDT77252
-	tristate "IDT 77252 (NICStAR II)"
-	depends on PCI
-	help
-	  Driver for the IDT 77252 ATM PCI chips.
-
-	  To compile this driver as a module, choose M here: the module will
-	  be called idt77252.
-
-config ATM_IDT77252_DEBUG
-	bool "Enable debugging messages"
-	depends on ATM_IDT77252
-	help
-	  Somewhat useful debugging messages are available. The choice of
-	  messages is controlled by a bitmap.  This may be specified as a
-	  module argument.  See the file <file:drivers/atm/idt77252.h> for
-	  the meanings of the bits in the mask.
-
-	  When active, these messages can have a significant impact on the
-	  speed of the driver, and the size of your syslog files! When
-	  inactive, they will have only a modest impact on performance.
-
-config ATM_IDT77252_RCV_ALL
-	bool "Receive ALL cells in raw queue"
-	depends on ATM_IDT77252
-	help
-	  Enable receiving of all cells on the ATM link, that do not match
-	  an open connection in the raw cell queue of the driver.  Useful
-	  for debugging or special applications only, so the safe answer is N.
-
-config ATM_IDT77252_USE_SUNI
-	bool
-	depends on ATM_IDT77252
-	default y
-
-config ATM_IA
-	tristate "Interphase ATM PCI x575/x525/x531"
-	depends on PCI
-	help
-	  This is a driver for the Interphase (i)ChipSAR adapter cards
-	  which include a variety of variants in term of the size of the
-	  control memory (128K-1KVC, 512K-4KVC), the size of the packet
-	  memory (128K, 512K, 1M), and the PHY type (Single/Multi mode OC3,
-	  UTP155, UTP25, DS3 and E3). Go to:
-	  	<http://www.iphase.com/>
-	  for more info about the cards. Say Y (or M to compile as a module
-	  named iphase) here if you have one of these cards.
-
-	  See the file
-	  <file:Documentation/networking/device_drivers/atm/iphase.rst>
-	  for further details.
-
-config ATM_IA_DEBUG
-	bool "Enable debugging messages"
-	depends on ATM_IA
-	help
-	  Somewhat useful debugging messages are available. The choice of
-	  messages is controlled by a bitmap. This may be specified as a
-	  module argument (kernel command line argument as well?), changed
-	  dynamically using an ioctl (Get the debug utility, iadbg, from
-	  <ftp://ftp.iphase.com/pub/atm/pci/>).
-
-	  See the file <file:drivers/atm/iphase.h> for the meanings of the
-	  bits in the mask.
-
-	  When active, these messages can have a significant impact on the
-	  speed of the driver, and the size of your syslog files! When
-	  inactive, they will have only a modest impact on performance.
-
-config ATM_FORE200E
-	tristate "FORE Systems 200E-series"
-	depends on (PCI || SBUS)
-	select FW_LOADER
-	help
-	  This is a driver for the FORE Systems 200E-series ATM adapter
-	  cards. It simultaneously supports PCA-200E and SBA-200E models
-	  on PCI and SBUS hosts. Say Y (or M to compile as a module
-	  named fore_200e) here if you have one of these ATM adapters.
-
-	  See the file
-	  <file:Documentation/networking/device_drivers/atm/fore200e.rst> for
-	  further details.
-
-config ATM_FORE200E_USE_TASKLET
-	bool "Defer interrupt work to a tasklet"
-	depends on ATM_FORE200E
-	default n
-	help
-	  This defers work to be done by the interrupt handler to a
-	  tasklet instead of handling everything at interrupt time.  This
-	  may improve the responsive of the host.
-
-config ATM_FORE200E_TX_RETRY
-	int "Maximum number of tx retries"
-	depends on ATM_FORE200E
-	default "16"
-	help
-	  Specifies the number of times the driver attempts to transmit
-	  a message before giving up, if the transmit queue of the ATM card
-	  is transiently saturated.
-
-	  Saturation of the transmit queue may occur only under extreme
-	  conditions, e.g. when a fast host continuously submits very small
-	  frames (<64 bytes) or raw AAL0 cells (48 bytes) to the ATM adapter.
-
-	  Note that under common conditions, it is unlikely that you encounter
-	  a saturation of the transmit queue, so the retry mechanism never
-	  comes into play.
-
-config ATM_FORE200E_DEBUG
-	int "Debugging level (0-3)"
-	depends on ATM_FORE200E
-	default "0"
-	help
-	  Specifies the level of debugging messages issued by the driver.
-	  The verbosity of the driver increases with the value of this
-	  parameter.
-
-	  When active, these messages can have a significant impact on
-	  the performances of the driver, and the size of your syslog files!
-	  Keep the debugging level to 0 during normal operations.
-
-config ATM_HE
-	tristate "ForeRunner HE Series"
-	depends on PCI
-	help
-	  This is a driver for the Marconi ForeRunner HE-series ATM adapter
-	  cards. It simultaneously supports the 155 and 622 versions.
-
-config ATM_HE_USE_SUNI
-	bool "Use S/UNI PHY driver"
-	depends on ATM_HE
-	help
-	  Support for the S/UNI-Ultra and S/UNI-622 found in the ForeRunner
-	  HE cards.  This driver provides carrier detection some statistics.
-
-config ATM_SOLOS
-	tristate "Solos ADSL2+ PCI Multiport card driver"
-	depends on PCI
-	select FW_LOADER
-	help
-	  Support for the Solos multiport ADSL2+ card.
-
-endif # ATM
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 8ec98f6dfef9..19cc389028ba 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -501,8 +501,6 @@ config SUNGEM_PHY
 
 source "drivers/net/arcnet/Kconfig"
 
-source "drivers/atm/Kconfig"
-
 source "drivers/net/dsa/Kconfig"
 
 source "drivers/net/ethernet/Kconfig"
diff --git a/net/atm/Kconfig b/net/atm/Kconfig
index 77343d57ff2a..9a2f376d3d2b 100644
--- a/net/atm/Kconfig
+++ b/net/atm/Kconfig
@@ -14,61 +14,3 @@ config ATM
 	  In order to participate in an ATM network, your Linux box needs an
 	  ATM networking card. If you have that, say Y here and to the driver
 	  of your ATM card below.
-
-	  Note that you need a set of user-space programs to actually make use
-	  of ATM.  See the file <file:Documentation/networking/atm.rst> for
-	  further details.
-
-config ATM_CLIP
-	tristate "Classical IP over ATM"
-	depends on ATM && INET
-	help
-	  Classical IP over ATM for PVCs and SVCs, supporting InARP and
-	  ATMARP. If you want to communication with other IP hosts on your ATM
-	  network, you will typically either say Y here or to "LAN Emulation
-	  (LANE)" below.
-
-config ATM_CLIP_NO_ICMP
-	bool "Do NOT send ICMP if no neighbour"
-	depends on ATM_CLIP
-	help
-	  Normally, an "ICMP host unreachable" message is sent if a neighbour
-	  cannot be reached because there is no VC to it in the kernel's
-	  ATMARP table. This may cause problems when ATMARP table entries are
-	  briefly removed during revalidation. If you say Y here, packets to
-	  such neighbours are silently discarded instead.
-
-config ATM_LANE
-	tristate "LAN Emulation (LANE) support"
-	depends on ATM
-	help
-	  LAN Emulation emulates services of existing LANs across an ATM
-	  network. Besides operating as a normal ATM end station client, Linux
-	  LANE client can also act as an proxy client bridging packets between
-	  ELAN and Ethernet segments. You need LANE if you want to try MPOA.
-
-config ATM_MPOA
-	tristate "Multi-Protocol Over ATM (MPOA) support"
-	depends on ATM && INET && ATM_LANE!=n
-	help
-	  Multi-Protocol Over ATM allows ATM edge devices such as routers,
-	  bridges and ATM attached hosts establish direct ATM VCs across
-	  subnetwork boundaries. These shortcut connections bypass routers
-	  enhancing overall network performance.
-
-config ATM_BR2684
-	tristate "RFC1483/2684 Bridged protocols"
-	depends on ATM && INET
-	help
-	  ATM PVCs can carry ethernet PDUs according to RFC2684 (formerly 1483)
-	  This device will act like an ethernet from the kernels point of view,
-	  with the traffic being carried by ATM PVCs (currently 1 PVC/device).
-	  This is sometimes used over DSL lines.  If in doubt, say N.
-
-config ATM_BR2684_IPFILTER
-	bool "Per-VC IP filter kludge"
-	depends on ATM_BR2684
-	help
-	  This is an experimental mechanism for users who need to terminate a
-	  large number of IP-only vcc's.  Do not enable this unless you are sure
-	  you know what you are doing.
diff --git a/drivers/Makefile b/drivers/Makefile
index 0841ea851847..cc5fdb1ef79f 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -90,7 +90,6 @@ obj-$(CONFIG_SPMI)		+= spmi/
 obj-$(CONFIG_HSI)		+= hsi/
 obj-$(CONFIG_SLIMBUS)		+= slimbus/
 obj-y				+= net/
-obj-$(CONFIG_ATM)		+= atm/
 obj-$(CONFIG_FUSION)		+= message/
 obj-y				+= firewire/
 obj-$(CONFIG_UIO)		+= uio/
diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile
deleted file mode 100644
index c9eade92019b..000000000000
--- a/drivers/atm/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the Linux network (ATM) device drivers.
-#
-
-fore_200e-y	:= fore200e.o
-
-obj-$(CONFIG_ATM_NICSTAR)	+= nicstar.o
-obj-$(CONFIG_ATM_IA)		+= iphase.o suni.o
-obj-$(CONFIG_ATM_FORE200E)	+= fore_200e.o
-obj-$(CONFIG_ATM_ENI)		+= eni.o suni.o
-obj-$(CONFIG_ATM_IDT77252)	+= idt77252.o
-obj-$(CONFIG_ATM_SOLOS)		+= solos-pci.o
-
-ifeq ($(CONFIG_ATM_NICSTAR_USE_SUNI),y)
-  obj-$(CONFIG_ATM_NICSTAR)	+= suni.o
-endif
-ifeq ($(CONFIG_ATM_NICSTAR_USE_IDT77105),y)
-  obj-$(CONFIG_ATM_NICSTAR)	+= idt77105.o
-endif
-ifeq ($(CONFIG_ATM_IDT77252_USE_SUNI),y)
-  obj-$(CONFIG_ATM_IDT77252)	+= suni.o
-endif
-
-obj-$(CONFIG_ATM_DUMMY)		+= adummy.o
-obj-$(CONFIG_ATM_TCP)		+= atmtcp.o
-obj-$(CONFIG_ATM_LANAI)		+= lanai.o
-
-obj-$(CONFIG_ATM_HE)		+= he.o
-ifeq ($(CONFIG_ATM_HE_USE_SUNI),y)
-  obj-$(CONFIG_ATM_HE)		+= suni.o
-endif
diff --git a/net/atm/Makefile b/net/atm/Makefile
index bfec0f2d83b5..226eecbe3825 100644
--- a/net/atm/Makefile
+++ b/net/atm/Makefile
@@ -4,13 +4,7 @@
 #
 
 atm-y		:= addr.o pvc.o signaling.o svc.o ioctl.o common.o atm_misc.o raw.o resources.o atm_sysfs.o
-mpoa-objs	:= mpc.o mpoa_caches.o mpoa_proc.o
-
-obj-$(CONFIG_ATM) += atm.o
-obj-$(CONFIG_ATM_CLIP) += clip.o
-obj-$(CONFIG_ATM_BR2684) += br2684.o
 atm-$(CONFIG_PROC_FS) += proc.o
 
-obj-$(CONFIG_ATM_LANE) += lec.o
-obj-$(CONFIG_ATM_MPOA) += mpoa.o
+obj-$(CONFIG_ATM) += atm.o
 obj-$(CONFIG_PPPOATM) += pppoatm.o
diff --git a/drivers/atm/eni.h b/drivers/atm/eni.h
deleted file mode 100644
index de1ed802cbf8..000000000000
--- a/drivers/atm/eni.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* drivers/atm/eni.h - Efficient Networks ENI155P device driver declarations */
- 
-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
- 
- 
-#ifndef DRIVER_ATM_ENI_H
-#define DRIVER_ATM_ENI_H
-
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <linux/interrupt.h>
-#include <linux/sonet.h>
-#include <linux/skbuff.h>
-#include <linux/time.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/atomic.h>
-
-#include "midway.h"
-
-
-#define DEV_LABEL	"eni"
-
-#define UBR_BUFFER	(128*1024)	/* UBR buffer size */
-
-#define RX_DMA_BUF	  8		/* burst and skip a few things */
-#define TX_DMA_BUF	100		/* should be enough for 64 kB */
-
-#define DEFAULT_RX_MULT	300		/* max_sdu*3 */
-#define DEFAULT_TX_MULT	300		/* max_sdu*3 */
-
-#define ENI_ZEROES_SIZE	  4		/* need that many DMA-able zero bytes */
-
-
-struct eni_free {
-	void __iomem *start;		/* counting in bytes */
-	int order;
-};
-
-struct eni_tx {
-	void __iomem *send;		/* base, 0 if unused */
-	int prescaler;			/* shaping prescaler */
-	int resolution;			/* shaping divider */
-	unsigned long tx_pos;		/* current TX write position */
-	unsigned long words;		/* size of TX queue */
-	int index;			/* TX channel number */
-	int reserved;			/* reserved peak cell rate */
-	int shaping;			/* shaped peak cell rate */
-	struct sk_buff_head backlog;	/* queue of waiting TX buffers */
-};
-
-struct eni_vcc {
-	int (*rx)(struct atm_vcc *vcc);	/* RX function, NULL if none */
-	void __iomem *recv;		/* receive buffer */
-	unsigned long words;		/* its size in words */
-	unsigned long descr;		/* next descriptor (RX) */
-	unsigned long rx_pos;		/* current RX descriptor pos */
-	struct eni_tx *tx;		/* TXer, NULL if none */
-	int rxing;			/* number of pending PDUs */
-	int servicing;			/* number of waiting VCs (0 or 1) */
-	int txing;			/* number of pending TX bytes */
-	ktime_t timestamp;		/* for RX timing */
-	struct atm_vcc *next;		/* next pending RX */
-	struct sk_buff *last;		/* last PDU being DMAed (used to carry
-					   discard information) */
-};
-
-struct eni_dev {
-	/*-------------------------------- spinlock */
-	spinlock_t lock;		/* sync with interrupt */
-	struct tasklet_struct task;	/* tasklet for interrupt work */
-	u32 events;			/* pending events */
-	/*-------------------------------- base pointers into Midway address
-					   space */
-	void __iomem *ioaddr;
-	void __iomem *phy;		/* PHY interface chip registers */
-	void __iomem *reg;		/* register base */
-	void __iomem *ram;		/* RAM base */
-	void __iomem *vci;		/* VCI table */
-	void __iomem *rx_dma;		/* RX DMA queue */
-	void __iomem *tx_dma;		/* TX DMA queue */
-	void __iomem *service;		/* service list */
-	/*-------------------------------- TX part */
-	struct eni_tx tx[NR_CHAN];	/* TX channels */
-	struct eni_tx *ubr;		/* UBR channel */
-	struct sk_buff_head tx_queue;	/* PDUs currently being TX DMAed*/
-	wait_queue_head_t tx_wait;	/* for close */
-	int tx_bw;			/* remaining bandwidth */
-	u32 dma[TX_DMA_BUF*2];		/* DMA request scratch area */
-	struct eni_zero {		/* aligned "magic" zeroes */
-		u32 *addr;
-		dma_addr_t dma;
-	} zero;
-	int tx_mult;			/* buffer size multiplier (percent) */
-	/*-------------------------------- RX part */
-	u32 serv_read;			/* host service read index */
-	struct atm_vcc *fast,*last_fast;/* queues of VCCs with pending PDUs */
-	struct atm_vcc *slow,*last_slow;
-	struct atm_vcc **rx_map;	/* for fast lookups */
-	struct sk_buff_head rx_queue;	/* PDUs currently being RX-DMAed */
-	wait_queue_head_t rx_wait;	/* for close */
-	int rx_mult;			/* buffer size multiplier (percent) */
-	/*-------------------------------- statistics */
-	unsigned long lost;		/* number of lost cells (RX) */
-	/*-------------------------------- memory management */
-	unsigned long base_diff;	/* virtual-real base address */
-	int free_len;			/* free list length */
-	struct eni_free *free_list;	/* free list */
-	int free_list_size;		/* maximum size of free list */
-	/*-------------------------------- ENI links */
-	struct atm_dev *more;		/* other ENI devices */
-	/*-------------------------------- general information */
-	int mem;			/* RAM on board (in bytes) */
-	int asic;			/* PCI interface type, 0 for FPGA */
-	unsigned int irq;		/* IRQ */
-	struct pci_dev *pci_dev;	/* PCI stuff */
-};
-
-
-#define ENI_DEV(d) ((struct eni_dev *) (d)->dev_data)
-#define ENI_VCC(d) ((struct eni_vcc *) (d)->dev_data)
-
-
-struct eni_skb_prv {
-	struct atm_skb_data _;		/* reserved */
-	unsigned long pos;		/* position of next descriptor */
-	int size;			/* PDU size in reassembly buffer */
-	dma_addr_t paddr;		/* DMA handle */
-};
-
-#define ENI_PRV_SIZE(skb) (((struct eni_skb_prv *) (skb)->cb)->size)
-#define ENI_PRV_POS(skb) (((struct eni_skb_prv *) (skb)->cb)->pos)
-#define ENI_PRV_PADDR(skb) (((struct eni_skb_prv *) (skb)->cb)->paddr)
-
-#endif
diff --git a/drivers/atm/fore200e.h b/drivers/atm/fore200e.h
deleted file mode 100644
index 5d95fe9fd836..000000000000
--- a/drivers/atm/fore200e.h
+++ /dev/null
@@ -1,973 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _FORE200E_H
-#define _FORE200E_H
-
-#ifdef __KERNEL__
-
-/* rx buffer sizes */
-
-#define SMALL_BUFFER_SIZE    384     /* size of small buffers (multiple of 48 (PCA) and 64 (SBA) bytes) */
-#define LARGE_BUFFER_SIZE    4032    /* size of large buffers (multiple of 48 (PCA) and 64 (SBA) bytes) */
-
-
-#define RBD_BLK_SIZE	     32      /* nbr of supplied rx buffers per rbd */
-
-
-#define MAX_PDU_SIZE	     65535   /* maximum PDU size supported by AALs */
-
-
-#define BUFFER_S1_SIZE       SMALL_BUFFER_SIZE    /* size of small buffers, scheme 1 */
-#define BUFFER_L1_SIZE       LARGE_BUFFER_SIZE    /* size of large buffers, scheme 1 */
-
-#define BUFFER_S2_SIZE       SMALL_BUFFER_SIZE    /* size of small buffers, scheme 2 */
-#define BUFFER_L2_SIZE       LARGE_BUFFER_SIZE    /* size of large buffers, scheme 2 */
-
-#define BUFFER_S1_NBR        (RBD_BLK_SIZE * 6)
-#define BUFFER_L1_NBR        (RBD_BLK_SIZE * 4)
-
-#define BUFFER_S2_NBR        (RBD_BLK_SIZE * 6)
-#define BUFFER_L2_NBR        (RBD_BLK_SIZE * 4)
-
-
-#define QUEUE_SIZE_CMD       16	     /* command queue capacity       */
-#define QUEUE_SIZE_RX	     64	     /* receive queue capacity       */
-#define QUEUE_SIZE_TX	     256     /* transmit queue capacity      */
-#define QUEUE_SIZE_BS        32	     /* buffer supply queue capacity */
-
-#define FORE200E_VPI_BITS     0
-#define FORE200E_VCI_BITS    10
-#define NBR_CONNECT          (1 << (FORE200E_VPI_BITS + FORE200E_VCI_BITS)) /* number of connections */
-
-
-#define TSD_FIXED            2
-#define TSD_EXTENSION        0
-#define TSD_NBR              (TSD_FIXED + TSD_EXTENSION)
-
-
-/* the cp starts putting a received PDU into one *small* buffer,
-   then it uses a number of *large* buffers for the trailing data. 
-   we compute here the total number of receive segment descriptors 
-   required to hold the largest possible PDU */
-
-#define RSD_REQUIRED  (((MAX_PDU_SIZE - SMALL_BUFFER_SIZE + LARGE_BUFFER_SIZE) / LARGE_BUFFER_SIZE) + 1)
-
-#define RSD_FIXED     3
-
-/* RSD_REQUIRED receive segment descriptors are enough to describe a max-sized PDU,
-   but we have to keep the size of the receive PDU descriptor multiple of 32 bytes,
-   so we add one extra RSD to RSD_EXTENSION 
-   (WARNING: THIS MAY CHANGE IF BUFFER SIZES ARE MODIFIED) */
-
-#define RSD_EXTENSION  ((RSD_REQUIRED - RSD_FIXED) + 1)
-#define RSD_NBR         (RSD_FIXED + RSD_EXTENSION)
-
-
-#define FORE200E_DEV(d)          ((struct fore200e*)((d)->dev_data))
-#define FORE200E_VCC(d)          ((struct fore200e_vcc*)((d)->dev_data))
-
-/* bitfields endian games */
-
-#if defined(__LITTLE_ENDIAN_BITFIELD)
-#define BITFIELD2(b1, b2)                    b1; b2;
-#define BITFIELD3(b1, b2, b3)                b1; b2; b3;
-#define BITFIELD4(b1, b2, b3, b4)            b1; b2; b3; b4;
-#define BITFIELD5(b1, b2, b3, b4, b5)        b1; b2; b3; b4; b5;
-#define BITFIELD6(b1, b2, b3, b4, b5, b6)    b1; b2; b3; b4; b5; b6;
-#elif defined(__BIG_ENDIAN_BITFIELD)
-#define BITFIELD2(b1, b2)                                    b2; b1;
-#define BITFIELD3(b1, b2, b3)                            b3; b2; b1;
-#define BITFIELD4(b1, b2, b3, b4)                    b4; b3; b2; b1;
-#define BITFIELD5(b1, b2, b3, b4, b5)            b5; b4; b3; b2; b1;
-#define BITFIELD6(b1, b2, b3, b4, b5, b6)    b6; b5; b4; b3; b2; b1;
-#else
-#error unknown bitfield endianess
-#endif
-
- 
-/* ATM cell header (minus HEC byte) */
-
-typedef struct atm_header {
-    BITFIELD5( 
-        u32 clp :  1,    /* cell loss priority         */
-        u32 plt :  3,    /* payload type               */
-        u32 vci : 16,    /* virtual channel identifier */
-        u32 vpi :  8,    /* virtual path identifier    */
-        u32 gfc :  4     /* generic flow control       */
-   )
-} atm_header_t;
-
-
-/* ATM adaptation layer id */
-
-typedef enum fore200e_aal {
-    FORE200E_AAL0  = 0,
-    FORE200E_AAL34 = 4,
-    FORE200E_AAL5  = 5,
-} fore200e_aal_t;
-
-
-/* transmit PDU descriptor specification */
-
-typedef struct tpd_spec {
-    BITFIELD4(
-        u32               length : 16,    /* total PDU length            */
-        u32               nseg   :  8,    /* number of transmit segments */
-        enum fore200e_aal aal    :  4,    /* adaptation layer            */
-        u32               intr   :  4     /* interrupt requested         */
-    )
-} tpd_spec_t;
-
-
-/* transmit PDU rate control */
-
-typedef struct tpd_rate
-{
-    BITFIELD2( 
-        u32 idle_cells : 16,    /* number of idle cells to insert   */
-        u32 data_cells : 16     /* number of data cells to transmit */
-    )
-} tpd_rate_t;
-
-
-/* transmit segment descriptor */
-
-typedef struct tsd {
-    u32 buffer;    /* transmit buffer DMA address */
-    u32 length;    /* number of bytes in buffer   */
-} tsd_t;
-
-
-/* transmit PDU descriptor */
-
-typedef struct tpd {
-    struct atm_header atm_header;        /* ATM header minus HEC byte    */
-    struct tpd_spec   spec;              /* tpd specification            */
-    struct tpd_rate   rate;              /* tpd rate control             */
-    u32               pad;               /* reserved                     */
-    struct tsd        tsd[ TSD_NBR ];    /* transmit segment descriptors */
-} tpd_t;
-
-
-/* receive segment descriptor */
-
-typedef struct rsd {
-    u32 handle;    /* host supplied receive buffer handle */
-    u32 length;    /* number of bytes in buffer           */
-} rsd_t;
-
-
-/* receive PDU descriptor */
-
-typedef struct rpd {
-    struct atm_header atm_header;        /* ATM header minus HEC byte   */
-    u32               nseg;              /* number of receive segments  */
-    struct rsd        rsd[ RSD_NBR ];    /* receive segment descriptors */
-} rpd_t;
-
-
-/* buffer scheme */
-
-typedef enum buffer_scheme {
-    BUFFER_SCHEME_ONE,
-    BUFFER_SCHEME_TWO,
-    BUFFER_SCHEME_NBR    /* always last */
-} buffer_scheme_t;
-
-
-/* buffer magnitude */
-
-typedef enum buffer_magn {
-    BUFFER_MAGN_SMALL,
-    BUFFER_MAGN_LARGE,
-    BUFFER_MAGN_NBR    /* always last */
-} buffer_magn_t;
-
-
-/* receive buffer descriptor */
-
-typedef struct rbd {
-    u32 handle;          /* host supplied handle            */
-    u32 buffer_haddr;    /* host DMA address of host buffer */
-} rbd_t;
-
-
-/* receive buffer descriptor block */
-
-typedef struct rbd_block {
-    struct rbd rbd[ RBD_BLK_SIZE ];    /* receive buffer descriptor */
-} rbd_block_t;
-
-
-/* tpd DMA address */
-
-typedef struct tpd_haddr {
-    BITFIELD3( 
-        u32 size  :  4,    /* tpd size expressed in 32 byte blocks     */
-        u32 pad   :  1,    /* reserved                                 */
-        u32 haddr : 27     /* tpd DMA addr aligned on 32 byte boundary */
-    )
-} tpd_haddr_t;
-
-#define TPD_HADDR_SHIFT 5  /* addr aligned on 32 byte boundary */
-
-/* cp resident transmit queue entry */
-
-typedef struct cp_txq_entry {
-    struct tpd_haddr tpd_haddr;       /* host DMA address of tpd                */
-    u32              status_haddr;    /* host DMA address of completion status  */
-} cp_txq_entry_t;
-
-
-/* cp resident receive queue entry */
-
-typedef struct cp_rxq_entry {
-    u32 rpd_haddr;       /* host DMA address of rpd                */
-    u32 status_haddr;    /* host DMA address of completion status  */
-} cp_rxq_entry_t;
-
-
-/* cp resident buffer supply queue entry */
-
-typedef struct cp_bsq_entry {
-    u32 rbd_block_haddr;    /* host DMA address of rbd block          */
-    u32 status_haddr;       /* host DMA address of completion status  */
-} cp_bsq_entry_t;
-
-
-/* completion status */
-
-typedef volatile enum status {
-    STATUS_PENDING  = (1<<0),    /* initial status (written by host)  */
-    STATUS_COMPLETE = (1<<1),    /* completion status (written by cp) */
-    STATUS_FREE     = (1<<2),    /* initial status (written by host)  */
-    STATUS_ERROR    = (1<<3)     /* completion status (written by cp) */
-} status_t;
-
-
-/* cp operation code */
-
-typedef enum opcode {
-    OPCODE_INITIALIZE = 1,          /* initialize board                       */
-    OPCODE_ACTIVATE_VCIN,           /* activate incoming VCI                  */
-    OPCODE_ACTIVATE_VCOUT,          /* activate outgoing VCI                  */
-    OPCODE_DEACTIVATE_VCIN,         /* deactivate incoming VCI                */
-    OPCODE_DEACTIVATE_VCOUT,        /* deactivate incoing VCI                 */
-    OPCODE_GET_STATS,               /* get board statistics                   */
-    OPCODE_SET_OC3,                 /* set OC-3 registers                     */
-    OPCODE_GET_OC3,                 /* get OC-3 registers                     */
-    OPCODE_RESET_STATS,             /* reset board statistics                 */
-    OPCODE_GET_PROM,                /* get expansion PROM data (PCI specific) */
-    OPCODE_SET_VPI_BITS,            /* set x bits of those decoded by the
-				       firmware to be low order bits from
-				       the VPI field of the ATM cell header   */
-    OPCODE_REQUEST_INTR = (1<<7)    /* request interrupt                      */
-} opcode_t;
-
-
-/* virtual path / virtual channel identifiers */
-
-typedef struct vpvc {
-    BITFIELD3(
-        u32 vci : 16,    /* virtual channel identifier */
-        u32 vpi :  8,    /* virtual path identifier    */
-        u32 pad :  8     /* reserved                   */
-    )
-} vpvc_t;
-
-
-/* activate VC command opcode */
-
-typedef struct activate_opcode {
-    BITFIELD4( 
-        enum opcode        opcode : 8,    /* cp opcode        */
-        enum fore200e_aal  aal    : 8,    /* adaptation layer */
-        enum buffer_scheme scheme : 8,    /* buffer scheme    */
-        u32  pad                  : 8     /* reserved         */
-   )
-} activate_opcode_t;
-
-
-/* activate VC command block */
-
-typedef struct activate_block {
-    struct activate_opcode  opcode;    /* activate VC command opcode */
-    struct vpvc             vpvc;      /* VPI/VCI                    */
-    u32                     mtu;       /* for AAL0 only              */
-
-} activate_block_t;
-
-
-/* deactivate VC command opcode */
-
-typedef struct deactivate_opcode {
-    BITFIELD2(
-        enum opcode opcode :  8,    /* cp opcode */
-        u32         pad    : 24     /* reserved  */
-    )
-} deactivate_opcode_t;
-
-
-/* deactivate VC command block */
-
-typedef struct deactivate_block {
-    struct deactivate_opcode opcode;    /* deactivate VC command opcode */
-    struct vpvc              vpvc;      /* VPI/VCI                      */
-} deactivate_block_t;
-
-
-/* OC-3 registers */
-
-typedef struct oc3_regs {
-    u32 reg[ 128 ];    /* see the PMC Sierra PC5346 S/UNI-155-Lite
-			  Saturn User Network Interface documentation
-			  for a description of the OC-3 chip registers */
-} oc3_regs_t;
-
-
-/* set/get OC-3 regs command opcode */
-
-typedef struct oc3_opcode {
-    BITFIELD4(
-        enum opcode opcode : 8,    /* cp opcode                           */
-	u32         reg    : 8,    /* register index                      */
-	u32         value  : 8,    /* register value                      */
-	u32         mask   : 8     /* register mask that specifies which
-				      bits of the register value field
-				      are significant                     */
-    )
-} oc3_opcode_t;
-
-
-/* set/get OC-3 regs command block */
-
-typedef struct oc3_block {
-    struct oc3_opcode opcode;        /* set/get OC-3 regs command opcode     */
-    u32               regs_haddr;    /* host DMA address of OC-3 regs buffer */
-} oc3_block_t;
-
-
-/* physical encoding statistics */
-
-typedef struct stats_phy {
-    __be32 crc_header_errors;    /* cells received with bad header CRC */
-    __be32 framing_errors;       /* cells received with bad framing    */
-    __be32 pad[ 2 ];             /* i960 padding                       */
-} stats_phy_t;
-
-
-/* OC-3 statistics */
-
-typedef struct stats_oc3 {
-    __be32 section_bip8_errors;    /* section 8 bit interleaved parity    */
-    __be32 path_bip8_errors;       /* path 8 bit interleaved parity       */
-    __be32 line_bip24_errors;      /* line 24 bit interleaved parity      */
-    __be32 line_febe_errors;       /* line far end block errors           */
-    __be32 path_febe_errors;       /* path far end block errors           */
-    __be32 corr_hcs_errors;        /* correctable header check sequence   */
-    __be32 ucorr_hcs_errors;       /* uncorrectable header check sequence */
-    __be32 pad[ 1 ];               /* i960 padding                        */
-} stats_oc3_t;
-
-
-/* ATM statistics */
-
-typedef struct stats_atm {
-    __be32	cells_transmitted;    /* cells transmitted                 */
-    __be32	cells_received;       /* cells received                    */
-    __be32	vpi_bad_range;        /* cell drops: VPI out of range      */
-    __be32	vpi_no_conn;          /* cell drops: no connection for VPI */
-    __be32	vci_bad_range;        /* cell drops: VCI out of range      */
-    __be32	vci_no_conn;          /* cell drops: no connection for VCI */
-    __be32	pad[ 2 ];             /* i960 padding                      */
-} stats_atm_t;
-
-/* AAL0 statistics */
-
-typedef struct stats_aal0 {
-    __be32	cells_transmitted;    /* cells transmitted */
-    __be32	cells_received;       /* cells received    */
-    __be32	cells_dropped;        /* cells dropped     */
-    __be32	pad[ 1 ];             /* i960 padding      */
-} stats_aal0_t;
-
-
-/* AAL3/4 statistics */
-
-typedef struct stats_aal34 {
-    __be32	cells_transmitted;         /* cells transmitted from segmented PDUs */
-    __be32	cells_received;            /* cells reassembled into PDUs           */
-    __be32	cells_crc_errors;          /* payload CRC error count               */
-    __be32	cells_protocol_errors;     /* SAR or CS layer protocol errors       */
-    __be32	cells_dropped;             /* cells dropped: partial reassembly     */
-    __be32	cspdus_transmitted;        /* CS PDUs transmitted                   */
-    __be32	cspdus_received;           /* CS PDUs received                      */
-    __be32	cspdus_protocol_errors;    /* CS layer protocol errors              */
-    __be32	cspdus_dropped;            /* reassembled PDUs drop'd (in cells)    */
-    __be32	pad[ 3 ];                  /* i960 padding                          */
-} stats_aal34_t;
-
-
-/* AAL5 statistics */
-
-typedef struct stats_aal5 {
-    __be32	cells_transmitted;         /* cells transmitted from segmented SDUs */
-    __be32	cells_received;		   /* cells reassembled into SDUs           */
-    __be32	cells_dropped;		   /* reassembled PDUs dropped (in cells)   */
-    __be32	congestion_experienced;    /* CRC error and length wrong            */
-    __be32	cspdus_transmitted;        /* CS PDUs transmitted                   */
-    __be32	cspdus_received;           /* CS PDUs received                      */
-    __be32	cspdus_crc_errors;         /* CS PDUs CRC errors                    */
-    __be32	cspdus_protocol_errors;    /* CS layer protocol errors              */
-    __be32	cspdus_dropped;            /* reassembled PDUs dropped              */
-    __be32	pad[ 3 ];                  /* i960 padding                          */
-} stats_aal5_t;
-
-
-/* auxiliary statistics */
-
-typedef struct stats_aux {
-    __be32	small_b1_failed;     /* receive BD allocation failures  */
-    __be32	large_b1_failed;     /* receive BD allocation failures  */
-    __be32	small_b2_failed;     /* receive BD allocation failures  */
-    __be32	large_b2_failed;     /* receive BD allocation failures  */
-    __be32	rpd_alloc_failed;    /* receive PDU allocation failures */
-    __be32	receive_carrier;     /* no carrier = 0, carrier = 1     */
-    __be32	pad[ 2 ];            /* i960 padding                    */
-} stats_aux_t;
-
-
-/* whole statistics buffer */
-
-typedef struct stats {
-    struct stats_phy   phy;      /* physical encoding statistics */
-    struct stats_oc3   oc3;      /* OC-3 statistics              */
-    struct stats_atm   atm;      /* ATM statistics               */
-    struct stats_aal0  aal0;     /* AAL0 statistics              */
-    struct stats_aal34 aal34;    /* AAL3/4 statistics            */
-    struct stats_aal5  aal5;     /* AAL5 statistics              */
-    struct stats_aux   aux;      /* auxiliary statistics         */
-} stats_t;
-
-
-/* get statistics command opcode */
-
-typedef struct stats_opcode {
-    BITFIELD2(
-        enum opcode opcode :  8,    /* cp opcode */
-        u32         pad    : 24     /* reserved  */
-    )
-} stats_opcode_t;
-
-
-/* get statistics command block */
-
-typedef struct stats_block {
-    struct stats_opcode opcode;         /* get statistics command opcode    */
-    u32                 stats_haddr;    /* host DMA address of stats buffer */
-} stats_block_t;
-
-
-/* expansion PROM data (PCI specific) */
-
-typedef struct prom_data {
-    u32 hw_revision;      /* hardware revision   */
-    u32 serial_number;    /* board serial number */
-    u8  mac_addr[ 8 ];    /* board MAC address   */
-} prom_data_t;
-
-
-/* get expansion PROM data command opcode */
-
-typedef struct prom_opcode {
-    BITFIELD2(
-        enum opcode opcode :  8,    /* cp opcode */
-        u32         pad    : 24     /* reserved  */
-    )
-} prom_opcode_t;
-
-
-/* get expansion PROM data command block */
-
-typedef struct prom_block {
-    struct prom_opcode opcode;        /* get PROM data command opcode    */
-    u32                prom_haddr;    /* host DMA address of PROM buffer */
-} prom_block_t;
-
-
-/* cp command */
-
-typedef union cmd {
-    enum   opcode           opcode;           /* operation code          */
-    struct activate_block   activate_block;   /* activate VC             */
-    struct deactivate_block deactivate_block; /* deactivate VC           */
-    struct stats_block      stats_block;      /* get statistics          */
-    struct prom_block       prom_block;       /* get expansion PROM data */
-    struct oc3_block        oc3_block;        /* get/set OC-3 registers  */
-    u32                     pad[ 4 ];         /* i960 padding            */
-} cmd_t;
-
-
-/* cp resident command queue */
-
-typedef struct cp_cmdq_entry {
-    union cmd cmd;             /* command                               */
-    u32       status_haddr;    /* host DMA address of completion status */
-    u32       pad[ 3 ];        /* i960 padding                          */
-} cp_cmdq_entry_t;
-
-
-/* host resident transmit queue entry */
-
-typedef struct host_txq_entry {
-    struct cp_txq_entry __iomem *cp_entry;    /* addr of cp resident tx queue entry       */
-    enum   status*          status;      /* addr of host resident status             */
-    struct tpd*             tpd;         /* addr of transmit PDU descriptor          */
-    u32                     tpd_dma;     /* DMA address of tpd                       */
-    struct sk_buff*         skb;         /* related skb                              */
-    void*                   data;        /* copy of misaligned data                  */
-    unsigned long           incarn;      /* vc_map incarnation when submitted for tx */
-    struct fore200e_vc_map* vc_map;
-
-} host_txq_entry_t;
-
-
-/* host resident receive queue entry */
-
-typedef struct host_rxq_entry {
-    struct cp_rxq_entry __iomem *cp_entry;    /* addr of cp resident rx queue entry */
-    enum   status*       status;      /* addr of host resident status       */
-    struct rpd*          rpd;         /* addr of receive PDU descriptor     */
-    u32                  rpd_dma;     /* DMA address of rpd                 */
-} host_rxq_entry_t;
-
-
-/* host resident buffer supply queue entry */
-
-typedef struct host_bsq_entry {
-    struct cp_bsq_entry __iomem *cp_entry;         /* addr of cp resident buffer supply queue entry */
-    enum   status*       status;           /* addr of host resident status                  */
-    struct rbd_block*    rbd_block;        /* addr of receive buffer descriptor block       */
-    u32                  rbd_block_dma;    /* DMA address od rdb                            */
-} host_bsq_entry_t;
-
-
-/* host resident command queue entry */
-
-typedef struct host_cmdq_entry {
-    struct cp_cmdq_entry __iomem *cp_entry;    /* addr of cp resident cmd queue entry */
-    enum status *status;	       /* addr of host resident status        */
-} host_cmdq_entry_t;
-
-
-/* chunk of memory */
-
-typedef struct chunk {
-    void* alloc_addr;    /* base address of allocated chunk */
-    void* align_addr;    /* base address of aligned chunk   */
-    dma_addr_t dma_addr; /* DMA address of aligned chunk    */
-    int   direction;     /* direction of DMA mapping        */
-    u32   alloc_size;    /* length of allocated chunk       */
-    u32   align_size;    /* length of aligned chunk         */
-} chunk_t;
-
-#define dma_size align_size             /* DMA useable size */
-
-
-/* host resident receive buffer */
-
-typedef struct buffer {
-    struct buffer*       next;        /* next receive buffer     */
-    enum   buffer_scheme scheme;      /* buffer scheme           */
-    enum   buffer_magn   magn;        /* buffer magnitude        */
-    struct chunk         data;        /* data buffer             */
-#ifdef FORE200E_BSQ_DEBUG
-    unsigned long        index;       /* buffer # in queue       */
-    int                  supplied;    /* 'buffer supplied' flag  */
-#endif
-} buffer_t;
-
-
-#if (BITS_PER_LONG == 32)
-#define FORE200E_BUF2HDL(buffer)    ((u32)(buffer))
-#define FORE200E_HDL2BUF(handle)    ((struct buffer*)(handle))
-#else   /* deal with 64 bit pointers */
-#define FORE200E_BUF2HDL(buffer)    ((u32)((u64)(buffer)))
-#define FORE200E_HDL2BUF(handle)    ((struct buffer*)(((u64)(handle)) | PAGE_OFFSET))
-#endif
-
-
-/* host resident command queue */
-
-typedef struct host_cmdq {
-    struct host_cmdq_entry host_entry[ QUEUE_SIZE_CMD ];    /* host resident cmd queue entries        */
-    int                    head;                            /* head of cmd queue                      */
-    struct chunk           status;                          /* array of completion status      */
-} host_cmdq_t;
-
-
-/* host resident transmit queue */
-
-typedef struct host_txq {
-    struct host_txq_entry host_entry[ QUEUE_SIZE_TX ];    /* host resident tx queue entries         */
-    int                   head;                           /* head of tx queue                       */
-    int                   tail;                           /* tail of tx queue                       */
-    struct chunk          tpd;                            /* array of tpds                          */
-    struct chunk          status;                         /* arry of completion status              */
-    int                   txing;                          /* number of pending PDUs in tx queue     */
-} host_txq_t;
-
-
-/* host resident receive queue */
-
-typedef struct host_rxq {
-    struct host_rxq_entry  host_entry[ QUEUE_SIZE_RX ];    /* host resident rx queue entries         */
-    int                    head;                           /* head of rx queue                       */
-    struct chunk           rpd;                            /* array of rpds                          */
-    struct chunk           status;                         /* array of completion status             */
-} host_rxq_t;
-
-
-/* host resident buffer supply queues */
-
-typedef struct host_bsq {
-    struct host_bsq_entry host_entry[ QUEUE_SIZE_BS ];    /* host resident buffer supply queue entries */
-    int                   head;                           /* head of buffer supply queue               */
-    struct chunk          rbd_block;                      /* array of rbds                             */
-    struct chunk          status;                         /* array of completion status                */
-    struct buffer*        buffer;                         /* array of rx buffers                       */
-    struct buffer*        freebuf;                        /* list of free rx buffers                   */
-    volatile int          freebuf_count;                  /* count of free rx buffers                  */
-} host_bsq_t;
-
-
-/* header of the firmware image */
-
-typedef struct fw_header {
-    __le32 magic;           /* magic number                               */
-    __le32 version;         /* firmware version id                        */
-    __le32 load_offset;     /* fw load offset in board memory             */
-    __le32 start_offset;    /* fw execution start address in board memory */
-} fw_header_t;
-
-#define FW_HEADER_MAGIC  0x65726f66    /* 'fore' */
-
-
-/* receive buffer supply queues scheme specification */
-
-typedef struct bs_spec {
-    u32	queue_length;      /* queue capacity                     */
-    u32	buffer_size;	   /* host buffer size			 */
-    u32	pool_size;	   /* number of rbds			 */
-    u32	supply_blksize;    /* num of rbds in I/O block (multiple
-			      of 4 between 4 and 124 inclusive)	 */
-} bs_spec_t;
-
-
-/* initialization command block (one-time command, not in cmd queue) */
-
-typedef struct init_block {
-    enum opcode  opcode;               /* initialize command             */
-    enum status	 status;	       /* related status word            */
-    u32          receive_threshold;    /* not used                       */
-    u32          num_connect;          /* ATM connections                */
-    u32          cmd_queue_len;        /* length of command queue        */
-    u32          tx_queue_len;         /* length of transmit queue       */
-    u32          rx_queue_len;         /* length of receive queue        */
-    u32          rsd_extension;        /* number of extra 32 byte blocks */
-    u32          tsd_extension;        /* number of extra 32 byte blocks */
-    u32          conless_vpvc;         /* not used                       */
-    u32          pad[ 2 ];             /* force quad alignment           */
-    struct bs_spec bs_spec[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ];      /* buffer supply queues spec */
-} init_block_t;
-
-
-typedef enum media_type {
-    MEDIA_TYPE_CAT5_UTP  = 0x06,    /* unshielded twisted pair */
-    MEDIA_TYPE_MM_OC3_ST = 0x16,    /* multimode fiber ST      */
-    MEDIA_TYPE_MM_OC3_SC = 0x26,    /* multimode fiber SC      */
-    MEDIA_TYPE_SM_OC3_ST = 0x36,    /* single-mode fiber ST    */
-    MEDIA_TYPE_SM_OC3_SC = 0x46     /* single-mode fiber SC    */
-} media_type_t;
-
-#define FORE200E_MEDIA_INDEX(media_type)   ((media_type)>>4)
-
-
-/* cp resident queues */
-
-typedef struct cp_queues {
-    u32	              cp_cmdq;         /* command queue                      */
-    u32	              cp_txq;          /* transmit queue                     */
-    u32	              cp_rxq;          /* receive queue                      */
-    u32               cp_bsq[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ];        /* buffer supply queues */
-    u32	              imask;             /* 1 enables cp to host interrupts  */
-    u32	              istat;             /* 1 for interrupt posted           */
-    u32	              heap_base;         /* offset form beginning of ram     */
-    u32	              heap_size;         /* space available for queues       */
-    u32	              hlogger;           /* non zero for host logging        */
-    u32               heartbeat;         /* cp heartbeat                     */
-    u32	              fw_release;        /* firmware version                 */
-    u32	              mon960_release;    /* i960 monitor version             */
-    u32	              tq_plen;           /* transmit throughput measurements */
-    /* make sure the init block remains on a quad word boundary              */
-    struct init_block init;              /* one time cmd, not in cmd queue   */
-    enum   media_type media_type;        /* media type id                    */
-    u32               oc3_revision;      /* OC-3 revision number             */
-} cp_queues_t;
-
-
-/* boot status */
-
-typedef enum boot_status {
-    BSTAT_COLD_START    = (u32) 0xc01dc01d,    /* cold start              */
-    BSTAT_SELFTEST_OK   = (u32) 0x02201958,    /* self-test ok            */
-    BSTAT_SELFTEST_FAIL = (u32) 0xadbadbad,    /* self-test failed        */
-    BSTAT_CP_RUNNING    = (u32) 0xce11feed,    /* cp is running           */
-    BSTAT_MON_TOO_BIG   = (u32) 0x10aded00     /* i960 monitor is too big */
-} boot_status_t;
-
-
-/* software UART */
-
-typedef struct soft_uart {
-    u32 send;    /* write register */
-    u32 recv;    /* read register  */
-} soft_uart_t;
-
-#define FORE200E_CP_MONITOR_UART_FREE     0x00000000
-#define FORE200E_CP_MONITOR_UART_AVAIL    0x01000000
-
-
-/* i960 monitor */
-
-typedef struct cp_monitor {
-    struct soft_uart    soft_uart;      /* software UART           */
-    enum boot_status	bstat;          /* boot status             */
-    u32			app_base;       /* application base offset */
-    u32			mon_version;    /* i960 monitor version    */
-} cp_monitor_t;
-
-
-/* device state */
-
-typedef enum fore200e_state {
-    FORE200E_STATE_BLANK,         /* initial state                     */
-    FORE200E_STATE_REGISTER,      /* device registered                 */
-    FORE200E_STATE_CONFIGURE,     /* bus interface configured          */
-    FORE200E_STATE_MAP,           /* board space mapped in host memory */
-    FORE200E_STATE_RESET,         /* board resetted                    */
-    FORE200E_STATE_START_FW,      /* firmware started                  */
-    FORE200E_STATE_INITIALIZE,    /* initialize command successful     */
-    FORE200E_STATE_INIT_CMDQ,     /* command queue initialized         */
-    FORE200E_STATE_INIT_TXQ,      /* transmit queue initialized        */
-    FORE200E_STATE_INIT_RXQ,      /* receive queue initialized         */
-    FORE200E_STATE_INIT_BSQ,      /* buffer supply queue initialized   */
-    FORE200E_STATE_ALLOC_BUF,     /* receive buffers allocated         */
-    FORE200E_STATE_IRQ,           /* host interrupt requested          */
-    FORE200E_STATE_COMPLETE       /* initialization completed          */
-} fore200e_state;
-
-
-/* PCA-200E registers */
-
-typedef struct fore200e_pca_regs {
-    volatile u32 __iomem * hcr;    /* address of host control register        */
-    volatile u32 __iomem * imr;    /* address of host interrupt mask register */
-    volatile u32 __iomem * psr;    /* address of PCI specific register        */
-} fore200e_pca_regs_t;
-
-
-/* SBA-200E registers */
-
-typedef struct fore200e_sba_regs {
-    u32 __iomem *hcr;    /* address of host control register              */
-    u32 __iomem *bsr;    /* address of burst transfer size register       */
-    u32 __iomem *isr;    /* address of interrupt level selection register */
-} fore200e_sba_regs_t;
-
-
-/* model-specific registers */
-
-typedef union fore200e_regs {
-    struct fore200e_pca_regs pca;    /* PCA-200E registers */
-    struct fore200e_sba_regs sba;    /* SBA-200E registers */
-} fore200e_regs;
-
-
-struct fore200e;
-
-/* bus-dependent data */
-
-typedef struct fore200e_bus {
-    char*                model_name;          /* board model name                       */
-    char*                proc_name;           /* board name under /proc/atm             */
-    int                  descr_alignment;     /* tpd/rpd/rbd DMA alignment requirement  */
-    int                  buffer_alignment;    /* rx buffers DMA alignment requirement   */
-    int                  status_alignment;    /* status words DMA alignment requirement */
-    u32                  (*read)(volatile u32 __iomem *);
-    void                 (*write)(u32, volatile u32 __iomem *);
-    int                  (*configure)(struct fore200e*); 
-    int                  (*map)(struct fore200e*); 
-    void                 (*reset)(struct fore200e*);
-    int                  (*prom_read)(struct fore200e*, struct prom_data*);
-    void                 (*unmap)(struct fore200e*);
-    void                 (*irq_enable)(struct fore200e*);
-    int                  (*irq_check)(struct fore200e*);
-    void                 (*irq_ack)(struct fore200e*);
-    int                  (*proc_read)(struct fore200e*, char*);
-} fore200e_bus_t;
-
-/* vc mapping */
-
-typedef struct fore200e_vc_map {
-    struct atm_vcc* vcc;       /* vcc entry              */
-    unsigned long   incarn;    /* vcc incarnation number */
-} fore200e_vc_map_t;
-
-#define FORE200E_VC_MAP(fore200e, vpi, vci)  \
-        (& (fore200e)->vc_map[ ((vpi) << FORE200E_VCI_BITS) | (vci) ])
-
-
-/* per-device data */
-
-typedef struct fore200e {
-    const struct fore200e_bus* bus;                    /* bus-dependent code and data        */
-    union        fore200e_regs regs;                   /* bus-dependent registers            */
-    struct       atm_dev*      atm_dev;                /* ATM device                         */
-
-    enum fore200e_state        state;                  /* device state                       */
-
-    char                       name[16];               /* device name                        */
-    struct device	       *dev;
-    int                        irq;                    /* irq number                         */
-    unsigned long              phys_base;              /* physical base address              */
-    void __iomem *             virt_base;              /* virtual base address               */
-    
-    unsigned char              esi[ ESI_LEN ];         /* end system identifier              */
-
-    struct cp_monitor __iomem *         cp_monitor;    /* i960 monitor address               */
-    struct cp_queues __iomem *          cp_queues;              /* cp resident queues                 */
-    struct host_cmdq           host_cmdq;              /* host resident cmd queue            */
-    struct host_txq            host_txq;               /* host resident tx queue             */
-    struct host_rxq            host_rxq;               /* host resident rx queue             */
-                                                       /* host resident buffer supply queues */
-    struct host_bsq            host_bsq[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ];       
-
-    u32                        available_cell_rate;    /* remaining pseudo-CBR bw on link    */
-
-    int                        loop_mode;              /* S/UNI loopback mode                */
-
-    struct stats*              stats;                  /* last snapshot of the stats         */
-    
-    struct mutex               rate_mtx;               /* protects rate reservation ops      */
-    spinlock_t                 q_lock;                 /* protects queue ops                 */
-#ifdef FORE200E_USE_TASKLET
-    struct tasklet_struct      tx_tasklet;             /* performs tx interrupt work         */
-    struct tasklet_struct      rx_tasklet;             /* performs rx interrupt work         */
-#endif
-    unsigned long              tx_sat;                 /* tx queue saturation count          */
-
-    unsigned long              incarn_count;
-    struct fore200e_vc_map     vc_map[ NBR_CONNECT ];  /* vc mapping                         */
-} fore200e_t;
-
-
-/* per-vcc data */
-
-typedef struct fore200e_vcc {
-    enum buffer_scheme     scheme;             /* rx buffer scheme                   */
-    struct tpd_rate        rate;               /* tx rate control data               */
-    int                    rx_min_pdu;         /* size of smallest PDU received      */
-    int                    rx_max_pdu;         /* size of largest PDU received       */
-    int                    tx_min_pdu;         /* size of smallest PDU transmitted   */
-    int                    tx_max_pdu;         /* size of largest PDU transmitted    */
-    unsigned long          tx_pdu;             /* nbr of tx pdus                     */
-    unsigned long          rx_pdu;             /* nbr of rx pdus                     */
-} fore200e_vcc_t;
-
-
-
-/* 200E-series common memory layout */
-
-#define FORE200E_CP_MONITOR_OFFSET	0x00000400    /* i960 monitor interface */
-#define FORE200E_CP_QUEUES_OFFSET	0x00004d40    /* cp resident queues     */
-
-
-/* PCA-200E memory layout */
-
-#define PCA200E_IOSPACE_LENGTH	        0x00200000
-
-#define PCA200E_HCR_OFFSET		0x00100000    /* board control register */
-#define PCA200E_IMR_OFFSET		0x00100004    /* host IRQ mask register */
-#define PCA200E_PSR_OFFSET		0x00100008    /* PCI specific register  */
-
-
-/* PCA-200E host control register */
-
-#define PCA200E_HCR_RESET     (1<<0)    /* read / write */
-#define PCA200E_HCR_HOLD_LOCK (1<<1)    /* read / write */
-#define PCA200E_HCR_I960FAIL  (1<<2)    /* read         */
-#define PCA200E_HCR_INTRB     (1<<2)    /* write        */
-#define PCA200E_HCR_HOLD_ACK  (1<<3)    /* read         */
-#define PCA200E_HCR_INTRA     (1<<3)    /* write        */
-#define PCA200E_HCR_OUTFULL   (1<<4)    /* read         */
-#define PCA200E_HCR_CLRINTR   (1<<4)    /* write        */
-#define PCA200E_HCR_ESPHOLD   (1<<5)    /* read         */
-#define PCA200E_HCR_INFULL    (1<<6)    /* read         */
-#define PCA200E_HCR_TESTMODE  (1<<7)    /* read         */
-
-
-/* PCA-200E PCI bus interface regs (offsets in PCI config space) */
-
-#define PCA200E_PCI_LATENCY      0x40    /* maximum slave latenty            */
-#define PCA200E_PCI_MASTER_CTRL  0x41    /* master control                   */
-#define PCA200E_PCI_THRESHOLD    0x42    /* burst / continuous req threshold  */
-
-/* PBI master control register */
-
-#define PCA200E_CTRL_DIS_CACHE_RD      (1<<0)    /* disable cache-line reads                         */
-#define PCA200E_CTRL_DIS_WRT_INVAL     (1<<1)    /* disable writes and invalidates                   */
-#define PCA200E_CTRL_2_CACHE_WRT_INVAL (1<<2)    /* require 2 cache-lines for writes and invalidates */
-#define PCA200E_CTRL_IGN_LAT_TIMER     (1<<3)    /* ignore the latency timer                         */
-#define PCA200E_CTRL_ENA_CONT_REQ_MODE (1<<4)    /* enable continuous request mode                   */
-#define PCA200E_CTRL_LARGE_PCI_BURSTS  (1<<5)    /* force large PCI bus bursts                       */
-#define PCA200E_CTRL_CONVERT_ENDIAN    (1<<6)    /* convert endianess of slave RAM accesses          */
-
-
-
-#define SBA200E_PROM_NAME  "FORE,sba-200e"    /* device name in openprom tree */
-
-
-/* size of SBA-200E registers */
-
-#define SBA200E_HCR_LENGTH        4
-#define SBA200E_BSR_LENGTH        4
-#define SBA200E_ISR_LENGTH        4
-#define SBA200E_RAM_LENGTH  0x40000
-
-
-/* SBA-200E SBUS burst transfer size register */
-
-#define SBA200E_BSR_BURST4   0x04
-#define SBA200E_BSR_BURST8   0x08
-#define SBA200E_BSR_BURST16  0x10
-
-
-/* SBA-200E host control register */
-
-#define SBA200E_HCR_RESET        (1<<0)    /* read / write (sticky) */
-#define SBA200E_HCR_HOLD_LOCK    (1<<1)    /* read / write (sticky) */
-#define SBA200E_HCR_I960FAIL     (1<<2)    /* read                  */
-#define SBA200E_HCR_I960SETINTR  (1<<2)    /* write                 */
-#define SBA200E_HCR_OUTFULL      (1<<3)    /* read                  */
-#define SBA200E_HCR_INTR_CLR     (1<<3)    /* write                 */
-#define SBA200E_HCR_INTR_ENA     (1<<4)    /* read / write (sticky) */
-#define SBA200E_HCR_ESPHOLD      (1<<5)    /* read                  */
-#define SBA200E_HCR_INFULL       (1<<6)    /* read                  */
-#define SBA200E_HCR_TESTMODE     (1<<7)    /* read                  */
-#define SBA200E_HCR_INTR_REQ     (1<<8)    /* read                  */
-
-#define SBA200E_HCR_STICKY       (SBA200E_HCR_RESET | SBA200E_HCR_HOLD_LOCK | SBA200E_HCR_INTR_ENA)
-
-
-#endif /* __KERNEL__ */
-#endif /* _FORE200E_H */
diff --git a/drivers/atm/he.h b/drivers/atm/he.h
deleted file mode 100644
index f3f53674ef3f..000000000000
--- a/drivers/atm/he.h
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
-
-  he.h
-
-  ForeRunnerHE ATM Adapter driver for ATM on Linux
-  Copyright (C) 1999-2001  Naval Research Laboratory
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-
-/*
-
-  he.h
-
-  ForeRunnerHE ATM Adapter driver for ATM on Linux
-  Copyright (C) 1999-2000  Naval Research Laboratory
-
-  Permission to use, copy, modify and distribute this software and its
-  documentation is hereby granted, provided that both the copyright
-  notice and this permission notice appear in all copies of the software,
-  derivative works or modified versions, and any portions thereof, and
-  that both notices appear in supporting documentation.
-
-  NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
-  DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
-  RESULTING FROM THE USE OF THIS SOFTWARE.
-
- */
-
-#ifndef _HE_H_
-#define _HE_H_
-
-#define DEV_LABEL       "he"
-
-#define CONFIG_DEFAULT_VCIBITS	12
-#define CONFIG_DEFAULT_VPIBITS	0
-
-#define CONFIG_IRQ_SIZE		128
-#define CONFIG_IRQ_THRESH	(CONFIG_IRQ_SIZE/2)
-
-#define CONFIG_TPDRQ_SIZE	512
-#define TPDRQ_MASK(x)		(((unsigned long)(x))&((CONFIG_TPDRQ_SIZE<<3)-1))
-
-#define CONFIG_RBRQ_SIZE	512
-#define CONFIG_RBRQ_THRESH	400
-#define RBRQ_MASK(x)		(((unsigned long)(x))&((CONFIG_RBRQ_SIZE<<3)-1))
-
-#define CONFIG_TBRQ_SIZE	512
-#define CONFIG_TBRQ_THRESH	400
-#define TBRQ_MASK(x)		(((unsigned long)(x))&((CONFIG_TBRQ_SIZE<<2)-1))
-
-#define CONFIG_RBPL_SIZE	512
-#define CONFIG_RBPL_THRESH	64
-#define CONFIG_RBPL_BUFSIZE	4096
-#define RBPL_MASK(x)		(((unsigned long)(x))&((CONFIG_RBPL_SIZE<<3)-1))
-
-/* 5.1.3 initialize connection memory */
-
-#define CONFIG_RSRA		0x00000
-#define CONFIG_RCMLBM		0x08000
-#define CONFIG_RCMABR		0x0d800
-#define CONFIG_RSRB		0x0e000
-
-#define CONFIG_TSRA		0x00000
-#define CONFIG_TSRB		0x08000
-#define CONFIG_TSRC		0x0c000
-#define CONFIG_TSRD		0x0e000
-#define CONFIG_TMABR		0x0f000
-#define CONFIG_TPDBA		0x10000
-
-#define HE_MAXCIDBITS		12
-
-/* 2.9.3.3 interrupt encodings */
-
-struct he_irq {
-	volatile u32 isw;
-};
-
-#define IRQ_ALIGNMENT		0x1000
-
-#define NEXT_ENTRY(base, tail, mask) \
-				(((unsigned long)base)|(((unsigned long)(tail+1))&mask))
-
-#define ITYPE_INVALID		0xffffffff
-#define ITYPE_TBRQ_THRESH	(0<<3)
-#define ITYPE_TPD_COMPLETE	(1<<3)
-#define ITYPE_RBPS_THRESH	(2<<3)
-#define ITYPE_RBPL_THRESH	(3<<3)
-#define ITYPE_RBRQ_THRESH	(4<<3)
-#define ITYPE_RBRQ_TIMER	(5<<3)
-#define ITYPE_PHY		(6<<3)
-#define ITYPE_OTHER		0x80
-#define ITYPE_PARITY		0x81
-#define ITYPE_ABORT		0x82
-
-#define ITYPE_GROUP(x)		(x & 0x7)
-#define ITYPE_TYPE(x)		(x & 0xf8)
-
-#define HE_NUM_GROUPS 8
-
-/* 2.1.4 transmit packet descriptor */
-
-struct he_tpd {
-
-	/* read by the adapter */
-
-	volatile u32 status;
-	volatile u32 reserved;
-
-#define TPD_MAXIOV	3
-	struct {
-		u32 addr, len;
-	} iovec[TPD_MAXIOV];
-
-#define address0 iovec[0].addr
-#define length0 iovec[0].len
-
-	/* linux-atm extensions */
-
-	struct sk_buff *skb;
-	struct atm_vcc *vcc;
-
-	struct list_head entry;
-};
-
-#define TPD_ALIGNMENT	64
-#define TPD_LEN_MASK	0xffff
-
-#define TPD_ADDR_SHIFT  6
-#define TPD_MASK	0xffffffc0
-#define TPD_ADDR(x)	((x) & TPD_MASK)
-#define TPD_INDEX(x)	(TPD_ADDR(x) >> TPD_ADDR_SHIFT)
-
-
-/* table 2.3 transmit buffer return elements */
-
-struct he_tbrq {
-	volatile u32 tbre;
-};
-
-#define TBRQ_ALIGNMENT	CONFIG_TBRQ_SIZE
-
-#define TBRQ_TPD(tbrq)		((tbrq)->tbre & 0xffffffc0)
-#define TBRQ_EOS(tbrq)		((tbrq)->tbre & (1<<3))
-#define TBRQ_MULTIPLE(tbrq)	((tbrq)->tbre & (1))
-
-/* table 2.21 receive buffer return queue element field organization */
-
-struct he_rbrq {
-	volatile u32 addr;
-	volatile u32 cidlen;
-};
-
-#define RBRQ_ALIGNMENT	CONFIG_RBRQ_SIZE
-
-#define RBRQ_ADDR(rbrq)		((rbrq)->addr & 0xffffffc0)
-#define RBRQ_CRC_ERR(rbrq)	((rbrq)->addr & (1<<5))
-#define RBRQ_LEN_ERR(rbrq)	((rbrq)->addr & (1<<4))
-#define RBRQ_END_PDU(rbrq)	((rbrq)->addr & (1<<3))
-#define RBRQ_AAL5_PROT(rbrq)	((rbrq)->addr & (1<<2))
-#define RBRQ_CON_CLOSED(rbrq)	((rbrq)->addr & (1<<1))
-#define RBRQ_HBUF_ERR(rbrq)	((rbrq)->addr & 1)
-#define RBRQ_CID(rbrq)		(((rbrq)->cidlen >> 16) & 0x1fff)
-#define RBRQ_BUFLEN(rbrq)	((rbrq)->cidlen & 0xffff)
-
-/* figure 2.3 transmit packet descriptor ready queue */
-
-struct he_tpdrq {
-	volatile u32 tpd;
-	volatile u32 cid;
-};
-
-#define TPDRQ_ALIGNMENT CONFIG_TPDRQ_SIZE
-
-/* table 2.30 host status page detail */
-
-#define HSP_ALIGNMENT	0x400		/* must align on 1k boundary */
-
-struct he_hsp {
-	struct he_hsp_entry {
-		volatile u32 tbrq_tail; 
-		volatile u32 reserved1[15];
-		volatile u32 rbrq_tail; 
-		volatile u32 reserved2[15];
-	} group[HE_NUM_GROUPS];
-};
-
-/*
- * figure 2.9 receive buffer pools
- *
- * since a virtual address might be more than 32 bits, we store an index
- * in the virt member of he_rbp.  NOTE: the lower six bits in the  rbrq
- * addr member are used for buffer status further limiting us to 26 bits.
- */
-
-struct he_rbp {
-	volatile u32 phys;
-	volatile u32 idx;	/* virt */
-};
-
-#define RBP_IDX_OFFSET 6
-
-/*
- * the he dma engine will try to hold an extra 16 buffers in its local
- * caches.  and add a couple buffers for safety.
- */
-
-#define RBPL_TABLE_SIZE (CONFIG_RBPL_SIZE + 16 + 2)
-
-struct he_buff {
-	struct list_head entry;
-	dma_addr_t mapping;
-	unsigned long len;
-	u8 data[];
-};
-
-#ifdef notyet
-struct he_group {
-	u32 rpbl_size, rpbl_qsize;
-	struct he_rpb_entry *rbpl_ba;
-};
-#endif
-
-#define HE_LOOKUP_VCC(dev, cid) ((dev)->he_vcc_table[(cid)].vcc)
-
-struct he_vcc_table 
-{
-	struct atm_vcc *vcc;
-};
-
-struct he_cs_stper
-{
-	long pcr;
-	int inuse;
-};
-
-#define HE_NUM_CS_STPER		16
-
-struct he_dev {
-	unsigned int number;
-	unsigned int irq;
-	void __iomem *membase;
-
-	char prod_id[30];
-	char mac_addr[6];
-	int media;
-
-	unsigned int vcibits, vpibits;
-	unsigned int cells_per_row;
-	unsigned int bytes_per_row;
-	unsigned int cells_per_lbuf;
-	unsigned int r0_numrows, r0_startrow, r0_numbuffs;
-	unsigned int r1_numrows, r1_startrow, r1_numbuffs;
-	unsigned int tx_numrows, tx_startrow, tx_numbuffs;
-	unsigned int buffer_limit;
-
-	struct he_vcc_table *he_vcc_table;
-
-#ifdef notyet
-	struct he_group group[HE_NUM_GROUPS];
-#endif
-	struct he_cs_stper cs_stper[HE_NUM_CS_STPER];
-	unsigned total_bw;
-
-	dma_addr_t irq_phys;
-	struct he_irq *irq_base, *irq_head, *irq_tail;
-	volatile unsigned *irq_tailoffset;
-	int irq_peak;
-
-	struct tasklet_struct tasklet;
-	struct dma_pool *tpd_pool;
-	struct list_head outstanding_tpds;
-
-	dma_addr_t tpdrq_phys;
-	struct he_tpdrq *tpdrq_base, *tpdrq_tail, *tpdrq_head;
-
-	spinlock_t global_lock;		/* 8.1.5 pci transaction ordering
-					  error problem */
-	dma_addr_t rbrq_phys;
-	struct he_rbrq *rbrq_base, *rbrq_head;
-	int rbrq_peak;
-
-	struct he_buff **rbpl_virt;
-	unsigned long *rbpl_table;
-	unsigned long rbpl_hint;
-	struct dma_pool *rbpl_pool;
-	dma_addr_t rbpl_phys;
-	struct he_rbp *rbpl_base, *rbpl_tail;
-	struct list_head rbpl_outstanding;
-	int rbpl_peak;
-
-	dma_addr_t tbrq_phys;
-	struct he_tbrq *tbrq_base, *tbrq_head;
-	int tbrq_peak;
-
-	dma_addr_t hsp_phys;
-	struct he_hsp *hsp;
-
-	struct pci_dev *pci_dev;
-	struct atm_dev *atm_dev;
-	struct he_dev *next;
-};
-
-#define HE_MAXIOV 20
-
-struct he_vcc
-{
-	struct list_head buffers;
-	int pdu_len;
-	int rc_index;
-
-	wait_queue_head_t rx_waitq;
-	wait_queue_head_t tx_waitq;
-};
-
-#define HE_VCC(vcc)	((struct he_vcc *)(vcc->dev_data))
-
-#define PCI_VENDOR_ID_FORE	0x1127
-#define PCI_DEVICE_ID_FORE_HE	0x400
-
-#define GEN_CNTL_0				0x40
-#define  INT_PROC_ENBL		(1<<25)
-#define  SLAVE_ENDIAN_MODE	(1<<16)
-#define  MRL_ENB		(1<<5)
-#define  MRM_ENB		(1<<4)
-#define  INIT_ENB		(1<<2)
-#define  IGNORE_TIMEOUT		(1<<1)
-#define  ENBL_64		(1<<0)
-
-#define MIN_PCI_LATENCY		32	/* errata 8.1.3 */
-
-#define HE_DEV(dev) ((struct he_dev *) (dev)->dev_data)
-
-#define he_is622(dev)	((dev)->media & 0x1)
-#define he_isMM(dev)	((dev)->media & 0x20)
-
-#define HE_REGMAP_SIZE	0x100000
-
-#define RESET_CNTL	0x80000
-#define  BOARD_RST_STATUS	(1<<6)
-
-#define HOST_CNTL	0x80004
-#define  PCI_BUS_SIZE64			(1<<27)
-#define  DESC_RD_STATIC_64		(1<<26)
-#define  DATA_RD_STATIC_64		(1<<25)
-#define  DATA_WR_STATIC_64		(1<<24)
-#define  ID_CS				(1<<12)
-#define  ID_WREN			(1<<11)
-#define  ID_DOUT			(1<<10)
-#define   ID_DOFFSET			10
-#define  ID_DIN				(1<<9)
-#define  ID_CLOCK			(1<<8)
-#define  QUICK_RD_RETRY			(1<<7)
-#define  QUICK_WR_RETRY			(1<<6)
-#define  OUTFF_ENB			(1<<5)
-#define  CMDFF_ENB			(1<<4)
-#define  PERR_INT_ENB			(1<<2)
-#define  IGNORE_INTR			(1<<0)
-
-#define LB_SWAP		0x80008
-#define  SWAP_RNUM_MAX(x)	(x<<27)
-#define  DATA_WR_SWAP		(1<<20)
-#define  DESC_RD_SWAP		(1<<19)
-#define  DATA_RD_SWAP		(1<<18)
-#define  INTR_SWAP		(1<<17)
-#define  DESC_WR_SWAP		(1<<16)
-#define  SDRAM_INIT		(1<<15)
-#define  BIG_ENDIAN_HOST	(1<<14)
-#define  XFER_SIZE		(1<<7)
-
-#define LB_MEM_ADDR	0x8000c
-#define LB_MEM_DATA	0x80010
-
-#define LB_MEM_ACCESS	0x80014
-#define  LB_MEM_HNDSHK		(1<<30)
-#define  LM_MEM_WRITE		(0x7)
-#define  LM_MEM_READ		(0x3)
-
-#define SDRAM_CTL	0x80018
-#define  LB_64_ENB		(1<<3)
-#define  LB_TWR			(1<<2)
-#define  LB_TRP			(1<<1)
-#define  LB_TRAS		(1<<0)
-
-#define INT_FIFO	0x8001c
-#define  INT_MASK_D		(1<<15)
-#define  INT_MASK_C		(1<<14)
-#define  INT_MASK_B		(1<<13)
-#define  INT_MASK_A		(1<<12)
-#define  INT_CLEAR_D		(1<<11)
-#define  INT_CLEAR_C		(1<<10)
-#define  INT_CLEAR_B		(1<<9)
-#define  INT_CLEAR_A		(1<<8)
-
-#define ABORT_ADDR	0x80020
-
-#define IRQ0_BASE	0x80080
-#define  IRQ_BASE(x)		(x<<12)
-#define  IRQ_MASK		((CONFIG_IRQ_SIZE<<2)-1)	/* was 0x3ff */
-#define  IRQ_TAIL(x)		(((unsigned long)(x)) & IRQ_MASK)
-#define IRQ0_HEAD	0x80084
-#define  IRQ_SIZE(x)		(x<<22)
-#define  IRQ_THRESH(x)		(x<<12)
-#define  IRQ_HEAD(x)		(x<<2)
-/* #define  IRQ_PENDING		(1) 		conflict with linux/irq.h */
-#define IRQ0_CNTL	0x80088
-#define  IRQ_ADDRSEL(x)		(x<<2)
-#define  IRQ_INT_A		(0<<2)
-#define  IRQ_INT_B		(1<<2)
-#define  IRQ_INT_C		(2<<2)
-#define  IRQ_INT_D		(3<<2)
-#define  IRQ_TYPE_ADDR		0x1
-#define  IRQ_TYPE_LINE		0x0
-#define IRQ0_DATA	0x8008c
-
-#define IRQ1_BASE	0x80090
-#define IRQ1_HEAD	0x80094
-#define IRQ1_CNTL	0x80098
-#define IRQ1_DATA	0x8009c
-
-#define IRQ2_BASE	0x800a0
-#define IRQ2_HEAD	0x800a4
-#define IRQ2_CNTL	0x800a8
-#define IRQ2_DATA	0x800ac
-
-#define IRQ3_BASE	0x800b0
-#define IRQ3_HEAD	0x800b4
-#define IRQ3_CNTL	0x800b8
-#define IRQ3_DATA	0x800bc
-
-#define GRP_10_MAP	0x800c0
-#define GRP_32_MAP	0x800c4
-#define GRP_54_MAP	0x800c8
-#define GRP_76_MAP	0x800cc
-
-#define	G0_RBPS_S	0x80400
-#define G0_RBPS_T	0x80404
-#define  RBP_TAIL(x)		((x)<<3)
-#define  RBP_MASK(x)		((x)|0x1fff)
-#define G0_RBPS_QI	0x80408
-#define  RBP_QSIZE(x)		((x)<<14)
-#define  RBP_INT_ENB		(1<<13)
-#define  RBP_THRESH(x)		(x)
-#define G0_RBPS_BS	0x8040c
-#define G0_RBPL_S	0x80410
-#define G0_RBPL_T	0x80414
-#define G0_RBPL_QI	0x80418 
-#define G0_RBPL_BS	0x8041c
-
-#define	G1_RBPS_S	0x80420
-#define G1_RBPS_T	0x80424
-#define G1_RBPS_QI	0x80428
-#define G1_RBPS_BS	0x8042c
-#define G1_RBPL_S	0x80430
-#define G1_RBPL_T	0x80434
-#define G1_RBPL_QI	0x80438
-#define G1_RBPL_BS	0x8043c
-
-#define	G2_RBPS_S	0x80440
-#define G2_RBPS_T	0x80444
-#define G2_RBPS_QI	0x80448
-#define G2_RBPS_BS	0x8044c
-#define G2_RBPL_S	0x80450
-#define G2_RBPL_T	0x80454
-#define G2_RBPL_QI	0x80458
-#define G2_RBPL_BS	0x8045c
-
-#define	G3_RBPS_S	0x80460
-#define G3_RBPS_T	0x80464
-#define G3_RBPS_QI	0x80468
-#define G3_RBPS_BS	0x8046c
-#define G3_RBPL_S	0x80470
-#define G3_RBPL_T	0x80474
-#define G3_RBPL_QI	0x80478
-#define G3_RBPL_BS	0x8047c
-
-#define	G4_RBPS_S	0x80480
-#define G4_RBPS_T	0x80484
-#define G4_RBPS_QI	0x80488
-#define G4_RBPS_BS	0x8048c
-#define G4_RBPL_S	0x80490
-#define G4_RBPL_T	0x80494
-#define G4_RBPL_QI	0x80498
-#define G4_RBPL_BS	0x8049c
-
-#define	G5_RBPS_S	0x804a0
-#define G5_RBPS_T	0x804a4
-#define G5_RBPS_QI	0x804a8
-#define G5_RBPS_BS	0x804ac
-#define G5_RBPL_S	0x804b0
-#define G5_RBPL_T	0x804b4
-#define G5_RBPL_QI	0x804b8
-#define G5_RBPL_BS	0x804bc
-
-#define	G6_RBPS_S	0x804c0
-#define G6_RBPS_T	0x804c4
-#define G6_RBPS_QI	0x804c8
-#define G6_RBPS_BS	0x804cc
-#define G6_RBPL_S	0x804d0
-#define G6_RBPL_T	0x804d4
-#define G6_RBPL_QI	0x804d8
-#define G6_RBPL_BS	0x804dc
-
-#define	G7_RBPS_S	0x804e0
-#define G7_RBPS_T	0x804e4
-#define G7_RBPS_QI	0x804e8
-#define G7_RBPS_BS	0x804ec
-
-#define G7_RBPL_S	0x804f0
-#define G7_RBPL_T	0x804f4
-#define G7_RBPL_QI	0x804f8
-#define G7_RBPL_BS	0x804fc
-
-#define G0_RBRQ_ST	0x80500
-#define G0_RBRQ_H	0x80504
-#define G0_RBRQ_Q	0x80508
-#define  RBRQ_THRESH(x)		((x)<<13)
-#define  RBRQ_SIZE(x)		(x)
-#define G0_RBRQ_I	0x8050c
-#define  RBRQ_TIME(x)		((x)<<8)
-#define  RBRQ_COUNT(x)		(x)
-
-/* fill in 1 ... 7 later */
-
-#define G0_TBRQ_B_T	0x80600
-#define G0_TBRQ_H	0x80604
-#define G0_TBRQ_S	0x80608
-#define G0_TBRQ_THRESH	0x8060c
-#define  TBRQ_THRESH(x)		(x)
-
-/* fill in 1 ... 7 later */
-
-#define RH_CONFIG	0x805c0
-#define  PHY_INT_ENB	(1<<10)
-#define  OAM_GID(x)	(x<<7)
-#define  PTMR_PRE(x)	(x)
-
-#define G0_INMQ_S	0x80580
-#define G0_INMQ_L	0x80584
-#define G1_INMQ_S	0x80588
-#define G1_INMQ_L	0x8058c
-#define G2_INMQ_S	0x80590
-#define G2_INMQ_L	0x80594
-#define G3_INMQ_S	0x80598
-#define G3_INMQ_L	0x8059c
-#define G4_INMQ_S	0x805a0
-#define G4_INMQ_L	0x805a4
-#define G5_INMQ_S	0x805a8
-#define G5_INMQ_L	0x805ac
-#define G6_INMQ_S	0x805b0
-#define G6_INMQ_L	0x805b4
-#define G7_INMQ_S	0x805b8
-#define G7_INMQ_L	0x805bc
-
-#define TPDRQ_B_H	0x80680
-#define TPDRQ_T		0x80684
-#define TPDRQ_S		0x80688
-
-#define UBUFF_BA	0x8068c
-
-#define RLBF0_H		0x806c0
-#define RLBF0_T		0x806c4
-#define RLBF1_H		0x806c8
-#define RLBF1_T		0x806cc
-#define RLBC_H		0x806d0
-#define RLBC_T		0x806d4
-#define RLBC_H2		0x806d8
-#define TLBF_H		0x806e0
-#define TLBF_T		0x806e4
-#define RLBF0_C		0x806e8
-#define RLBF1_C		0x806ec
-#define RXTHRSH		0x806f0
-#define LITHRSH		0x806f4
-
-#define LBARB		0x80700
-#define  SLICE_X(x)		 (x<<28)
-#define  ARB_RNUM_MAX(x)	 (x<<23)
-#define  TH_PRTY(x)		 (x<<21)
-#define  RH_PRTY(x)		 (x<<19)
-#define  TL_PRTY(x)		 (x<<17)
-#define  RL_PRTY(x)		 (x<<15)
-#define  BUS_MULTI(x)		 (x<<8)
-#define  NET_PREF(x)		 (x)
-
-#define SDRAMCON	0x80704
-#define	 BANK_ON		(1<<14)
-#define	 WIDE_DATA		(1<<13)
-#define	 TWR_WAIT		(1<<12)
-#define	 TRP_WAIT		(1<<11)
-#define	 TRAS_WAIT		(1<<10)
-#define	 REF_RATE(x)		(x)
-
-#define LBSTAT		0x80708
-
-#define RCC_STAT	0x8070c
-#define  RCC_BUSY		(1)
-
-#define TCMCONFIG	0x80740
-#define  TM_DESL2		(1<<10)
-#define	 TM_BANK_WAIT(x)	(x<<6)
-#define	 TM_ADD_BANK4(x)	(x<<4)
-#define  TM_PAR_CHECK(x)	(x<<3)
-#define  TM_RW_WAIT(x)		(x<<2)
-#define  TM_SRAM_TYPE(x)	(x)
-
-#define TSRB_BA		0x80744	
-#define TSRC_BA		0x80748	
-#define TMABR_BA	0x8074c	
-#define TPD_BA		0x80750	
-#define TSRD_BA		0x80758	
-
-#define TX_CONFIG	0x80760
-#define  DRF_THRESH(x)		(x<<22)
-#define  TX_UT_MODE(x)		(x<<21)
-#define  TX_VCI_MASK(x)		(x<<17)
-#define  LBFREE_CNT(x)		(x)
-
-#define TXAAL5_PROTO	0x80764
-#define  CPCS_UU(x)		(x<<8)
-#define  CPI(x)			(x)
-
-#define RCMCONFIG	0x80780
-#define  RM_DESL2(x)		(x<<10)
-#define  RM_BANK_WAIT(x)	(x<<6)
-#define  RM_ADD_BANK(x)		(x<<4)
-#define  RM_PAR_CHECK(x)	(x<<3)
-#define  RM_RW_WAIT(x)		(x<<2)
-#define  RM_SRAM_TYPE(x)	(x)
-
-#define RCMRSRB_BA	0x80784
-#define RCMLBM_BA	0x80788
-#define RCMABR_BA	0x8078c
-
-#define RC_CONFIG	0x807c0
-#define  UT_RD_DELAY(x)		(x<<11)
-#define  WRAP_MODE(x)		(x<<10)
-#define  RC_UT_MODE(x)		(x<<9)
-#define  RX_ENABLE		(1<<8)
-#define  RX_VALVP(x)		(x<<4)
-#define  RX_VALVC(x)		(x)
-
-#define MCC		0x807c4
-#define OEC		0x807c8
-#define DCC		0x807cc
-#define CEC		0x807d0
-
-#define HSP_BA		0x807f0
-
-#define LB_CONFIG	0x807f4
-#define  LB_SIZE(x)		(x)
-
-#define CON_DAT		0x807f8
-#define CON_CTL		0x807fc
-#define  CON_CTL_MBOX		(2<<30)
-#define  CON_CTL_TCM		(1<<30)
-#define  CON_CTL_RCM		(0<<30)
-#define  CON_CTL_WRITE		(1<<29)
-#define  CON_CTL_READ		(0<<29)
-#define  CON_CTL_BUSY		(1<<28)
-#define  CON_BYTE_DISABLE_3	(1<<22)		/* 24..31 */
-#define  CON_BYTE_DISABLE_2	(1<<21)		/* 16..23 */
-#define  CON_BYTE_DISABLE_1	(1<<20)		/* 8..15 */
-#define  CON_BYTE_DISABLE_0	(1<<19)		/* 0..7 */
-#define  CON_CTL_ADDR(x)	(x)
-
-#define FRAMER		0x80800		/* to 0x80bfc */
-
-/* 3.3 network controller (internal) mailbox registers */
-
-#define CS_STPER0	0x0
-	/* ... */
-#define CS_STPER31	0x01f
-
-#define CS_STTIM0	0x020
-	/* ... */
-#define CS_STTIM31	0x03f
-
-#define CS_TGRLD0	0x040
-	/* ... */
-#define CS_TGRLD15	0x04f
-
-#define CS_ERTHR0	0x050
-#define CS_ERTHR1	0x051
-#define CS_ERTHR2	0x052
-#define CS_ERTHR3	0x053
-#define CS_ERTHR4	0x054
-#define CS_ERCTL0	0x055
-#define  TX_ENABLE		(1<<28)
-#define  ER_ENABLE		(1<<27)
-#define CS_ERCTL1	0x056
-#define CS_ERCTL2	0x057
-#define CS_ERSTAT0	0x058
-#define CS_ERSTAT1	0x059
-
-#define CS_RTCCT	0x060
-#define CS_RTFWC	0x061
-#define CS_RTFWR	0x062
-#define CS_RTFTC	0x063
-#define CS_RTATR	0x064
-
-#define CS_TFBSET	0x070
-#define CS_TFBADD	0x071
-#define CS_TFBSUB	0x072
-#define CS_WCRMAX	0x073
-#define CS_WCRMIN	0x074
-#define CS_WCRINC	0x075
-#define CS_WCRDEC	0x076
-#define CS_WCRCEIL	0x077
-#define CS_BWDCNT	0x078
-
-#define CS_OTPPER	0x080
-#define CS_OTWPER	0x081
-#define CS_OTTLIM	0x082
-#define CS_OTTCNT	0x083
-
-#define CS_HGRRT0	0x090
-	/* ... */
-#define CS_HGRRT7	0x097
-
-#define CS_ORPTRS	0x0a0
-
-#define RXCON_CLOSE	0x100
-
-
-#define RCM_MEM_SIZE	0x10000		/* 1M of 32-bit registers */
-#define TCM_MEM_SIZE	0x20000		/* 2M of 32-bit registers */
-
-/* 2.5 transmit connection memory registers */
-
-#define TSR0_CONN_STATE(x)	((x>>28) & 0x7)
-#define TSR0_USE_WMIN		(1<<23)
-#define TSR0_GROUP(x)		((x & 0x7)<<18)
-#define TSR0_ABR		(2<<16)
-#define TSR0_UBR		(1<<16)
-#define TSR0_CBR		(0<<16)
-#define TSR0_PROT		(1<<15)
-#define TSR0_AAL0_SDU		(2<<12)
-#define TSR0_AAL0		(1<<12)
-#define TSR0_AAL5		(0<<12)
-#define TSR0_HALT_ER		(1<<11)
-#define TSR0_MARK_CI		(1<<10)
-#define TSR0_MARK_ER		(1<<9)
-#define TSR0_UPDATE_GER		(1<<8)
-#define TSR0_RC_INDEX(x)	(x & 0x1F)
-
-#define TSR1_PCR(x)		((x & 0x7FFF)<<16)
-#define TSR1_MCR(x)		(x & 0x7FFF)
-
-#define TSR2_ACR(x)		((x & 0x7FFF)<<16)
-
-#define TSR3_NRM_CNT(x)		((x & 0xFF)<<24)
-#define TSR3_CRM_CNT(x)		(x & 0xFFFF)
-
-#define TSR4_FLUSH_CONN		(1<<31)
-#define TSR4_SESSION_ENDED	(1<<30)
-#define TSR4_CRC10		(1<<28)
-#define TSR4_NULL_CRC10		(1<<27)
-#define TSR4_PROT		(1<<26)
-#define TSR4_AAL0_SDU		(2<<23)
-#define TSR4_AAL0		(1<<23)
-#define TSR4_AAL5		(0<<23)
-
-#define TSR9_OPEN_CONN		(1<<20)
-
-#define TSR11_ICR(x)		((x & 0x7FFF)<<16)
-#define TSR11_TRM(x)		((x & 0x7)<<13)
-#define TSR11_NRM(x)		((x & 0x7)<<10)
-#define TSR11_ADTF(x)		(x & 0x3FF)
-
-#define TSR13_RDF(x)		((x & 0xF)<<23)
-#define TSR13_RIF(x)		((x & 0xF)<<19)
-#define TSR13_CDF(x)		((x & 0x7)<<16)
-#define TSR13_CRM(x)		(x & 0xFFFF)
-
-#define TSR14_DELETE		(1<<31)
-#define TSR14_ABR_CLOSE		(1<<16)
-
-/* 2.7.1 per connection receieve state registers */
-
-#define RSR0_START_PDU	(1<<10)
-#define RSR0_OPEN_CONN	(1<<6)
-#define RSR0_CLOSE_CONN	(0<<6)
-#define RSR0_PPD_ENABLE	(1<<5)
-#define RSR0_EPD_ENABLE	(1<<4)
-#define RSR0_TCP_CKSUM	(1<<3)
-#define RSR0_AAL5		(0)
-#define RSR0_AAL0		(1)
-#define RSR0_AAL0_SDU		(2)
-#define RSR0_RAWCELL		(3)
-#define RSR0_RAWCELL_CRC10	(4)
-
-#define RSR1_AQI_ENABLE	(1<<20)
-#define RSR1_RBPL_ONLY	(1<<19)
-#define RSR1_GROUP(x)	((x)<<16)
-
-#define RSR4_AQI_ENABLE (1<<30)
-#define RSR4_GROUP(x)	((x)<<27)
-#define RSR4_RBPL_ONLY	(1<<26)
-
-/* 2.1.4 transmit packet descriptor */
-
-#define	TPD_USERCELL		0x0
-#define	TPD_SEGMENT_OAMF5	0x4
-#define	TPD_END2END_OAMF5	0x5
-#define	TPD_RMCELL		0x6
-#define TPD_CELLTYPE(x)		(x<<3)
-#define TPD_EOS			(1<<2)
-#define TPD_CLP			(1<<1)
-#define TPD_INT			(1<<0)
-#define TPD_LST		(1<<31)
-
-/* table 4.3 serial eeprom information */
-
-#define PROD_ID		0x08	/* char[] */
-#define  PROD_ID_LEN	30
-#define HW_REV		0x26	/* char[] */
-#define M_SN		0x3a	/* integer */
-#define MEDIA		0x3e	/* integer */
-#define  HE155MM	0x26
-#define  HE622MM	0x27
-#define  HE155SM	0x46
-#define  HE622SM	0x47
-#define MAC_ADDR	0x42	/* char[] */
-
-#define CS_LOW		0x0
-#define CS_HIGH		ID_CS /* HOST_CNTL_ID_PROM_SEL */
-#define CLK_LOW		0x0
-#define CLK_HIGH	ID_CLOCK /* HOST_CNTL_ID_PROM_CLOCK */
-#define SI_HIGH		ID_DIN /* HOST_CNTL_ID_PROM_DATA_IN */
-#define EEPROM_DELAY	400 /* microseconds */
-
-#endif /* _HE_H_ */
diff --git a/drivers/atm/idt77105.h b/drivers/atm/idt77105.h
deleted file mode 100644
index 8dfea9e361de..000000000000
--- a/drivers/atm/idt77105.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* drivers/atm/idt77105.h - IDT77105 (PHY) declarations */
- 
-/* Written 1999 by Greg Banks, NEC Australia <gnb@linuxfan.com>. Based on suni.h */
- 
-
-#ifndef DRIVER_ATM_IDT77105_H
-#define DRIVER_ATM_IDT77105_H
-
-#include <linux/atmdev.h>
-#include <linux/atmioc.h>
-
-
-/* IDT77105 registers */
-
-#define IDT77105_MCR		0x0	/* Master Control Register */
-#define IDT77105_ISTAT	        0x1	/* Interrupt Status */
-#define IDT77105_DIAG   	0x2	/* Diagnostic Control */
-#define IDT77105_LEDHEC		0x3	/* LED Driver & HEC Status/Control */
-#define IDT77105_CTRLO		0x4	/* Low Byte Counter Register */
-#define IDT77105_CTRHI		0x5	/* High Byte Counter Register */
-#define IDT77105_CTRSEL		0x6	/* Counter Register Read Select */
-
-/* IDT77105 register values */
-
-/* MCR */
-#define IDT77105_MCR_UPLO	0x80	/* R/W, User Prog'le Output Latch */
-#define IDT77105_MCR_DREC	0x40	/* R/W, Discard Receive Error Cells */
-#define IDT77105_MCR_ECEIO	0x20	/* R/W, Enable Cell Error Interrupts
-                                         * Only */
-#define IDT77105_MCR_TDPC	0x10	/* R/W, Transmit Data Parity Check */
-#define IDT77105_MCR_DRIC	0x08	/* R/W, Discard Received Idle Cells */
-#define IDT77105_MCR_HALTTX	0x04	/* R/W, Halt Tx */
-#define IDT77105_MCR_UMODE	0x02	/* R/W, Utopia (cell/byte) Mode */
-#define IDT77105_MCR_EIP	0x01	/* R/W, Enable Interrupt Pin */
-
-/* ISTAT */
-#define IDT77105_ISTAT_GOODSIG	0x40	/* R, Good Signal Bit */
-#define IDT77105_ISTAT_HECERR	0x20	/* sticky, HEC Error*/
-#define IDT77105_ISTAT_SCR	0x10	/* sticky, Short Cell Received */
-#define IDT77105_ISTAT_TPE	0x08	/* sticky, Transmit Parity Error */
-#define IDT77105_ISTAT_RSCC	0x04	/* sticky, Rx Signal Condition Change */
-#define IDT77105_ISTAT_RSE	0x02	/* sticky, Rx Symbol Error */
-#define IDT77105_ISTAT_RFO	0x01	/* sticky, Rx FIFO Overrun */
-
-/* DIAG */
-#define IDT77105_DIAG_FTD	0x80	/* R/W, Force TxClav deassert */
-#define IDT77105_DIAG_ROS	0x40	/* R/W, RxClav operation select */
-#define IDT77105_DIAG_MPCS	0x20	/* R/W, Multi-PHY config'n select */
-#define IDT77105_DIAG_RFLUSH	0x10	/* R/W, clear receive FIFO */
-#define IDT77105_DIAG_ITPE	0x08	/* R/W, Insert Tx payload error */
-#define IDT77105_DIAG_ITHE	0x04	/* R/W, Insert Tx HEC error */
-#define IDT77105_DIAG_UMODE	0x02	/* R/W, Utopia (cell/byte) Mode */
-#define IDT77105_DIAG_LCMASK	0x03	/* R/W, Loopback Control */
-
-#define IDT77105_DIAG_LC_NORMAL         0x00	/* Receive from network */
-#define IDT77105_DIAG_LC_PHY_LOOPBACK	0x02
-#define IDT77105_DIAG_LC_LINE_LOOPBACK	0x03
-
-/* LEDHEC */
-#define IDT77105_LEDHEC_DRHC	0x40	/* R/W, Disable Rx HEC check */
-#define IDT77105_LEDHEC_DTHC	0x20	/* R/W, Disable Tx HEC calculation */
-#define IDT77105_LEDHEC_RPWMASK	0x18	/* R/W, RxRef pulse width select */
-#define IDT77105_LEDHEC_TFS	0x04	/* R, Tx FIFO Status (1=empty) */
-#define IDT77105_LEDHEC_TLS	0x02	/* R, Tx LED Status (1=lit) */
-#define IDT77105_LEDHEC_RLS	0x01	/* R, Rx LED Status (1=lit) */
-
-#define IDT77105_LEDHEC_RPW_1	0x00	/* RxRef active for 1 RxClk cycle */
-#define IDT77105_LEDHEC_RPW_2	0x08	/* RxRef active for 2 RxClk cycle */
-#define IDT77105_LEDHEC_RPW_4	0x10	/* RxRef active for 4 RxClk cycle */
-#define IDT77105_LEDHEC_RPW_8	0x18	/* RxRef active for 8 RxClk cycle */
-
-/* CTRSEL */
-#define IDT77105_CTRSEL_SEC	0x08	/* W, Symbol Error Counter */
-#define IDT77105_CTRSEL_TCC	0x04	/* W, Tx Cell Counter */
-#define IDT77105_CTRSEL_RCC	0x02	/* W, Rx Cell Counter */
-#define IDT77105_CTRSEL_RHEC	0x01	/* W, Rx HEC Error Counter */
-
-#ifdef __KERNEL__
-int idt77105_init(struct atm_dev *dev);
-#endif
-
-/*
- * Tunable parameters
- */
- 
-/* Time between samples of the hardware cell counters. Should be <= 1 sec */
-#define IDT77105_STATS_TIMER_PERIOD     (HZ) 
-/* Time between checks to see if the signal has been found again */
-#define IDT77105_RESTART_TIMER_PERIOD   (5 * HZ)
-
-#endif
diff --git a/drivers/atm/idt77252.h b/drivers/atm/idt77252.h
deleted file mode 100644
index b059d31364dd..000000000000
--- a/drivers/atm/idt77252.h
+++ /dev/null
@@ -1,816 +0,0 @@
-/******************************************************************* 
- *
- * Copyright (c) 2000 ATecoM GmbH 
- *
- * The author may be reached at ecd@atecom.com.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *******************************************************************/
-
-#ifndef _IDT77252_H
-#define _IDT77252_H 1
-
-
-#include <linux/ptrace.h>
-#include <linux/skbuff.h>
-#include <linux/workqueue.h>
-#include <linux/mutex.h>
-
-/*****************************************************************************/
-/*                                                                           */
-/* Makros                                                                    */
-/*                                                                           */
-/*****************************************************************************/
-#define VPCI2VC(card, vpi, vci) \
-        (((vpi) << card->vcibits) | ((vci) & card->vcimask))
-
-/*****************************************************************************/
-/*                                                                           */
-/*   DEBUGGING definitions                                                   */
-/*                                                                           */
-/*****************************************************************************/
-
-#define DBG_RAW_CELL	0x00000400
-#define DBG_TINY	0x00000200
-#define DBG_GENERAL     0x00000100
-#define DBG_XGENERAL    0x00000080
-#define DBG_INIT        0x00000040
-#define DBG_DEINIT      0x00000020
-#define DBG_INTERRUPT   0x00000010
-#define DBG_OPEN_CONN   0x00000008
-#define DBG_CLOSE_CONN  0x00000004
-#define DBG_RX_DATA     0x00000002
-#define DBG_TX_DATA     0x00000001
-
-#ifdef CONFIG_ATM_IDT77252_DEBUG
-
-#define CPRINTK(args...)   do { if (debug & DBG_CLOSE_CONN) printk(args); } while(0)
-#define OPRINTK(args...)   do { if (debug & DBG_OPEN_CONN)  printk(args); } while(0)
-#define IPRINTK(args...)   do { if (debug & DBG_INIT)       printk(args); } while(0)
-#define INTPRINTK(args...) do { if (debug & DBG_INTERRUPT)  printk(args); } while(0)
-#define DIPRINTK(args...)  do { if (debug & DBG_DEINIT)     printk(args); } while(0)
-#define TXPRINTK(args...)  do { if (debug & DBG_TX_DATA)    printk(args); } while(0)
-#define RXPRINTK(args...)  do { if (debug & DBG_RX_DATA)    printk(args); } while(0)
-#define XPRINTK(args...)   do { if (debug & DBG_XGENERAL)   printk(args); } while(0)
-#define DPRINTK(args...)   do { if (debug & DBG_GENERAL)    printk(args); } while(0)
-#define NPRINTK(args...)   do { if (debug & DBG_TINY)	    printk(args); } while(0)
-#define RPRINTK(args...)   do { if (debug & DBG_RAW_CELL)   printk(args); } while(0)
-
-#else
-
-#define CPRINTK(args...)	do { } while(0)
-#define OPRINTK(args...)	do { } while(0)
-#define IPRINTK(args...)	do { } while(0)
-#define INTPRINTK(args...)	do { } while(0)
-#define DIPRINTK(args...)	do { } while(0)
-#define TXPRINTK(args...)	do { } while(0)
-#define RXPRINTK(args...)	do { } while(0)
-#define XPRINTK(args...)	do { } while(0)
-#define DPRINTK(args...)	do { } while(0)
-#define NPRINTK(args...)	do { } while(0)
-#define RPRINTK(args...)	do { } while(0)
-
-#endif
-
-#define SCHED_UBR0		0
-#define SCHED_UBR		1
-#define SCHED_VBR		2
-#define SCHED_ABR		3
-#define SCHED_CBR		4
-
-#define SCQFULL_TIMEOUT		HZ
-
-/*****************************************************************************/
-/*                                                                           */
-/*   Free Buffer Queue Layout                                                */
-/*                                                                           */
-/*****************************************************************************/
-#define SAR_FB_SIZE_0		(2048 - 256)
-#define SAR_FB_SIZE_1		(4096 - 256)
-#define SAR_FB_SIZE_2		(8192 - 256)
-#define SAR_FB_SIZE_3		(16384 - 256)
-
-#define SAR_FBQ0_LOW		4
-#define SAR_FBQ0_HIGH		8
-#define SAR_FBQ1_LOW		2
-#define SAR_FBQ1_HIGH		4
-#define SAR_FBQ2_LOW		1
-#define SAR_FBQ2_HIGH		2
-#define SAR_FBQ3_LOW		1
-#define SAR_FBQ3_HIGH		2
-
-#if 0
-#define SAR_TST_RESERVED	44	/* Num TST reserved for UBR/ABR/VBR */
-#else
-#define SAR_TST_RESERVED	0	/* Num TST reserved for UBR/ABR/VBR */
-#endif
-
-#define TCT_CBR			0x00000000
-#define TCT_UBR			0x00000000
-#define TCT_VBR			0x40000000
-#define TCT_ABR			0x80000000
-#define TCT_TYPE		0xc0000000
-
-#define TCT_RR			0x20000000
-#define TCT_LMCR		0x08000000
-#define TCT_SCD_MASK		0x0007ffff
-
-#define TCT_TSIF		0x00004000
-#define TCT_HALT		0x80000000
-#define TCT_IDLE		0x40000000
-#define TCT_FLAG_UBR		0x80000000
-
-/*****************************************************************************/
-/*                                                                           */
-/*   Structure describing an IDT77252                                        */
-/*                                                                           */
-/*****************************************************************************/
-
-struct scqe
-{
-	u32		word_1;
-	u32		word_2;
-	u32		word_3;
-	u32		word_4;
-};
-
-#define SCQ_ENTRIES	64
-#define SCQ_SIZE	(SCQ_ENTRIES * sizeof(struct scqe))
-#define SCQ_MASK	(SCQ_SIZE - 1)
-
-struct scq_info
-{
-	struct scqe		*base;
-	struct scqe		*next;
-	struct scqe		*last;
-	dma_addr_t		paddr;
-	spinlock_t		lock;
-	atomic_t		used;
-	unsigned long		trans_start;
-        unsigned long		scd;
-	spinlock_t		skblock;
-	struct sk_buff_head	transmit;
-	struct sk_buff_head	pending;
-};
-
-struct rx_pool {
-	struct sk_buff_head	queue;
-	unsigned int		len;
-};
-
-struct aal1 {
-	unsigned int		total;
-	unsigned int		count;
-	struct sk_buff		*data;
-	unsigned char		sequence;
-};
-
-struct vc_map;
-
-struct rate_estimator {
-	struct timer_list	timer;
-	unsigned int		interval;
-	unsigned int		ewma_log;
-	u64			cells;
-	u64			last_cells;
-	long			avcps;
-	u32			cps;
-	u32			maxcps;
-	struct vc_map		*vc;
-};
-
-struct vc_map {
-	unsigned int		index;
-	unsigned long		flags;
-#define VCF_TX		0
-#define VCF_RX		1
-#define VCF_IDLE	2
-#define VCF_RSV		3
-	unsigned int		class;
-	u8			init_er;
-	u8			lacr;
-	u8			max_er;
-	unsigned int		ntste;
-	spinlock_t		lock;
-	struct atm_vcc		*tx_vcc;
-	struct atm_vcc		*rx_vcc;
-	struct idt77252_dev	*card;
-	struct scq_info		*scq;		/* To keep track of the SCQ */
-	struct rate_estimator	*estimator;
-	int			scd_index;
-	union {
-		struct rx_pool	rx_pool;
-		struct aal1	aal1;
-	} rcv;
-};
-
-/*****************************************************************************/
-/*                                                                           */
-/*   RCTE - Receive Connection Table Entry                                   */
-/*                                                                           */
-/*****************************************************************************/
-
-struct rct_entry
-{
-	u32		word_1;
-	u32		buffer_handle;
-	u32		dma_address;
-	u32		aal5_crc32;
-};
-
-/*****************************************************************************/
-/*                                                                           */
-/*   RSQ - Receive Status Queue                                              */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_RSQE_VALID      0x80000000
-#define SAR_RSQE_IDLE       0x40000000
-#define SAR_RSQE_BUF_MASK   0x00030000
-#define SAR_RSQE_BUF_ASGN   0x00008000
-#define SAR_RSQE_NZGFC      0x00004000
-#define SAR_RSQE_EPDU       0x00002000
-#define SAR_RSQE_BUF_CONT   0x00001000
-#define SAR_RSQE_EFCIE      0x00000800
-#define SAR_RSQE_CLP        0x00000400
-#define SAR_RSQE_CRC        0x00000200
-#define SAR_RSQE_CELLCNT    0x000001FF
-
-
-#define RSQSIZE            8192
-#define RSQ_NUM_ENTRIES    (RSQSIZE / 16)
-#define RSQ_ALIGNMENT      8192
-
-struct rsq_entry {
-	u32			word_1;
-	u32			word_2;
-	u32			word_3;
-	u32			word_4;
-};
-
-struct rsq_info {
-	struct rsq_entry	*base;
-	struct rsq_entry	*next;
-	struct rsq_entry	*last;
-	dma_addr_t		paddr;
-};
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   TSQ - Transmit Status Queue                                             */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_TSQE_INVALID         0x80000000
-#define SAR_TSQE_TIMESTAMP       0x00FFFFFF
-#define SAR_TSQE_TYPE		 0x60000000
-#define SAR_TSQE_TYPE_TIMER      0x00000000
-#define SAR_TSQE_TYPE_TSR        0x20000000
-#define SAR_TSQE_TYPE_IDLE       0x40000000
-#define SAR_TSQE_TYPE_TBD_COMP   0x60000000
-
-#define SAR_TSQE_TAG(stat)	(((stat) >> 24) & 0x1f)
-
-#define TSQSIZE            8192
-#define TSQ_NUM_ENTRIES    1024
-#define TSQ_ALIGNMENT      8192
-
-struct tsq_entry
-{
-	u32			word_1;
-	u32			word_2;
-};
-
-struct tsq_info
-{
-	struct tsq_entry	*base;
-	struct tsq_entry	*next;
-	struct tsq_entry	*last;
-	dma_addr_t		paddr;
-};
-
-struct tst_info
-{
-	struct vc_map		*vc;
-	u32			tste;
-};
-
-#define TSTE_MASK		0x601fffff
-
-#define TSTE_OPC_MASK		0x60000000
-#define TSTE_OPC_NULL		0x00000000
-#define TSTE_OPC_CBR		0x20000000
-#define TSTE_OPC_VAR		0x40000000
-#define TSTE_OPC_JMP		0x60000000
-
-#define TSTE_PUSH_IDLE		0x01000000
-#define TSTE_PUSH_ACTIVE	0x02000000
-
-#define TST_SWITCH_DONE		0
-#define TST_SWITCH_PENDING	1
-#define TST_SWITCH_WAIT		2
-
-#define FBQ_SHIFT		9
-#define FBQ_SIZE		(1 << FBQ_SHIFT)
-#define FBQ_MASK		(FBQ_SIZE - 1)
-
-struct sb_pool
-{
-	unsigned int		index;
-	struct sk_buff		*skb[FBQ_SIZE];
-};
-
-#define POOL_HANDLE(queue, index)	(((queue + 1) << 16) | (index))
-#define POOL_QUEUE(handle)		(((handle) >> 16) - 1)
-#define POOL_INDEX(handle)		((handle) & 0xffff)
-
-struct idt77252_dev
-{
-        struct tsq_info		tsq;		/* Transmit Status Queue */
-        struct rsq_info		rsq;		/* Receive Status Queue */
-
-	struct pci_dev		*pcidev;	/* PCI handle (desriptor) */
-	struct atm_dev		*atmdev;	/* ATM device desriptor */
-
-	void __iomem		*membase;	/* SAR's memory base address */
-	unsigned long		srambase;	/* SAR's sram  base address */
-	void __iomem		*fbq[4];	/* FBQ fill addresses */
-
-	struct mutex		mutex;
-	spinlock_t		cmd_lock;	/* for r/w utility/sram */
-
-	unsigned long		softstat;
-	unsigned long		flags;		/* see blow */
-
-	struct work_struct	tqueue;
-
-	unsigned long		tct_base;	/* TCT base address in SRAM */
-        unsigned long		rct_base;	/* RCT base address in SRAM */
-        unsigned long		rt_base;	/* Rate Table base in SRAM */
-        unsigned long		scd_base;	/* SCD base address in SRAM */
-        unsigned long		tst[2];		/* TST base address in SRAM */
-	unsigned long		abrst_base;	/* ABRST base address in SRAM */
-        unsigned long		fifo_base;	/* RX FIFO base in SRAM */
-
-	unsigned long		irqstat[16];
-
-	unsigned int		sramsize;	/* SAR's sram size */
-
-        unsigned int		tct_size;	/* total TCT entries */
-        unsigned int		rct_size;	/* total RCT entries */
-        unsigned int		scd_size;	/* length of SCD */
-        unsigned int		tst_size;	/* total TST entries */
-        unsigned int		tst_free;	/* free TSTEs in TST */
-        unsigned int		abrst_size;	/* size of ABRST in words */
-        unsigned int		fifo_size;	/* size of RX FIFO in words */
-
-        unsigned int		vpibits;	/* Bits used for VPI index */
-        unsigned int		vcibits;	/* Bits used for VCI index */
-        unsigned int		vcimask;	/* Mask for VCI index */
-
-	unsigned int		utopia_pcr;	/* Utopia Itf's Cell Rate */
-	unsigned int		link_pcr;	/* PHY's Peek Cell Rate */
-
-	struct vc_map		**vcs;		/* Open Connections */
-	struct vc_map		**scd2vc;	/* SCD to Connection map */
-
-	struct tst_info		*soft_tst;	/* TST to Connection map */
-	unsigned int		tst_index;	/* Current TST in use */
-	struct timer_list	tst_timer;
-	spinlock_t		tst_lock;
-	unsigned long		tst_state;
-
-	struct sb_pool		sbpool[4];	/* Pool of RX skbuffs */
-	struct sk_buff		*raw_cell_head; /* Pointer to raw cell queue */
-	u32			*raw_cell_hnd;	/* Pointer to RCQ handle */
-	dma_addr_t		raw_cell_paddr;
-
-	int			index;		/* SAR's ID */
-	int			revision;	/* chip revision */
-
-	char			name[16];	/* Device name */
-
-	struct idt77252_dev	*next;
-};
-
-
-/* definition for flag field above */
-#define IDT77252_BIT_INIT		1
-#define IDT77252_BIT_INTERRUPT		2
-
-
-#define ATM_CELL_PAYLOAD         48
-
-#define FREEBUF_ALIGNMENT        16
-
-/*****************************************************************************/
-/*                                                                           */
-/* Makros                                                                    */
-/*                                                                           */
-/*****************************************************************************/
-#define ALIGN_ADDRESS(addr, alignment) \
-        ((((u32)(addr)) + (((u32)(alignment))-1)) & ~(((u32)(alignment)) - 1))
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   ABR SAR Network operation Register                                      */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_REG_DR0	(card->membase + 0x00)
-#define SAR_REG_DR1	(card->membase + 0x04)
-#define SAR_REG_DR2	(card->membase + 0x08)
-#define SAR_REG_DR3	(card->membase + 0x0C)
-#define SAR_REG_CMD	(card->membase + 0x10)
-#define SAR_REG_CFG	(card->membase + 0x14)
-#define SAR_REG_STAT	(card->membase + 0x18)
-#define SAR_REG_RSQB	(card->membase + 0x1C)
-#define SAR_REG_RSQT	(card->membase + 0x20)
-#define SAR_REG_RSQH	(card->membase + 0x24)
-#define SAR_REG_CDC	(card->membase + 0x28)
-#define SAR_REG_VPEC	(card->membase + 0x2C)
-#define SAR_REG_ICC	(card->membase + 0x30)
-#define SAR_REG_RAWCT	(card->membase + 0x34)
-#define SAR_REG_TMR	(card->membase + 0x38)
-#define SAR_REG_TSTB	(card->membase + 0x3C)
-#define SAR_REG_TSQB	(card->membase + 0x40)
-#define SAR_REG_TSQT	(card->membase + 0x44)
-#define SAR_REG_TSQH	(card->membase + 0x48)
-#define SAR_REG_GP	(card->membase + 0x4C)
-#define SAR_REG_VPM	(card->membase + 0x50)
-#define SAR_REG_RXFD	(card->membase + 0x54)
-#define SAR_REG_RXFT	(card->membase + 0x58)
-#define SAR_REG_RXFH	(card->membase + 0x5C)
-#define SAR_REG_RAWHND	(card->membase + 0x60)
-#define SAR_REG_RXSTAT	(card->membase + 0x64)
-#define SAR_REG_ABRSTD	(card->membase + 0x68)
-#define SAR_REG_ABRRQ	(card->membase + 0x6C)
-#define SAR_REG_VBRRQ	(card->membase + 0x70)
-#define SAR_REG_RTBL	(card->membase + 0x74)
-#define SAR_REG_MDFCT	(card->membase + 0x78)
-#define SAR_REG_TXSTAT	(card->membase + 0x7C)
-#define SAR_REG_TCMDQ	(card->membase + 0x80)
-#define SAR_REG_IRCP	(card->membase + 0x84)
-#define SAR_REG_FBQP0	(card->membase + 0x88)
-#define SAR_REG_FBQP1	(card->membase + 0x8C)
-#define SAR_REG_FBQP2	(card->membase + 0x90)
-#define SAR_REG_FBQP3	(card->membase + 0x94)
-#define SAR_REG_FBQS0	(card->membase + 0x98)
-#define SAR_REG_FBQS1	(card->membase + 0x9C)
-#define SAR_REG_FBQS2	(card->membase + 0xA0)
-#define SAR_REG_FBQS3	(card->membase + 0xA4)
-#define SAR_REG_FBQWP0	(card->membase + 0xA8)
-#define SAR_REG_FBQWP1	(card->membase + 0xAC)
-#define SAR_REG_FBQWP2	(card->membase + 0xB0)
-#define SAR_REG_FBQWP3	(card->membase + 0xB4)
-#define SAR_REG_NOW	(card->membase + 0xB8)
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   Commands                                                                */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_CMD_NO_OPERATION         0x00000000
-#define SAR_CMD_OPENCLOSE_CONNECTION 0x20000000
-#define SAR_CMD_WRITE_SRAM           0x40000000
-#define SAR_CMD_READ_SRAM            0x50000000
-#define SAR_CMD_READ_UTILITY         0x80000000
-#define SAR_CMD_WRITE_UTILITY        0x90000000
-
-#define SAR_CMD_OPEN_CONNECTION     (SAR_CMD_OPENCLOSE_CONNECTION | 0x00080000)
-#define SAR_CMD_CLOSE_CONNECTION     SAR_CMD_OPENCLOSE_CONNECTION
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   Configuration Register bits                                             */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_CFG_SWRST          0x80000000  /* Software reset                 */
-#define SAR_CFG_LOOP           0x40000000  /* Internal Loopback              */
-#define SAR_CFG_RXPTH          0x20000000  /* Receive Path Enable            */
-#define SAR_CFG_IDLE_CLP       0x10000000  /* SAR set CLP Bits of Null Cells */
-#define SAR_CFG_TX_FIFO_SIZE_1 0x04000000  /* TX FIFO Size = 1 cell          */
-#define SAR_CFG_TX_FIFO_SIZE_2 0x08000000  /* TX FIFO Size = 2 cells         */
-#define SAR_CFG_TX_FIFO_SIZE_4 0x0C000000  /* TX FIFO Size = 4 cells         */
-#define SAR_CFG_TX_FIFO_SIZE_9 0x00000000  /* TX FIFO Size = 9 cells (full)  */
-#define SAR_CFG_NO_IDLE        0x02000000  /* SAR sends no Null Cells        */
-#define SAR_CFG_RSVD1          0x01000000  /* Reserved                       */
-#define SAR_CFG_RXSTQ_SIZE_2k  0x00000000  /* RX Stat Queue Size = 2048 byte */
-#define SAR_CFG_RXSTQ_SIZE_4k  0x00400000  /* RX Stat Queue Size = 4096 byte */
-#define SAR_CFG_RXSTQ_SIZE_8k  0x00800000  /* RX Stat Queue Size = 8192 byte */
-#define SAR_CFG_RXSTQ_SIZE_R   0x00C00000  /* RX Stat Queue Size = reserved  */
-#define SAR_CFG_ICAPT          0x00200000  /* accept Invalid Cells           */
-#define SAR_CFG_IGGFC          0x00100000  /* Ignore GFC                     */
-#define SAR_CFG_VPVCS_0        0x00000000  /* VPI/VCI Select bit range       */
-#define SAR_CFG_VPVCS_1        0x00040000  /* VPI/VCI Select bit range       */
-#define SAR_CFG_VPVCS_2        0x00080000  /* VPI/VCI Select bit range       */
-#define SAR_CFG_VPVCS_8        0x000C0000  /* VPI/VCI Select bit range       */
-#define SAR_CFG_CNTBL_1k       0x00000000  /* Connection Table Size          */
-#define SAR_CFG_CNTBL_4k       0x00010000  /* Connection Table Size          */
-#define SAR_CFG_CNTBL_16k      0x00020000  /* Connection Table Size          */
-#define SAR_CFG_CNTBL_512      0x00030000  /* Connection Table Size          */
-#define SAR_CFG_VPECA          0x00008000  /* VPI/VCI Error Cell Accept      */
-#define SAR_CFG_RXINT_NOINT    0x00000000  /* No Interrupt on PDU received   */
-#define SAR_CFG_RXINT_NODELAY  0x00001000  /* Interrupt without delay to host*/
-#define SAR_CFG_RXINT_256US    0x00002000  /* Interrupt with delay 256 usec  */
-#define SAR_CFG_RXINT_505US    0x00003000  /* Interrupt with delay 505 usec  */
-#define SAR_CFG_RXINT_742US    0x00004000  /* Interrupt with delay 742 usec  */
-#define SAR_CFG_RAWIE          0x00000800  /* Raw Cell Queue Interrupt Enable*/
-#define SAR_CFG_RQFIE          0x00000400  /* RSQ Almost Full Int Enable     */
-#define SAR_CFG_RSVD2          0x00000200  /* Reserved                       */
-#define SAR_CFG_CACHE          0x00000100  /* DMA on Cache Line Boundary     */
-#define SAR_CFG_TMOIE          0x00000080  /* Timer Roll Over Int Enable     */
-#define SAR_CFG_FBIE           0x00000040  /* Free Buffer Queue Int Enable   */
-#define SAR_CFG_TXEN           0x00000020  /* Transmit Operation Enable      */
-#define SAR_CFG_TXINT          0x00000010  /* Transmit status Int Enable     */
-#define SAR_CFG_TXUIE          0x00000008  /* Transmit underrun Int Enable   */
-#define SAR_CFG_UMODE          0x00000004  /* Utopia Mode Select             */
-#define SAR_CFG_TXSFI          0x00000002  /* Transmit status Full Int Enable*/
-#define SAR_CFG_PHYIE          0x00000001  /* PHY Interrupt Enable           */
-
-#define SAR_CFG_TX_FIFO_SIZE_MASK 0x0C000000  /* TX FIFO Size Mask           */
-#define SAR_CFG_RXSTQSIZE_MASK 0x00C00000
-#define SAR_CFG_CNTBL_MASK     0x00030000
-#define SAR_CFG_RXINT_MASK     0x00007000
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   Status Register bits                                                    */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_STAT_FRAC_3     0xF0000000 /* Fraction of Free Buffer Queue 3 */
-#define SAR_STAT_FRAC_2     0x0F000000 /* Fraction of Free Buffer Queue 2 */
-#define SAR_STAT_FRAC_1     0x00F00000 /* Fraction of Free Buffer Queue 1 */
-#define SAR_STAT_FRAC_0     0x000F0000 /* Fraction of Free Buffer Queue 0 */
-#define SAR_STAT_TSIF       0x00008000 /* Transmit Status Indicator       */
-#define SAR_STAT_TXICP      0x00004000 /* Transmit Status Indicator       */
-#define SAR_STAT_RSVD1      0x00002000 /* Reserved                        */
-#define SAR_STAT_TSQF       0x00001000 /* Transmit Status Queue full      */
-#define SAR_STAT_TMROF      0x00000800 /* Timer overflow                  */
-#define SAR_STAT_PHYI       0x00000400 /* PHY device Interrupt flag       */
-#define SAR_STAT_CMDBZ      0x00000200 /* ABR SAR Command Busy Flag       */
-#define SAR_STAT_FBQ3A      0x00000100 /* Free Buffer Queue 3 Attention   */
-#define SAR_STAT_FBQ2A      0x00000080 /* Free Buffer Queue 2 Attention   */
-#define SAR_STAT_RSQF       0x00000040 /* Receive Status Queue full       */
-#define SAR_STAT_EPDU       0x00000020 /* End Of PDU Flag                 */
-#define SAR_STAT_RAWCF      0x00000010 /* Raw Cell Flag                   */ 
-#define SAR_STAT_FBQ1A      0x00000008 /* Free Buffer Queue 1 Attention   */
-#define SAR_STAT_FBQ0A      0x00000004 /* Free Buffer Queue 0 Attention   */
-#define SAR_STAT_RSQAF      0x00000002 /* Receive Status Queue almost full*/  
-#define SAR_STAT_RSVD2      0x00000001 /* Reserved                        */
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   General Purpose Register bits                                           */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_GP_TXNCC_MASK   0xff000000  /* Transmit Negative Credit Count   */
-#define SAR_GP_EEDI         0x00010000  /* EEPROM Data In                   */
-#define SAR_GP_BIGE         0x00008000  /* Big Endian Operation             */
-#define SAR_GP_RM_NORMAL    0x00000000  /* Normal handling of RM cells      */
-#define SAR_GP_RM_TO_RCQ    0x00002000  /* put RM cells into Raw Cell Queue */
-#define SAR_GP_RM_RSVD      0x00004000  /* Reserved                         */
-#define SAR_GP_RM_INHIBIT   0x00006000  /* Inhibit update of Connection tab */
-#define SAR_GP_PHY_RESET    0x00000008  /* PHY Reset                        */
-#define SAR_GP_EESCLK	    0x00000004	/* EEPROM SCLK			    */
-#define SAR_GP_EECS	    0x00000002	/* EEPROM Chip Select		    */
-#define SAR_GP_EEDO	    0x00000001	/* EEPROM Data Out		    */
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   SAR local SRAM layout for 128k work SRAM                                */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_SRAM_SCD_SIZE        12
-#define SAR_SRAM_TCT_SIZE         8
-#define SAR_SRAM_RCT_SIZE         4
-
-#define SAR_SRAM_TCT_128_BASE    0x00000
-#define SAR_SRAM_TCT_128_TOP     0x01fff
-#define SAR_SRAM_RCT_128_BASE    0x02000
-#define SAR_SRAM_RCT_128_TOP     0x02fff
-#define SAR_SRAM_FB0_128_BASE    0x03000
-#define SAR_SRAM_FB0_128_TOP     0x033ff
-#define SAR_SRAM_FB1_128_BASE    0x03400
-#define SAR_SRAM_FB1_128_TOP     0x037ff
-#define SAR_SRAM_FB2_128_BASE    0x03800
-#define SAR_SRAM_FB2_128_TOP     0x03bff
-#define SAR_SRAM_FB3_128_BASE    0x03c00
-#define SAR_SRAM_FB3_128_TOP     0x03fff
-#define SAR_SRAM_SCD_128_BASE    0x04000
-#define SAR_SRAM_SCD_128_TOP     0x07fff
-#define SAR_SRAM_TST1_128_BASE   0x08000
-#define SAR_SRAM_TST1_128_TOP    0x0bfff
-#define SAR_SRAM_TST2_128_BASE   0x0c000
-#define SAR_SRAM_TST2_128_TOP    0x0ffff
-#define SAR_SRAM_ABRSTD_128_BASE 0x10000
-#define SAR_SRAM_ABRSTD_128_TOP  0x13fff
-#define SAR_SRAM_RT_128_BASE     0x14000
-#define SAR_SRAM_RT_128_TOP      0x15fff
-
-#define SAR_SRAM_FIFO_128_BASE   0x18000
-#define SAR_SRAM_FIFO_128_TOP    0x1ffff
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   SAR local SRAM layout for 32k work SRAM                                 */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_SRAM_TCT_32_BASE     0x00000
-#define SAR_SRAM_TCT_32_TOP      0x00fff
-#define SAR_SRAM_RCT_32_BASE     0x01000
-#define SAR_SRAM_RCT_32_TOP      0x017ff
-#define SAR_SRAM_FB0_32_BASE     0x01800
-#define SAR_SRAM_FB0_32_TOP      0x01bff
-#define SAR_SRAM_FB1_32_BASE     0x01c00
-#define SAR_SRAM_FB1_32_TOP      0x01fff
-#define SAR_SRAM_FB2_32_BASE     0x02000
-#define SAR_SRAM_FB2_32_TOP      0x023ff
-#define SAR_SRAM_FB3_32_BASE     0x02400
-#define SAR_SRAM_FB3_32_TOP      0x027ff
-#define SAR_SRAM_SCD_32_BASE     0x02800
-#define SAR_SRAM_SCD_32_TOP      0x03fff
-#define SAR_SRAM_TST1_32_BASE    0x04000
-#define SAR_SRAM_TST1_32_TOP     0x04fff
-#define SAR_SRAM_TST2_32_BASE    0x05000
-#define SAR_SRAM_TST2_32_TOP     0x05fff
-#define SAR_SRAM_ABRSTD_32_BASE  0x06000
-#define SAR_SRAM_ABRSTD_32_TOP   0x067ff
-#define SAR_SRAM_RT_32_BASE      0x06800
-#define SAR_SRAM_RT_32_TOP       0x06fff
-#define SAR_SRAM_FIFO_32_BASE    0x07000
-#define SAR_SRAM_FIFO_32_TOP     0x07fff
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   TSR - Transmit Status Request                                           */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_TSR_TYPE_TSR  0x80000000
-#define SAR_TSR_TYPE_TBD  0x00000000
-#define SAR_TSR_TSIF      0x20000000
-#define SAR_TSR_TAG_MASK  0x01F00000
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   TBD - Transmit Buffer Descriptor                                        */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_TBD_EPDU      0x40000000
-#define SAR_TBD_TSIF      0x20000000
-#define SAR_TBD_OAM       0x10000000
-#define SAR_TBD_AAL0      0x00000000
-#define SAR_TBD_AAL34     0x04000000
-#define SAR_TBD_AAL5      0x08000000
-#define SAR_TBD_GTSI      0x02000000
-#define SAR_TBD_TAG_MASK  0x01F00000
-
-#define SAR_TBD_VPI_MASK  0x0FF00000
-#define SAR_TBD_VCI_MASK  0x000FFFF0
-#define SAR_TBD_VC_MASK   (SAR_TBD_VPI_MASK | SAR_TBD_VCI_MASK)
-
-#define SAR_TBD_VPI_SHIFT 20
-#define SAR_TBD_VCI_SHIFT 4
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   RXFD - Receive FIFO Descriptor                                          */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_RXFD_SIZE_MASK     0x0F000000
-#define SAR_RXFD_SIZE_512      0x00000000  /* 512 words                      */
-#define SAR_RXFD_SIZE_1K       0x01000000  /* 1k words                       */
-#define SAR_RXFD_SIZE_2K       0x02000000  /* 2k words                       */
-#define SAR_RXFD_SIZE_4K       0x03000000  /* 4k words                       */
-#define SAR_RXFD_SIZE_8K       0x04000000  /* 8k words                       */
-#define SAR_RXFD_SIZE_16K      0x05000000  /* 16k words                      */
-#define SAR_RXFD_SIZE_32K      0x06000000  /* 32k words                      */
-#define SAR_RXFD_SIZE_64K      0x07000000  /* 64k words                      */
-#define SAR_RXFD_SIZE_128K     0x08000000  /* 128k words                     */
-#define SAR_RXFD_SIZE_256K     0x09000000  /* 256k words                     */
-#define SAR_RXFD_ADDR_MASK     0x001ffc00
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   ABRSTD - ABR + VBR Schedule Tables                                      */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_ABRSTD_SIZE_MASK   0x07000000
-#define SAR_ABRSTD_SIZE_512    0x00000000  /* 512 words                      */
-#define SAR_ABRSTD_SIZE_1K     0x01000000  /* 1k words                       */
-#define SAR_ABRSTD_SIZE_2K     0x02000000  /* 2k words                       */
-#define SAR_ABRSTD_SIZE_4K     0x03000000  /* 4k words                       */
-#define SAR_ABRSTD_SIZE_8K     0x04000000  /* 8k words                       */
-#define SAR_ABRSTD_SIZE_16K    0x05000000  /* 16k words                      */
-#define SAR_ABRSTD_ADDR_MASK   0x001ffc00
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   RCTE - Receive Connection Table Entry                                   */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_RCTE_IL_MASK       0xE0000000  /* inactivity limit               */
-#define SAR_RCTE_IC_MASK       0x1C000000  /* inactivity count               */
-#define SAR_RCTE_RSVD          0x02000000  /* reserved                       */
-#define SAR_RCTE_LCD           0x01000000  /* last cell data                 */
-#define SAR_RCTE_CI_VC         0x00800000  /* EFCI in previous cell of VC    */
-#define SAR_RCTE_FBP_01        0x00000000  /* 1. cell->FBQ0, others->FBQ1    */
-#define SAR_RCTE_FBP_1         0x00200000  /* use FBQ 1 for all cells        */
-#define SAR_RCTE_FBP_2         0x00400000  /* use FBQ 2 for all cells        */
-#define SAR_RCTE_FBP_3         0x00600000  /* use FBQ 3 for all cells        */
-#define SAR_RCTE_NZ_GFC        0x00100000  /* non zero GFC in all cell of VC */
-#define SAR_RCTE_CONNECTOPEN   0x00080000  /* VC is open                     */
-#define SAR_RCTE_AAL_MASK      0x00070000  /* mask for AAL type field s.b.   */
-#define SAR_RCTE_RAWCELLINTEN  0x00008000  /* raw cell interrupt enable      */
-#define SAR_RCTE_RXCONCELLADDR 0x00004000  /* RX constant cell address       */
-#define SAR_RCTE_BUFFSTAT_MASK 0x00003000  /* buffer status                  */
-#define SAR_RCTE_EFCI          0x00000800  /* EFCI Congestion flag           */
-#define SAR_RCTE_CLP           0x00000400  /* Cell Loss Priority flag        */
-#define SAR_RCTE_CRC           0x00000200  /* Received CRC Error             */
-#define SAR_RCTE_CELLCNT_MASK  0x000001FF  /* cell Count                     */
-
-#define SAR_RCTE_AAL0          0x00000000  /* AAL types for ALL field        */
-#define SAR_RCTE_AAL34         0x00010000
-#define SAR_RCTE_AAL5          0x00020000
-#define SAR_RCTE_RCQ           0x00030000
-#define SAR_RCTE_OAM           0x00040000
-
-#define TCMDQ_START		0x01000000
-#define TCMDQ_LACR		0x02000000
-#define TCMDQ_START_LACR	0x03000000
-#define TCMDQ_INIT_ER		0x04000000
-#define TCMDQ_HALT		0x05000000
-
-
-struct idt77252_skb_prv {
-	struct scqe	tbd;	/* Transmit Buffer Descriptor */
-	dma_addr_t	paddr;	/* DMA handle */
-	u32		pool;	/* sb_pool handle */
-} __packed;
-
-#define IDT77252_PRV_TBD(skb)	\
-	(((struct idt77252_skb_prv *)(ATM_SKB(skb)+1))->tbd)
-#define IDT77252_PRV_PADDR(skb)	\
-	(((struct idt77252_skb_prv *)(ATM_SKB(skb)+1))->paddr)
-#define IDT77252_PRV_POOL(skb)	\
-	(((struct idt77252_skb_prv *)(ATM_SKB(skb)+1))->pool)
-
-/*****************************************************************************/
-/*                                                                           */
-/*   PCI related items                                                       */
-/*                                                                           */
-/*****************************************************************************/
-
-#ifndef PCI_VENDOR_ID_IDT
-#define PCI_VENDOR_ID_IDT 0x111D
-#endif /* PCI_VENDOR_ID_IDT */
-
-#ifndef PCI_DEVICE_ID_IDT_IDT77252
-#define PCI_DEVICE_ID_IDT_IDT77252 0x0003
-#endif /* PCI_DEVICE_ID_IDT_IDT772052 */
-
-
-#endif /* !(_IDT77252_H) */
diff --git a/drivers/atm/idt77252_tables.h b/drivers/atm/idt77252_tables.h
deleted file mode 100644
index 12b81e046a7b..000000000000
--- a/drivers/atm/idt77252_tables.h
+++ /dev/null
@@ -1,781 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Do not edit, automatically generated by `./genrtbl'.
- *
- * Cell Line Rate: 353207.55 (155520000 bps)
- */
-
-static unsigned int log_to_rate[] =
-{
-/* 000 */ 0x8d022e27, /* cps =     10.02, nrm =  3, interval = 35264.00 */
-/* 001 */ 0x8d362e11, /* cps =     10.42, nrm =  3, interval = 33856.00 */
-/* 002 */ 0x8d6e2bf8, /* cps =     10.86, nrm =  3, interval = 32512.00 */
-/* 003 */ 0x8da82bcf, /* cps =     11.31, nrm =  3, interval = 31200.00 */
-/* 004 */ 0x8de42ba8, /* cps =     11.78, nrm =  3, interval = 29952.00 */
-/* 005 */ 0x8e242b82, /* cps =     12.28, nrm =  3, interval = 28736.00 */
-/* 006 */ 0x8e662b5e, /* cps =     12.80, nrm =  3, interval = 27584.00 */
-/* 007 */ 0x8eaa2b3c, /* cps =     13.33, nrm =  3, interval = 26496.00 */
-/* 008 */ 0x8ef22b1a, /* cps =     13.89, nrm =  3, interval = 25408.00 */
-/* 009 */ 0x8f3e2afa, /* cps =     14.48, nrm =  3, interval = 24384.00 */
-/* 010 */ 0x8f8a2adc, /* cps =     15.08, nrm =  3, interval = 23424.00 */
-/* 011 */ 0x8fdc2abe, /* cps =     15.72, nrm =  3, interval = 22464.00 */
-/* 012 */ 0x90182aa2, /* cps =     16.38, nrm =  3, interval = 21568.00 */
-/* 013 */ 0x90422a87, /* cps =     17.03, nrm =  3, interval = 20704.00 */
-/* 014 */ 0x90702a6d, /* cps =     17.75, nrm =  3, interval = 19872.00 */
-/* 015 */ 0x90a02a54, /* cps =     18.50, nrm =  3, interval = 19072.00 */
-/* 016 */ 0x90d22a3c, /* cps =     19.28, nrm =  3, interval = 18304.00 */
-/* 017 */ 0x91062a25, /* cps =     20.09, nrm =  3, interval = 17568.00 */
-/* 018 */ 0x913c2a0f, /* cps =     20.94, nrm =  3, interval = 16864.00 */
-/* 019 */ 0x917427f3, /* cps =     21.81, nrm =  3, interval = 16176.00 */
-/* 020 */ 0x91b027ca, /* cps =     22.75, nrm =  3, interval = 15520.00 */
-/* 021 */ 0x91ec27a3, /* cps =     23.69, nrm =  3, interval = 14896.00 */
-/* 022 */ 0x922c277e, /* cps =     24.69, nrm =  3, interval = 14304.00 */
-/* 023 */ 0x926e275a, /* cps =     25.72, nrm =  3, interval = 13728.00 */
-/* 024 */ 0x92b42737, /* cps =     26.81, nrm =  3, interval = 13168.00 */
-/* 025 */ 0x92fc2716, /* cps =     27.94, nrm =  3, interval = 12640.00 */
-/* 026 */ 0x934626f6, /* cps =     29.09, nrm =  3, interval = 12128.00 */
-/* 027 */ 0x939426d8, /* cps =     30.31, nrm =  3, interval = 11648.00 */
-/* 028 */ 0x93e426bb, /* cps =     31.56, nrm =  3, interval = 11184.00 */
-/* 029 */ 0x941e269e, /* cps =     32.94, nrm =  3, interval = 10720.00 */
-/* 030 */ 0x944a2683, /* cps =     34.31, nrm =  3, interval = 10288.00 */
-/* 031 */ 0x9476266a, /* cps =     35.69, nrm =  3, interval =  9888.00 */
-/* 032 */ 0x94a62651, /* cps =     37.19, nrm =  3, interval =  9488.00 */
-/* 033 */ 0x94d82639, /* cps =     38.75, nrm =  3, interval =  9104.00 */
-/* 034 */ 0x950c6622, /* cps =     40.38, nrm =  4, interval =  8736.00 */
-/* 035 */ 0x9544660c, /* cps =     42.12, nrm =  4, interval =  8384.00 */
-/* 036 */ 0x957c63ee, /* cps =     43.88, nrm =  4, interval =  8048.00 */
-/* 037 */ 0x95b663c6, /* cps =     45.69, nrm =  4, interval =  7728.00 */
-/* 038 */ 0x95f4639f, /* cps =     47.62, nrm =  4, interval =  7416.00 */
-/* 039 */ 0x96346379, /* cps =     49.62, nrm =  4, interval =  7112.00 */
-/* 040 */ 0x96766356, /* cps =     51.69, nrm =  4, interval =  6832.00 */
-/* 041 */ 0x96bc6333, /* cps =     53.88, nrm =  4, interval =  6552.00 */
-/* 042 */ 0x97046312, /* cps =     56.12, nrm =  4, interval =  6288.00 */
-/* 043 */ 0x974e62f3, /* cps =     58.44, nrm =  4, interval =  6040.00 */
-/* 044 */ 0x979e62d4, /* cps =     60.94, nrm =  4, interval =  5792.00 */
-/* 045 */ 0x97f062b7, /* cps =     63.50, nrm =  4, interval =  5560.00 */
-/* 046 */ 0x9822629b, /* cps =     66.12, nrm =  4, interval =  5336.00 */
-/* 047 */ 0x984e6280, /* cps =     68.88, nrm =  4, interval =  5120.00 */
-/* 048 */ 0x987e6266, /* cps =     71.88, nrm =  4, interval =  4912.00 */
-/* 049 */ 0x98ac624e, /* cps =     74.75, nrm =  4, interval =  4720.00 */
-/* 050 */ 0x98e06236, /* cps =     78.00, nrm =  4, interval =  4528.00 */
-/* 051 */ 0x9914a21f, /* cps =     81.25, nrm =  8, interval =  4344.00 */
-/* 052 */ 0x994aa209, /* cps =     84.62, nrm =  8, interval =  4168.00 */
-/* 053 */ 0x99829fe9, /* cps =     88.12, nrm =  8, interval =  4004.00 */
-/* 054 */ 0x99be9fc1, /* cps =     91.88, nrm =  8, interval =  3844.00 */
-/* 055 */ 0x99fc9f9a, /* cps =     95.75, nrm =  8, interval =  3688.00 */
-/* 056 */ 0x9a3c9f75, /* cps =     99.75, nrm =  8, interval =  3540.00 */
-/* 057 */ 0x9a809f51, /* cps =    104.00, nrm =  8, interval =  3396.00 */
-/* 058 */ 0x9ac49f2f, /* cps =    108.25, nrm =  8, interval =  3260.00 */
-/* 059 */ 0x9b0e9f0e, /* cps =    112.88, nrm =  8, interval =  3128.00 */
-/* 060 */ 0x9b589eef, /* cps =    117.50, nrm =  8, interval =  3004.00 */
-/* 061 */ 0x9ba69ed1, /* cps =    122.38, nrm =  8, interval =  2884.00 */
-/* 062 */ 0x9bf89eb4, /* cps =    127.50, nrm =  8, interval =  2768.00 */
-/* 063 */ 0x9c269e98, /* cps =    132.75, nrm =  8, interval =  2656.00 */
-/* 064 */ 0x9c549e7d, /* cps =    138.50, nrm =  8, interval =  2548.00 */
-/* 065 */ 0x9c849e63, /* cps =    144.50, nrm =  8, interval =  2444.00 */
-/* 066 */ 0x9cb29e4b, /* cps =    150.25, nrm =  8, interval =  2348.00 */
-/* 067 */ 0x9ce69e33, /* cps =    156.75, nrm =  8, interval =  2252.00 */
-/* 068 */ 0x9d1cde1c, /* cps =    163.50, nrm = 16, interval =  2160.00 */
-/* 069 */ 0x9d50de07, /* cps =    170.00, nrm = 16, interval =  2076.00 */
-/* 070 */ 0x9d8adbe4, /* cps =    177.25, nrm = 16, interval =  1992.00 */
-/* 071 */ 0x9dc4dbbc, /* cps =    184.50, nrm = 16, interval =  1912.00 */
-/* 072 */ 0x9e02db96, /* cps =    192.25, nrm = 16, interval =  1836.00 */
-/* 073 */ 0x9e42db71, /* cps =    200.25, nrm = 16, interval =  1762.00 */
-/* 074 */ 0x9e86db4d, /* cps =    208.75, nrm = 16, interval =  1690.00 */
-/* 075 */ 0x9ecedb2b, /* cps =    217.75, nrm = 16, interval =  1622.00 */
-/* 076 */ 0x9f16db0a, /* cps =    226.75, nrm = 16, interval =  1556.00 */
-/* 077 */ 0x9f62daeb, /* cps =    236.25, nrm = 16, interval =  1494.00 */
-/* 078 */ 0x9fb2dacd, /* cps =    246.25, nrm = 16, interval =  1434.00 */
-/* 079 */ 0xa002dab0, /* cps =    256.50, nrm = 16, interval =  1376.00 */
-/* 080 */ 0xa02eda94, /* cps =    267.50, nrm = 16, interval =  1320.00 */
-/* 081 */ 0xa05ada7a, /* cps =    278.50, nrm = 16, interval =  1268.00 */
-/* 082 */ 0xa088da60, /* cps =    290.00, nrm = 16, interval =  1216.00 */
-/* 083 */ 0xa0b8da48, /* cps =    302.00, nrm = 16, interval =  1168.00 */
-/* 084 */ 0xa0ecda30, /* cps =    315.00, nrm = 16, interval =  1120.00 */
-/* 085 */ 0xa1211a1a, /* cps =    328.00, nrm = 32, interval =  1076.00 */
-/* 086 */ 0xa1591a04, /* cps =    342.00, nrm = 32, interval =  1032.00 */
-/* 087 */ 0xa19117df, /* cps =    356.00, nrm = 32, interval =   991.00 */
-/* 088 */ 0xa1cd17b7, /* cps =    371.00, nrm = 32, interval =   951.00 */
-/* 089 */ 0xa20b1791, /* cps =    386.50, nrm = 32, interval =   913.00 */
-/* 090 */ 0xa24d176c, /* cps =    403.00, nrm = 32, interval =   876.00 */
-/* 091 */ 0xa28f1749, /* cps =    419.50, nrm = 32, interval =   841.00 */
-/* 092 */ 0xa2d71727, /* cps =    437.50, nrm = 32, interval =   807.00 */
-/* 093 */ 0xa31f1707, /* cps =    455.50, nrm = 32, interval =   775.00 */
-/* 094 */ 0xa36d16e7, /* cps =    475.00, nrm = 32, interval =   743.00 */
-/* 095 */ 0xa3bd16c9, /* cps =    495.00, nrm = 32, interval =   713.00 */
-/* 096 */ 0xa40716ad, /* cps =    515.00, nrm = 32, interval =   685.00 */
-/* 097 */ 0xa4331691, /* cps =    537.00, nrm = 32, interval =   657.00 */
-/* 098 */ 0xa45f1677, /* cps =    559.00, nrm = 32, interval =   631.00 */
-/* 099 */ 0xa48f165d, /* cps =    583.00, nrm = 32, interval =   605.00 */
-/* 100 */ 0xa4bf1645, /* cps =    607.00, nrm = 32, interval =   581.00 */
-/* 101 */ 0xa4f1162e, /* cps =    632.00, nrm = 32, interval =   558.00 */
-/* 102 */ 0xa5291617, /* cps =    660.00, nrm = 32, interval =   535.00 */
-/* 103 */ 0xa55f1602, /* cps =    687.00, nrm = 32, interval =   514.00 */
-/* 104 */ 0xa59913da, /* cps =    716.00, nrm = 32, interval =   493.00 */
-/* 105 */ 0xa5d513b2, /* cps =    746.00, nrm = 32, interval =   473.00 */
-/* 106 */ 0xa613138c, /* cps =    777.00, nrm = 32, interval =   454.00 */
-/* 107 */ 0xa6551368, /* cps =    810.00, nrm = 32, interval =   436.00 */
-/* 108 */ 0xa6971345, /* cps =    843.00, nrm = 32, interval =   418.50 */
-/* 109 */ 0xa6df1323, /* cps =    879.00, nrm = 32, interval =   401.50 */
-/* 110 */ 0xa7291303, /* cps =    916.00, nrm = 32, interval =   385.50 */
-/* 111 */ 0xa77512e4, /* cps =    954.00, nrm = 32, interval =   370.00 */
-/* 112 */ 0xa7c512c6, /* cps =    994.00, nrm = 32, interval =   355.00 */
-/* 113 */ 0xa80d12a9, /* cps =   1036.00, nrm = 32, interval =   340.50 */
-/* 114 */ 0xa839128e, /* cps =   1080.00, nrm = 32, interval =   327.00 */
-/* 115 */ 0xa8651274, /* cps =   1124.00, nrm = 32, interval =   314.00 */
-/* 116 */ 0xa895125a, /* cps =   1172.00, nrm = 32, interval =   301.00 */
-/* 117 */ 0xa8c71242, /* cps =   1222.00, nrm = 32, interval =   289.00 */
-/* 118 */ 0xa8f9122b, /* cps =   1272.00, nrm = 32, interval =   277.50 */
-/* 119 */ 0xa92f1214, /* cps =   1326.00, nrm = 32, interval =   266.00 */
-/* 120 */ 0xa9670ffe, /* cps =   1382.00, nrm = 32, interval =   255.50 */
-/* 121 */ 0xa9a10fd5, /* cps =   1440.00, nrm = 32, interval =   245.25 */
-/* 122 */ 0xa9db0fae, /* cps =   1498.00, nrm = 32, interval =   235.50 */
-/* 123 */ 0xaa1b0f88, /* cps =   1562.00, nrm = 32, interval =   226.00 */
-/* 124 */ 0xaa5d0f63, /* cps =   1628.00, nrm = 32, interval =   216.75 */
-/* 125 */ 0xaaa10f41, /* cps =   1696.00, nrm = 32, interval =   208.25 */
-/* 126 */ 0xaae90f1f, /* cps =   1768.00, nrm = 32, interval =   199.75 */
-/* 127 */ 0xab330eff, /* cps =   1842.00, nrm = 32, interval =   191.75 */
-/* 128 */ 0xab7f0ee0, /* cps =   1918.00, nrm = 32, interval =   184.00 */
-/* 129 */ 0xabd10ec2, /* cps =   2000.00, nrm = 32, interval =   176.50 */
-/* 130 */ 0xac110ea6, /* cps =   2080.00, nrm = 32, interval =   169.50 */
-/* 131 */ 0xac3d0e8b, /* cps =   2168.00, nrm = 32, interval =   162.75 */
-/* 132 */ 0xac6d0e70, /* cps =   2264.00, nrm = 32, interval =   156.00 */
-/* 133 */ 0xac9b0e57, /* cps =   2356.00, nrm = 32, interval =   149.75 */
-/* 134 */ 0xaccd0e3f, /* cps =   2456.00, nrm = 32, interval =   143.75 */
-/* 135 */ 0xacff0e28, /* cps =   2556.00, nrm = 32, interval =   138.00 */
-/* 136 */ 0xad350e12, /* cps =   2664.00, nrm = 32, interval =   132.50 */
-/* 137 */ 0xad6d0bf9, /* cps =   2776.00, nrm = 32, interval =   127.12 */
-/* 138 */ 0xada70bd0, /* cps =   2892.00, nrm = 32, interval =   122.00 */
-/* 139 */ 0xade30ba9, /* cps =   3012.00, nrm = 32, interval =   117.12 */
-/* 140 */ 0xae230b83, /* cps =   3140.00, nrm = 32, interval =   112.38 */
-/* 141 */ 0xae650b5f, /* cps =   3272.00, nrm = 32, interval =   107.88 */
-/* 142 */ 0xaeab0b3c, /* cps =   3412.00, nrm = 32, interval =   103.50 */
-/* 143 */ 0xaef10b1b, /* cps =   3552.00, nrm = 32, interval =    99.38 */
-/* 144 */ 0xaf3b0afb, /* cps =   3700.00, nrm = 32, interval =    95.38 */
-/* 145 */ 0xaf8b0adc, /* cps =   3860.00, nrm = 32, interval =    91.50 */
-/* 146 */ 0xafd90abf, /* cps =   4016.00, nrm = 32, interval =    87.88 */
-/* 147 */ 0xb0170aa3, /* cps =   4184.00, nrm = 32, interval =    84.38 */
-/* 148 */ 0xb0430a87, /* cps =   4360.00, nrm = 32, interval =    80.88 */
-/* 149 */ 0xb0710a6d, /* cps =   4544.00, nrm = 32, interval =    77.62 */
-/* 150 */ 0xb0a10a54, /* cps =   4736.00, nrm = 32, interval =    74.50 */
-/* 151 */ 0xb0d30a3c, /* cps =   4936.00, nrm = 32, interval =    71.50 */
-/* 152 */ 0xb1070a25, /* cps =   5144.00, nrm = 32, interval =    68.62 */
-/* 153 */ 0xb13d0a0f, /* cps =   5360.00, nrm = 32, interval =    65.88 */
-/* 154 */ 0xb17507f4, /* cps =   5584.00, nrm = 32, interval =    63.25 */
-/* 155 */ 0xb1af07cb, /* cps =   5816.00, nrm = 32, interval =    60.69 */
-/* 156 */ 0xb1eb07a4, /* cps =   6056.00, nrm = 32, interval =    58.25 */
-/* 157 */ 0xb22b077f, /* cps =   6312.00, nrm = 32, interval =    55.94 */
-/* 158 */ 0xb26d075b, /* cps =   6576.00, nrm = 32, interval =    53.69 */
-/* 159 */ 0xb2b30738, /* cps =   6856.00, nrm = 32, interval =    51.50 */
-/* 160 */ 0xb2fb0717, /* cps =   7144.00, nrm = 32, interval =    49.44 */
-/* 161 */ 0xb34506f7, /* cps =   7440.00, nrm = 32, interval =    47.44 */
-/* 162 */ 0xb39306d9, /* cps =   7752.00, nrm = 32, interval =    45.56 */
-/* 163 */ 0xb3e506bb, /* cps =   8080.00, nrm = 32, interval =    43.69 */
-/* 164 */ 0xb41d069f, /* cps =   8416.00, nrm = 32, interval =    41.94 */
-/* 165 */ 0xb4490684, /* cps =   8768.00, nrm = 32, interval =    40.25 */
-/* 166 */ 0xb477066a, /* cps =   9136.00, nrm = 32, interval =    38.62 */
-/* 167 */ 0xb4a70651, /* cps =   9520.00, nrm = 32, interval =    37.06 */
-/* 168 */ 0xb4d90639, /* cps =   9920.00, nrm = 32, interval =    35.56 */
-/* 169 */ 0xb50d0622, /* cps =  10336.00, nrm = 32, interval =    34.12 */
-/* 170 */ 0xb545060c, /* cps =  10784.00, nrm = 32, interval =    32.75 */
-/* 171 */ 0xb57b03ef, /* cps =  11216.00, nrm = 32, interval =    31.47 */
-/* 172 */ 0xb5b503c7, /* cps =  11680.00, nrm = 32, interval =    30.22 */
-/* 173 */ 0xb5f303a0, /* cps =  12176.00, nrm = 32, interval =    29.00 */
-/* 174 */ 0xb633037a, /* cps =  12688.00, nrm = 32, interval =    27.81 */
-/* 175 */ 0xb6750357, /* cps =  13216.00, nrm = 32, interval =    26.72 */
-/* 176 */ 0xb6bb0334, /* cps =  13776.00, nrm = 32, interval =    25.62 */
-/* 177 */ 0xb7030313, /* cps =  14352.00, nrm = 32, interval =    24.59 */
-/* 178 */ 0xb74f02f3, /* cps =  14960.00, nrm = 32, interval =    23.59 */
-/* 179 */ 0xb79d02d5, /* cps =  15584.00, nrm = 32, interval =    22.66 */
-/* 180 */ 0xb7ed02b8, /* cps =  16224.00, nrm = 32, interval =    21.75 */
-/* 181 */ 0xb821029c, /* cps =  16896.00, nrm = 32, interval =    20.88 */
-/* 182 */ 0xb84f0281, /* cps =  17632.00, nrm = 32, interval =    20.03 */
-/* 183 */ 0xb87d0267, /* cps =  18368.00, nrm = 32, interval =    19.22 */
-/* 184 */ 0xb8ad024e, /* cps =  19136.00, nrm = 32, interval =    18.44 */
-/* 185 */ 0xb8dd0237, /* cps =  19904.00, nrm = 32, interval =    17.72 */
-/* 186 */ 0xb9130220, /* cps =  20768.00, nrm = 32, interval =    17.00 */
-/* 187 */ 0xb949020a, /* cps =  21632.00, nrm = 32, interval =    16.31 */
-/* 188 */ 0xb98301f5, /* cps =  22560.00, nrm = 32, interval =    15.66 */
-/* 189 */ 0xb9bd01e1, /* cps =  23488.00, nrm = 32, interval =    15.03 */
-/* 190 */ 0xb9fd01cd, /* cps =  24512.00, nrm = 32, interval =    14.41 */
-/* 191 */ 0xba3b01bb, /* cps =  25504.00, nrm = 32, interval =    13.84 */
-/* 192 */ 0xba7f01a9, /* cps =  26592.00, nrm = 32, interval =    13.28 */
-/* 193 */ 0xbac30198, /* cps =  27680.00, nrm = 32, interval =    12.75 */
-/* 194 */ 0xbb0f0187, /* cps =  28896.00, nrm = 32, interval =    12.22 */
-/* 195 */ 0xbb570178, /* cps =  30048.00, nrm = 32, interval =    11.75 */
-/* 196 */ 0xbbab0168, /* cps =  31392.00, nrm = 32, interval =    11.25 */
-/* 197 */ 0xbbf9015a, /* cps =  32640.00, nrm = 32, interval =    10.81 */
-/* 198 */ 0xbc27014c, /* cps =  33984.00, nrm = 32, interval =    10.38 */
-/* 199 */ 0xbc53013f, /* cps =  35392.00, nrm = 32, interval =     9.97 */
-/* 200 */ 0xbc830132, /* cps =  36928.00, nrm = 32, interval =     9.56 */
-/* 201 */ 0xbcb50125, /* cps =  38528.00, nrm = 32, interval =     9.16 */
-/* 202 */ 0xbce5011a, /* cps =  40064.00, nrm = 32, interval =     8.81 */
-/* 203 */ 0xbd1d010e, /* cps =  41856.00, nrm = 32, interval =     8.44 */
-/* 204 */ 0xbd530103, /* cps =  43584.00, nrm = 32, interval =     8.09 */
-/* 205 */ 0xbd8b00f9, /* cps =  45376.00, nrm = 32, interval =     7.78 */
-/* 206 */ 0xbdc500ef, /* cps =  47232.00, nrm = 32, interval =     7.47 */
-/* 207 */ 0xbe0700e5, /* cps =  49344.00, nrm = 32, interval =     7.16 */
-/* 208 */ 0xbe4500dc, /* cps =  51328.00, nrm = 32, interval =     6.88 */
-/* 209 */ 0xbe8900d3, /* cps =  53504.00, nrm = 32, interval =     6.59 */
-/* 210 */ 0xbecb00cb, /* cps =  55616.00, nrm = 32, interval =     6.34 */
-/* 211 */ 0xbf1d00c2, /* cps =  58240.00, nrm = 32, interval =     6.06 */
-/* 212 */ 0xbf6100bb, /* cps =  60416.00, nrm = 32, interval =     5.84 */
-/* 213 */ 0xbfb500b3, /* cps =  63104.00, nrm = 32, interval =     5.59 */
-/* 214 */ 0xc00300ac, /* cps =  65664.00, nrm = 32, interval =     5.38 */
-/* 215 */ 0xc02f00a5, /* cps =  68480.00, nrm = 32, interval =     5.16 */
-/* 216 */ 0xc05d009e, /* cps =  71424.00, nrm = 32, interval =     4.94 */
-/* 217 */ 0xc0890098, /* cps =  74240.00, nrm = 32, interval =     4.75 */
-/* 218 */ 0xc0b90092, /* cps =  77312.00, nrm = 32, interval =     4.56 */
-/* 219 */ 0xc0ed008c, /* cps =  80640.00, nrm = 32, interval =     4.38 */
-/* 220 */ 0xc1250086, /* cps =  84224.00, nrm = 32, interval =     4.19 */
-/* 221 */ 0xc1590081, /* cps =  87552.00, nrm = 32, interval =     4.03 */
-/* 222 */ 0xc191007c, /* cps =  91136.00, nrm = 32, interval =     3.88 */
-/* 223 */ 0xc1cd0077, /* cps =  94976.00, nrm = 32, interval =     3.72 */
-/* 224 */ 0xc20d0072, /* cps =  99072.00, nrm = 32, interval =     3.56 */
-/* 225 */ 0xc255006d, /* cps = 103680.00, nrm = 32, interval =     3.41 */
-/* 226 */ 0xc2910069, /* cps = 107520.00, nrm = 32, interval =     3.28 */
-/* 227 */ 0xc2d50065, /* cps = 111872.00, nrm = 32, interval =     3.16 */
-/* 228 */ 0xc32f0060, /* cps = 117632.00, nrm = 32, interval =     3.00 */
-/* 229 */ 0xc36b005d, /* cps = 121472.00, nrm = 32, interval =     2.91 */
-/* 230 */ 0xc3c10059, /* cps = 126976.00, nrm = 32, interval =     2.78 */
-/* 231 */ 0xc40f0055, /* cps = 132864.00, nrm = 32, interval =     2.66 */
-/* 232 */ 0xc4350052, /* cps = 137728.00, nrm = 32, interval =     2.56 */
-/* 233 */ 0xc46d004e, /* cps = 144896.00, nrm = 32, interval =     2.44 */
-/* 234 */ 0xc499004b, /* cps = 150528.00, nrm = 32, interval =     2.34 */
-/* 235 */ 0xc4cb0048, /* cps = 156928.00, nrm = 32, interval =     2.25 */
-/* 236 */ 0xc4ff0045, /* cps = 163584.00, nrm = 32, interval =     2.16 */
-/* 237 */ 0xc5250043, /* cps = 168448.00, nrm = 32, interval =     2.09 */
-/* 238 */ 0xc5630040, /* cps = 176384.00, nrm = 32, interval =     2.00 */
-/* 239 */ 0xc5a7003d, /* cps = 185088.00, nrm = 32, interval =     1.91 */
-/* 240 */ 0xc5d9003b, /* cps = 191488.00, nrm = 32, interval =     1.84 */
-/* 241 */ 0xc6290038, /* cps = 201728.00, nrm = 32, interval =     1.75 */
-/* 242 */ 0xc6630036, /* cps = 209152.00, nrm = 32, interval =     1.69 */
-/* 243 */ 0xc6a30034, /* cps = 217344.00, nrm = 32, interval =     1.62 */
-/* 244 */ 0xc6e70032, /* cps = 226048.00, nrm = 32, interval =     1.56 */
-/* 245 */ 0xc72f0030, /* cps = 235264.00, nrm = 32, interval =     1.50 */
-/* 246 */ 0xc77f002e, /* cps = 245504.00, nrm = 32, interval =     1.44 */
-/* 247 */ 0xc7d7002c, /* cps = 256768.00, nrm = 32, interval =     1.38 */
-/* 248 */ 0xc81b002a, /* cps = 268800.00, nrm = 32, interval =     1.31 */
-/* 249 */ 0xc84f0028, /* cps = 282112.00, nrm = 32, interval =     1.25 */
-/* 250 */ 0xc86d0027, /* cps = 289792.00, nrm = 32, interval =     1.22 */
-/* 251 */ 0xc8a90025, /* cps = 305152.00, nrm = 32, interval =     1.16 */
-/* 252 */ 0xc8cb0024, /* cps = 313856.00, nrm = 32, interval =     1.12 */
-/* 253 */ 0xc9130022, /* cps = 332288.00, nrm = 32, interval =     1.06 */
-/* 254 */ 0xc9390021, /* cps = 342016.00, nrm = 32, interval =     1.03 */
-/* 255 */ 0xc9630020, /* cps = 352768.00, nrm = 32, interval =     1.00 */
-};
-
-static unsigned char rate_to_log[] =
-{
-/*          1.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.06 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.12 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.19 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.25 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.31 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.38 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.44 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.56 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.62 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.69 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.75 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.81 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.88 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.94 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.12 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.25 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.38 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.62 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.75 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.88 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.12 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.25 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.38 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.62 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.75 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.88 =>   0 */ 0x00, /* =>     10.02 */
-/*          4.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          4.25 =>   0 */ 0x00, /* =>     10.02 */
-/*          4.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          4.75 =>   0 */ 0x00, /* =>     10.02 */
-/*          5.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          5.25 =>   0 */ 0x00, /* =>     10.02 */
-/*          5.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          5.75 =>   0 */ 0x00, /* =>     10.02 */
-/*          6.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          6.25 =>   0 */ 0x00, /* =>     10.02 */
-/*          6.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          6.75 =>   0 */ 0x00, /* =>     10.02 */
-/*          7.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          7.25 =>   0 */ 0x00, /* =>     10.02 */
-/*          7.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          7.75 =>   0 */ 0x00, /* =>     10.02 */
-/*          8.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          8.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          9.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          9.50 =>   0 */ 0x00, /* =>     10.02 */
-/*         10.00 =>   0 */ 0x00, /* =>     10.02 */
-/*         10.50 =>   1 */ 0x01, /* =>     10.42 */
-/*         11.00 =>   2 */ 0x02, /* =>     10.86 */
-/*         11.50 =>   3 */ 0x03, /* =>     11.31 */
-/*         12.00 =>   4 */ 0x04, /* =>     11.78 */
-/*         12.50 =>   5 */ 0x05, /* =>     12.28 */
-/*         13.00 =>   6 */ 0x06, /* =>     12.80 */
-/*         13.50 =>   7 */ 0x07, /* =>     13.33 */
-/*         14.00 =>   8 */ 0x08, /* =>     13.89 */
-/*         14.50 =>   9 */ 0x09, /* =>     14.48 */
-/*         15.00 =>   9 */ 0x09, /* =>     14.48 */
-/*         15.50 =>  10 */ 0x0a, /* =>     15.08 */
-/*         16.00 =>  11 */ 0x0b, /* =>     15.72 */
-/*         17.00 =>  12 */ 0x0c, /* =>     16.38 */
-/*         18.00 =>  14 */ 0x0e, /* =>     17.75 */
-/*         19.00 =>  15 */ 0x0f, /* =>     18.50 */
-/*         20.00 =>  16 */ 0x10, /* =>     19.28 */
-/*         21.00 =>  18 */ 0x12, /* =>     20.94 */
-/*         22.00 =>  19 */ 0x13, /* =>     21.81 */
-/*         23.00 =>  20 */ 0x14, /* =>     22.75 */
-/*         24.00 =>  21 */ 0x15, /* =>     23.69 */
-/*         25.00 =>  22 */ 0x16, /* =>     24.69 */
-/*         26.00 =>  23 */ 0x17, /* =>     25.72 */
-/*         27.00 =>  24 */ 0x18, /* =>     26.81 */
-/*         28.00 =>  25 */ 0x19, /* =>     27.94 */
-/*         29.00 =>  25 */ 0x19, /* =>     27.94 */
-/*         30.00 =>  26 */ 0x1a, /* =>     29.09 */
-/*         31.00 =>  27 */ 0x1b, /* =>     30.31 */
-/*         32.00 =>  28 */ 0x1c, /* =>     31.56 */
-/*         34.00 =>  29 */ 0x1d, /* =>     32.94 */
-/*         36.00 =>  31 */ 0x1f, /* =>     35.69 */
-/*         38.00 =>  32 */ 0x20, /* =>     37.19 */
-/*         40.00 =>  33 */ 0x21, /* =>     38.75 */
-/*         42.00 =>  34 */ 0x22, /* =>     40.38 */
-/*         44.00 =>  36 */ 0x24, /* =>     43.88 */
-/*         46.00 =>  37 */ 0x25, /* =>     45.69 */
-/*         48.00 =>  38 */ 0x26, /* =>     47.62 */
-/*         50.00 =>  39 */ 0x27, /* =>     49.62 */
-/*         52.00 =>  40 */ 0x28, /* =>     51.69 */
-/*         54.00 =>  41 */ 0x29, /* =>     53.88 */
-/*         56.00 =>  41 */ 0x29, /* =>     53.88 */
-/*         58.00 =>  42 */ 0x2a, /* =>     56.12 */
-/*         60.00 =>  43 */ 0x2b, /* =>     58.44 */
-/*         62.00 =>  44 */ 0x2c, /* =>     60.94 */
-/*         64.00 =>  45 */ 0x2d, /* =>     63.50 */
-/*         68.00 =>  46 */ 0x2e, /* =>     66.12 */
-/*         72.00 =>  48 */ 0x30, /* =>     71.88 */
-/*         76.00 =>  49 */ 0x31, /* =>     74.75 */
-/*         80.00 =>  50 */ 0x32, /* =>     78.00 */
-/*         84.00 =>  51 */ 0x33, /* =>     81.25 */
-/*         88.00 =>  52 */ 0x34, /* =>     84.62 */
-/*         92.00 =>  54 */ 0x36, /* =>     91.88 */
-/*         96.00 =>  55 */ 0x37, /* =>     95.75 */
-/*        100.00 =>  56 */ 0x38, /* =>     99.75 */
-/*        104.00 =>  56 */ 0x38, /* =>     99.75 */
-/*        108.00 =>  57 */ 0x39, /* =>    104.00 */
-/*        112.00 =>  58 */ 0x3a, /* =>    108.25 */
-/*        116.00 =>  59 */ 0x3b, /* =>    112.88 */
-/*        120.00 =>  60 */ 0x3c, /* =>    117.50 */
-/*        124.00 =>  61 */ 0x3d, /* =>    122.38 */
-/*        128.00 =>  62 */ 0x3e, /* =>    127.50 */
-/*        136.00 =>  63 */ 0x3f, /* =>    132.75 */
-/*        144.00 =>  64 */ 0x40, /* =>    138.50 */
-/*        152.00 =>  66 */ 0x42, /* =>    150.25 */
-/*        160.00 =>  67 */ 0x43, /* =>    156.75 */
-/*        168.00 =>  68 */ 0x44, /* =>    163.50 */
-/*        176.00 =>  69 */ 0x45, /* =>    170.00 */
-/*        184.00 =>  70 */ 0x46, /* =>    177.25 */
-/*        192.00 =>  71 */ 0x47, /* =>    184.50 */
-/*        200.00 =>  72 */ 0x48, /* =>    192.25 */
-/*        208.00 =>  73 */ 0x49, /* =>    200.25 */
-/*        216.00 =>  74 */ 0x4a, /* =>    208.75 */
-/*        224.00 =>  75 */ 0x4b, /* =>    217.75 */
-/*        232.00 =>  76 */ 0x4c, /* =>    226.75 */
-/*        240.00 =>  77 */ 0x4d, /* =>    236.25 */
-/*        248.00 =>  78 */ 0x4e, /* =>    246.25 */
-/*        256.00 =>  78 */ 0x4e, /* =>    246.25 */
-/*        272.00 =>  80 */ 0x50, /* =>    267.50 */
-/*        288.00 =>  81 */ 0x51, /* =>    278.50 */
-/*        304.00 =>  83 */ 0x53, /* =>    302.00 */
-/*        320.00 =>  84 */ 0x54, /* =>    315.00 */
-/*        336.00 =>  85 */ 0x55, /* =>    328.00 */
-/*        352.00 =>  86 */ 0x56, /* =>    342.00 */
-/*        368.00 =>  87 */ 0x57, /* =>    356.00 */
-/*        384.00 =>  88 */ 0x58, /* =>    371.00 */
-/*        400.00 =>  89 */ 0x59, /* =>    386.50 */
-/*        416.00 =>  90 */ 0x5a, /* =>    403.00 */
-/*        432.00 =>  91 */ 0x5b, /* =>    419.50 */
-/*        448.00 =>  92 */ 0x5c, /* =>    437.50 */
-/*        464.00 =>  93 */ 0x5d, /* =>    455.50 */
-/*        480.00 =>  94 */ 0x5e, /* =>    475.00 */
-/*        496.00 =>  95 */ 0x5f, /* =>    495.00 */
-/*        512.00 =>  95 */ 0x5f, /* =>    495.00 */
-/*        544.00 =>  97 */ 0x61, /* =>    537.00 */
-/*        576.00 =>  98 */ 0x62, /* =>    559.00 */
-/*        608.00 => 100 */ 0x64, /* =>    607.00 */
-/*        640.00 => 101 */ 0x65, /* =>    632.00 */
-/*        672.00 => 102 */ 0x66, /* =>    660.00 */
-/*        704.00 => 103 */ 0x67, /* =>    687.00 */
-/*        736.00 => 104 */ 0x68, /* =>    716.00 */
-/*        768.00 => 105 */ 0x69, /* =>    746.00 */
-/*        800.00 => 106 */ 0x6a, /* =>    777.00 */
-/*        832.00 => 107 */ 0x6b, /* =>    810.00 */
-/*        864.00 => 108 */ 0x6c, /* =>    843.00 */
-/*        896.00 => 109 */ 0x6d, /* =>    879.00 */
-/*        928.00 => 110 */ 0x6e, /* =>    916.00 */
-/*        960.00 => 111 */ 0x6f, /* =>    954.00 */
-/*        992.00 => 111 */ 0x6f, /* =>    954.00 */
-/*       1024.00 => 112 */ 0x70, /* =>    994.00 */
-/*       1088.00 => 114 */ 0x72, /* =>   1080.00 */
-/*       1152.00 => 115 */ 0x73, /* =>   1124.00 */
-/*       1216.00 => 116 */ 0x74, /* =>   1172.00 */
-/*       1280.00 => 118 */ 0x76, /* =>   1272.00 */
-/*       1344.00 => 119 */ 0x77, /* =>   1326.00 */
-/*       1408.00 => 120 */ 0x78, /* =>   1382.00 */
-/*       1472.00 => 121 */ 0x79, /* =>   1440.00 */
-/*       1536.00 => 122 */ 0x7a, /* =>   1498.00 */
-/*       1600.00 => 123 */ 0x7b, /* =>   1562.00 */
-/*       1664.00 => 124 */ 0x7c, /* =>   1628.00 */
-/*       1728.00 => 125 */ 0x7d, /* =>   1696.00 */
-/*       1792.00 => 126 */ 0x7e, /* =>   1768.00 */
-/*       1856.00 => 127 */ 0x7f, /* =>   1842.00 */
-/*       1920.00 => 128 */ 0x80, /* =>   1918.00 */
-/*       1984.00 => 128 */ 0x80, /* =>   1918.00 */
-/*       2048.00 => 129 */ 0x81, /* =>   2000.00 */
-/*       2176.00 => 131 */ 0x83, /* =>   2168.00 */
-/*       2304.00 => 132 */ 0x84, /* =>   2264.00 */
-/*       2432.00 => 133 */ 0x85, /* =>   2356.00 */
-/*       2560.00 => 135 */ 0x87, /* =>   2556.00 */
-/*       2688.00 => 136 */ 0x88, /* =>   2664.00 */
-/*       2816.00 => 137 */ 0x89, /* =>   2776.00 */
-/*       2944.00 => 138 */ 0x8a, /* =>   2892.00 */
-/*       3072.00 => 139 */ 0x8b, /* =>   3012.00 */
-/*       3200.00 => 140 */ 0x8c, /* =>   3140.00 */
-/*       3328.00 => 141 */ 0x8d, /* =>   3272.00 */
-/*       3456.00 => 142 */ 0x8e, /* =>   3412.00 */
-/*       3584.00 => 143 */ 0x8f, /* =>   3552.00 */
-/*       3712.00 => 144 */ 0x90, /* =>   3700.00 */
-/*       3840.00 => 144 */ 0x90, /* =>   3700.00 */
-/*       3968.00 => 145 */ 0x91, /* =>   3860.00 */
-/*       4096.00 => 146 */ 0x92, /* =>   4016.00 */
-/*       4352.00 => 147 */ 0x93, /* =>   4184.00 */
-/*       4608.00 => 149 */ 0x95, /* =>   4544.00 */
-/*       4864.00 => 150 */ 0x96, /* =>   4736.00 */
-/*       5120.00 => 151 */ 0x97, /* =>   4936.00 */
-/*       5376.00 => 153 */ 0x99, /* =>   5360.00 */
-/*       5632.00 => 154 */ 0x9a, /* =>   5584.00 */
-/*       5888.00 => 155 */ 0x9b, /* =>   5816.00 */
-/*       6144.00 => 156 */ 0x9c, /* =>   6056.00 */
-/*       6400.00 => 157 */ 0x9d, /* =>   6312.00 */
-/*       6656.00 => 158 */ 0x9e, /* =>   6576.00 */
-/*       6912.00 => 159 */ 0x9f, /* =>   6856.00 */
-/*       7168.00 => 160 */ 0xa0, /* =>   7144.00 */
-/*       7424.00 => 160 */ 0xa0, /* =>   7144.00 */
-/*       7680.00 => 161 */ 0xa1, /* =>   7440.00 */
-/*       7936.00 => 162 */ 0xa2, /* =>   7752.00 */
-/*       8192.00 => 163 */ 0xa3, /* =>   8080.00 */
-/*       8704.00 => 164 */ 0xa4, /* =>   8416.00 */
-/*       9216.00 => 166 */ 0xa6, /* =>   9136.00 */
-/*       9728.00 => 167 */ 0xa7, /* =>   9520.00 */
-/*      10240.00 => 168 */ 0xa8, /* =>   9920.00 */
-/*      10752.00 => 169 */ 0xa9, /* =>  10336.00 */
-/*      11264.00 => 171 */ 0xab, /* =>  11216.00 */
-/*      11776.00 => 172 */ 0xac, /* =>  11680.00 */
-/*      12288.00 => 173 */ 0xad, /* =>  12176.00 */
-/*      12800.00 => 174 */ 0xae, /* =>  12688.00 */
-/*      13312.00 => 175 */ 0xaf, /* =>  13216.00 */
-/*      13824.00 => 176 */ 0xb0, /* =>  13776.00 */
-/*      14336.00 => 176 */ 0xb0, /* =>  13776.00 */
-/*      14848.00 => 177 */ 0xb1, /* =>  14352.00 */
-/*      15360.00 => 178 */ 0xb2, /* =>  14960.00 */
-/*      15872.00 => 179 */ 0xb3, /* =>  15584.00 */
-/*      16384.00 => 180 */ 0xb4, /* =>  16224.00 */
-/*      17408.00 => 181 */ 0xb5, /* =>  16896.00 */
-/*      18432.00 => 183 */ 0xb7, /* =>  18368.00 */
-/*      19456.00 => 184 */ 0xb8, /* =>  19136.00 */
-/*      20480.00 => 185 */ 0xb9, /* =>  19904.00 */
-/*      21504.00 => 186 */ 0xba, /* =>  20768.00 */
-/*      22528.00 => 187 */ 0xbb, /* =>  21632.00 */
-/*      23552.00 => 189 */ 0xbd, /* =>  23488.00 */
-/*      24576.00 => 190 */ 0xbe, /* =>  24512.00 */
-/*      25600.00 => 191 */ 0xbf, /* =>  25504.00 */
-/*      26624.00 => 192 */ 0xc0, /* =>  26592.00 */
-/*      27648.00 => 192 */ 0xc0, /* =>  26592.00 */
-/*      28672.00 => 193 */ 0xc1, /* =>  27680.00 */
-/*      29696.00 => 194 */ 0xc2, /* =>  28896.00 */
-/*      30720.00 => 195 */ 0xc3, /* =>  30048.00 */
-/*      31744.00 => 196 */ 0xc4, /* =>  31392.00 */
-/*      32768.00 => 197 */ 0xc5, /* =>  32640.00 */
-/*      34816.00 => 198 */ 0xc6, /* =>  33984.00 */
-/*      36864.00 => 199 */ 0xc7, /* =>  35392.00 */
-/*      38912.00 => 201 */ 0xc9, /* =>  38528.00 */
-/*      40960.00 => 202 */ 0xca, /* =>  40064.00 */
-/*      43008.00 => 203 */ 0xcb, /* =>  41856.00 */
-/*      45056.00 => 204 */ 0xcc, /* =>  43584.00 */
-/*      47104.00 => 205 */ 0xcd, /* =>  45376.00 */
-/*      49152.00 => 206 */ 0xce, /* =>  47232.00 */
-/*      51200.00 => 207 */ 0xcf, /* =>  49344.00 */
-/*      53248.00 => 208 */ 0xd0, /* =>  51328.00 */
-/*      55296.00 => 209 */ 0xd1, /* =>  53504.00 */
-/*      57344.00 => 210 */ 0xd2, /* =>  55616.00 */
-/*      59392.00 => 211 */ 0xd3, /* =>  58240.00 */
-/*      61440.00 => 212 */ 0xd4, /* =>  60416.00 */
-/*      63488.00 => 213 */ 0xd5, /* =>  63104.00 */
-/*      65536.00 => 213 */ 0xd5, /* =>  63104.00 */
-/*      69632.00 => 215 */ 0xd7, /* =>  68480.00 */
-/*      73728.00 => 216 */ 0xd8, /* =>  71424.00 */
-/*      77824.00 => 218 */ 0xda, /* =>  77312.00 */
-/*      81920.00 => 219 */ 0xdb, /* =>  80640.00 */
-/*      86016.00 => 220 */ 0xdc, /* =>  84224.00 */
-/*      90112.00 => 221 */ 0xdd, /* =>  87552.00 */
-/*      94208.00 => 222 */ 0xde, /* =>  91136.00 */
-/*      98304.00 => 223 */ 0xdf, /* =>  94976.00 */
-/*     102400.00 => 224 */ 0xe0, /* =>  99072.00 */
-/*     106496.00 => 225 */ 0xe1, /* => 103680.00 */
-/*     110592.00 => 226 */ 0xe2, /* => 107520.00 */
-/*     114688.00 => 227 */ 0xe3, /* => 111872.00 */
-/*     118784.00 => 228 */ 0xe4, /* => 117632.00 */
-/*     122880.00 => 229 */ 0xe5, /* => 121472.00 */
-/*     126976.00 => 229 */ 0xe5, /* => 121472.00 */
-/*     131072.00 => 230 */ 0xe6, /* => 126976.00 */
-/*     139264.00 => 232 */ 0xe8, /* => 137728.00 */
-/*     147456.00 => 233 */ 0xe9, /* => 144896.00 */
-/*     155648.00 => 234 */ 0xea, /* => 150528.00 */
-/*     163840.00 => 236 */ 0xec, /* => 163584.00 */
-/*     172032.00 => 237 */ 0xed, /* => 168448.00 */
-/*     180224.00 => 238 */ 0xee, /* => 176384.00 */
-/*     188416.00 => 239 */ 0xef, /* => 185088.00 */
-/*     196608.00 => 240 */ 0xf0, /* => 191488.00 */
-/*     204800.00 => 241 */ 0xf1, /* => 201728.00 */
-/*     212992.00 => 242 */ 0xf2, /* => 209152.00 */
-/*     221184.00 => 243 */ 0xf3, /* => 217344.00 */
-/*     229376.00 => 244 */ 0xf4, /* => 226048.00 */
-/*     237568.00 => 245 */ 0xf5, /* => 235264.00 */
-/*     245760.00 => 246 */ 0xf6, /* => 245504.00 */
-/*     253952.00 => 246 */ 0xf6, /* => 245504.00 */
-/*     262144.00 => 247 */ 0xf7, /* => 256768.00 */
-/*     278528.00 => 248 */ 0xf8, /* => 268800.00 */
-/*     294912.00 => 250 */ 0xfa, /* => 289792.00 */
-/*     311296.00 => 251 */ 0xfb, /* => 305152.00 */
-/*     327680.00 => 252 */ 0xfc, /* => 313856.00 */
-/*     344064.00 => 254 */ 0xfe, /* => 342016.00 */
-/*     360448.00 => 255 */ 0xff, /* => 352768.00 */
-/*     376832.00 => 255 */ 0xff, /* => 352768.00 */
-/*     393216.00 => 255 */ 0xff, /* => 352768.00 */
-/*     409600.00 => 255 */ 0xff, /* => 352768.00 */
-/*     425984.00 => 255 */ 0xff, /* => 352768.00 */
-/*     442368.00 => 255 */ 0xff, /* => 352768.00 */
-/*     458752.00 => 255 */ 0xff, /* => 352768.00 */
-/*     475136.00 => 255 */ 0xff, /* => 352768.00 */
-/*     491520.00 => 255 */ 0xff, /* => 352768.00 */
-/*     507904.00 => 255 */ 0xff, /* => 352768.00 */
-/*     524288.00 => 255 */ 0xff, /* => 352768.00 */
-/*     557056.00 => 255 */ 0xff, /* => 352768.00 */
-/*     589824.00 => 255 */ 0xff, /* => 352768.00 */
-/*     622592.00 => 255 */ 0xff, /* => 352768.00 */
-/*     655360.00 => 255 */ 0xff, /* => 352768.00 */
-/*     688128.00 => 255 */ 0xff, /* => 352768.00 */
-/*     720896.00 => 255 */ 0xff, /* => 352768.00 */
-/*     753664.00 => 255 */ 0xff, /* => 352768.00 */
-/*     786432.00 => 255 */ 0xff, /* => 352768.00 */
-/*     819200.00 => 255 */ 0xff, /* => 352768.00 */
-/*     851968.00 => 255 */ 0xff, /* => 352768.00 */
-/*     884736.00 => 255 */ 0xff, /* => 352768.00 */
-/*     917504.00 => 255 */ 0xff, /* => 352768.00 */
-/*     950272.00 => 255 */ 0xff, /* => 352768.00 */
-/*     983040.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1015808.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1048576.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1114112.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1179648.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1245184.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1310720.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1376256.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1441792.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1507328.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1572864.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1638400.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1703936.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1769472.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1835008.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1900544.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1966080.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2031616.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2097152.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2228224.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2359296.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2490368.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2621440.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2752512.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2883584.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3014656.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3145728.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3276800.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3407872.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3538944.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3670016.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3801088.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3932160.00 => 255 */ 0xff, /* => 352768.00 */
-/*    4063232.00 => 255 */ 0xff, /* => 352768.00 */
-/*    4194304.00 => 255 */ 0xff, /* => 352768.00 */
-/*    4456448.00 => 255 */ 0xff, /* => 352768.00 */
-/*    4718592.00 => 255 */ 0xff, /* => 352768.00 */
-/*    4980736.00 => 255 */ 0xff, /* => 352768.00 */
-/*    5242880.00 => 255 */ 0xff, /* => 352768.00 */
-/*    5505024.00 => 255 */ 0xff, /* => 352768.00 */
-/*    5767168.00 => 255 */ 0xff, /* => 352768.00 */
-/*    6029312.00 => 255 */ 0xff, /* => 352768.00 */
-/*    6291456.00 => 255 */ 0xff, /* => 352768.00 */
-/*    6553600.00 => 255 */ 0xff, /* => 352768.00 */
-/*    6815744.00 => 255 */ 0xff, /* => 352768.00 */
-/*    7077888.00 => 255 */ 0xff, /* => 352768.00 */
-/*    7340032.00 => 255 */ 0xff, /* => 352768.00 */
-/*    7602176.00 => 255 */ 0xff, /* => 352768.00 */
-/*    7864320.00 => 255 */ 0xff, /* => 352768.00 */
-/*    8126464.00 => 255 */ 0xff, /* => 352768.00 */
-/*    8388608.00 => 255 */ 0xff, /* => 352768.00 */
-/*    8912896.00 => 255 */ 0xff, /* => 352768.00 */
-/*    9437184.00 => 255 */ 0xff, /* => 352768.00 */
-/*    9961472.00 => 255 */ 0xff, /* => 352768.00 */
-/*   10485760.00 => 255 */ 0xff, /* => 352768.00 */
-/*   11010048.00 => 255 */ 0xff, /* => 352768.00 */
-/*   11534336.00 => 255 */ 0xff, /* => 352768.00 */
-/*   12058624.00 => 255 */ 0xff, /* => 352768.00 */
-/*   12582912.00 => 255 */ 0xff, /* => 352768.00 */
-/*   13107200.00 => 255 */ 0xff, /* => 352768.00 */
-/*   13631488.00 => 255 */ 0xff, /* => 352768.00 */
-/*   14155776.00 => 255 */ 0xff, /* => 352768.00 */
-/*   14680064.00 => 255 */ 0xff, /* => 352768.00 */
-/*   15204352.00 => 255 */ 0xff, /* => 352768.00 */
-/*   15728640.00 => 255 */ 0xff, /* => 352768.00 */
-/*   16252928.00 => 255 */ 0xff, /* => 352768.00 */
-/*   16777216.00 => 255 */ 0xff, /* => 352768.00 */
-/*   17825792.00 => 255 */ 0xff, /* => 352768.00 */
-/*   18874368.00 => 255 */ 0xff, /* => 352768.00 */
-/*   19922944.00 => 255 */ 0xff, /* => 352768.00 */
-/*   20971520.00 => 255 */ 0xff, /* => 352768.00 */
-/*   22020096.00 => 255 */ 0xff, /* => 352768.00 */
-/*   23068672.00 => 255 */ 0xff, /* => 352768.00 */
-/*   24117248.00 => 255 */ 0xff, /* => 352768.00 */
-/*   25165824.00 => 255 */ 0xff, /* => 352768.00 */
-/*   26214400.00 => 255 */ 0xff, /* => 352768.00 */
-/*   27262976.00 => 255 */ 0xff, /* => 352768.00 */
-/*   28311552.00 => 255 */ 0xff, /* => 352768.00 */
-/*   29360128.00 => 255 */ 0xff, /* => 352768.00 */
-/*   30408704.00 => 255 */ 0xff, /* => 352768.00 */
-/*   31457280.00 => 255 */ 0xff, /* => 352768.00 */
-/*   32505856.00 => 255 */ 0xff, /* => 352768.00 */
-/*   33554432.00 => 255 */ 0xff, /* => 352768.00 */
-/*   35651584.00 => 255 */ 0xff, /* => 352768.00 */
-/*   37748736.00 => 255 */ 0xff, /* => 352768.00 */
-/*   39845888.00 => 255 */ 0xff, /* => 352768.00 */
-/*   41943040.00 => 255 */ 0xff, /* => 352768.00 */
-/*   44040192.00 => 255 */ 0xff, /* => 352768.00 */
-/*   46137344.00 => 255 */ 0xff, /* => 352768.00 */
-/*   48234496.00 => 255 */ 0xff, /* => 352768.00 */
-/*   50331648.00 => 255 */ 0xff, /* => 352768.00 */
-/*   52428800.00 => 255 */ 0xff, /* => 352768.00 */
-/*   54525952.00 => 255 */ 0xff, /* => 352768.00 */
-/*   56623104.00 => 255 */ 0xff, /* => 352768.00 */
-/*   58720256.00 => 255 */ 0xff, /* => 352768.00 */
-/*   60817408.00 => 255 */ 0xff, /* => 352768.00 */
-/*   62914560.00 => 255 */ 0xff, /* => 352768.00 */
-/*   65011712.00 => 255 */ 0xff, /* => 352768.00 */
-/*   67108864.00 => 255 */ 0xff, /* => 352768.00 */
-/*   71303168.00 => 255 */ 0xff, /* => 352768.00 */
-/*   75497472.00 => 255 */ 0xff, /* => 352768.00 */
-/*   79691776.00 => 255 */ 0xff, /* => 352768.00 */
-/*   83886080.00 => 255 */ 0xff, /* => 352768.00 */
-/*   88080384.00 => 255 */ 0xff, /* => 352768.00 */
-/*   92274688.00 => 255 */ 0xff, /* => 352768.00 */
-/*   96468992.00 => 255 */ 0xff, /* => 352768.00 */
-/*  100663296.00 => 255 */ 0xff, /* => 352768.00 */
-/*  104857600.00 => 255 */ 0xff, /* => 352768.00 */
-/*  109051904.00 => 255 */ 0xff, /* => 352768.00 */
-/*  113246208.00 => 255 */ 0xff, /* => 352768.00 */
-/*  117440512.00 => 255 */ 0xff, /* => 352768.00 */
-/*  121634816.00 => 255 */ 0xff, /* => 352768.00 */
-/*  125829120.00 => 255 */ 0xff, /* => 352768.00 */
-/*  130023424.00 => 255 */ 0xff, /* => 352768.00 */
-/*  134217728.00 => 255 */ 0xff, /* => 352768.00 */
-/*  142606336.00 => 255 */ 0xff, /* => 352768.00 */
-/*  150994944.00 => 255 */ 0xff, /* => 352768.00 */
-/*  159383552.00 => 255 */ 0xff, /* => 352768.00 */
-/*  167772160.00 => 255 */ 0xff, /* => 352768.00 */
-/*  176160768.00 => 255 */ 0xff, /* => 352768.00 */
-/*  184549376.00 => 255 */ 0xff, /* => 352768.00 */
-/*  192937984.00 => 255 */ 0xff, /* => 352768.00 */
-/*  201326592.00 => 255 */ 0xff, /* => 352768.00 */
-/*  209715200.00 => 255 */ 0xff, /* => 352768.00 */
-/*  218103808.00 => 255 */ 0xff, /* => 352768.00 */
-/*  226492416.00 => 255 */ 0xff, /* => 352768.00 */
-/*  234881024.00 => 255 */ 0xff, /* => 352768.00 */
-/*  243269632.00 => 255 */ 0xff, /* => 352768.00 */
-/*  251658240.00 => 255 */ 0xff, /* => 352768.00 */
-/*  260046848.00 => 255 */ 0xff, /* => 352768.00 */
-/*  268435456.00 => 255 */ 0xff, /* => 352768.00 */
-/*  285212672.00 => 255 */ 0xff, /* => 352768.00 */
-/*  301989888.00 => 255 */ 0xff, /* => 352768.00 */
-/*  318767104.00 => 255 */ 0xff, /* => 352768.00 */
-/*  335544320.00 => 255 */ 0xff, /* => 352768.00 */
-/*  352321536.00 => 255 */ 0xff, /* => 352768.00 */
-/*  369098752.00 => 255 */ 0xff, /* => 352768.00 */
-/*  385875968.00 => 255 */ 0xff, /* => 352768.00 */
-/*  402653184.00 => 255 */ 0xff, /* => 352768.00 */
-/*  419430400.00 => 255 */ 0xff, /* => 352768.00 */
-/*  436207616.00 => 255 */ 0xff, /* => 352768.00 */
-/*  452984832.00 => 255 */ 0xff, /* => 352768.00 */
-/*  469762048.00 => 255 */ 0xff, /* => 352768.00 */
-/*  486539264.00 => 255 */ 0xff, /* => 352768.00 */
-/*  503316480.00 => 255 */ 0xff, /* => 352768.00 */
-/*  520093696.00 => 255 */ 0xff, /* => 352768.00 */
-/*  536870912.00 => 255 */ 0xff, /* => 352768.00 */
-/*  570425344.00 => 255 */ 0xff, /* => 352768.00 */
-/*  603979776.00 => 255 */ 0xff, /* => 352768.00 */
-/*  637534208.00 => 255 */ 0xff, /* => 352768.00 */
-/*  671088640.00 => 255 */ 0xff, /* => 352768.00 */
-/*  704643072.00 => 255 */ 0xff, /* => 352768.00 */
-/*  738197504.00 => 255 */ 0xff, /* => 352768.00 */
-/*  771751936.00 => 255 */ 0xff, /* => 352768.00 */
-/*  805306368.00 => 255 */ 0xff, /* => 352768.00 */
-/*  838860800.00 => 255 */ 0xff, /* => 352768.00 */
-/*  872415232.00 => 255 */ 0xff, /* => 352768.00 */
-/*  905969664.00 => 255 */ 0xff, /* => 352768.00 */
-/*  939524096.00 => 255 */ 0xff, /* => 352768.00 */
-/*  973078528.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1006632960.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1040187392.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1073741824.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1140850688.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1207959552.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1275068416.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1342177280.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1409286144.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1476395008.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1543503872.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1610612736.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1677721600.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1744830464.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1811939328.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1879048192.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1946157056.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2013265920.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2080374784.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2147483648.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2281701376.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2415919104.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2550136832.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2684354560.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2818572288.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2952790016.00 => 255 */ 0xff, /* => 352768.00 */
-/* 3087007744.00 => 255 */ 0xff, /* => 352768.00 */
-/* 3221225472.00 => 255 */ 0xff, /* => 352768.00 */
-/* 3355443200.00 => 255 */ 0xff, /* => 352768.00 */
-/* 3489660928.00 => 255 */ 0xff, /* => 352768.00 */
-/* 3623878656.00 => 255 */ 0xff, /* => 352768.00 */
-/* 3758096384.00 => 255 */ 0xff, /* => 352768.00 */
-/* 3892314112.00 => 255 */ 0xff, /* => 352768.00 */
-/* 4026531840.00 => 255 */ 0xff, /* => 352768.00 */
-/* 4160749568.00 => 255 */ 0xff, /* => 352768.00 */
-};
diff --git a/drivers/atm/iphase.h b/drivers/atm/iphase.h
deleted file mode 100644
index 2f5f8875cbd1..000000000000
--- a/drivers/atm/iphase.h
+++ /dev/null
@@ -1,1452 +0,0 @@
-/******************************************************************************
-             Device driver for Interphase ATM PCI adapter cards 
-                    Author: Peter Wang  <pwang@iphase.com>            
-                   Interphase Corporation  <www.iphase.com>           
-                               Version: 1.0   
-               iphase.h:  This is the header file for iphase.c. 
-*******************************************************************************
-      
-      This software may be used and distributed according to the terms
-      of the GNU General Public License (GPL), incorporated herein by reference.
-      Drivers based on this skeleton fall under the GPL and must retain
-      the authorship (implicit copyright) notice.
-
-      This program is distributed in the hope that it will be useful, but
-      WITHOUT ANY WARRANTY; without even the implied warranty of
-      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-      General Public License for more details.
-      
-      Modified from an incomplete driver for Interphase 5575 1KVC 1M card which 
-      was originally written by Monalisa Agrawal at UNH. Now this driver 
-      supports a variety of varients of Interphase ATM PCI (i)Chip adapter 
-      card family (See www.iphase.com/products/ClassSheet.cfm?ClassID=ATM) 
-      in terms of PHY type, the size of control memory and the size of 
-      packet memory. The following are the change log and history:
-     
-          Bugfix the Mona's UBR driver.
-          Modify the basic memory allocation and dma logic.
-          Port the driver to the latest kernel from 2.0.46.
-          Complete the ABR logic of the driver, and added the ABR work-
-              around for the hardware anormalies.
-          Add the CBR support.
-	  Add the flow control logic to the driver to allow rate-limit VC.
-          Add 4K VC support to the board with 512K control memory.
-          Add the support of all the variants of the Interphase ATM PCI 
-          (i)Chip adapter cards including x575 (155M OC3 and UTP155), x525
-          (25M UTP25) and x531 (DS3 and E3).
-          Add SMP support.
-
-      Support and updates available at: ftp://ftp.iphase.com/pub/atm
-
-*******************************************************************************/
-  
-#ifndef IPHASE_H  
-#define IPHASE_H  
-
-
-/************************ IADBG DEFINE *********************************/
-/* IADebugFlag Bit Map */ 
-#define IF_IADBG_INIT_ADAPTER   0x00000001        // init adapter info
-#define IF_IADBG_TX             0x00000002        // debug TX
-#define IF_IADBG_RX             0x00000004        // debug RX
-#define IF_IADBG_QUERY_INFO     0x00000008        // debug Request call
-#define IF_IADBG_SHUTDOWN       0x00000010        // debug shutdown event
-#define IF_IADBG_INTR           0x00000020        // debug interrupt DPC
-#define IF_IADBG_TXPKT          0x00000040  	  // debug TX PKT
-#define IF_IADBG_RXPKT          0x00000080  	  // debug RX PKT
-#define IF_IADBG_ERR            0x00000100        // debug system error
-#define IF_IADBG_EVENT          0x00000200        // debug event
-#define IF_IADBG_DIS_INTR       0x00001000        // debug disable interrupt
-#define IF_IADBG_EN_INTR        0x00002000        // debug enable interrupt
-#define IF_IADBG_LOUD           0x00004000        // debugging info
-#define IF_IADBG_VERY_LOUD      0x00008000        // excessive debugging info
-#define IF_IADBG_CBR            0x00100000  	  //
-#define IF_IADBG_UBR            0x00200000  	  //
-#define IF_IADBG_ABR            0x00400000        //
-#define IF_IADBG_DESC           0x01000000        //
-#define IF_IADBG_SUNI_STAT      0x02000000        // suni statistics
-#define IF_IADBG_RESET          0x04000000        
-
-#define IF_IADBG(f) if (IADebugFlag & (f))
-
-#ifdef  CONFIG_ATM_IA_DEBUG   /* Debug build */
-
-#define IF_LOUD(A) IF_IADBG(IF_IADBG_LOUD) { A }
-#define IF_ERR(A) IF_IADBG(IF_IADBG_ERR) { A }
-#define IF_VERY_LOUD(A) IF_IADBG( IF_IADBG_VERY_LOUD ) { A }
-
-#define IF_INIT_ADAPTER(A) IF_IADBG( IF_IADBG_INIT_ADAPTER ) { A }
-#define IF_INIT(A) IF_IADBG( IF_IADBG_INIT_ADAPTER ) { A }
-#define IF_SUNI_STAT(A) IF_IADBG( IF_IADBG_SUNI_STAT ) { A }
-#define IF_QUERY_INFO(A) IF_IADBG( IF_IADBG_QUERY_INFO ) { A }
-#define IF_COPY_OVER(A) IF_IADBG( IF_IADBG_COPY_OVER ) { A }
-
-#define IF_INTR(A) IF_IADBG( IF_IADBG_INTR ) { A }
-#define IF_DIS_INTR(A) IF_IADBG( IF_IADBG_DIS_INTR ) { A }
-#define IF_EN_INTR(A) IF_IADBG( IF_IADBG_EN_INTR ) { A }
-
-#define IF_TX(A) IF_IADBG( IF_IADBG_TX ) { A }
-#define IF_RX(A) IF_IADBG( IF_IADBG_RX ) { A }
-#define IF_TXPKT(A) IF_IADBG( IF_IADBG_TXPKT ) { A }
-#define IF_RXPKT(A) IF_IADBG( IF_IADBG_RXPKT ) { A }
-
-#define IF_SHUTDOWN(A) IF_IADBG(IF_IADBG_SHUTDOWN) { A }
-#define IF_CBR(A) IF_IADBG( IF_IADBG_CBR ) { A }
-#define IF_UBR(A) IF_IADBG( IF_IADBG_UBR ) { A }
-#define IF_ABR(A) IF_IADBG( IF_IADBG_ABR ) { A }
-#define IF_EVENT(A) IF_IADBG( IF_IADBG_EVENT) { A }
-
-#else /* free build */
-#define IF_LOUD(A)
-#define IF_VERY_LOUD(A)
-#define IF_INIT_ADAPTER(A)
-#define IF_INIT(A)
-#define IF_SUNI_STAT(A)
-#define IF_PVC_CHKPKT(A)
-#define IF_QUERY_INFO(A)
-#define IF_COPY_OVER(A)
-#define IF_HANG(A)
-#define IF_INTR(A)
-#define IF_DIS_INTR(A)
-#define IF_EN_INTR(A)
-#define IF_TX(A)
-#define IF_RX(A)
-#define IF_TXDEBUG(A)
-#define IF_VC(A)
-#define IF_ERR(A) 
-#define IF_CBR(A)
-#define IF_UBR(A)
-#define IF_ABR(A)
-#define IF_SHUTDOWN(A)
-#define DbgPrint(A)
-#define IF_EVENT(A)
-#define IF_TXPKT(A) 
-#define IF_RXPKT(A)
-#endif /* CONFIG_ATM_IA_DEBUG */ 
-
-#define ATM_DESC(skb) (skb->protocol)
-#define IA_SKB_STATE(skb) (skb->protocol)
-#define IA_DLED   1
-#define IA_TX_DONE 2
-
-/* iadbg defines */
-#define IA_CMD   0x7749
-typedef struct {
-	int cmd;
-        int sub_cmd;
-        int len;
-        u32 maddr;
-        int status;
-        void __user *buf;
-} IA_CMDBUF, *PIA_CMDBUF;
-
-/* cmds */
-#define MEMDUMP     		0x01
-
-/* sub_cmds */
-#define MEMDUMP_SEGREG          0x2
-#define MEMDUMP_DEV  		0x1
-#define MEMDUMP_REASSREG        0x3
-#define MEMDUMP_FFL             0x4
-#define READ_REG                0x5
-#define WAKE_DBG_WAIT           0x6
-
-/************************ IADBG DEFINE END ***************************/
-
-#define Boolean(x)    	((x) ? 1 : 0)
-#define NR_VCI 1024		/* number of VCIs */  
-#define NR_VCI_LD 10		/* log2(NR_VCI) */  
-#define NR_VCI_4K 4096 		/* number of VCIs */  
-#define NR_VCI_4K_LD 12		/* log2(NR_VCI) */  
-#define MEM_VALID 0xfffffff0	/* mask base address with this */  
-  
-#ifndef PCI_VENDOR_ID_IPHASE  
-#define PCI_VENDOR_ID_IPHASE 0x107e  
-#endif  
-#ifndef PCI_DEVICE_ID_IPHASE_5575  
-#define PCI_DEVICE_ID_IPHASE_5575 0x0008  
-#endif  
-#define DEV_LABEL 	"ia"  
-#define PCR	207692  
-#define ICR	100000  
-#define MCR	0  
-#define TBE	1000  
-#define FRTT	1  
-#define RIF	2		  
-#define RDF	4  
-#define NRMCODE 5	/* 0 - 7 */  
-#define TRMCODE	3	/* 0 - 7 */  
-#define CDFCODE	6  
-#define ATDFCODE 2	/* 0 - 15 */  
-  
-/*---------------------- Packet/Cell Memory ------------------------*/  
-#define TX_PACKET_RAM 	0x00000 /* start of Trasnmit Packet memory - 0 */  
-#define DFL_TX_BUF_SZ	10240	/* 10 K buffers */  
-#define DFL_TX_BUFFERS     50 	/* number of packet buffers for Tx   
-					- descriptor 0 unused */  
-#define REASS_RAM_SIZE 0x10000  /* for 64K 1K VC board */  
-#define RX_PACKET_RAM 	0x80000 /* start of Receive Packet memory - 512K */  
-#define DFL_RX_BUF_SZ	10240	/* 10k buffers */  
-#define DFL_RX_BUFFERS      50	/* number of packet buffers for Rx   
-					- descriptor 0 unused */  
-  
-struct cpcs_trailer 
-{  
-	u_short control;  
-	u_short length;  
-	u_int	crc32;  
-};  
-
-struct cpcs_trailer_desc
-{
-	struct cpcs_trailer *cpcs;
-	dma_addr_t dma_addr;
-};
-
-struct ia_vcc 
-{ 
-	int rxing;	 
-	int txing;		 
-        int NumCbrEntry;
-        u32 pcr;
-        u32 saved_tx_quota;
-        int flow_inc;
-        struct sk_buff_head txing_skb; 
-        int  ltimeout;                  
-        u8  vc_desc_cnt;                
-                
-};  
-  
-struct abr_vc_table 
-{  
-	u_char status;  
-	u_char rdf;  
-	u_short air;  
-	u_int res[3];  
-	u_int req_rm_cell_data1;  
-	u_int req_rm_cell_data2;  
-	u_int add_rm_cell_data1;  
-	u_int add_rm_cell_data2;  
-};  
-    
-/* 32 byte entries */  
-struct main_vc 
-{  
-	u_short 	type;  
-#define ABR	0x8000  
-#define UBR 	0xc000  
-#define CBR	0x0000  
-	/* ABR fields */  
-	u_short 	nrm;	 
- 	u_short 	trm;	   
-	u_short 	rm_timestamp_hi;  
-	u_short 	rm_timestamp_lo:8,  
-			crm:8;		  
-	u_short 	remainder; 	/* ABR and UBR fields - last 10 bits*/  
-	u_short 	next_vc_sched;  
-	u_short 	present_desc;	/* all classes */  
-	u_short 	last_cell_slot;	/* ABR and UBR */  
-	u_short 	pcr;  
-	u_short 	fraction;  
-	u_short 	icr;  
-	u_short 	atdf;  
-	u_short 	mcr;  
-	u_short 	acr;		 
-	u_short 	unack:8,  
-			status:8;	/* all classes */  
-#define UIOLI 0x80  
-#define CRC_APPEND 0x40			/* for status field - CRC-32 append */  
-#define ABR_STATE 0x02  
-  
-};  
-  
-  
-/* 8 byte entries */  
-struct ext_vc 
-{  
-	u_short 	atm_hdr1;  
-	u_short 	atm_hdr2;  
-	u_short 	last_desc;  
-      	u_short 	out_of_rate_link;   /* reserved for UBR and CBR */  
-};  
-  
-  
-#define DLE_ENTRIES 256  
-#define DMA_INT_ENABLE 0x0002	/* use for both Tx and Rx */  
-#define TX_DLE_PSI 0x0001  
-#define DLE_TOTAL_SIZE (sizeof(struct dle)*DLE_ENTRIES)
-  
-/* Descriptor List Entries (DLE) */  
-struct dle 
-{  
-	u32 	sys_pkt_addr;  
-	u32 	local_pkt_addr;  
-	u32 	bytes;  
-	u16 	prq_wr_ptr_data;  
-	u16 	mode;  
-};  
-  
-struct dle_q 
-{  
-	struct dle 	*start;  
-	struct dle 	*end;  
-	struct dle 	*read;  
-	struct dle 	*write;  
-};  
-  
-struct free_desc_q 
-{  
-	int 	desc;	/* Descriptor number */  
-	struct free_desc_q *next;  
-};  
-  
-struct tx_buf_desc {  
-	unsigned short desc_mode;  
-	unsigned short vc_index;  
-	unsigned short res1;		/* reserved field */  
-	unsigned short bytes;  
-	unsigned short buf_start_hi;  
-	unsigned short buf_start_lo;  
-	unsigned short res2[10];	/* reserved field */  
-};  
-	  
-  
-struct rx_buf_desc { 
-	unsigned short desc_mode;
-	unsigned short vc_index;
-	unsigned short vpi; 
-	unsigned short bytes; 
-	unsigned short buf_start_hi;  
-	unsigned short buf_start_lo;  
-	unsigned short dma_start_hi;  
-	unsigned short dma_start_lo;  
-	unsigned short crc_upper;  
-	unsigned short crc_lower;  
-	unsigned short res:8, timeout:8;  
-	unsigned short res2[5];	/* reserved field */  
-};  
-  
-/*--------SAR stuff ---------------------*/  
-  
-#define EPROM_SIZE 0x40000	/* says 64K in the docs ??? */  
-#define MAC1_LEN	4	   					  
-#define MAC2_LEN	2  
-   
-/*------------ PCI Memory Space Map, 128K SAR memory ----------------*/  
-#define IPHASE5575_PCI_CONFIG_REG_BASE	0x0000  
-#define IPHASE5575_BUS_CONTROL_REG_BASE 0x1000	/* offsets 0x00 - 0x3c */  
-#define IPHASE5575_FRAG_CONTROL_REG_BASE 0x2000  
-#define IPHASE5575_REASS_CONTROL_REG_BASE 0x3000  
-#define IPHASE5575_DMA_CONTROL_REG_BASE	0x4000  
-#define IPHASE5575_FRONT_END_REG_BASE IPHASE5575_DMA_CONTROL_REG_BASE  
-#define IPHASE5575_FRAG_CONTROL_RAM_BASE 0x10000  
-#define IPHASE5575_REASS_CONTROL_RAM_BASE 0x20000  
-  
-/*------------ Bus interface control registers -----------------*/  
-#define IPHASE5575_BUS_CONTROL_REG	0x00  
-#define IPHASE5575_BUS_STATUS_REG	0x01	/* actual offset 0x04 */  
-#define IPHASE5575_MAC1			0x02  
-#define IPHASE5575_REV			0x03  
-#define IPHASE5575_MAC2			0x03	/*actual offset 0x0e-reg 0x0c*/  
-#define IPHASE5575_EXT_RESET		0x04  
-#define IPHASE5575_INT_RESET		0x05	/* addr 1c ?? reg 0x06 */  
-#define IPHASE5575_PCI_ADDR_PAGE	0x07	/* reg 0x08, 0x09 ?? */  
-#define IPHASE5575_EEPROM_ACCESS	0x0a	/* actual offset 0x28 */  
-#define IPHASE5575_CELL_FIFO_QUEUE_SZ	0x0b  
-#define IPHASE5575_CELL_FIFO_MARK_STATE	0x0c  
-#define IPHASE5575_CELL_FIFO_READ_PTR	0x0d  
-#define IPHASE5575_CELL_FIFO_WRITE_PTR	0x0e  
-#define IPHASE5575_CELL_FIFO_CELLS_AVL	0x0f	/* actual offset 0x3c */  
-  
-/* Bus Interface Control Register bits */  
-#define CTRL_FE_RST	0x80000000  
-#define CTRL_LED	0x40000000  
-#define CTRL_25MBPHY	0x10000000  
-#define CTRL_ENCMBMEM	0x08000000  
-#define CTRL_ENOFFSEG	0x01000000  
-#define CTRL_ERRMASK	0x00400000  
-#define CTRL_DLETMASK	0x00100000  
-#define CTRL_DLERMASK	0x00080000  
-#define CTRL_FEMASK	0x00040000  
-#define CTRL_SEGMASK	0x00020000  
-#define CTRL_REASSMASK	0x00010000  
-#define CTRL_CSPREEMPT	0x00002000  
-#define CTRL_B128	0x00000200  
-#define CTRL_B64	0x00000100  
-#define CTRL_B48	0x00000080  
-#define CTRL_B32	0x00000040  
-#define CTRL_B16	0x00000020  
-#define CTRL_B8		0x00000010  
-  
-/* Bus Interface Status Register bits */  
-#define STAT_CMEMSIZ	0xc0000000  
-#define STAT_ADPARCK	0x20000000  
-#define STAT_RESVD	0x1fffff80  
-#define STAT_ERRINT	0x00000040  
-#define STAT_MARKINT	0x00000020  
-#define STAT_DLETINT	0x00000010  
-#define STAT_DLERINT	0x00000008  
-#define STAT_FEINT	0x00000004  
-#define STAT_SEGINT	0x00000002  
-#define STAT_REASSINT	0x00000001  
-  
-  
-/*--------------- Segmentation control registers -----------------*/  
-/* The segmentation registers are 16 bits access and the addresses  
-	are defined as such so the addresses are the actual "offsets" */  
-#define IDLEHEADHI	0x00  
-#define IDLEHEADLO	0x01  
-#define MAXRATE		0x02  
-/* Values for MAXRATE register for 155Mbps and 25.6 Mbps operation */  
-#define RATE155		0x64b1 // 16 bits float format 
-#define MAX_ATM_155     352768 // Cells/second p.118
-#define RATE25		0x5f9d  
-  
-#define STPARMS		0x03  
-#define STPARMS_1K	0x008c  
-#define STPARMS_2K	0x0049  
-#define STPARMS_4K	0x0026  
-#define COMP_EN		0x4000  
-#define CBR_EN		0x2000  
-#define ABR_EN		0x0800  
-#define UBR_EN		0x0400  
-  
-#define ABRUBR_ARB	0x04  
-#define RM_TYPE		0x05  
-/*Value for RM_TYPE register for ATM Forum Traffic Mangement4.0 support*/  
-#define RM_TYPE_4_0	0x0100  
-  
-#define SEG_COMMAND_REG		0x17  
-/* Values for the command register */  
-#define RESET_SEG 0x0055  
-#define RESET_SEG_STATE	0x00aa  
-#define RESET_TX_CELL_CTR 0x00cc  
-  
-#define CBR_PTR_BASE	0x20  
-#define ABR_SBPTR_BASE	0x22  
-#define UBR_SBPTR_BASE  0x23  
-#define ABRWQ_BASE	0x26  
-#define UBRWQ_BASE	0x27  
-#define VCT_BASE	0x28  
-#define VCTE_BASE	0x29  
-#define CBR_TAB_BEG	0x2c  
-#define CBR_TAB_END	0x2d  
-#define PRQ_ST_ADR	0x30  
-#define PRQ_ED_ADR	0x31  
-#define PRQ_RD_PTR	0x32  
-#define PRQ_WR_PTR	0x33  
-#define TCQ_ST_ADR	0x34  
-#define TCQ_ED_ADR 	0x35  
-#define TCQ_RD_PTR	0x36  
-#define TCQ_WR_PTR	0x37  
-#define SEG_QUEUE_BASE	0x40  
-#define SEG_DESC_BASE	0x41  
-#define MODE_REG_0	0x45  
-#define T_ONLINE	0x0002		/* (i)chipSAR is online */  
-  
-#define MODE_REG_1	0x46  
-#define MODE_REG_1_VAL	0x0400		/*for propoer device operation*/  
-  
-#define SEG_INTR_STATUS_REG 0x47  
-#define SEG_MASK_REG	0x48  
-#define TRANSMIT_DONE 0x0200
-#define TCQ_NOT_EMPTY 0x1000	/* this can be used for both the interrupt   
-				status registers as well as the mask register */  
-  
-#define CELL_CTR_HIGH_AUTO 0x49  
-#define CELL_CTR_HIGH_NOAUTO 0xc9  
-#define CELL_CTR_LO_AUTO 0x4a  
-#define CELL_CTR_LO_NOAUTO 0xca  
-  
-/* Diagnostic registers */  
-#define NEXTDESC 	0x59  
-#define NEXTVC		0x5a  
-#define PSLOTCNT	0x5d  
-#define NEWDN		0x6a  
-#define NEWVC		0x6b  
-#define SBPTR		0x6c  
-#define ABRWQ_WRPTR	0x6f  
-#define ABRWQ_RDPTR	0x70  
-#define UBRWQ_WRPTR	0x71  
-#define UBRWQ_RDPTR	0x72  
-#define CBR_VC		0x73  
-#define ABR_SBVC	0x75  
-#define UBR_SBVC	0x76  
-#define ABRNEXTLINK	0x78  
-#define UBRNEXTLINK	0x79  
-  
-  
-/*----------------- Reassembly control registers ---------------------*/  
-/* The reassembly registers are 16 bits access and the addresses  
-	are defined as such so the addresses are the actual "offsets" */  
-#define MODE_REG	0x00  
-#define R_ONLINE	0x0002		/* (i)chip is online */  
-#define IGN_RAW_FL     	0x0004
-  
-#define PROTOCOL_ID	0x01  
-#define REASS_MASK_REG	0x02  
-#define REASS_INTR_STATUS_REG	0x03  
-/* Interrupt Status register bits */  
-#define RX_PKT_CTR_OF	0x8000  
-#define RX_ERR_CTR_OF	0x4000  
-#define RX_CELL_CTR_OF	0x1000  
-#define RX_FREEQ_EMPT	0x0200  
-#define RX_EXCPQ_FL	0x0080  
-#define	RX_RAWQ_FL	0x0010  
-#define RX_EXCP_RCVD	0x0008  
-#define RX_PKT_RCVD	0x0004  
-#define RX_RAW_RCVD	0x0001  
-  
-#define DRP_PKT_CNTR	0x04  
-#define ERR_CNTR	0x05  
-#define RAW_BASE_ADR	0x08  
-#define CELL_CTR0	0x0c  
-#define CELL_CTR1	0x0d  
-#define REASS_COMMAND_REG	0x0f  
-/* Values for command register */  
-#define RESET_REASS	0x0055  
-#define RESET_REASS_STATE 0x00aa  
-#define RESET_DRP_PKT_CNTR 0x00f1  
-#define RESET_ERR_CNTR	0x00f2  
-#define RESET_CELL_CNTR 0x00f8  
-#define RESET_REASS_ALL_REGS 0x00ff  
-  
-#define REASS_DESC_BASE	0x10  
-#define VC_LKUP_BASE	0x11  
-#define REASS_TABLE_BASE 0x12  
-#define REASS_QUEUE_BASE 0x13  
-#define PKT_TM_CNT	0x16  
-#define TMOUT_RANGE	0x17  
-#define INTRVL_CNTR	0x18  
-#define TMOUT_INDX	0x19  
-#define VP_LKUP_BASE	0x1c  
-#define VP_FILTER	0x1d  
-#define ABR_LKUP_BASE	0x1e  
-#define FREEQ_ST_ADR	0x24  
-#define FREEQ_ED_ADR	0x25  
-#define FREEQ_RD_PTR	0x26  
-#define FREEQ_WR_PTR	0x27  
-#define PCQ_ST_ADR	0x28  
-#define PCQ_ED_ADR	0x29  
-#define PCQ_RD_PTR	0x2a  
-#define PCQ_WR_PTR	0x2b  
-#define EXCP_Q_ST_ADR	0x2c  
-#define EXCP_Q_ED_ADR	0x2d  
-#define EXCP_Q_RD_PTR	0x2e  
-#define EXCP_Q_WR_PTR	0x2f  
-#define CC_FIFO_ST_ADR	0x34  
-#define CC_FIFO_ED_ADR	0x35  
-#define CC_FIFO_RD_PTR	0x36  
-#define CC_FIFO_WR_PTR	0x37  
-#define STATE_REG	0x38  
-#define BUF_SIZE	0x42  
-#define XTRA_RM_OFFSET	0x44  
-#define DRP_PKT_CNTR_NC	0x84  
-#define ERR_CNTR_NC	0x85  
-#define CELL_CNTR0_NC	0x8c  
-#define CELL_CNTR1_NC	0x8d  
-  
-/* State Register bits */  
-#define EXCPQ_EMPTY	0x0040  
-#define PCQ_EMPTY	0x0010  
-#define FREEQ_EMPTY	0x0004  
-  
-  
-/*----------------- Front End registers/ DMA control --------------*/  
-/* There is a lot of documentation error regarding these offsets ???   
-	eg:- 2 offsets given 800, a00 for rx counter  
-	similarly many others  
-   Remember again that the offsets are to be 4*register number, so  
-	correct the #defines here   
-*/  
-#define IPHASE5575_TX_COUNTER		0x200	/* offset - 0x800 */  
-#define IPHASE5575_RX_COUNTER		0x280	/* offset - 0xa00 */  
-#define IPHASE5575_TX_LIST_ADDR		0x300	/* offset - 0xc00 */  
-#define IPHASE5575_RX_LIST_ADDR		0x380	/* offset - 0xe00 */  
-  
-/*--------------------------- RAM ---------------------------*/  
-/* These memory maps are actually offsets from the segmentation and reassembly  RAM base addresses */  
-  
-/* Segmentation Control Memory map */  
-#define TX_DESC_BASE	0x0000	/* Buffer Decriptor Table */  
-#define TX_COMP_Q	0x1000	/* Transmit Complete Queue */  
-#define PKT_RDY_Q	0x1400	/* Packet Ready Queue */  
-#define CBR_SCHED_TABLE	0x1800	/* CBR Table */  
-#define UBR_SCHED_TABLE	0x3000	/* UBR Table */  
-#define UBR_WAIT_Q	0x4000	/* UBR Wait Queue */  
-#define ABR_SCHED_TABLE	0x5000	/* ABR Table */  
-#define ABR_WAIT_Q	0x5800	/* ABR Wait Queue */  
-#define EXT_VC_TABLE	0x6000	/* Extended VC Table */  
-#define MAIN_VC_TABLE	0x8000	/* Main VC Table */  
-#define SCHEDSZ		1024	/* ABR and UBR Scheduling Table size */  
-#define TX_DESC_TABLE_SZ 128	/* Number of entries in the Transmit   
-					Buffer Descriptor Table */  
-  
-/* These are used as table offsets in Descriptor Table address generation */  
-#define DESC_MODE	0x0  
-#define VC_INDEX	0x1  
-#define BYTE_CNT	0x3  
-#define PKT_START_HI	0x4  
-#define PKT_START_LO	0x5  
-  
-/* Descriptor Mode Word Bits */  
-#define EOM_EN	0x0800  
-#define AAL5	0x0100  
-#define APP_CRC32 0x0400  
-#define CMPL_INT  0x1000
-  
-#define TABLE_ADDRESS(db, dn, to) \
-	(((unsigned long)(db & 0x04)) << 16) | (dn << 5) | (to << 1)  
-  
-/* Reassembly Control Memory Map */  
-#define RX_DESC_BASE	0x0000	/* Buffer Descriptor Table */  
-#define VP_TABLE	0x5c00	/* VP Table */  
-#define EXCEPTION_Q	0x5e00	/* Exception Queue */  
-#define FREE_BUF_DESC_Q	0x6000	/* Free Buffer Descriptor Queue */  
-#define PKT_COMP_Q	0x6800	/* Packet Complete Queue */  
-#define REASS_TABLE	0x7000	/* Reassembly Table */  
-#define RX_VC_TABLE	0x7800	/* VC Table */  
-#define ABR_VC_TABLE	0x8000	/* ABR VC Table */  
-#define RX_DESC_TABLE_SZ 736	/* Number of entries in the Receive   
-					Buffer Descriptor Table */  
-#define VP_TABLE_SZ	256	 /* Number of entries in VPTable */   
-#define RX_VC_TABLE_SZ 	1024	/* Number of entries in VC Table */   
-#define REASS_TABLE_SZ 	1024	/* Number of entries in Reassembly Table */  
- /* Buffer Descriptor Table */  
-#define RX_ACT	0x8000  
-#define RX_VPVC	0x4000  
-#define RX_CNG	0x0040  
-#define RX_CER	0x0008  
-#define RX_PTE	0x0004  
-#define RX_OFL	0x0002  
-#define NUM_RX_EXCP   32
-
-/* Reassembly Table */  
-#define NO_AAL5_PKT	0x0000  
-#define AAL5_PKT_REASSEMBLED 0x4000  
-#define AAL5_PKT_TERMINATED 0x8000  
-#define RAW_PKT		0xc000  
-#define REASS_ABR	0x2000  
-  
-/*-------------------- Base Registers --------------------*/  
-#define REG_BASE IPHASE5575_BUS_CONTROL_REG_BASE  
-#define RAM_BASE IPHASE5575_FRAG_CONTROL_RAM_BASE  
-#define PHY_BASE IPHASE5575_FRONT_END_REG_BASE  
-#define SEG_BASE IPHASE5575_FRAG_CONTROL_REG_BASE  
-#define REASS_BASE IPHASE5575_REASS_CONTROL_REG_BASE  
-
-typedef volatile u_int	ffreg_t;
-typedef u_int   rreg_t;
-
-typedef struct _ffredn_t {
-	ffreg_t	idlehead_high;	/* Idle cell header (high)		*/
-	ffreg_t	idlehead_low;	/* Idle cell header (low)		*/
-	ffreg_t	maxrate;	/* Maximum rate				*/
-	ffreg_t	stparms;	/* Traffic Management Parameters	*/
-	ffreg_t	abrubr_abr;	/* ABRUBR Priority Byte 1, TCR Byte 0	*/
-	ffreg_t	rm_type;	/*					*/
-	u_int	filler5[0x17 - 0x06];
-	ffreg_t	cmd_reg;	/* Command register			*/
-	u_int	filler18[0x20 - 0x18];
-	ffreg_t	cbr_base;	/* CBR Pointer Base			*/
-	ffreg_t	vbr_base;	/* VBR Pointer Base			*/
-	ffreg_t	abr_base;	/* ABR Pointer Base			*/
-	ffreg_t	ubr_base;	/* UBR Pointer Base			*/
-	u_int	filler24;
-	ffreg_t	vbrwq_base;	/* VBR Wait Queue Base			*/
-	ffreg_t	abrwq_base;	/* ABR Wait Queue Base			*/
-	ffreg_t	ubrwq_base;	/* UBR Wait Queue Base			*/
-	ffreg_t	vct_base;	/* Main VC Table Base			*/
-	ffreg_t	vcte_base;	/* Extended Main VC Table Base		*/
-	u_int	filler2a[0x2C - 0x2A];
-	ffreg_t	cbr_tab_beg;	/* CBR Table Begin			*/
-	ffreg_t	cbr_tab_end;	/* CBR Table End			*/
-	ffreg_t	cbr_pointer;	/* CBR Pointer				*/
-	u_int	filler2f[0x30 - 0x2F];
-	ffreg_t	prq_st_adr;	/* Packet Ready Queue Start Address	*/
-	ffreg_t	prq_ed_adr;	/* Packet Ready Queue End Address	*/
-	ffreg_t	prq_rd_ptr;	/* Packet Ready Queue read pointer	*/
-	ffreg_t	prq_wr_ptr;	/* Packet Ready Queue write pointer	*/
-	ffreg_t	tcq_st_adr;	/* Transmit Complete Queue Start Address*/
-	ffreg_t	tcq_ed_adr;	/* Transmit Complete Queue End Address	*/
-	ffreg_t	tcq_rd_ptr;	/* Transmit Complete Queue read pointer */
-	ffreg_t	tcq_wr_ptr;	/* Transmit Complete Queue write pointer*/
-	u_int	filler38[0x40 - 0x38];
-	ffreg_t	queue_base;	/* Base address for PRQ and TCQ		*/
-	ffreg_t	desc_base;	/* Base address of descriptor table	*/
-	u_int	filler42[0x45 - 0x42];
-	ffreg_t	mode_reg_0;	/* Mode register 0			*/
-	ffreg_t	mode_reg_1;	/* Mode register 1			*/
-	ffreg_t	intr_status_reg;/* Interrupt Status register		*/
-	ffreg_t	mask_reg;	/* Mask Register			*/
-	ffreg_t	cell_ctr_high1; /* Total cell transfer count (high)	*/
-	ffreg_t	cell_ctr_lo1;	/* Total cell transfer count (low)	*/
-	ffreg_t	state_reg;	/* Status register			*/
-	u_int	filler4c[0x58 - 0x4c];
-	ffreg_t	curr_desc_num;	/* Contains the current descriptor num	*/
-	ffreg_t	next_desc;	/* Next descriptor			*/
-	ffreg_t	next_vc;	/* Next VC				*/
-	u_int	filler5b[0x5d - 0x5b];
-	ffreg_t	present_slot_cnt;/* Present slot count			*/
-	u_int	filler5e[0x6a - 0x5e];
-	ffreg_t	new_desc_num;	/* New descriptor number		*/
-	ffreg_t	new_vc;		/* New VC				*/
-	ffreg_t	sched_tbl_ptr;	/* Schedule table pointer		*/
-	ffreg_t	vbrwq_wptr;	/* VBR wait queue write pointer		*/
-	ffreg_t	vbrwq_rptr;	/* VBR wait queue read pointer		*/
-	ffreg_t	abrwq_wptr;	/* ABR wait queue write pointer		*/
-	ffreg_t	abrwq_rptr;	/* ABR wait queue read pointer		*/
-	ffreg_t	ubrwq_wptr;	/* UBR wait queue write pointer		*/
-	ffreg_t	ubrwq_rptr;	/* UBR wait queue read pointer		*/
-	ffreg_t	cbr_vc;		/* CBR VC				*/
-	ffreg_t	vbr_sb_vc;	/* VBR SB VC				*/
-	ffreg_t	abr_sb_vc;	/* ABR SB VC				*/
-	ffreg_t	ubr_sb_vc;	/* UBR SB VC				*/
-	ffreg_t	vbr_next_link;	/* VBR next link			*/
-	ffreg_t	abr_next_link;	/* ABR next link			*/
-	ffreg_t	ubr_next_link;	/* UBR next link			*/
-	u_int	filler7a[0x7c-0x7a];
-	ffreg_t	out_rate_head;	/* Out of rate head			*/
-	u_int	filler7d[0xca-0x7d]; /* pad out to full address space	*/
-	ffreg_t	cell_ctr_high1_nc;/* Total cell transfer count (high)	*/
-	ffreg_t	cell_ctr_lo1_nc;/* Total cell transfer count (low)	*/
-	u_int	fillercc[0x100-0xcc]; /* pad out to full address space	 */
-} ffredn_t;
-
-typedef struct _rfredn_t {
-        rreg_t  mode_reg_0;     /* Mode register 0                      */
-        rreg_t  protocol_id;    /* Protocol ID                          */
-        rreg_t  mask_reg;       /* Mask Register                        */
-        rreg_t  intr_status_reg;/* Interrupt status register            */
-        rreg_t  drp_pkt_cntr;   /* Dropped packet cntr (clear on read)  */
-        rreg_t  err_cntr;       /* Error Counter (cleared on read)      */
-        u_int   filler6[0x08 - 0x06];
-        rreg_t  raw_base_adr;   /* Base addr for raw cell Q             */
-        u_int   filler2[0x0c - 0x09];
-        rreg_t  cell_ctr0;      /* Cell Counter 0 (cleared when read)   */
-        rreg_t  cell_ctr1;      /* Cell Counter 1 (cleared when read)   */
-        u_int   filler3[0x0f - 0x0e];
-        rreg_t  cmd_reg;        /* Command register                     */
-        rreg_t  desc_base;      /* Base address for description table   */
-        rreg_t  vc_lkup_base;   /* Base address for VC lookup table     */
-        rreg_t  reass_base;     /* Base address for reassembler table   */
-        rreg_t  queue_base;     /* Base address for Communication queue */
-        u_int   filler14[0x16 - 0x14];
-        rreg_t  pkt_tm_cnt;     /* Packet Timeout and count register    */
-        rreg_t  tmout_range;    /* Range of reassembley IDs for timeout */
-        rreg_t  intrvl_cntr;    /* Packet aging interval counter        */
-        rreg_t  tmout_indx;     /* index of pkt being tested for aging  */
-        u_int   filler1a[0x1c - 0x1a];
-        rreg_t  vp_lkup_base;   /* Base address for VP lookup table     */
-        rreg_t  vp_filter;      /* VP filter register                   */
-        rreg_t  abr_lkup_base;  /* Base address of ABR VC Table         */
-        u_int   filler1f[0x24 - 0x1f];
-        rreg_t  fdq_st_adr;     /* Free desc queue start address        */
-        rreg_t  fdq_ed_adr;     /* Free desc queue end address          */
-        rreg_t  fdq_rd_ptr;     /* Free desc queue read pointer         */
-        rreg_t  fdq_wr_ptr;     /* Free desc queue write pointer        */
-        rreg_t  pcq_st_adr;     /* Packet Complete queue start address  */
-        rreg_t  pcq_ed_adr;     /* Packet Complete queue end address    */
-        rreg_t  pcq_rd_ptr;     /* Packet Complete queue read pointer   */
-        rreg_t  pcq_wr_ptr;     /* Packet Complete queue write pointer  */
-        rreg_t  excp_st_adr;    /* Exception queue start address        */
-        rreg_t  excp_ed_adr;    /* Exception queue end address          */
-        rreg_t  excp_rd_ptr;    /* Exception queue read pointer         */
-        rreg_t  excp_wr_ptr;    /* Exception queue write pointer        */
-        u_int   filler30[0x34 - 0x30];
-        rreg_t  raw_st_adr;     /* Raw Cell start address               */
-        rreg_t  raw_ed_adr;     /* Raw Cell end address                 */
-        rreg_t  raw_rd_ptr;     /* Raw Cell read pointer                */
-        rreg_t  raw_wr_ptr;     /* Raw Cell write pointer               */
-        rreg_t  state_reg;      /* State Register                       */
-        u_int   filler39[0x42 - 0x39];
-        rreg_t  buf_size;       /* Buffer size                          */
-        u_int   filler43;
-        rreg_t  xtra_rm_offset; /* Offset of the additional turnaround RM */
-        u_int   filler45[0x84 - 0x45];
-        rreg_t  drp_pkt_cntr_nc;/* Dropped Packet cntr, Not clear on rd */
-        rreg_t  err_cntr_nc;    /* Error Counter, Not clear on read     */
-        u_int   filler86[0x8c - 0x86];
-        rreg_t  cell_ctr0_nc;   /* Cell Counter 0,  Not clear on read   */
-        rreg_t  cell_ctr1_nc;   /* Cell Counter 1, Not clear on read    */
-        u_int   filler8e[0x100-0x8e]; /* pad out to full address space   */
-} rfredn_t;
-
-typedef struct {
-        /* Atlantic */
-        ffredn_t        ffredn;         /* F FRED                       */
-        rfredn_t        rfredn;         /* R FRED                       */
-} ia_regs_t;
-
-typedef struct {
-	u_short		f_vc_type;	/* VC type              */
-	u_short		f_nrm;		/* Nrm			*/
-	u_short		f_nrmexp;	/* Nrm Exp              */
-	u_short		reserved6;	/* 			*/
-	u_short		f_crm;		/* Crm			*/
-	u_short		reserved10;	/* Reserved		*/
-	u_short		reserved12;	/* Reserved		*/
-	u_short		reserved14;	/* Reserved		*/
-	u_short		last_cell_slot;	/* last_cell_slot_count	*/
-	u_short		f_pcr;		/* Peak Cell Rate	*/
-	u_short		fraction;	/* fraction		*/
-	u_short		f_icr;		/* Initial Cell Rate	*/
-	u_short		f_cdf;		/* */
-	u_short		f_mcr;		/* Minimum Cell Rate	*/
-	u_short		f_acr;		/* Allowed Cell Rate	*/
-	u_short		f_status;	/* */
-} f_vc_abr_entry;
-
-typedef struct {
-        u_short         r_status_rdf;   /* status + RDF         */
-        u_short         r_air;          /* AIR                  */
-        u_short         reserved4[14];  /* Reserved             */
-} r_vc_abr_entry;   
-
-#define MRM 3
-
-typedef struct srv_cls_param {
-        u32 class_type;         /* CBR/VBR/ABR/UBR; use the enum above */
-        u32 pcr;                /* Peak Cell Rate (24-bit) */ 
-        /* VBR parameters */
-        u32 scr;                /* sustainable cell rate */
-        u32 max_burst_size;     /* ?? cell rate or data rate */
- 
-        /* ABR only UNI 4.0 Parameters */
-        u32 mcr;                /* Min Cell Rate (24-bit) */
-        u32 icr;                /* Initial Cell Rate (24-bit) */
-        u32 tbe;                /* Transient Buffer Exposure (24-bit) */
-        u32 frtt;               /* Fixed Round Trip Time (24-bit) */
- 
-#if 0   /* Additional Parameters of TM 4.0 */
-bits  31          30           29          28       27-25 24-22 21-19  18-9
------------------------------------------------------------------------------
-| NRM present | TRM prsnt | CDF prsnt | ADTF prsnt | NRM | TRM | CDF | ADTF |
------------------------------------------------------------------------------
-#endif /* 0 */
- 
-        u8 nrm;                 /* Max # of Cells for each forward RM
-                                        cell (3-bit) */
-        u8 trm;                 /* Time between forward RM cells (3-bit) */
-        u16 adtf;               /* ACR Decrease Time Factor (10-bit) */
-        u8 cdf;                 /* Cutoff Decrease Factor (3-bit) */
-        u8 rif;                 /* Rate Increment Factor (4-bit) */
-        u8 rdf;                 /* Rate Decrease Factor (4-bit) */
-        u8 reserved;            /* 8 bits to keep structure word aligned */
-} srv_cls_param_t;
-
-struct testTable_t {
-	u16 lastTime; 
-	u16 fract; 
-	u8 vc_status;
-}; 
-
-typedef struct {
-	u16 vci;
-	u16 error;
-} RX_ERROR_Q;
-
-typedef struct {
-	u8 active: 1; 
-	u8 abr: 1; 
-	u8 ubr: 1; 
-	u8 cnt: 5;
-#define VC_ACTIVE 	0x01
-#define VC_ABR		0x02
-#define VC_UBR		0x04
-} vcstatus_t;
-  
-struct ia_rfL_t {
-    	u32  fdq_st;     /* Free desc queue start address        */
-        u32  fdq_ed;     /* Free desc queue end address          */
-        u32  fdq_rd;     /* Free desc queue read pointer         */
-        u32  fdq_wr;     /* Free desc queue write pointer        */
-        u32  pcq_st;     /* Packet Complete queue start address  */
-        u32  pcq_ed;     /* Packet Complete queue end address    */
-        u32  pcq_rd;     /* Packet Complete queue read pointer   */
-        u32  pcq_wr;     /* Packet Complete queue write pointer  */ 
-};
-
-struct ia_ffL_t {
-	u32  prq_st;     /* Packet Ready Queue Start Address     */
-        u32  prq_ed;     /* Packet Ready Queue End Address       */
-        u32  prq_wr;     /* Packet Ready Queue write pointer     */
-        u32  tcq_st;     /* Transmit Complete Queue Start Address*/
-        u32  tcq_ed;     /* Transmit Complete Queue End Address  */
-        u32  tcq_rd;     /* Transmit Complete Queue read pointer */
-};
-
-struct desc_tbl_t {
-        u32 timestamp;
-        struct ia_vcc *iavcc;
-        struct sk_buff *txskb;
-}; 
-
-typedef struct ia_rtn_q {
-   struct desc_tbl_t data;
-   struct ia_rtn_q *next, *tail;
-} IARTN_Q;
-
-#define SUNI_LOSV   	0x04
-enum ia_suni {
-	SUNI_MASTER_RESET	= 0x000, /* SUNI Master Reset and Identity   */
-	SUNI_MASTER_CONFIG	= 0x004, /* SUNI Master Configuration        */
-	SUNI_MASTER_INTR_STAT	= 0x008, /* SUNI Master Interrupt Status     */
-	SUNI_RESERVED1		= 0x00c, /* Reserved                         */
-	SUNI_MASTER_CLK_MONITOR	= 0x010, /* SUNI Master Clock Monitor        */
-	SUNI_MASTER_CONTROL	= 0x014, /* SUNI Master Clock Monitor        */
-					 /* Reserved (10)                    */
-	SUNI_RSOP_CONTROL	= 0x040, /* RSOP Control/Interrupt Enable    */
-	SUNI_RSOP_STATUS	= 0x044, /* RSOP Status/Interrupt States     */
-	SUNI_RSOP_SECTION_BIP8L	= 0x048, /* RSOP Section BIP-8 LSB           */
-	SUNI_RSOP_SECTION_BIP8M	= 0x04c, /* RSOP Section BIP-8 MSB           */
-
-	SUNI_TSOP_CONTROL	= 0x050, /* TSOP Control                     */
-	SUNI_TSOP_DIAG		= 0x054, /* TSOP Disgnostics                 */
-					 /* Reserved (2)                     */
-	SUNI_RLOP_CS		= 0x060, /* RLOP Control/Status              */
-	SUNI_RLOP_INTR		= 0x064, /* RLOP Interrupt Enable/Status     */
-	SUNI_RLOP_LINE_BIP24L	= 0x068, /* RLOP Line BIP-24 LSB             */
-	SUNI_RLOP_LINE_BIP24	= 0x06c, /* RLOP Line BIP-24                 */
-	SUNI_RLOP_LINE_BIP24M	= 0x070, /* RLOP Line BIP-24 MSB             */
-	SUNI_RLOP_LINE_FEBEL	= 0x074, /* RLOP Line FEBE LSB               */
-	SUNI_RLOP_LINE_FEBE	= 0x078, /* RLOP Line FEBE                   */
-	SUNI_RLOP_LINE_FEBEM	= 0x07c, /* RLOP Line FEBE MSB               */
-
-	SUNI_TLOP_CONTROL	= 0x080, /* TLOP Control                     */
-	SUNI_TLOP_DISG		= 0x084, /* TLOP Disgnostics                 */
-					 /* Reserved (14)                    */
-	SUNI_RPOP_CS		= 0x0c0, /* RPOP Status/Control              */
-	SUNI_RPOP_INTR		= 0x0c4, /* RPOP Interrupt/Status            */
-	SUNI_RPOP_RESERVED	= 0x0c8, /* RPOP Reserved                    */
-	SUNI_RPOP_INTR_ENA	= 0x0cc, /* RPOP Interrupt Enable            */
-					 /* Reserved (3)                     */
-	SUNI_RPOP_PATH_SIG	= 0x0dc, /* RPOP Path Signal Label           */
-	SUNI_RPOP_BIP8L		= 0x0e0, /* RPOP Path BIP-8 LSB              */
-	SUNI_RPOP_BIP8M		= 0x0e4, /* RPOP Path BIP-8 MSB              */
-	SUNI_RPOP_FEBEL		= 0x0e8, /* RPOP Path FEBE LSB               */
-	SUNI_RPOP_FEBEM		= 0x0ec, /* RPOP Path FEBE MSB               */
-					 /* Reserved (4)                     */
-	SUNI_TPOP_CNTRL_DAIG	= 0x100, /* TPOP Control/Disgnostics         */
-	SUNI_TPOP_POINTER_CTRL	= 0x104, /* TPOP Pointer Control             */
-	SUNI_TPOP_SOURCER_CTRL	= 0x108, /* TPOP Source Control              */
-					 /* Reserved (2)                     */
-	SUNI_TPOP_ARB_PRTL	= 0x114, /* TPOP Arbitrary Pointer LSB       */
-	SUNI_TPOP_ARB_PRTM	= 0x118, /* TPOP Arbitrary Pointer MSB       */
-	SUNI_TPOP_RESERVED2	= 0x11c, /* TPOP Reserved                    */
-	SUNI_TPOP_PATH_SIG	= 0x120, /* TPOP Path Signal Lable           */
-	SUNI_TPOP_PATH_STATUS	= 0x124, /* TPOP Path Status                 */
-					 /* Reserved (6)                     */
-	SUNI_RACP_CS		= 0x140, /* RACP Control/Status              */
-	SUNI_RACP_INTR		= 0x144, /* RACP Interrupt Enable/Status     */
-	SUNI_RACP_HDR_PATTERN	= 0x148, /* RACP Match Header Pattern        */
-	SUNI_RACP_HDR_MASK	= 0x14c, /* RACP Match Header Mask           */
-	SUNI_RACP_CORR_HCS	= 0x150, /* RACP Correctable HCS Error Count */
-	SUNI_RACP_UNCORR_HCS	= 0x154, /* RACP Uncorrectable HCS Err Count */
-					 /* Reserved (10)                    */
-	SUNI_TACP_CONTROL	= 0x180, /* TACP Control                     */
-	SUNI_TACP_IDLE_HDR_PAT	= 0x184, /* TACP Idle Cell Header Pattern    */
-	SUNI_TACP_IDLE_PAY_PAY	= 0x188, /* TACP Idle Cell Payld Octet Patrn */
-					 /* Reserved (5)                     */
-					 /* Reserved (24)                    */
-	/* FIXME: unused but name conflicts.
-	 * SUNI_MASTER_TEST	= 0x200,    SUNI Master Test                 */
-	SUNI_RESERVED_TEST	= 0x204  /* SUNI Reserved for Test           */
-};
-
-typedef struct _SUNI_STATS_
-{
-   u32 valid;                       // 1 = oc3 PHY card
-   u32 carrier_detect;              // GPIN input
-   // RSOP: receive section overhead processor
-   u16 rsop_oof_state;              // 1 = out of frame
-   u16 rsop_lof_state;              // 1 = loss of frame
-   u16 rsop_los_state;              // 1 = loss of signal
-   u32 rsop_los_count;              // loss of signal count
-   u32 rsop_bse_count;              // section BIP-8 error count
-   // RLOP: receive line overhead processor
-   u16 rlop_ferf_state;             // 1 = far end receive failure
-   u16 rlop_lais_state;             // 1 = line AIS
-   u32 rlop_lbe_count;              // BIP-24 count
-   u32 rlop_febe_count;             // FEBE count;
-   // RPOP: receive path overhead processor
-   u16 rpop_lop_state;              // 1 = LOP
-   u16 rpop_pais_state;             // 1 = path AIS
-   u16 rpop_pyel_state;             // 1 = path yellow alert
-   u32 rpop_bip_count;              // path BIP-8 error count
-   u32 rpop_febe_count;             // path FEBE error count
-   u16 rpop_psig;                   // path signal label value
-   // RACP: receive ATM cell processor
-   u16 racp_hp_state;               // hunt/presync state
-   u32 racp_fu_count;               // FIFO underrun count
-   u32 racp_fo_count;               // FIFO overrun count
-   u32 racp_chcs_count;             // correctable HCS error count
-   u32 racp_uchcs_count;            // uncorrectable HCS error count
-} IA_SUNI_STATS; 
-
-typedef struct iadev_priv {
-	/*-----base pointers into (i)chipSAR+ address space */   
-	u32 __iomem *phy;	/* Base pointer into phy (SUNI). */
-	u32 __iomem *dma;	/* Base pointer into DMA control registers. */
-	u32 __iomem *reg;	/* Base pointer to SAR registers. */
-	u32 __iomem *seg_reg;		/* base pointer to segmentation engine  
-						internal registers */  
-	u32 __iomem *reass_reg;		/* base pointer to reassemble engine  
-						internal registers */  
-	u32 __iomem *ram;		/* base pointer to SAR RAM */  
-	void __iomem *seg_ram;  
-	void __iomem *reass_ram;  
-	struct dle_q tx_dle_q;  
-	struct free_desc_q *tx_free_desc_qhead;  
-	struct sk_buff_head tx_dma_q, tx_backlog;  
-        spinlock_t            tx_lock;
-        IARTN_Q               tx_return_q;
-        u32                   close_pending;
-        wait_queue_head_t    close_wait;
-        wait_queue_head_t    timeout_wait;
-	struct cpcs_trailer_desc *tx_buf;
-        u16 num_tx_desc, tx_buf_sz, rate_limit;
-        u32 tx_cell_cnt, tx_pkt_cnt;
-        void __iomem *MAIN_VC_TABLE_ADDR, *EXT_VC_TABLE_ADDR, *ABR_SCHED_TABLE_ADDR;
-	struct dle_q rx_dle_q;  
-	struct free_desc_q *rx_free_desc_qhead;  
-	struct sk_buff_head rx_dma_q;  
-	spinlock_t rx_lock;
-	struct atm_vcc **rx_open;	/* list of all open VCs */  
-        u16 num_rx_desc, rx_buf_sz, rxing;
-        u32 rx_pkt_ram, rx_tmp_cnt;
-        unsigned long rx_tmp_jif;
-        void __iomem *RX_DESC_BASE_ADDR;
-        u32 drop_rxpkt, drop_rxcell, rx_cell_cnt, rx_pkt_cnt;
-	struct atm_dev *next_board;	/* other iphase devices */  
-	struct pci_dev *pci;  
-	int mem;  
-	unsigned int real_base;	/* real and virtual base address */  
-	void __iomem *base;
-	unsigned int pci_map_size;	/*pci map size of board */  
-	unsigned char irq;  
-	unsigned char bus;  
-	unsigned char dev_fn;  
-        u_short  phy_type;
-        u_short  num_vc, memSize, memType;
-        struct ia_ffL_t ffL;
-        struct ia_rfL_t rfL;
-        /* Suni stat */
-        // IA_SUNI_STATS suni_stats;
-        unsigned char carrier_detect;
-        /* CBR related */
-        // transmit DMA & Receive
-        unsigned int tx_dma_cnt;     // number of elements on dma queue
-        unsigned int rx_dma_cnt;     // number of elements on rx dma queue
-        unsigned int NumEnabledCBR;  // number of CBR VCI's enabled.     CBR
-        // receive MARK  for Cell FIFO
-        unsigned int rx_mark_cnt;    // number of elements on mark queue
-        unsigned int CbrTotEntries;  // Total CBR Entries in Scheduling Table.
-        unsigned int CbrRemEntries;  // Remaining CBR Entries in Scheduling Table.
-        unsigned int CbrEntryPt;     // CBR Sched Table Entry Point.
-        unsigned int Granularity;    // CBR Granularity given Table Size.
-        /* ABR related */
-	unsigned int  sum_mcr, sum_cbr, LineRate;
-	unsigned int  n_abr;
-        struct desc_tbl_t *desc_tbl;
-        u_short host_tcq_wr;
-        struct testTable_t **testTable;
-	dma_addr_t tx_dle_dma;
-	dma_addr_t rx_dle_dma;
-} IADEV;
-  
-  
-#define INPH_IA_DEV(d) ((IADEV *) (d)->dev_data)  
-#define INPH_IA_VCC(v) ((struct ia_vcc *) (v)->dev_data)  
-
-/******************* IDT77105 25MB/s PHY DEFINE *****************************/
-enum ia_mb25 {
-	MB25_MASTER_CTRL	= 0x00, /* Master control		     */
-	MB25_INTR_STATUS	= 0x04,	/* Interrupt status		     */
-	MB25_DIAG_CONTROL	= 0x08,	/* Diagnostic control		     */
-	MB25_LED_HEC		= 0x0c,	/* LED driver and HEC status/control */
-	MB25_LOW_BYTE_COUNTER	= 0x10,
-	MB25_HIGH_BYTE_COUNTER	= 0x14
-};
-
-/*
- * Master Control
- */
-#define	MB25_MC_UPLO	0x80		/* UPLO				     */
-#define	MB25_MC_DREC	0x40		/* Discard receive cell errors	     */
-#define	MB25_MC_ECEIO	0x20		/* Enable Cell Error Interrupts Only */
-#define	MB25_MC_TDPC	0x10		/* Transmit data parity check	     */
-#define	MB25_MC_DRIC	0x08		/* Discard receive idle cells	     */
-#define	MB25_MC_HALTTX	0x04		/* Halt Tx			     */
-#define	MB25_MC_UMS	0x02		/* UTOPIA mode select		     */
-#define	MB25_MC_ENABLED	0x01		/* Enable interrupt		     */
-
-/*
- * Interrupt Status
- */
-#define	MB25_IS_GSB	0x40		/* GOOD Symbol Bit		     */	
-#define	MB25_IS_HECECR	0x20		/* HEC error cell received	     */
-#define	MB25_IS_SCR	0x10		/* "Short Cell" Received	     */
-#define	MB25_IS_TPE	0x08		/* Trnamsit Parity Error	     */
-#define	MB25_IS_RSCC	0x04		/* Receive Signal Condition change   */
-#define	MB25_IS_RCSE	0x02		/* Received Cell Symbol Error	     */
-#define	MB25_IS_RFIFOO	0x01		/* Received FIFO Overrun	     */
-
-/*
- * Diagnostic Control
- */
-#define	MB25_DC_FTXCD	0x80		/* Force TxClav deassert	     */	
-#define	MB25_DC_RXCOS	0x40		/* RxClav operation select	     */
-#define	MB25_DC_ECEIO	0x20		/* Single/Multi-PHY config select    */
-#define	MB25_DC_RLFLUSH	0x10		/* Clear receive FIFO		     */
-#define	MB25_DC_IXPE	0x08		/* Insert xmit payload error	     */
-#define	MB25_DC_IXHECE	0x04		/* Insert Xmit HEC Error	     */
-#define	MB25_DC_LB_MASK	0x03		/* Loopback control mask	     */
-
-#define	MB25_DC_LL	0x03		/* Line Loopback		     */
-#define	MB25_DC_PL	0x02		/* PHY Loopback			     */
-#define	MB25_DC_NM	0x00		
-
-#define FE_MASK 	0x00F0
-#define FE_MULTI_MODE	0x0000
-#define FE_SINGLE_MODE  0x0010 
-#define FE_UTP_OPTION  	0x0020
-#define FE_25MBIT_PHY	0x0040
-#define FE_DS3_PHY      0x0080          /* DS3 */
-#define FE_E3_PHY       0x0090          /* E3 */
-		     
-/*********************** SUNI_PM7345 PHY DEFINE HERE *********************/
-enum suni_pm7345 {
-	SUNI_CONFIG			= 0x000, /* SUNI Configuration */
-	SUNI_INTR_ENBL			= 0x004, /* SUNI Interrupt Enable */
-	SUNI_INTR_STAT			= 0x008, /* SUNI Interrupt Status */
-	SUNI_CONTROL			= 0x00c, /* SUNI Control */
-	SUNI_ID_RESET			= 0x010, /* SUNI Reset and Identity */
-	SUNI_DATA_LINK_CTRL		= 0x014,
-	SUNI_RBOC_CONF_INTR_ENBL	= 0x018,
-	SUNI_RBOC_STAT			= 0x01c,
-	SUNI_DS3_FRM_CFG		= 0x020,
-	SUNI_DS3_FRM_INTR_ENBL		= 0x024,
-	SUNI_DS3_FRM_INTR_STAT		= 0x028,
-	SUNI_DS3_FRM_STAT		= 0x02c,
-	SUNI_RFDL_CFG			= 0x030,
-	SUNI_RFDL_ENBL_STAT		= 0x034,
-	SUNI_RFDL_STAT			= 0x038,
-	SUNI_RFDL_DATA			= 0x03c,
-	SUNI_PMON_CHNG			= 0x040,
-	SUNI_PMON_INTR_ENBL_STAT	= 0x044,
-	/* SUNI_RESERVED1 (0x13 - 0x11) */
-	SUNI_PMON_LCV_EVT_CNT_LSB	= 0x050,
-	SUNI_PMON_LCV_EVT_CNT_MSB	= 0x054,
-	SUNI_PMON_FBE_EVT_CNT_LSB	= 0x058,
-	SUNI_PMON_FBE_EVT_CNT_MSB	= 0x05c,
-	SUNI_PMON_SEZ_DET_CNT_LSB	= 0x060,
-	SUNI_PMON_SEZ_DET_CNT_MSB	= 0x064,
-	SUNI_PMON_PE_EVT_CNT_LSB	= 0x068,
-	SUNI_PMON_PE_EVT_CNT_MSB	= 0x06c,
-	SUNI_PMON_PPE_EVT_CNT_LSB	= 0x070,
-	SUNI_PMON_PPE_EVT_CNT_MSB	= 0x074,
-	SUNI_PMON_FEBE_EVT_CNT_LSB	= 0x078,
-	SUNI_PMON_FEBE_EVT_CNT_MSB	= 0x07c,
-	SUNI_DS3_TRAN_CFG		= 0x080,
-	SUNI_DS3_TRAN_DIAG		= 0x084,
-	/* SUNI_RESERVED2 (0x23 - 0x21) */
-	SUNI_XFDL_CFG			= 0x090,
-	SUNI_XFDL_INTR_ST		= 0x094,
-	SUNI_XFDL_XMIT_DATA		= 0x098,
-	SUNI_XBOC_CODE			= 0x09c,
-	SUNI_SPLR_CFG			= 0x0a0,
-	SUNI_SPLR_INTR_EN		= 0x0a4,
-	SUNI_SPLR_INTR_ST		= 0x0a8,
-	SUNI_SPLR_STATUS		= 0x0ac,
-	SUNI_SPLT_CFG			= 0x0b0,
-	SUNI_SPLT_CNTL			= 0x0b4,
-	SUNI_SPLT_DIAG_G1		= 0x0b8,
-	SUNI_SPLT_F1			= 0x0bc,
-	SUNI_CPPM_LOC_METERS		= 0x0c0,
-	SUNI_CPPM_CHG_OF_CPPM_PERF_METR	= 0x0c4,
-	SUNI_CPPM_B1_ERR_CNT_LSB	= 0x0c8,
-	SUNI_CPPM_B1_ERR_CNT_MSB	= 0x0cc,
-	SUNI_CPPM_FRAMING_ERR_CNT_LSB	= 0x0d0,
-	SUNI_CPPM_FRAMING_ERR_CNT_MSB	= 0x0d4,
-	SUNI_CPPM_FEBE_CNT_LSB		= 0x0d8,
-	SUNI_CPPM_FEBE_CNT_MSB		= 0x0dc,
-	SUNI_CPPM_HCS_ERR_CNT_LSB	= 0x0e0,
-	SUNI_CPPM_HCS_ERR_CNT_MSB	= 0x0e4,
-	SUNI_CPPM_IDLE_UN_CELL_CNT_LSB	= 0x0e8,
-	SUNI_CPPM_IDLE_UN_CELL_CNT_MSB	= 0x0ec,
-	SUNI_CPPM_RCV_CELL_CNT_LSB	= 0x0f0,
-	SUNI_CPPM_RCV_CELL_CNT_MSB	= 0x0f4,
-	SUNI_CPPM_XMIT_CELL_CNT_LSB	= 0x0f8,
-	SUNI_CPPM_XMIT_CELL_CNT_MSB	= 0x0fc,
-	SUNI_RXCP_CTRL			= 0x100,
-	SUNI_RXCP_FCTRL			= 0x104,
-	SUNI_RXCP_INTR_EN_STS		= 0x108,
-	SUNI_RXCP_IDLE_PAT_H1		= 0x10c,
-	SUNI_RXCP_IDLE_PAT_H2		= 0x110,
-	SUNI_RXCP_IDLE_PAT_H3		= 0x114,
-	SUNI_RXCP_IDLE_PAT_H4		= 0x118,
-	SUNI_RXCP_IDLE_MASK_H1		= 0x11c,
-	SUNI_RXCP_IDLE_MASK_H2		= 0x120,
-	SUNI_RXCP_IDLE_MASK_H3		= 0x124,
-	SUNI_RXCP_IDLE_MASK_H4		= 0x128,
-	SUNI_RXCP_CELL_PAT_H1		= 0x12c,
-	SUNI_RXCP_CELL_PAT_H2		= 0x130,
-	SUNI_RXCP_CELL_PAT_H3		= 0x134,
-	SUNI_RXCP_CELL_PAT_H4		= 0x138,
-	SUNI_RXCP_CELL_MASK_H1		= 0x13c,
-	SUNI_RXCP_CELL_MASK_H2		= 0x140,
-	SUNI_RXCP_CELL_MASK_H3		= 0x144,
-	SUNI_RXCP_CELL_MASK_H4		= 0x148,
-	SUNI_RXCP_HCS_CS		= 0x14c,
-	SUNI_RXCP_LCD_CNT_THRESHOLD	= 0x150,
-	/* SUNI_RESERVED3 (0x57 - 0x54) */
-	SUNI_TXCP_CTRL			= 0x160,
-	SUNI_TXCP_INTR_EN_STS		= 0x164,
-	SUNI_TXCP_IDLE_PAT_H1		= 0x168,
-	SUNI_TXCP_IDLE_PAT_H2		= 0x16c,
-	SUNI_TXCP_IDLE_PAT_H3		= 0x170,
-	SUNI_TXCP_IDLE_PAT_H4		= 0x174,
-	SUNI_TXCP_IDLE_PAT_H5		= 0x178,
-	SUNI_TXCP_IDLE_PAYLOAD		= 0x17c,
-	SUNI_E3_FRM_FRAM_OPTIONS	= 0x180,
-	SUNI_E3_FRM_MAINT_OPTIONS	= 0x184,
-	SUNI_E3_FRM_FRAM_INTR_ENBL	= 0x188,
-	SUNI_E3_FRM_FRAM_INTR_IND_STAT	= 0x18c,
-	SUNI_E3_FRM_MAINT_INTR_ENBL	= 0x190,
-	SUNI_E3_FRM_MAINT_INTR_IND	= 0x194,
-	SUNI_E3_FRM_MAINT_STAT		= 0x198,
-	SUNI_RESERVED4			= 0x19c,
-	SUNI_E3_TRAN_FRAM_OPTIONS	= 0x1a0,
-	SUNI_E3_TRAN_STAT_DIAG_OPTIONS	= 0x1a4,
-	SUNI_E3_TRAN_BIP_8_ERR_MASK	= 0x1a8,
-	SUNI_E3_TRAN_MAINT_ADAPT_OPTS	= 0x1ac,
-	SUNI_TTB_CTRL			= 0x1b0,
-	SUNI_TTB_TRAIL_TRACE_ID_STAT	= 0x1b4,
-	SUNI_TTB_IND_ADDR		= 0x1b8,
-	SUNI_TTB_IND_DATA		= 0x1bc,
-	SUNI_TTB_EXP_PAYLOAD_TYPE	= 0x1c0,
-	SUNI_TTB_PAYLOAD_TYPE_CTRL_STAT	= 0x1c4,
-	/* SUNI_PAD5 (0x7f - 0x71) */
-	SUNI_MASTER_TEST		= 0x200,
-	/* SUNI_PAD6 (0xff - 0x80) */
-};
-
-#define SUNI_PM7345_T suni_pm7345_t
-#define SUNI_PM7345     0x20            /* Suni chip type */
-#define SUNI_PM5346     0x30            /* Suni chip type */
-/*
- * SUNI_PM7345 Configuration
- */
-#define SUNI_PM7345_CLB         0x01    /* Cell loopback        */
-#define SUNI_PM7345_PLB         0x02    /* Payload loopback     */
-#define SUNI_PM7345_DLB         0x04    /* Diagnostic loopback  */
-#define SUNI_PM7345_LLB         0x80    /* Line loopback        */
-#define SUNI_PM7345_E3ENBL      0x40    /* E3 enable bit        */
-#define SUNI_PM7345_LOOPT       0x10    /* LOOPT enable bit     */
-#define SUNI_PM7345_FIFOBP      0x20    /* FIFO bypass          */
-#define SUNI_PM7345_FRMRBP      0x08    /* Framer bypass        */
-/*
- * DS3 FRMR Interrupt Enable
- */
-#define SUNI_DS3_COFAE  0x80            /* Enable change of frame align */
-#define SUNI_DS3_REDE   0x40            /* Enable DS3 RED state intr    */
-#define SUNI_DS3_CBITE  0x20            /* Enable Appl ID channel intr  */
-#define SUNI_DS3_FERFE  0x10            /* Enable Far End Receive Failure intr*/
-#define SUNI_DS3_IDLE   0x08            /* Enable Idle signal intr      */
-#define SUNI_DS3_AISE   0x04            /* Enable Alarm Indication signal intr*/
-#define SUNI_DS3_OOFE   0x02            /* Enable Out of frame intr     */
-#define SUNI_DS3_LOSE   0x01            /* Enable Loss of signal intr   */
- 
-/*
- * DS3 FRMR Status
- */
-#define SUNI_DS3_ACE    0x80            /* Additional Configuration Reg */
-#define SUNI_DS3_REDV   0x40            /* DS3 RED state                */
-#define SUNI_DS3_CBITV  0x20            /* Application ID channel state */
-#define SUNI_DS3_FERFV  0x10            /* Far End Receive Failure state*/
-#define SUNI_DS3_IDLV   0x08            /* Idle signal state            */
-#define SUNI_DS3_AISV   0x04            /* Alarm Indication signal state*/
-#define SUNI_DS3_OOFV   0x02            /* Out of frame state           */
-#define SUNI_DS3_LOSV   0x01            /* Loss of signal state         */
-
-/*
- * E3 FRMR Interrupt/Status
- */
-#define SUNI_E3_CZDI    0x40            /* Consecutive Zeros indicator  */
-#define SUNI_E3_LOSI    0x20            /* Loss of signal intr status   */
-#define SUNI_E3_LCVI    0x10            /* Line code violation intr     */
-#define SUNI_E3_COFAI   0x08            /* Change of frame align intr   */
-#define SUNI_E3_OOFI    0x04            /* Out of frame intr status     */
-#define SUNI_E3_LOS     0x02            /* Loss of signal state         */
-#define SUNI_E3_OOF     0x01            /* Out of frame state           */
-
-/*
- * E3 FRMR Maintenance Status
- */
-#define SUNI_E3_AISD    0x80            /* Alarm Indication signal state*/
-#define SUNI_E3_FERF_RAI        0x40    /* FERF/RAI indicator           */
-#define SUNI_E3_FEBE    0x20            /* Far End Block Error indicator*/
-
-/*
- * RXCP Control/Status
- */
-#define SUNI_DS3_HCSPASS        0x80    /* Pass cell with HEC errors    */
-#define SUNI_DS3_HCSDQDB        0x40    /* Control octets in HCS calc   */
-#define SUNI_DS3_HCSADD         0x20    /* Add coset poly               */
-#define SUNI_DS3_HCK            0x10    /* Control FIFO data path integ chk*/
-#define SUNI_DS3_BLOCK          0x08    /* Enable cell filtering        */
-#define SUNI_DS3_DSCR           0x04    /* Disable payload descrambling */
-#define SUNI_DS3_OOCDV          0x02    /* Cell delineation state       */
-#define SUNI_DS3_FIFORST        0x01    /* Cell FIFO reset              */
-
-/*
- * RXCP Interrupt Enable/Status
- */
-#define SUNI_DS3_OOCDE  0x80            /* Intr enable, change in CDS   */
-#define SUNI_DS3_HCSE   0x40            /* Intr enable, corr HCS errors */
-#define SUNI_DS3_FIFOE  0x20            /* Intr enable, unco HCS errors */
-#define SUNI_DS3_OOCDI  0x10            /* SYNC state                   */
-#define SUNI_DS3_UHCSI  0x08            /* Uncorr. HCS errors detected  */
-#define SUNI_DS3_COCAI  0x04            /* Corr. HCS errors detected    */
-#define SUNI_DS3_FOVRI  0x02            /* FIFO overrun                 */
-#define SUNI_DS3_FUDRI  0x01            /* FIFO underrun                */
-
-///////////////////SUNI_PM7345 PHY DEFINE END /////////////////////////////
-
-/* ia_eeprom define*/
-#define MEM_SIZE_MASK   0x000F          /* mask of 4 bits defining memory size*/
-#define MEM_SIZE_128K   0x0000          /* board has 128k buffer */
-#define MEM_SIZE_512K   0x0001          /* board has 512K of buffer */
-#define MEM_SIZE_1M     0x0002          /* board has 1M of buffer */
-                                        /* 0x3 to 0xF are reserved for future */
-
-#define FE_MASK         0x00F0          /* mask of 4 bits defining FE type */
-#define FE_MULTI_MODE   0x0000          /* 155 MBit multimode fiber */
-#define FE_SINGLE_MODE  0x0010          /* 155 MBit single mode laser */
-#define FE_UTP_OPTION   0x0020          /* 155 MBit UTP front end */
-
-#define	NOVRAM_SIZE	64
-#define	CMD_LEN		10
-
-/***********
- *
- *	Switches and defines for header files.
- *
- *	The following defines are used to turn on and off
- *	various options in the header files. Primarily useful
- *	for debugging.
- *
- ***********/
-
-/*
- * a list of the commands that can be sent to the NOVRAM
- */
-
-#define	EXTEND	0x100
-#define	IAWRITE	0x140
-#define	IAREAD	0x180
-#define	ERASE	0x1c0
-
-#define	EWDS	0x00
-#define	WRAL	0x10
-#define	ERAL	0x20
-#define	EWEN	0x30
-
-/*
- * these bits duplicate the hw_flip.h register settings
- * note: how the data in / out bits are defined in the flipper specification 
- */
-
-#define	NVCE	0x02
-#define	NVSK	0x01
-#define	NVDO	0x08	
-#define NVDI	0x04
-/***********************
- *
- * This define ands the value and the current config register and puts
- * the result in the config register
- *
- ***********************/
-
-#define	CFG_AND(val) { \
-		u32 t; \
-		t = readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); \
-		t &= (val); \
-		writel(t, iadev->reg+IPHASE5575_EEPROM_ACCESS); \
-	}
-
-/***********************
- *
- * This define ors the value and the current config register and puts
- * the result in the config register
- *
- ***********************/
-
-#define	CFG_OR(val) { \
-		u32 t; \
-		t =  readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); \
-		t |= (val); \
-		writel(t, iadev->reg+IPHASE5575_EEPROM_ACCESS); \
-	}
-
-/***********************
- *
- * Send a command to the NOVRAM, the command is in cmd.
- *
- * clear CE and SK. Then assert CE.
- * Clock each of the command bits out in the correct order with SK
- * exit with CE still asserted
- *
- ***********************/
-
-#define	NVRAM_CMD(cmd) { \
-		int	i; \
-		u_short c = cmd; \
-		CFG_AND(~(NVCE|NVSK)); \
-		CFG_OR(NVCE); \
-		for (i=0; i<CMD_LEN; i++) { \
-			NVRAM_CLKOUT((c & (1 << (CMD_LEN - 1))) ? 1 : 0); \
-			c <<= 1; \
-		} \
-	}
-
-/***********************
- *
- * clear the CE, this must be used after each command is complete
- *
- ***********************/
-
-#define	NVRAM_CLR_CE	{CFG_AND(~NVCE)}
-
-/***********************
- *
- * clock the data bit in bitval out to the NOVRAM.  The bitval must be
- * a 1 or 0, or the clockout operation is undefined
- *
- ***********************/
-
-#define	NVRAM_CLKOUT(bitval) { \
-		CFG_AND(~NVDI); \
-		CFG_OR((bitval) ? NVDI : 0); \
-		CFG_OR(NVSK); \
-		CFG_AND( ~NVSK); \
-	}
-
-/***********************
- *
- * clock the data bit in and return a 1 or 0, depending on the value
- * that was received from the NOVRAM
- *
- ***********************/
-
-#define	NVRAM_CLKIN(value) { \
-		u32 _t; \
-		CFG_OR(NVSK); \
-		CFG_AND(~NVSK); \
-		_t = readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); \
-		value = (_t & NVDO) ? 1 : 0; \
-	}
-
-
-#endif /* IPHASE_H */
diff --git a/drivers/atm/midway.h b/drivers/atm/midway.h
deleted file mode 100644
index d47307adc0c9..000000000000
--- a/drivers/atm/midway.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* drivers/atm/midway.h - Efficient Networks Midway (SAR) description */
- 
-/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */
- 
-
-#ifndef DRIVERS_ATM_MIDWAY_H
-#define DRIVERS_ATM_MIDWAY_H
-
-
-#define NR_VCI		1024		/* number of VCIs */
-#define NR_VCI_LD	10		/* log2(NR_VCI) */
-#define NR_DMA_RX	512		/* RX DMA queue entries */
-#define NR_DMA_TX	512		/* TX DMA queue entries */
-#define NR_SERVICE	NR_VCI		/* service list size */
-#define NR_CHAN		8		/* number of TX channels */
-#define TS_CLOCK	25000000	/* traffic shaper clock (cell/sec) */
-
-#define MAP_MAX_SIZE	0x00400000	/* memory window for max config */
-#define EPROM_SIZE	0x00010000
-#define	MEM_VALID	0xffc00000	/* mask base address with this */
-#define PHY_BASE	0x00020000	/* offset of PHY register are */
-#define REG_BASE	0x00040000	/* offset of Midway register area */
-#define RAM_BASE	0x00200000	/* offset of RAM area */
-#define RAM_INCREMENT	0x00020000	/* probe for RAM every 128kB */
-
-#define MID_VCI_BASE	RAM_BASE
-#define MID_DMA_RX_BASE	(MID_VCI_BASE+NR_VCI*16)
-#define MID_DMA_TX_BASE	(MID_DMA_RX_BASE+NR_DMA_RX*8)
-#define MID_SERVICE_BASE (MID_DMA_TX_BASE+NR_DMA_TX*8)
-#define MID_FREE_BASE	(MID_SERVICE_BASE+NR_SERVICE*4)
-
-#define MAC_LEN 6 /* atm.h */
-
-#define MID_MIN_BUF_SIZE (1024)		/*   1 kB is minimum */
-#define MID_MAX_BUF_SIZE (128*1024)	/* 128 kB is maximum */
-
-#define RX_DESCR_SIZE	1		/* RX PDU descr is 1 longword */
-#define TX_DESCR_SIZE	2		/* TX PDU descr is 2 longwords */
-#define AAL5_TRAILER	(ATM_AAL5_TRAILER/4) /* AAL5 trailer is 2 longwords */
-
-#define TX_GAP		8		/* TX buffer gap (words) */
-
-/*
- * Midway Reset/ID
- *
- * All values read-only. Writing to this register resets Midway chip.
- */
-
-#define MID_RES_ID_MCON	0x00		/* Midway Reset/ID */
-
-#define MID_ID		0xf0000000	/* Midway version */
-#define MID_SHIFT	24
-#define MID_MOTHER_ID	0x00000700	/* mother board id */
-#define MID_MOTHER_SHIFT 8
-#define MID_CON_TI	0x00000080	/* 0: normal ctrl; 1: SABRE */
-#define MID_CON_SUNI	0x00000040	/* 0: UTOPIA; 1: SUNI */
-#define MID_CON_V6	0x00000020	/* 0: non-pipel UTOPIA (required iff
-					   !CON_SUNI; 1: UTOPIA */
-#define DAUGHTER_ID	0x0000001f	/* daughter board id */
-
-/*
- * Interrupt Status Acknowledge, Interrupt Status & Interrupt Enable
- */
-
-#define MID_ISA		0x01		/* Interrupt Status Acknowledge */
-#define MID_IS		0x02		/* Interrupt Status */
-#define MID_IE		0x03		/* Interrupt Enable */
-
-#define MID_TX_COMPLETE_7 0x00010000	/* channel N completed a PDU */
-#define MID_TX_COMPLETE_6 0x00008000	/* transmission */
-#define MID_TX_COMPLETE_5 0x00004000
-#define MID_TX_COMPLETE_4 0x00002000
-#define MID_TX_COMPLETE_3 0x00001000
-#define MID_TX_COMPLETE_2 0x00000800
-#define MID_TX_COMPLETE_1 0x00000400
-#define MID_TX_COMPLETE_0 0x00000200
-#define MID_TX_COMPLETE	0x0001fe00	/* any TX */
-#define MID_TX_DMA_OVFL	0x00000100	/* DMA to adapter overflow */
-#define MID_TX_IDENT_MISM 0x00000080	/* TX: ident mismatch => halted */
-#define MID_DMA_LERR_ACK 0x00000040	/* LERR - SBus ? */
-#define MID_DMA_ERR_ACK	0x00000020	/* DMA error */
-#define	MID_RX_DMA_COMPLETE 0x00000010	/* DMA to host done */
-#define MID_TX_DMA_COMPLETE 0x00000008	/* DMA from host done */
-#define MID_SERVICE	0x00000004	/* something in service list */
-#define MID_SUNI_INT	0x00000002	/* interrupt from SUNI */
-#define MID_STAT_OVFL	0x00000001	/* statistics overflow */
-
-/*
- * Master Control/Status
- */
-
-#define MID_MC_S	0x04
-
-#define MID_INT_SELECT	0x000001C0	/* Interrupt level (000: off) */
-#define MID_INT_SEL_SHIFT 6
-#define	MID_TX_LOCK_MODE 0x00000020	/* 0: streaming; 1: TX ovfl->lock */
-#define MID_DMA_ENABLE	0x00000010	/* R: 0: disable; 1: enable
-					   W: 0: no change; 1: enable */
-#define MID_TX_ENABLE	0x00000008	/* R: 0: TX disabled; 1: enabled
-					   W: 0: no change; 1: enable */
-#define MID_RX_ENABLE	0x00000004	/* like TX */
-#define MID_WAIT_1MS	0x00000002	/* R: 0: timer not running; 1: running
-					   W: 0: no change; 1: no interrupts
-							       for 1 ms */
-#define MID_WAIT_500US	0x00000001	/* like WAIT_1MS, but 0.5 ms */
-
-/*
- * Statistics
- *
- * Cleared when reading.
- */
-
-#define MID_STAT		0x05
-
-#define MID_VCI_TRASH	0xFFFF0000	/* trashed cells because of VCI mode */
-#define MID_VCI_TRASH_SHIFT 16
-#define MID_OVFL_TRASH	0x0000FFFF	/* trashed cells because of overflow */
-
-/*
- * Address registers
- */
-
-#define MID_SERV_WRITE	0x06	/* free pos in service area (R, 10 bits) */
-#define MID_DMA_ADDR	0x07	/* virtual DMA address (R, 32 bits) */
-#define MID_DMA_WR_RX	0x08	/* (RW, 9 bits) */
-#define MID_DMA_RD_RX	0x09
-#define MID_DMA_WR_TX	0x0A
-#define MID_DMA_RD_TX	0x0B
-
-/*
- * Transmit Place Registers (0x10+4*channel)
- */
-
-#define MID_TX_PLACE(c)	(0x10+4*(c))
-
-#define MID_SIZE	0x00003800	/* size, N*256 x 32 bit */
-#define MID_SIZE_SHIFT	11
-#define MID_LOCATION	0x000007FF	/* location in adapter memory (word) */
-
-#define MID_LOC_SKIP	8		/* 8 bits of location are always zero
-					   (applies to all uses of location) */
-
-/*
- * Transmit ReadPtr Registers (0x11+4*channel)
- */
-
-#define MID_TX_RDPTR(c)	(0x11+4*(c))
-
-#define MID_READ_PTR	0x00007FFF	/* next word for PHY */
-
-/*
- * Transmit DescrStart Registers (0x12+4*channel)
- */
-
-#define MID_TX_DESCRSTART(c) (0x12+4*(c))
-
-#define MID_DESCR_START	0x00007FFF	/* seg buffer being DMAed */
-
-#define ENI155_MAGIC	0xa54b872d
-
-struct midway_eprom {
-	unsigned char mac[MAC_LEN],inv_mac[MAC_LEN];
-	unsigned char pad[36];
-	u32 serial,inv_serial;
-	u32 magic,inv_magic;
-};
-
-
-/*
- * VCI table entry
- */
-
-#define MID_VCI_IN_SERVICE	0x00000001	/* set if VCI is currently in
-						   service list */
-#define MID_VCI_SIZE		0x00038000	/* reassembly buffer size,
-						   2*<size> kB */
-#define MID_VCI_SIZE_SHIFT	15
-#define MID_VCI_LOCATION	0x1ffc0000	/* buffer location */
-#define MID_VCI_LOCATION_SHIFT	18
-#define MID_VCI_PTI_MODE	0x20000000	/* 0: trash, 1: preserve */
-#define MID_VCI_MODE		0xc0000000
-#define MID_VCI_MODE_SHIFT	30
-#define MID_VCI_READ		0x00007fff
-#define MID_VCI_READ_SHIFT	0
-#define MID_VCI_DESCR		0x7fff0000
-#define MID_VCI_DESCR_SHIFT	16
-#define MID_VCI_COUNT		0x000007ff
-#define MID_VCI_COUNT_SHIFT	0
-#define MID_VCI_STATE		0x0000c000
-#define MID_VCI_STATE_SHIFT	14
-#define MID_VCI_WRITE		0x7fff0000
-#define MID_VCI_WRITE_SHIFT	16
-
-#define MID_MODE_TRASH	0
-#define MID_MODE_RAW	1
-#define MID_MODE_AAL5	2
-
-/*
- * Reassembly buffer descriptor
- */
-
-#define MID_RED_COUNT		0x000007ff
-#define MID_RED_CRC_ERR		0x00000800
-#define MID_RED_T		0x00001000
-#define MID_RED_CE		0x00010000
-#define MID_RED_CLP		0x01000000
-#define MID_RED_IDEN		0xfe000000
-#define MID_RED_SHIFT		25
-
-#define MID_RED_RX_ID		0x1b		/* constant identifier */
-
-/*
- * Segmentation buffer descriptor
- */
-
-#define MID_SEG_COUNT		MID_RED_COUNT
-#define MID_SEG_RATE		0x01f80000
-#define MID_SEG_RATE_SHIFT	19
-#define MID_SEG_PR		0x06000000
-#define MID_SEG_PR_SHIFT	25
-#define MID_SEG_AAL5		0x08000000
-#define MID_SEG_ID		0xf0000000
-#define MID_SEG_ID_SHIFT	28
-#define MID_SEG_MAX_RATE	63
-
-#define MID_SEG_CLP		0x00000001
-#define MID_SEG_PTI		0x0000000e
-#define MID_SEG_PTI_SHIFT	1
-#define MID_SEG_VCI		0x00003ff0
-#define MID_SEG_VCI_SHIFT	4
-
-#define MID_SEG_TX_ID		0xb		/* constant identifier */
-
-/*
- * DMA entry
- */
-
-#define MID_DMA_COUNT		0xffff0000
-#define MID_DMA_COUNT_SHIFT	16
-#define MID_DMA_END		0x00000020
-#define MID_DMA_TYPE		0x0000000f
-
-#define MID_DT_JK	0x3
-#define MID_DT_WORD	0x0
-#define MID_DT_2W	0x7
-#define MID_DT_4W	0x4
-#define MID_DT_8W	0x5
-#define MID_DT_16W	0x6
-#define MID_DT_2WM	0xf
-#define MID_DT_4WM	0xc
-#define MID_DT_8WM	0xd
-#define MID_DT_16WM	0xe
-
-/* only for RX*/
-#define MID_DMA_VCI		0x0000ffc0
-#define	MID_DMA_VCI_SHIFT	6
-
-/* only for TX */
-#define MID_DMA_CHAN		0x000001c0
-#define MID_DMA_CHAN_SHIFT	6
-
-#define MID_DT_BYTE	0x1
-#define MID_DT_HWORD	0x2
-
-#endif
diff --git a/drivers/atm/nicstar.h b/drivers/atm/nicstar.h
deleted file mode 100644
index 1b7f1dfc1735..000000000000
--- a/drivers/atm/nicstar.h
+++ /dev/null
@@ -1,759 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * nicstar.h
- *
- * Header file for the nicstar device driver.
- *
- * Author: Rui Prior (rprior@inescn.pt)
- * PowerPC support by Jay Talbott (jay_talbott@mcg.mot.com) April 1999
- *
- * (C) INESC 1998
- */
-
-#ifndef _LINUX_NICSTAR_H_
-#define _LINUX_NICSTAR_H_
-
-/* Includes */
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/idr.h>
-#include <linux/uio.h>
-#include <linux/skbuff.h>
-#include <linux/atmdev.h>
-#include <linux/atm_nicstar.h>
-
-/* Options */
-
-#define NS_MAX_CARDS 4		/* Maximum number of NICStAR based cards
-				   controlled by the device driver. Must
-				   be <= 5 */
-
-#undef RCQ_SUPPORT		/* Do not define this for now */
-
-#define NS_TST_NUM_ENTRIES 2340	/* + 1 for return */
-#define NS_TST_RESERVED 340	/* N. entries reserved for UBR/ABR/VBR */
-
-#define NS_SMBUFSIZE 48		/* 48, 96, 240 or 2048 */
-#define NS_LGBUFSIZE 16384	/* 2048, 4096, 8192 or 16384 */
-#define NS_RSQSIZE 8192		/* 2048, 4096 or 8192 */
-#define NS_VPIBITS 2		/* 0, 1, 2, or 8 */
-
-#define NS_MAX_RCTSIZE 4096	/* Number of entries. 4096 or 16384.
-				   Define 4096 only if (all) your card(s)
-				   have 32K x 32bit SRAM, in which case
-				   setting this to 16384 will just waste a
-				   lot of memory.
-				   Setting this to 4096 for a card with
-				   128K x 32bit SRAM will limit the maximum
-				   VCI. */
-
-				/*#define NS_PCI_LATENCY 64*//* Must be a multiple of 32 */
-
-	/* Number of buffers initially allocated */
-#define NUM_SB 32		/* Must be even */
-#define NUM_LB 24		/* Must be even */
-#define NUM_HB 8		/* Pre-allocated huge buffers */
-#define NUM_IOVB 48		/* Iovec buffers */
-
-	/* Lower level for count of buffers */
-#define MIN_SB 8		/* Must be even */
-#define MIN_LB 8		/* Must be even */
-#define MIN_HB 6
-#define MIN_IOVB 8
-
-	/* Upper level for count of buffers */
-#define MAX_SB 64		/* Must be even, <= 508 */
-#define MAX_LB 48		/* Must be even, <= 508 */
-#define MAX_HB 10
-#define MAX_IOVB 80
-
-	/* These are the absolute maximum allowed for the ioctl() */
-#define TOP_SB 256		/* Must be even, <= 508 */
-#define TOP_LB 128		/* Must be even, <= 508 */
-#define TOP_HB 64
-#define TOP_IOVB 256
-
-#define MAX_TBD_PER_VC 1	/* Number of TBDs before a TSR */
-#define MAX_TBD_PER_SCQ 10	/* Only meaningful for variable rate SCQs */
-
-#undef ENABLE_TSQFIE
-
-#define SCQFULL_TIMEOUT (5 * HZ)
-
-#define NS_POLL_PERIOD (HZ)
-
-#define PCR_TOLERANCE (1.0001)
-
-/* ESI stuff */
-
-#define NICSTAR_EPROM_MAC_ADDR_OFFSET 0x6C
-#define NICSTAR_EPROM_MAC_ADDR_OFFSET_ALT 0xF6
-
-/* #defines */
-
-#define NS_IOREMAP_SIZE 4096
-
-/*
- * BUF_XX distinguish the Rx buffers depending on their (small/large) size.
- * BUG_SM and BUG_LG are both used by the driver and the device.
- * BUF_NONE is only used by the driver.
- */
-#define BUF_SM		0x00000000	/* These two are used for push_rxbufs() */
-#define BUF_LG		0x00000001	/* CMD, Write_FreeBufQ, LBUF bit */
-#define BUF_NONE 	0xffffffff	/* Software only: */
-
-#define NS_HBUFSIZE 65568	/* Size of max. AAL5 PDU */
-#define NS_MAX_IOVECS (2 + (65568 - NS_SMBUFSIZE) / \
-                       (NS_LGBUFSIZE - (NS_LGBUFSIZE % 48)))
-#define NS_IOVBUFSIZE (NS_MAX_IOVECS * (sizeof(struct iovec)))
-
-#define NS_SMBUFSIZE_USABLE (NS_SMBUFSIZE - NS_SMBUFSIZE % 48)
-#define NS_LGBUFSIZE_USABLE (NS_LGBUFSIZE - NS_LGBUFSIZE % 48)
-
-#define NS_AAL0_HEADER (ATM_AAL0_SDU - ATM_CELL_PAYLOAD)	/* 4 bytes */
-
-#define NS_SMSKBSIZE (NS_SMBUFSIZE + NS_AAL0_HEADER)
-#define NS_LGSKBSIZE (NS_SMBUFSIZE + NS_LGBUFSIZE)
-
-/* NICStAR structures located in host memory */
-
-/*
- * RSQ - Receive Status Queue
- *
- * Written by the NICStAR, read by the device driver.
- */
-
-typedef struct ns_rsqe {
-	u32 word_1;
-	u32 buffer_handle;
-	u32 final_aal5_crc32;
-	u32 word_4;
-} ns_rsqe;
-
-#define ns_rsqe_vpi(ns_rsqep) \
-        ((le32_to_cpu((ns_rsqep)->word_1) & 0x00FF0000) >> 16)
-#define ns_rsqe_vci(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_1) & 0x0000FFFF)
-
-#define NS_RSQE_VALID      0x80000000
-#define NS_RSQE_NZGFC      0x00004000
-#define NS_RSQE_EOPDU      0x00002000
-#define NS_RSQE_BUFSIZE    0x00001000
-#define NS_RSQE_CONGESTION 0x00000800
-#define NS_RSQE_CLP        0x00000400
-#define NS_RSQE_CRCERR     0x00000200
-
-#define NS_RSQE_BUFSIZE_SM 0x00000000
-#define NS_RSQE_BUFSIZE_LG 0x00001000
-
-#define ns_rsqe_valid(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_VALID)
-#define ns_rsqe_nzgfc(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_NZGFC)
-#define ns_rsqe_eopdu(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_EOPDU)
-#define ns_rsqe_bufsize(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_BUFSIZE)
-#define ns_rsqe_congestion(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_CONGESTION)
-#define ns_rsqe_clp(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_CLP)
-#define ns_rsqe_crcerr(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_CRCERR)
-
-#define ns_rsqe_cellcount(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & 0x000001FF)
-#define ns_rsqe_init(ns_rsqep) \
-        ((ns_rsqep)->word_4 = cpu_to_le32(0x00000000))
-
-#define NS_RSQ_NUM_ENTRIES (NS_RSQSIZE / 16)
-#define NS_RSQ_ALIGNMENT NS_RSQSIZE
-
-/*
- * RCQ - Raw Cell Queue
- *
- * Written by the NICStAR, read by the device driver.
- */
-
-typedef struct cell_payload {
-	u32 word[12];
-} cell_payload;
-
-typedef struct ns_rcqe {
-	u32 word_1;
-	u32 word_2;
-	u32 word_3;
-	u32 word_4;
-	cell_payload payload;
-} ns_rcqe;
-
-#define NS_RCQE_SIZE 64		/* bytes */
-
-#define ns_rcqe_islast(ns_rcqep) \
-        (le32_to_cpu((ns_rcqep)->word_2) != 0x00000000)
-#define ns_rcqe_cellheader(ns_rcqep) \
-        (le32_to_cpu((ns_rcqep)->word_1))
-#define ns_rcqe_nextbufhandle(ns_rcqep) \
-        (le32_to_cpu((ns_rcqep)->word_2))
-
-/*
- * SCQ - Segmentation Channel Queue
- *
- * Written by the device driver, read by the NICStAR.
- */
-
-typedef struct ns_scqe {
-	u32 word_1;
-	u32 word_2;
-	u32 word_3;
-	u32 word_4;
-} ns_scqe;
-
-   /* NOTE: SCQ entries can be either a TBD (Transmit Buffer Descriptors)
-      or TSR (Transmit Status Requests) */
-
-#define NS_SCQE_TYPE_TBD 0x00000000
-#define NS_SCQE_TYPE_TSR 0x80000000
-
-#define NS_TBD_EOPDU 0x40000000
-#define NS_TBD_AAL0  0x00000000
-#define NS_TBD_AAL34 0x04000000
-#define NS_TBD_AAL5  0x08000000
-
-#define NS_TBD_VPI_MASK 0x0FF00000
-#define NS_TBD_VCI_MASK 0x000FFFF0
-#define NS_TBD_VC_MASK (NS_TBD_VPI_MASK | NS_TBD_VCI_MASK)
-
-#define NS_TBD_VPI_SHIFT 20
-#define NS_TBD_VCI_SHIFT 4
-
-#define ns_tbd_mkword_1(flags, m, n, buflen) \
-      (cpu_to_le32((flags) | (m) << 23 | (n) << 16 | (buflen)))
-#define ns_tbd_mkword_1_novbr(flags, buflen) \
-      (cpu_to_le32((flags) | (buflen) | 0x00810000))
-#define ns_tbd_mkword_3(control, pdulen) \
-      (cpu_to_le32((control) << 16 | (pdulen)))
-#define ns_tbd_mkword_4(gfc, vpi, vci, pt, clp) \
-      (cpu_to_le32((gfc) << 28 | (vpi) << 20 | (vci) << 4 | (pt) << 1 | (clp)))
-
-#define NS_TSR_INTENABLE 0x20000000
-
-#define NS_TSR_SCDISVBR 0xFFFF	/* Use as scdi for VBR SCD */
-
-#define ns_tsr_mkword_1(flags) \
-        (cpu_to_le32(NS_SCQE_TYPE_TSR | (flags)))
-#define ns_tsr_mkword_2(scdi, scqi) \
-        (cpu_to_le32((scdi) << 16 | 0x00008000 | (scqi)))
-
-#define ns_scqe_is_tsr(ns_scqep) \
-        (le32_to_cpu((ns_scqep)->word_1) & NS_SCQE_TYPE_TSR)
-
-#define VBR_SCQ_NUM_ENTRIES 512
-#define VBR_SCQSIZE 8192
-#define CBR_SCQ_NUM_ENTRIES 64
-#define CBR_SCQSIZE 1024
-
-#define NS_SCQE_SIZE 16
-
-/*
- * TSQ - Transmit Status Queue
- *
- * Written by the NICStAR, read by the device driver.
- */
-
-typedef struct ns_tsi {
-	u32 word_1;
-	u32 word_2;
-} ns_tsi;
-
-   /* NOTE: The first word can be a status word copied from the TSR which
-      originated the TSI, or a timer overflow indicator. In this last
-      case, the value of the first word is all zeroes. */
-
-#define NS_TSI_EMPTY          0x80000000
-#define NS_TSI_TIMESTAMP_MASK 0x00FFFFFF
-
-#define ns_tsi_isempty(ns_tsip) \
-        (le32_to_cpu((ns_tsip)->word_2) & NS_TSI_EMPTY)
-#define ns_tsi_gettimestamp(ns_tsip) \
-        (le32_to_cpu((ns_tsip)->word_2) & NS_TSI_TIMESTAMP_MASK)
-
-#define ns_tsi_init(ns_tsip) \
-        ((ns_tsip)->word_2 = cpu_to_le32(NS_TSI_EMPTY))
-
-#define NS_TSQSIZE 8192
-#define NS_TSQ_NUM_ENTRIES 1024
-#define NS_TSQ_ALIGNMENT 8192
-
-#define NS_TSI_SCDISVBR NS_TSR_SCDISVBR
-
-#define ns_tsi_tmrof(ns_tsip) \
-        (le32_to_cpu((ns_tsip)->word_1) == 0x00000000)
-#define ns_tsi_getscdindex(ns_tsip) \
-        ((le32_to_cpu((ns_tsip)->word_1) & 0xFFFF0000) >> 16)
-#define ns_tsi_getscqpos(ns_tsip) \
-        (le32_to_cpu((ns_tsip)->word_1) & 0x00007FFF)
-
-/* NICStAR structures located in local SRAM */
-
-/*
- * RCT - Receive Connection Table
- *
- * Written by both the NICStAR and the device driver.
- */
-
-typedef struct ns_rcte {
-	u32 word_1;
-	u32 buffer_handle;
-	u32 dma_address;
-	u32 aal5_crc32;
-} ns_rcte;
-
-#define NS_RCTE_BSFB            0x00200000	/* Rev. D only */
-#define NS_RCTE_NZGFC           0x00100000
-#define NS_RCTE_CONNECTOPEN     0x00080000
-#define NS_RCTE_AALMASK         0x00070000
-#define NS_RCTE_AAL0            0x00000000
-#define NS_RCTE_AAL34           0x00010000
-#define NS_RCTE_AAL5            0x00020000
-#define NS_RCTE_RCQ             0x00030000
-#define NS_RCTE_RAWCELLINTEN    0x00008000
-#define NS_RCTE_RXCONSTCELLADDR 0x00004000
-#define NS_RCTE_BUFFVALID       0x00002000
-#define NS_RCTE_FBDSIZE         0x00001000
-#define NS_RCTE_EFCI            0x00000800
-#define NS_RCTE_CLP             0x00000400
-#define NS_RCTE_CRCERROR        0x00000200
-#define NS_RCTE_CELLCOUNT_MASK  0x000001FF
-
-#define NS_RCTE_FBDSIZE_SM 0x00000000
-#define NS_RCTE_FBDSIZE_LG 0x00001000
-
-#define NS_RCT_ENTRY_SIZE 4	/* Number of dwords */
-
-   /* NOTE: We could make macros to contruct the first word of the RCTE,
-      but that doesn't seem to make much sense... */
-
-/*
- * FBD - Free Buffer Descriptor
- *
- * Written by the device driver using via the command register.
- */
-
-typedef struct ns_fbd {
-	u32 buffer_handle;
-	u32 dma_address;
-} ns_fbd;
-
-/*
- * TST - Transmit Schedule Table
- *
- * Written by the device driver.
- */
-
-typedef u32 ns_tste;
-
-#define NS_TST_OPCODE_MASK 0x60000000
-
-#define NS_TST_OPCODE_NULL     0x00000000	/* Insert null cell */
-#define NS_TST_OPCODE_FIXED    0x20000000	/* Cell from a fixed rate channel */
-#define NS_TST_OPCODE_VARIABLE 0x40000000
-#define NS_TST_OPCODE_END      0x60000000	/* Jump */
-
-#define ns_tste_make(opcode, sramad) (opcode | sramad)
-
-   /* NOTE:
-
-      - When the opcode is FIXED, sramad specifies the SRAM address of the
-      SCD for that fixed rate channel.
-      - When the opcode is END, sramad specifies the SRAM address of the
-      location of the next TST entry to read.
-    */
-
-/*
- * SCD - Segmentation Channel Descriptor
- *
- * Written by both the device driver and the NICStAR
- */
-
-typedef struct ns_scd {
-	u32 word_1;
-	u32 word_2;
-	u32 partial_aal5_crc;
-	u32 reserved;
-	ns_scqe cache_a;
-	ns_scqe cache_b;
-} ns_scd;
-
-#define NS_SCD_BASE_MASK_VAR 0xFFFFE000	/* Variable rate */
-#define NS_SCD_BASE_MASK_FIX 0xFFFFFC00	/* Fixed rate */
-#define NS_SCD_TAIL_MASK_VAR 0x00001FF0
-#define NS_SCD_TAIL_MASK_FIX 0x000003F0
-#define NS_SCD_HEAD_MASK_VAR 0x00001FF0
-#define NS_SCD_HEAD_MASK_FIX 0x000003F0
-#define NS_SCD_XMITFOREVER   0x02000000
-
-   /* NOTE: There are other fields in word 2 of the SCD, but as they should
-      not be needed in the device driver they are not defined here. */
-
-/* NICStAR local SRAM memory map */
-
-#define NS_RCT           0x00000
-#define NS_RCT_32_END    0x03FFF
-#define NS_RCT_128_END   0x0FFFF
-#define NS_UNUSED_32     0x04000
-#define NS_UNUSED_128    0x10000
-#define NS_UNUSED_END    0x1BFFF
-#define NS_TST_FRSCD     0x1C000
-#define NS_TST_FRSCD_END 0x1E7DB
-#define NS_VRSCD2        0x1E7DC
-#define NS_VRSCD2_END    0x1E7E7
-#define NS_VRSCD1        0x1E7E8
-#define NS_VRSCD1_END    0x1E7F3
-#define NS_VRSCD0        0x1E7F4
-#define NS_VRSCD0_END    0x1E7FF
-#define NS_RXFIFO        0x1E800
-#define NS_RXFIFO_END    0x1F7FF
-#define NS_SMFBQ         0x1F800
-#define NS_SMFBQ_END     0x1FBFF
-#define NS_LGFBQ         0x1FC00
-#define NS_LGFBQ_END     0x1FFFF
-
-/* NISCtAR operation registers */
-
-/* See Section 3.4 of `IDT77211 NICStAR User Manual' from www.idt.com */
-
-enum ns_regs {
-	DR0 = 0x00,		/* Data Register 0 R/W */
-	DR1 = 0x04,		/* Data Register 1 W */
-	DR2 = 0x08,		/* Data Register 2 W */
-	DR3 = 0x0C,		/* Data Register 3 W */
-	CMD = 0x10,		/* Command W */
-	CFG = 0x14,		/* Configuration R/W */
-	STAT = 0x18,		/* Status R/W */
-	RSQB = 0x1C,		/* Receive Status Queue Base W */
-	RSQT = 0x20,		/* Receive Status Queue Tail R */
-	RSQH = 0x24,		/* Receive Status Queue Head W */
-	CDC = 0x28,		/* Cell Drop Counter R/clear */
-	VPEC = 0x2C,		/* VPI/VCI Lookup Error Count R/clear */
-	ICC = 0x30,		/* Invalid Cell Count R/clear */
-	RAWCT = 0x34,		/* Raw Cell Tail R */
-	TMR = 0x38,		/* Timer R */
-	TSTB = 0x3C,		/* Transmit Schedule Table Base R/W */
-	TSQB = 0x40,		/* Transmit Status Queue Base W */
-	TSQT = 0x44,		/* Transmit Status Queue Tail R */
-	TSQH = 0x48,		/* Transmit Status Queue Head W */
-	GP = 0x4C,		/* General Purpose R/W */
-	VPM = 0x50		/* VPI/VCI Mask W */
-};
-
-/* NICStAR commands issued to the CMD register */
-
-/* Top 4 bits are command opcode, lower 28 are parameters. */
-
-#define NS_CMD_NO_OPERATION         0x00000000
-	/* params always 0 */
-
-#define NS_CMD_OPENCLOSE_CONNECTION 0x20000000
-	/* b19{1=open,0=close} b18-2{SRAM addr} */
-
-#define NS_CMD_WRITE_SRAM           0x40000000
-	/* b18-2{SRAM addr} b1-0{burst size} */
-
-#define NS_CMD_READ_SRAM            0x50000000
-	/* b18-2{SRAM addr} */
-
-#define NS_CMD_WRITE_FREEBUFQ       0x60000000
-	/* b0{large buf indicator} */
-
-#define NS_CMD_READ_UTILITY         0x80000000
-	/* b8{1=select UTL_CS1} b9{1=select UTL_CS0} b7-0{bus addr} */
-
-#define NS_CMD_WRITE_UTILITY        0x90000000
-	/* b8{1=select UTL_CS1} b9{1=select UTL_CS0} b7-0{bus addr} */
-
-#define NS_CMD_OPEN_CONNECTION (NS_CMD_OPENCLOSE_CONNECTION | 0x00080000)
-#define NS_CMD_CLOSE_CONNECTION NS_CMD_OPENCLOSE_CONNECTION
-
-/* NICStAR configuration bits */
-
-#define NS_CFG_SWRST          0x80000000	/* Software Reset */
-#define NS_CFG_RXPATH         0x20000000	/* Receive Path Enable */
-#define NS_CFG_SMBUFSIZE_MASK 0x18000000	/* Small Receive Buffer Size */
-#define NS_CFG_LGBUFSIZE_MASK 0x06000000	/* Large Receive Buffer Size */
-#define NS_CFG_EFBIE          0x01000000	/* Empty Free Buffer Queue
-						   Interrupt Enable */
-#define NS_CFG_RSQSIZE_MASK   0x00C00000	/* Receive Status Queue Size */
-#define NS_CFG_ICACCEPT       0x00200000	/* Invalid Cell Accept */
-#define NS_CFG_IGNOREGFC      0x00100000	/* Ignore General Flow Control */
-#define NS_CFG_VPIBITS_MASK   0x000C0000	/* VPI/VCI Bits Size Select */
-#define NS_CFG_RCTSIZE_MASK   0x00030000	/* Receive Connection Table Size */
-#define NS_CFG_VCERRACCEPT    0x00008000	/* VPI/VCI Error Cell Accept */
-#define NS_CFG_RXINT_MASK     0x00007000	/* End of Receive PDU Interrupt
-						   Handling */
-#define NS_CFG_RAWIE          0x00000800	/* Raw Cell Qu' Interrupt Enable */
-#define NS_CFG_RSQAFIE        0x00000400	/* Receive Queue Almost Full
-						   Interrupt Enable */
-#define NS_CFG_RXRM           0x00000200	/* Receive RM Cells */
-#define NS_CFG_TMRROIE        0x00000080	/* Timer Roll Over Interrupt
-						   Enable */
-#define NS_CFG_TXEN           0x00000020	/* Transmit Operation Enable */
-#define NS_CFG_TXIE           0x00000010	/* Transmit Status Interrupt
-						   Enable */
-#define NS_CFG_TXURIE         0x00000008	/* Transmit Under-run Interrupt
-						   Enable */
-#define NS_CFG_UMODE          0x00000004	/* Utopia Mode (cell/byte) Select */
-#define NS_CFG_TSQFIE         0x00000002	/* Transmit Status Queue Full
-						   Interrupt Enable */
-#define NS_CFG_PHYIE          0x00000001	/* PHY Interrupt Enable */
-
-#define NS_CFG_SMBUFSIZE_48    0x00000000
-#define NS_CFG_SMBUFSIZE_96    0x08000000
-#define NS_CFG_SMBUFSIZE_240   0x10000000
-#define NS_CFG_SMBUFSIZE_2048  0x18000000
-
-#define NS_CFG_LGBUFSIZE_2048  0x00000000
-#define NS_CFG_LGBUFSIZE_4096  0x02000000
-#define NS_CFG_LGBUFSIZE_8192  0x04000000
-#define NS_CFG_LGBUFSIZE_16384 0x06000000
-
-#define NS_CFG_RSQSIZE_2048 0x00000000
-#define NS_CFG_RSQSIZE_4096 0x00400000
-#define NS_CFG_RSQSIZE_8192 0x00800000
-
-#define NS_CFG_VPIBITS_0 0x00000000
-#define NS_CFG_VPIBITS_1 0x00040000
-#define NS_CFG_VPIBITS_2 0x00080000
-#define NS_CFG_VPIBITS_8 0x000C0000
-
-#define NS_CFG_RCTSIZE_4096_ENTRIES  0x00000000
-#define NS_CFG_RCTSIZE_8192_ENTRIES  0x00010000
-#define NS_CFG_RCTSIZE_16384_ENTRIES 0x00020000
-
-#define NS_CFG_RXINT_NOINT   0x00000000
-#define NS_CFG_RXINT_NODELAY 0x00001000
-#define NS_CFG_RXINT_314US   0x00002000
-#define NS_CFG_RXINT_624US   0x00003000
-#define NS_CFG_RXINT_899US   0x00004000
-
-/* NICStAR STATus bits */
-
-#define NS_STAT_SFBQC_MASK 0xFF000000	/* hi 8 bits Small Buffer Queue Count */
-#define NS_STAT_LFBQC_MASK 0x00FF0000	/* hi 8 bits Large Buffer Queue Count */
-#define NS_STAT_TSIF       0x00008000	/* Transmit Status Queue Indicator */
-#define NS_STAT_TXICP      0x00004000	/* Transmit Incomplete PDU */
-#define NS_STAT_TSQF       0x00001000	/* Transmit Status Queue Full */
-#define NS_STAT_TMROF      0x00000800	/* Timer Overflow */
-#define NS_STAT_PHYI       0x00000400	/* PHY Device Interrupt */
-#define NS_STAT_CMDBZ      0x00000200	/* Command Busy */
-#define NS_STAT_SFBQF      0x00000100	/* Small Buffer Queue Full */
-#define NS_STAT_LFBQF      0x00000080	/* Large Buffer Queue Full */
-#define NS_STAT_RSQF       0x00000040	/* Receive Status Queue Full */
-#define NS_STAT_EOPDU      0x00000020	/* End of PDU */
-#define NS_STAT_RAWCF      0x00000010	/* Raw Cell Flag */
-#define NS_STAT_SFBQE      0x00000008	/* Small Buffer Queue Empty */
-#define NS_STAT_LFBQE      0x00000004	/* Large Buffer Queue Empty */
-#define NS_STAT_RSQAF      0x00000002	/* Receive Status Queue Almost Full */
-
-#define ns_stat_sfbqc_get(stat) (((stat) & NS_STAT_SFBQC_MASK) >> 23)
-#define ns_stat_lfbqc_get(stat) (((stat) & NS_STAT_LFBQC_MASK) >> 15)
-
-/* #defines which depend on other #defines */
-
-#define NS_TST0 NS_TST_FRSCD
-#define NS_TST1 (NS_TST_FRSCD + NS_TST_NUM_ENTRIES + 1)
-
-#define NS_FRSCD (NS_TST1 + NS_TST_NUM_ENTRIES + 1)
-#define NS_FRSCD_SIZE 12	/* 12 dwords */
-#define NS_FRSCD_NUM ((NS_TST_FRSCD_END + 1 - NS_FRSCD) / NS_FRSCD_SIZE)
-
-#if (NS_SMBUFSIZE == 48)
-#define NS_CFG_SMBUFSIZE NS_CFG_SMBUFSIZE_48
-#elif (NS_SMBUFSIZE == 96)
-#define NS_CFG_SMBUFSIZE NS_CFG_SMBUFSIZE_96
-#elif (NS_SMBUFSIZE == 240)
-#define NS_CFG_SMBUFSIZE NS_CFG_SMBUFSIZE_240
-#elif (NS_SMBUFSIZE == 2048)
-#define NS_CFG_SMBUFSIZE NS_CFG_SMBUFSIZE_2048
-#else
-#error NS_SMBUFSIZE is incorrect in nicstar.h
-#endif /* NS_SMBUFSIZE */
-
-#if (NS_LGBUFSIZE == 2048)
-#define NS_CFG_LGBUFSIZE NS_CFG_LGBUFSIZE_2048
-#elif (NS_LGBUFSIZE == 4096)
-#define NS_CFG_LGBUFSIZE NS_CFG_LGBUFSIZE_4096
-#elif (NS_LGBUFSIZE == 8192)
-#define NS_CFG_LGBUFSIZE NS_CFG_LGBUFSIZE_8192
-#elif (NS_LGBUFSIZE == 16384)
-#define NS_CFG_LGBUFSIZE NS_CFG_LGBUFSIZE_16384
-#else
-#error NS_LGBUFSIZE is incorrect in nicstar.h
-#endif /* NS_LGBUFSIZE */
-
-#if (NS_RSQSIZE == 2048)
-#define NS_CFG_RSQSIZE NS_CFG_RSQSIZE_2048
-#elif (NS_RSQSIZE == 4096)
-#define NS_CFG_RSQSIZE NS_CFG_RSQSIZE_4096
-#elif (NS_RSQSIZE == 8192)
-#define NS_CFG_RSQSIZE NS_CFG_RSQSIZE_8192
-#else
-#error NS_RSQSIZE is incorrect in nicstar.h
-#endif /* NS_RSQSIZE */
-
-#if (NS_VPIBITS == 0)
-#define NS_CFG_VPIBITS NS_CFG_VPIBITS_0
-#elif (NS_VPIBITS == 1)
-#define NS_CFG_VPIBITS NS_CFG_VPIBITS_1
-#elif (NS_VPIBITS == 2)
-#define NS_CFG_VPIBITS NS_CFG_VPIBITS_2
-#elif (NS_VPIBITS == 8)
-#define NS_CFG_VPIBITS NS_CFG_VPIBITS_8
-#else
-#error NS_VPIBITS is incorrect in nicstar.h
-#endif /* NS_VPIBITS */
-
-#ifdef RCQ_SUPPORT
-#define NS_CFG_RAWIE_OPT NS_CFG_RAWIE
-#else
-#define NS_CFG_RAWIE_OPT 0x00000000
-#endif /* RCQ_SUPPORT */
-
-#ifdef ENABLE_TSQFIE
-#define NS_CFG_TSQFIE_OPT NS_CFG_TSQFIE
-#else
-#define NS_CFG_TSQFIE_OPT 0x00000000
-#endif /* ENABLE_TSQFIE */
-
-/* PCI stuff */
-
-#ifndef PCI_VENDOR_ID_IDT
-#define PCI_VENDOR_ID_IDT 0x111D
-#endif /* PCI_VENDOR_ID_IDT */
-
-#ifndef PCI_DEVICE_ID_IDT_IDT77201
-#define PCI_DEVICE_ID_IDT_IDT77201 0x0001
-#endif /* PCI_DEVICE_ID_IDT_IDT77201 */
-
-/* Device driver structures */
-
-struct ns_skb_prv {
-	u32 buf_type;		/* BUF_SM/BUF_LG/BUF_NONE */
-	u32 dma;
-	int iovcnt;
-};
-
-#define NS_PRV_BUFTYPE(skb)   \
-        (((struct ns_skb_prv *)(ATM_SKB(skb)+1))->buf_type)
-#define NS_PRV_DMA(skb) \
-        (((struct ns_skb_prv *)(ATM_SKB(skb)+1))->dma)
-#define NS_PRV_IOVCNT(skb) \
-        (((struct ns_skb_prv *)(ATM_SKB(skb)+1))->iovcnt)
-
-typedef struct tsq_info {
-	void *org;
-        dma_addr_t dma;
-	ns_tsi *base;
-	ns_tsi *next;
-	ns_tsi *last;
-} tsq_info;
-
-typedef struct scq_info {
-	void *org;
-	dma_addr_t dma;
-	ns_scqe *base;
-	ns_scqe *last;
-	ns_scqe *next;
-	volatile ns_scqe *tail;	/* Not related to the nicstar register */
-	unsigned num_entries;
-	struct sk_buff **skb;	/* Pointer to an array of pointers
-				   to the sk_buffs used for tx */
-	u32 scd;		/* SRAM address of the corresponding
-				   SCD */
-	int tbd_count;		/* Only meaningful on variable rate */
-	wait_queue_head_t scqfull_waitq;
-	volatile char full;	/* SCQ full indicator */
-	spinlock_t lock;	/* SCQ spinlock */
-} scq_info;
-
-typedef struct rsq_info {
-	void *org;
-        dma_addr_t dma;
-	ns_rsqe *base;
-	ns_rsqe *next;
-	ns_rsqe *last;
-} rsq_info;
-
-typedef struct skb_pool {
-	volatile int count;	/* number of buffers in the queue */
-	struct sk_buff_head queue;
-} skb_pool;
-
-/* NOTE: for small and large buffer pools, the count is not used, as the
-         actual value used for buffer management is the one read from the
-	 card. */
-
-typedef struct vc_map {
-	volatile unsigned int tx:1;	/* TX vc? */
-	volatile unsigned int rx:1;	/* RX vc? */
-	struct atm_vcc *tx_vcc, *rx_vcc;
-	struct sk_buff *rx_iov;	/* RX iovector skb */
-	scq_info *scq;		/* To keep track of the SCQ */
-	u32 cbr_scd;		/* SRAM address of the corresponding
-				   SCD. 0x00000000 for UBR/VBR/ABR */
-	int tbd_count;
-} vc_map;
-
-typedef struct ns_dev {
-	int index;		/* Card ID to the device driver */
-	int sram_size;		/* In k x 32bit words. 32 or 128 */
-	void __iomem *membase;	/* Card's memory base address */
-	unsigned long max_pcr;
-	int rct_size;		/* Number of entries */
-	int vpibits;
-	int vcibits;
-	struct pci_dev *pcidev;
-	struct idr idr;
-	struct atm_dev *atmdev;
-	tsq_info tsq;
-	rsq_info rsq;
-	scq_info *scq0, *scq1, *scq2;	/* VBR SCQs */
-	skb_pool sbpool;	/* Small buffers */
-	skb_pool lbpool;	/* Large buffers */
-	skb_pool hbpool;	/* Pre-allocated huge buffers */
-	skb_pool iovpool;	/* iovector buffers */
-	volatile int efbie;	/* Empty free buf. queue int. enabled */
-	volatile u32 tst_addr;	/* SRAM address of the TST in use */
-	volatile int tst_free_entries;
-	vc_map vcmap[NS_MAX_RCTSIZE];
-	vc_map *tste2vc[NS_TST_NUM_ENTRIES];
-	vc_map *scd2vc[NS_FRSCD_NUM];
-	buf_nr sbnr;
-	buf_nr lbnr;
-	buf_nr hbnr;
-	buf_nr iovnr;
-	int sbfqc;
-	int lbfqc;
-	struct sk_buff *sm_handle;
-	u32 sm_addr;
-	struct sk_buff *lg_handle;
-	u32 lg_addr;
-	struct sk_buff *rcbuf;	/* Current raw cell buffer */
-        struct ns_rcqe *rawcell;
-	u32 rawch;		/* Raw cell queue head */
-	unsigned intcnt;	/* Interrupt counter */
-	spinlock_t int_lock;	/* Interrupt lock */
-	spinlock_t res_lock;	/* Card resource lock */
-} ns_dev;
-
-   /* NOTE: Each tste2vc entry relates a given TST entry to the corresponding
-      CBR vc. If the entry is not allocated, it must be NULL.
-
-      There are two TSTs so the driver can modify them on the fly
-      without stopping the transmission.
-
-      scd2vc allows us to find out unused fixed rate SCDs, because
-      they must have a NULL pointer here. */
-
-#endif /* _LINUX_NICSTAR_H_ */
diff --git a/drivers/atm/suni.h b/drivers/atm/suni.h
deleted file mode 100644
index d28a50d47d8b..000000000000
--- a/drivers/atm/suni.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * drivers/atm/suni.h - S/UNI PHY driver
- */
- 
-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
-
-#ifndef DRIVER_ATM_SUNI_H
-#define DRIVER_ATM_SUNI_H
-
-#include <linux/atmdev.h>
-#include <linux/atmioc.h>
-#include <linux/sonet.h>
-
-/* SUNI registers */
-
-#define SUNI_MRI		0x00	/* Master Reset and Identity / Load
-					   Meter */
-#define SUNI_MC			0x01	/* Master Configuration */
-#define SUNI_MIS		0x02	/* Master Interrupt Status */
-			  /* no 0x03 */
-#define SUNI_MCM		0x04	/* Master Clock Monitor */
-#define SUNI_MCT		0x05	/* Master Control */
-#define SUNI_CSCS		0x06	/* Clock Synthesis Control and Status */
-#define SUNI_CRCS		0x07	/* Clock Recovery Control and Status */
-			     /* 0x08-0x0F reserved */
-#define SUNI_RSOP_CIE		0x10	/* RSOP Control/Interrupt Enable */
-#define SUNI_RSOP_SIS		0x11	/* RSOP Status/Interrupt Status */
-#define SUNI_RSOP_SBL		0x12	/* RSOP Section BIP-8 LSB */
-#define SUNI_RSOP_SBM		0x13	/* RSOP Section BIP-8 MSB */
-#define SUNI_TSOP_CTRL		0x14	/* TSOP Control */
-#define SUNI_TSOP_DIAG		0x15	/* TSOP Diagnostic */
-			     /* 0x16-0x17 reserved */
-#define SUNI_RLOP_CS		0x18	/* RLOP Control/Status */
-#define SUNI_RLOP_IES		0x19	/* RLOP Interrupt Enable/Status */
-#define SUNI_RLOP_LBL		0x1A	/* RLOP Line BIP-8/24 LSB */
-#define SUNI_RLOP_LB		0x1B	/* RLOP Line BIP-8/24 */
-#define SUNI_RLOP_LBM		0x1C	/* RLOP Line BIP-8/24 MSB */
-#define SUNI_RLOP_LFL		0x1D	/* RLOP Line FEBE LSB */
-#define SUNI_RLOP_LF 		0x1E	/* RLOP Line FEBE */
-#define SUNI_RLOP_LFM		0x1F	/* RLOP Line FEBE MSB */
-#define SUNI_TLOP_CTRL		0x20	/* TLOP Control */
-#define SUNI_TLOP_DIAG		0x21	/* TLOP Diagnostic */
-			     /* 0x22-0x27 reserved */
-#define SUNI_SSTB_CTRL		0x28
-#define SUNI_RPOP_SC		0x30	/* RPOP Status/Control */
-#define SUNI_RPOP_IS		0x31	/* RPOP Interrupt Status */
-			     /* 0x32 reserved */
-#define SUNI_RPOP_IE		0x33	/* RPOP Interrupt Enable */
-			     /* 0x34-0x36 reserved */
-#define SUNI_RPOP_PSL		0x37	/* RPOP Path Signal Label */
-#define SUNI_RPOP_PBL		0x38	/* RPOP Path BIP-8 LSB */
-#define SUNI_RPOP_PBM		0x39	/* RPOP Path BIP-8 MSB */
-#define SUNI_RPOP_PFL		0x3A	/* RPOP Path FEBE LSB */
-#define SUNI_RPOP_PFM		0x3B	/* RPOP Path FEBE MSB */
-			     /* 0x3C reserved */
-#define SUNI_RPOP_PBC		0x3D	/* RPOP Path BIP-8 Configuration */
-#define SUNI_RPOP_RC		0x3D	/* RPOP Ring Control (PM5355) */
-			     /* 0x3E-0x3F reserved */
-#define SUNI_TPOP_CD		0x40	/* TPOP Control/Diagnostic */
-#define SUNI_TPOP_PC		0x41	/* TPOP Pointer Control */
-			     /* 0x42-0x44 reserved */
-#define SUNI_TPOP_APL		0x45	/* TPOP Arbitrary Pointer LSB */
-#define SUNI_TPOP_APM		0x46	/* TPOP Arbitrary Pointer MSB */
-			     /* 0x47 reserved */
-#define SUNI_TPOP_PSL		0x48	/* TPOP Path Signal Label */
-#define SUNI_TPOP_PS		0x49	/* TPOP Path Status */
-			     /* 0x4A-0x4F reserved */
-#define SUNI_RACP_CS		0x50	/* RACP Control/Status */
-#define SUNI_RACP_IES		0x51	/* RACP Interrupt Enable/Status */
-#define SUNI_RACP_MHP		0x52	/* RACP Match Header Pattern */
-#define SUNI_RACP_MHM		0x53	/* RACP Match Header Mask */
-#define SUNI_RACP_CHEC		0x54	/* RACP Correctable HCS Error Count */
-#define SUNI_RACP_UHEC		0x55	/* RACP Uncorrectable HCS Err Count */
-#define SUNI_RACP_RCCL		0x56	/* RACP Receive Cell Counter LSB */
-#define SUNI_RACP_RCC		0x57	/* RACP Receive Cell Counter */
-#define SUNI_RACP_RCCM		0x58	/* RACP Receive Cell Counter MSB */
-#define SUNI_RACP_CFG		0x59	/* RACP Configuration */
-			     /* 0x5A-0x5F reserved */
-#define SUNI_TACP_CS		0x60	/* TACP Control/Status */
-#define SUNI_TACP_IUCHP		0x61	/* TACP Idle/Unassigned Cell Hdr Pat */
-#define SUNI_TACP_IUCPOP	0x62	/* TACP Idle/Unassigned Cell Payload
-					   Octet Pattern */
-#define SUNI_TACP_FIFO		0x63	/* TACP FIFO Configuration */
-#define SUNI_TACP_TCCL		0x64	/* TACP Transmit Cell Counter LSB */
-#define SUNI_TACP_TCC		0x65	/* TACP Transmit Cell Counter */
-#define SUNI_TACP_TCCM		0x66	/* TACP Transmit Cell Counter MSB */
-#define SUNI_TACP_CFG		0x67	/* TACP Configuration */
-#define SUNI_SPTB_CTRL		0x68	/* SPTB Control */
-			     /* 0x69-0x7F reserved */
-#define	SUNI_MT			0x80	/* Master Test */
-			     /* 0x81-0xFF reserved */
-
-/* SUNI register values */
-
-
-/* MRI is reg 0 */
-#define SUNI_MRI_ID		0x0f	/* R, SUNI revision number */
-#define SUNI_MRI_ID_SHIFT 	0
-#define SUNI_MRI_TYPE		0x70	/* R, SUNI type (lite is 011) */
-#define SUNI_MRI_TYPE_SHIFT 	4
-#define SUNI_MRI_TYPE_PM5346	0x3	/* S/UNI 155 LITE */
-#define SUNI_MRI_TYPE_PM5347	0x4	/* S/UNI 155 PLUS */
-#define SUNI_MRI_TYPE_PM5350	0x7	/* S/UNI 155 ULTRA */
-#define SUNI_MRI_TYPE_PM5355	0x1	/* S/UNI 622 */
-#define SUNI_MRI_RESET		0x80	/* RW, reset & power down chip
-					   0: normal operation
-					   1: reset & low power */
-
-/* MCM is reg 0x4 */
-#define SUNI_MCM_LLE		0x20	/* line loopback (PM5355) */
-#define SUNI_MCM_DLE		0x10	/* diagnostic loopback (PM5355) */
-
-/* MCT is reg 5 */
-#define SUNI_MCT_LOOPT		0x01	/* RW, timing source, 0: from
-					   TRCLK+/- */
-#define SUNI_MCT_DLE		0x02	/* RW, diagnostic loopback */
-#define SUNI_MCT_LLE		0x04	/* RW, line loopback */
-#define SUNI_MCT_FIXPTR		0x20	/* RW, disable transmit payload pointer
-					   adjustments
-					   0: payload ptr controlled by TPOP
-					      ptr control reg
-					   1: payload pointer fixed at 522 */
-#define SUNI_MCT_LCDV		0x40	/* R, loss of cell delineation */
-#define SUNI_MCT_LCDE		0x80	/* RW, loss of cell delineation
-					   interrupt (1: on) */
-/* RSOP_CIE is reg 0x10 */
-#define SUNI_RSOP_CIE_OOFE	0x01	/* RW, enable interrupt on frame alarm
-					   state change */
-#define SUNI_RSOP_CIE_LOFE	0x02	/* RW, enable interrupt on loss of
-					   frame state change */
-#define SUNI_RSOP_CIE_LOSE	0x04	/* RW, enable interrupt on loss of
-					   signal state change */
-#define SUNI_RSOP_CIE_BIPEE	0x08	/* RW, enable interrupt on section
-					   BIP-8 error (B1) */
-#define SUNI_RSOP_CIE_FOOF	0x20	/* W, force RSOP out of frame at next
-					   boundary */
-#define SUNI_RSOP_CIE_DDS	0x40	/* RW, disable scrambling */
-
-/* RSOP_SIS is reg 0x11 */
-#define SUNI_RSOP_SIS_OOFV	0x01	/* R, out of frame */
-#define SUNI_RSOP_SIS_LOFV	0x02	/* R, loss of frame */
-#define SUNI_RSOP_SIS_LOSV	0x04	/* R, loss of signal */
-#define SUNI_RSOP_SIS_OOFI	0x08	/* R, out of frame interrupt */
-#define SUNI_RSOP_SIS_LOFI	0x10	/* R, loss of frame interrupt */
-#define SUNI_RSOP_SIS_LOSI	0x20	/* R, loss of signal interrupt */
-#define SUNI_RSOP_SIS_BIPEI	0x40	/* R, section BIP-8 interrupt */
-
-/* TSOP_CTRL is reg 0x14 */
-#define SUNI_TSOP_CTRL_LAIS	0x01	/* insert alarm indication signal */
-#define SUNI_TSOP_CTRL_DS	0x40	/* disable scrambling */
-
-/* TSOP_DIAG is reg 0x15 */
-#define SUNI_TSOP_DIAG_DFP	0x01	/* insert single bit error cont. */
-#define SUNI_TSOP_DIAG_DBIP8	0x02	/* insert section BIP err (cont) */
-#define SUNI_TSOP_DIAG_DLOS	0x04	/* set line to zero (loss of signal) */
-
-/* TLOP_DIAG is reg 0x21 */
-#define SUNI_TLOP_DIAG_DBIP	0x01	/* insert line BIP err (continuously) */
-
-/* SSTB_CTRL is reg 0x28 */
-#define SUNI_SSTB_CTRL_LEN16	0x01	/* path trace message length bit */
-
-/* RPOP_RC is reg 0x3D (PM5355) */
-#define SUNI_RPOP_RC_ENSS	0x40	/* enable size bit */
-
-/* TPOP_DIAG is reg 0x40 */
-#define SUNI_TPOP_DIAG_PAIS	0x01	/* insert STS path alarm ind (cont) */
-#define SUNI_TPOP_DIAG_DB3	0x02	/* insert path BIP err (continuously) */
-
-/* TPOP_APM is reg 0x46 */
-#define SUNI_TPOP_APM_APTR	0x03	/* RW, arbitrary pointer, upper 2
-					   bits */
-#define SUNI_TPOP_APM_APTR_SHIFT 0
-#define SUNI_TPOP_APM_S		0x0c	/* RW, "unused" bits of payload
-					   pointer */
-#define SUNI_TPOP_APM_S_SHIFT	2
-#define SUNI_TPOP_APM_NDF	0xf0	 /* RW, NDF bits */
-#define SUNI_TPOP_APM_NDF_SHIFT	4
-
-#define SUNI_TPOP_S_SONET	0	/* set S bits to 00 */
-#define SUNI_TPOP_S_SDH		2	/* set S bits to 10 */
-
-/* RACP_IES is reg 0x51 */
-#define SUNI_RACP_IES_FOVRI	0x02	/* R, FIFO overrun */
-#define SUNI_RACP_IES_UHCSI	0x04	/* R, uncorrectable HCS error */
-#define SUNI_RACP_IES_CHCSI	0x08	/* R, correctable HCS error */
-#define SUNI_RACP_IES_OOCDI	0x10	/* R, change of cell delineation
-					   state */
-#define SUNI_RACP_IES_FIFOE	0x20	/* RW, enable FIFO overrun interrupt */
-#define SUNI_RACP_IES_HCSE	0x40	/* RW, enable HCS error interrupt */
-#define SUNI_RACP_IES_OOCDE	0x80	/* RW, enable cell delineation state
-					   change interrupt */
-
-/* TACP_CS is reg 0x60 */
-#define SUNI_TACP_CS_FIFORST	0x01	/* RW, reset transmit FIFO (sticky) */
-#define SUNI_TACP_CS_DSCR	0x02	/* RW, disable payload scrambling */
-#define SUNI_TACP_CS_HCAADD	0x04	/* RW, add coset polynomial to HCS */
-#define SUNI_TACP_CS_DHCS	0x10	/* RW, insert HCS errors */
-#define SUNI_TACP_CS_FOVRI	0x20	/* R, FIFO overrun */
-#define SUNI_TACP_CS_TSOCI	0x40	/* R, TSOC input high */
-#define SUNI_TACP_CS_FIFOE	0x80	/* RW, enable FIFO overrun interrupt */
-
-/* TACP_IUCHP is reg 0x61 */
-#define SUNI_TACP_IUCHP_CLP	0x01	/* RW, 8th bit of 4th octet of i/u
-					   pattern */
-#define SUNI_TACP_IUCHP_PTI	0x0e	/* RW, 5th-7th bits of 4th octet of i/u
-					   pattern */
-#define SUNI_TACP_IUCHP_PTI_SHIFT 1
-#define SUNI_TACP_IUCHP_GFC	0xf0	/* RW, 1st-4th bits of 1st octet of i/u
-					   pattern */
-#define SUNI_TACP_IUCHP_GFC_SHIFT 4
-
-/* SPTB_CTRL is reg 0x68 */
-#define SUNI_SPTB_CTRL_LEN16	0x01	/* path trace message length */
-
-/* MT is reg 0x80 */
-#define SUNI_MT_HIZIO		0x01	/* RW, all but data bus & MP interface
-					   tri-state */
-#define SUNI_MT_HIZDATA		0x02	/* W, also tri-state data bus */
-#define SUNI_MT_IOTST		0x04	/* RW, enable test mode */
-#define SUNI_MT_DBCTRL		0x08	/* W, control data bus by CSB pin */
-#define SUNI_MT_PMCTST		0x10	/* W, PMC test mode */
-#define SUNI_MT_DS27_53		0x80	/* RW, select between 8- or 16- bit */
-
-
-#define SUNI_IDLE_PATTERN       0x6a    /* idle pattern */
-
-
-#ifdef __KERNEL__
-struct suni_priv {
-	struct k_sonet_stats sonet_stats;	/* link diagnostics */
-	int loop_mode;				/* loopback mode */
-	int type;				/* phy type */
-	struct atm_dev *dev;			/* device back-pointer */
-	struct suni_priv *next;			/* next SUNI */
-};
-
-int suni_init(struct atm_dev *dev);
-#endif
-
-#endif
diff --git a/drivers/atm/tonga.h b/drivers/atm/tonga.h
deleted file mode 100644
index 771b3f95246c..000000000000
--- a/drivers/atm/tonga.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* drivers/atm/tonga.h - Efficient Networks Tonga (PCI bridge) declarations */
- 
-/* Written 1995 by Werner Almesberger, EPFL LRC */
- 
-
-#ifndef DRIVER_ATM_TONGA_H
-#define DRIVER_ATM_TONGA_H
-
-#define PCI_TONGA_CTRL	0x60	/* control register */
-
-#define END_SWAP_DMA	0x80	/* endian swap on DMA */
-#define END_SWAP_BYTE	0x40	/* endian swap on slave byte accesses */
-#define END_SWAP_WORD	0x20	/* endian swap on slave word accesses */
-#define SEPROM_MAGIC	0x0c	/* obscure required pattern (ASIC only) */
-#define SEPROM_DATA	0x02	/* serial EEPROM data (ASIC only) */
-#define SEPROM_CLK	0x01	/* serial EEPROM clock (ASIC only) */
-
-#define SEPROM_ESI_BASE	64	/* start of ESI in serial EEPROM */
-
-#endif
diff --git a/drivers/atm/zeprom.h b/drivers/atm/zeprom.h
deleted file mode 100644
index 8e8819a3840d..000000000000
--- a/drivers/atm/zeprom.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* drivers/atm/zeprom.h - ZeitNet ZN122x EEPROM (NM93C46) declarations */
-
-/* Written 1995,1996 by Werner Almesberger, EPFL LRC */
-
-
-#ifndef DRIVER_ATM_ZEPROM_H
-#define DRIVER_ATM_ZEPROM_H
-
-/* Different versions use different control registers */
-
-#define ZEPROM_V1_REG	PCI_VENDOR_ID	/* PCI register */
-#define ZEPROM_V2_REG	0x40
-
-/* Bits in control register */
-
-#define ZEPROM_SK	0x80000000	/* strobe (probably on raising edge) */
-#define ZEPROM_CS	0x40000000	/* Chip Select */
-#define ZEPROM_DI	0x20000000	/* Data Input */
-#define ZEPROM_DO	0x10000000	/* Data Output */
-
-#define ZEPROM_SIZE	32		/* 32 bytes */
-#define ZEPROM_V1_ESI_OFF 24		/* ESI offset in EEPROM (V1) */
-#define ZEPROM_V2_ESI_OFF 4		/* ESI offset in EEPROM (V2) */
-
-#define ZEPROM_CMD_LEN	3		/* commands are three bits */
-#define ZEPROM_ADDR_LEN	6		/* addresses are six bits */
-
-/* Commands (3 bits) */
-
-#define ZEPROM_CMD_READ	6
-
-/* No other commands are needed. */
-
-#endif
diff --git a/net/atm/lec.h b/net/atm/lec.h
deleted file mode 100644
index ec85709bf818..000000000000
--- a/net/atm/lec.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Lan Emulation client header file
- *
- * Marko Kiiskila <mkiiskila@yahoo.com>
- */
-
-#ifndef _LEC_H_
-#define _LEC_H_
-
-#include <linux/atmdev.h>
-#include <linux/netdevice.h>
-#include <linux/atmlec.h>
-
-#define LEC_HEADER_LEN 16
-
-struct lecdatahdr_8023 {
-	__be16 le_header;
-	unsigned char h_dest[ETH_ALEN];
-	unsigned char h_source[ETH_ALEN];
-	__be16 h_type;
-};
-
-struct lecdatahdr_8025 {
-	__be16 le_header;
-	unsigned char ac_pad;
-	unsigned char fc;
-	unsigned char h_dest[ETH_ALEN];
-	unsigned char h_source[ETH_ALEN];
-};
-
-#define LEC_MINIMUM_8023_SIZE   62
-#define LEC_MINIMUM_8025_SIZE   16
-
-/*
- * Operations that LANE2 capable device can do. Two first functions
- * are used to make the device do things. See spec 3.1.3 and 3.1.4.
- *
- * The third function is intended for the MPOA component sitting on
- * top of the LANE device. The MPOA component assigns it's own function
- * to (*associate_indicator)() and the LANE device will use that
- * function to tell about TLVs it sees floating through.
- *
- */
-struct lane2_ops {
-	int (*resolve) (struct net_device *dev, const u8 *dst_mac, int force,
-			u8 **tlvs, u32 *sizeoftlvs);
-	int (*associate_req) (struct net_device *dev, const u8 *lan_dst,
-			      const u8 *tlvs, u32 sizeoftlvs);
-	void (*associate_indicator) (struct net_device *dev, const u8 *mac_addr,
-				     const u8 *tlvs, u32 sizeoftlvs);
-};
-
-/*
- * ATM LAN Emulation supports both LLC & Dix Ethernet EtherType
- * frames.
- *
- * 1. Dix Ethernet EtherType frames encoded by placing EtherType
- *    field in h_type field. Data follows immediately after header.
- * 2. LLC Data frames whose total length, including LLC field and data,
- *    but not padding required to meet the minimum data frame length,
- *    is less than ETH_P_802_3_MIN MUST be encoded by placing that length
- *    in the h_type field. The LLC field follows header immediately.
- * 3. LLC data frames longer than this maximum MUST be encoded by placing
- *    the value 0 in the h_type field.
- *
- */
-
-/* Hash table size */
-#define LEC_ARP_TABLE_SIZE 16
-
-struct lec_priv {
-	unsigned short lecid;			/* Lecid of this client */
-	struct hlist_head lec_arp_empty_ones;
-						/* Used for storing VCC's that don't have a MAC address attached yet */
-	struct hlist_head lec_arp_tables[LEC_ARP_TABLE_SIZE];
-						/* Actual LE ARP table */
-	struct hlist_head lec_no_forward;
-						/*
-						 * Used for storing VCC's (and forward packets from) which are to
-						 * age out by not using them to forward packets.
-						 * This is because to some LE clients there will be 2 VCCs. Only
-						 * one of them gets used.
-						 */
-	struct hlist_head mcast_fwds;
-						/*
-						 * With LANEv2 it is possible that BUS (or a special multicast server)
-						 * establishes multiple Multicast Forward VCCs to us. This list
-						 * collects all those VCCs. LANEv1 client has only one item in this
-						 * list. These entries are not aged out.
-						 */
-	spinlock_t lec_arp_lock;
-	struct atm_vcc *mcast_vcc;		/* Default Multicast Send VCC */
-	struct atm_vcc __rcu *lecd;
-	struct delayed_work lec_arp_work;	/* C10 */
-	unsigned int maximum_unknown_frame_count;
-						/*
-						 * Within the period of time defined by this variable, the client will send
-						 * no more than C10 frames to BUS for a given unicast destination. (C11)
-						 */
-	unsigned long max_unknown_frame_time;
-						/*
-						 * If no traffic has been sent in this vcc for this period of time,
-						 * vcc will be torn down (C12)
-						 */
-	unsigned long vcc_timeout_period;
-						/*
-						 * An LE Client MUST not retry an LE_ARP_REQUEST for a
-						 * given frame's LAN Destination more than maximum retry count times,
-						 * after the first LEC_ARP_REQUEST (C13)
-						 */
-	unsigned short max_retry_count;
-						/*
-						 * Max time the client will maintain an entry in its arp cache in
-						 * absence of a verification of that relationship (C17)
-						 */
-	unsigned long aging_time;
-						/*
-						 * Max time the client will maintain an entry in cache when
-						 * topology change flag is true (C18)
-						 */
-	unsigned long forward_delay_time;	/* Topology change flag (C19) */
-	int topology_change;
-						/*
-						 * Max time the client expects an LE_ARP_REQUEST/LE_ARP_RESPONSE
-						 * cycle to take (C20)
-						 */
-	unsigned long arp_response_time;
-						/*
-						 * Time limit ot wait to receive an LE_FLUSH_RESPONSE after the
-						 * LE_FLUSH_REQUEST has been sent before taking recover action. (C21)
-						 */
-	unsigned long flush_timeout;
-						/* The time since sending a frame to the bus after which the
-						 * LE Client may assume that the frame has been either discarded or
-						 * delivered to the recipient (C22)
-						 */
-	unsigned long path_switching_delay;
-
-	u8 *tlvs;				/* LANE2: TLVs are new */
-	u32 sizeoftlvs;				/* The size of the tlv array in bytes */
-	int lane_version;			/* LANE2 */
-	int itfnum;				/* e.g. 2 for lec2, 5 for lec5 */
-	struct lane2_ops *lane2_ops;		/* can be NULL for LANE v1 */
-	int is_proxy;				/* bridge between ATM and Ethernet */
-};
-
-struct lec_vcc_priv {
-	void (*old_pop) (struct atm_vcc *vcc, struct sk_buff *skb);
-	int xoff;
-};
-
-#define LEC_VCC_PRIV(vcc)	((struct lec_vcc_priv *)((vcc)->user_back))
-
-#endif				/* _LEC_H_ */
diff --git a/net/atm/lec_arpc.h b/net/atm/lec_arpc.h
deleted file mode 100644
index 39115fe074c4..000000000000
--- a/net/atm/lec_arpc.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Lec arp cache
- *
- * Marko Kiiskila <mkiiskila@yahoo.com>
- */
-#ifndef _LEC_ARP_H_
-#define _LEC_ARP_H_
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <linux/if_ether.h>
-#include <linux/atmlec.h>
-
-struct lec_arp_table {
-	struct hlist_node next;		/* Linked entry list */
-	unsigned char atm_addr[ATM_ESA_LEN];	/* Atm address */
-	unsigned char mac_addr[ETH_ALEN];	/* Mac address */
-	int is_rdesc;			/* Mac address is a route descriptor */
-	struct atm_vcc *vcc;		/* Vcc this entry is attached */
-	struct atm_vcc *recv_vcc;	/* Vcc we receive data from */
-
-	void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb);
-					/* Push that leads to daemon */
-
-	void (*old_recv_push) (struct atm_vcc *vcc, struct sk_buff *skb);
-					/* Push that leads to daemon */
-
-	unsigned long last_used;	/* For expiry */
-	unsigned long timestamp;	/* Used for various timestamping things:
-					 * 1. FLUSH started
-					 *    (status=ESI_FLUSH_PENDING)
-					 * 2. Counting to
-					 *    max_unknown_frame_time
-					 *    (status=ESI_ARP_PENDING||
-					 *     status=ESI_VC_PENDING)
-					 */
-	unsigned char no_tries;		/* No of times arp retry has been tried */
-	unsigned char status;		/* Status of this entry */
-	unsigned short flags;		/* Flags for this entry */
-	unsigned short packets_flooded;	/* Data packets flooded */
-	unsigned long flush_tran_id;	/* Transaction id in flush protocol */
-	struct timer_list timer;	/* Arping timer */
-	struct lec_priv *priv;		/* Pointer back */
-	u8 *tlvs;
-	u32 sizeoftlvs;			/*
-					 * LANE2: Each MAC address can have TLVs
-					 * associated with it.  sizeoftlvs tells
-					 * the length of the tlvs array
-					 */
-	struct sk_buff_head tx_wait;	/* wait queue for outgoing packets */
-	refcount_t usage;		/* usage count */
-};
-
-/*
- * LANE2: Template tlv struct for accessing
- * the tlvs in the lec_arp_table->tlvs array
- */
-struct tlv {
-	u32 type;
-	u8 length;
-	u8 value[255];
-};
-
-/* Status fields */
-#define ESI_UNKNOWN 0		/*
-				 * Next packet sent to this mac address
-				 * causes ARP-request to be sent
-				 */
-#define ESI_ARP_PENDING 1	/*
-				 * There is no ATM address associated with this
-				 * 48-bit address.  The LE-ARP protocol is in
-				 * progress.
-				 */
-#define ESI_VC_PENDING 2	/*
-				 * There is a valid ATM address associated with
-				 * this 48-bit address but there is no VC set
-				 * up to that ATM address.  The signaling
-				 * protocol is in process.
-				 */
-#define ESI_FLUSH_PENDING 4	/*
-				 * The LEC has been notified of the FLUSH_START
-				 * status and it is assumed that the flush
-				 * protocol is in process.
-				 */
-#define ESI_FORWARD_DIRECT 5	/*
-				 * Either the Path Switching Delay (C22) has
-				 * elapsed or the LEC has notified the Mapping
-				 * that the flush protocol has completed.  In
-				 * either case, it is safe to forward packets
-				 * to this address via the data direct VC.
-				 */
-
-/* Flag values */
-#define LEC_REMOTE_FLAG      0x0001
-#define LEC_PERMANENT_FLAG   0x0002
-
-#endif /* _LEC_ARP_H_ */
diff --git a/net/atm/mpc.h b/net/atm/mpc.h
deleted file mode 100644
index 454abd07651a..000000000000
--- a/net/atm/mpc.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _MPC_H_
-#define _MPC_H_
-
-#include <linux/types.h>
-#include <linux/atm.h>
-#include <linux/atmmpc.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include "mpoa_caches.h"
-
-/* kernel -> mpc-daemon */
-int msg_to_mpoad(struct k_message *msg, struct mpoa_client *mpc);
-
-struct mpoa_client {
-	struct mpoa_client *next;
-	struct net_device *dev;      /* lec in question                     */
-	int dev_num;                 /* e.g. 2 for lec2                     */
-
-	struct atm_vcc *mpoad_vcc;   /* control channel to mpoad            */
-	uint8_t mps_ctrl_addr[ATM_ESA_LEN];  /* MPS control ATM address     */
-	uint8_t our_ctrl_addr[ATM_ESA_LEN];  /* MPC's control ATM address   */
-
-	rwlock_t ingress_lock;
-	const struct in_cache_ops *in_ops; /* ingress cache operations      */
-	in_cache_entry *in_cache;    /* the ingress cache of this MPC       */
-
-	rwlock_t egress_lock;
-	const struct eg_cache_ops *eg_ops; /* egress cache operations       */
-	eg_cache_entry *eg_cache;    /* the egress  cache of this MPC       */
-
-	uint8_t *mps_macs;           /* array of MPS MAC addresses, >=1     */
-	int number_of_mps_macs;      /* number of the above MAC addresses   */
-	struct mpc_parameters parameters;  /* parameters for this client    */
-
-	const struct net_device_ops *old_ops;
-	struct net_device_ops new_ops;
-};
-
-
-struct atm_mpoa_qos {
-	struct atm_mpoa_qos *next;
-	__be32 ipaddr;
-	struct atm_qos qos;
-};
-
-
-/* MPOA QoS operations */
-struct atm_mpoa_qos *atm_mpoa_add_qos(__be32 dst_ip, struct atm_qos *qos);
-struct atm_mpoa_qos *atm_mpoa_search_qos(__be32 dst_ip);
-int atm_mpoa_delete_qos(struct atm_mpoa_qos *qos);
-
-/* Display QoS entries. This is for the procfs */
-struct seq_file;
-void atm_mpoa_disp_qos(struct seq_file *m);
-
-#ifdef CONFIG_PROC_FS
-int mpc_proc_init(void);
-void mpc_proc_clean(void);
-#else
-#define mpc_proc_init() (0)
-#define mpc_proc_clean() do { } while(0)
-#endif
-
-#endif /* _MPC_H_ */
diff --git a/net/atm/mpoa_caches.h b/net/atm/mpoa_caches.h
deleted file mode 100644
index 464c4c7f8d1f..000000000000
--- a/net/atm/mpoa_caches.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef MPOA_CACHES_H
-#define MPOA_CACHES_H
-
-#include <linux/time64.h>
-#include <linux/netdevice.h>
-#include <linux/types.h>
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <linux/atmmpc.h>
-#include <linux/refcount.h>
-
-struct mpoa_client;
-
-void atm_mpoa_init_cache(struct mpoa_client *mpc);
-
-typedef struct in_cache_entry {
-	struct in_cache_entry *next;
-	struct in_cache_entry *prev;
-	time64_t  time;
-	time64_t  reply_wait;
-	time64_t  hold_down;
-	uint32_t  packets_fwded;
-	uint16_t  entry_state;
-	uint32_t retry_time;
-	uint32_t refresh_time;
-	uint32_t count;
-	struct   atm_vcc *shortcut;
-	uint8_t  MPS_ctrl_ATM_addr[ATM_ESA_LEN];
-	struct   in_ctrl_info ctrl_info;
-	refcount_t use;
-} in_cache_entry;
-
-struct in_cache_ops{
-	in_cache_entry *(*add_entry)(__be32 dst_ip,
-				      struct mpoa_client *client);
-	in_cache_entry *(*get)(__be32 dst_ip, struct mpoa_client *client);
-	in_cache_entry *(*get_with_mask)(__be32 dst_ip,
-					 struct mpoa_client *client,
-					 __be32 mask);
-	in_cache_entry *(*get_by_vcc)(struct atm_vcc *vcc,
-				      struct mpoa_client *client);
-	void            (*put)(in_cache_entry *entry);
-	void            (*remove_entry)(in_cache_entry *delEntry,
-					struct mpoa_client *client );
-	int             (*cache_hit)(in_cache_entry *entry,
-				     struct mpoa_client *client);
-	void            (*clear_count)(struct mpoa_client *client);
-	void            (*check_resolving)(struct mpoa_client *client);
-	void            (*refresh)(struct mpoa_client *client);
-	void            (*destroy_cache)(struct mpoa_client *mpc);
-};
-
-typedef struct eg_cache_entry{
-	struct               eg_cache_entry *next;
-	struct               eg_cache_entry *prev;
-	time64_t	     time;
-	uint8_t              MPS_ctrl_ATM_addr[ATM_ESA_LEN];
-	struct atm_vcc       *shortcut;
-	uint32_t             packets_rcvd;
-	uint16_t             entry_state;
-	__be32             latest_ip_addr;    /* The src IP address of the last packet */
-	struct eg_ctrl_info  ctrl_info;
-	refcount_t             use;
-} eg_cache_entry;
-
-struct eg_cache_ops{
-	eg_cache_entry *(*add_entry)(struct k_message *msg, struct mpoa_client *client);
-	eg_cache_entry *(*get_by_cache_id)(__be32 cache_id, struct mpoa_client *client);
-	eg_cache_entry *(*get_by_tag)(__be32 cache_id, struct mpoa_client *client);
-	eg_cache_entry *(*get_by_vcc)(struct atm_vcc *vcc, struct mpoa_client *client);
-	eg_cache_entry *(*get_by_src_ip)(__be32 ipaddr, struct mpoa_client *client);
-	void            (*put)(eg_cache_entry *entry);
-	void            (*remove_entry)(eg_cache_entry *entry, struct mpoa_client *client);
-	void            (*update)(eg_cache_entry *entry, uint16_t holding_time);
-	void            (*clear_expired)(struct mpoa_client *client);
-	void            (*destroy_cache)(struct mpoa_client *mpc);
-};
-
-
-/* Ingress cache entry states */
-
-#define INGRESS_REFRESHING 3
-#define INGRESS_RESOLVED   2
-#define INGRESS_RESOLVING  1
-#define INGRESS_INVALID    0
-
-/* VCC states */
-
-#define OPEN   1
-#define CLOSED 0
-
-/* Egress cache entry states */
-
-#define EGRESS_RESOLVED 2
-#define EGRESS_PURGE    1
-#define EGRESS_INVALID  0
-
-#endif
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 361a9b84451e..bed1b1d9b282 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -855,7 +855,6 @@ void br_fdb_delete_by_port(struct net_bridge *br,
 struct net_bridge_fdb_entry *br_fdb_find_rcu(struct net_bridge *br,
 					     const unsigned char *addr,
 					     __u16 vid);
-int br_fdb_test_addr(struct net_device *dev, unsigned char *addr);
 int br_fdb_fillbuf(struct net_bridge *br, void *buf, unsigned long count,
 		   unsigned long off);
 int br_fdb_add_local(struct net_bridge *br, struct net_bridge_port *source,
@@ -2065,9 +2064,6 @@ void br_stp_port_timer_init(struct net_bridge_port *p);
 unsigned long br_timer_value(const struct timer_list *timer);
 
 /* br.c */
-#if IS_ENABLED(CONFIG_ATM_LANE)
-extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr);
-#endif
 
 /* br_mrp.c */
 #if IS_ENABLED(CONFIG_BRIDGE_MRP)
diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c
deleted file mode 100644
index c8d00537d236..000000000000
--- a/drivers/atm/adummy.c
+++ /dev/null
@@ -1,202 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * adummy.c: a dummy ATM driver
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-#include <linux/uaccess.h>
-
-#include <linux/atmdev.h>
-#include <linux/atm.h>
-#include <linux/sonet.h>
-
-/* version definition */
-
-#define DRV_VERSION "1.0"
-
-#define DEV_LABEL "adummy"
-
-#define ADUMMY_DEV(dev) ((struct adummy_dev *) (dev)->dev_data)
-
-struct adummy_dev {
-	struct atm_dev *atm_dev;
-
-	struct list_head entry;
-};
-
-/* globals */
-
-static LIST_HEAD(adummy_devs);
-
-static ssize_t __set_signal(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf, size_t len)
-{
-	struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev);
-	int signal;
-
-	if (sscanf(buf, "%d", &signal) == 1) {
-
-		if (signal < ATM_PHY_SIG_LOST || signal > ATM_PHY_SIG_FOUND)
-			signal = ATM_PHY_SIG_UNKNOWN;
-
-		atm_dev_signal_change(atm_dev, signal);
-		return 1;
-	}
-	return -EINVAL;
-}
-
-static ssize_t __show_signal(struct device *dev,
-	struct device_attribute *attr, char *buf)
-{
-	struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev);
-	return sprintf(buf, "%d\n", atm_dev->signal);
-}
-static DEVICE_ATTR(signal, 0644, __show_signal, __set_signal);
-
-static struct attribute *adummy_attrs[] = {
-	&dev_attr_signal.attr,
-	NULL
-};
-
-static const struct attribute_group adummy_group_attrs = {
-	.name = NULL, /* We want them in dev's root folder */
-	.attrs = adummy_attrs
-};
-
-static int __init
-adummy_start(struct atm_dev *dev)
-{
-	dev->ci_range.vpi_bits = 4;
-	dev->ci_range.vci_bits = 12;
-
-	return 0;
-}
-
-static int
-adummy_open(struct atm_vcc *vcc)
-{
-	short vpi = vcc->vpi;
-	int vci = vcc->vci;
-
-	if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
-		return 0;
-
-	set_bit(ATM_VF_ADDR, &vcc->flags);
-	set_bit(ATM_VF_READY, &vcc->flags);
-
-	return 0;
-}
-
-static void
-adummy_close(struct atm_vcc *vcc)
-{
-	clear_bit(ATM_VF_READY, &vcc->flags);
-	clear_bit(ATM_VF_ADDR, &vcc->flags);
-}
-
-static int
-adummy_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	if (vcc->pop)
-		vcc->pop(vcc, skb);
-	else
-		dev_kfree_skb_any(skb);
-	atomic_inc(&vcc->stats->tx);
-
-	return 0;
-}
-
-static int
-adummy_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
-{
-	int left = *pos;
-
-	if (!left--)
-		return sprintf(page, "version %s\n", DRV_VERSION);
-
-	return 0;
-}
-
-static const struct atmdev_ops adummy_ops =
-{
-	.open =		adummy_open,
-	.close =	adummy_close,	
-	.send =		adummy_send,
-	.proc_read =	adummy_proc_read,
-	.owner =	THIS_MODULE
-};
-
-static int __init adummy_init(void)
-{
-	struct atm_dev *atm_dev;
-	struct adummy_dev *adummy_dev;
-	int err = 0;
-
-	printk(KERN_ERR "adummy: version %s\n", DRV_VERSION);
-
-	adummy_dev = kzalloc_obj(struct adummy_dev);
-	if (!adummy_dev) {
-		printk(KERN_ERR DEV_LABEL ": kzalloc() failed\n");
-		err = -ENOMEM;
-		goto out;
-	}
-	atm_dev = atm_dev_register(DEV_LABEL, NULL, &adummy_ops, -1, NULL);
-	if (!atm_dev) {
-		printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
-		err = -ENODEV;
-		goto out_kfree;
-	}
-
-	adummy_dev->atm_dev = atm_dev;
-	atm_dev->dev_data = adummy_dev;
-
-	if (sysfs_create_group(&atm_dev->class_dev.kobj, &adummy_group_attrs))
-		dev_err(&atm_dev->class_dev, "Could not register attrs for adummy\n");
-
-	if (adummy_start(atm_dev)) {
-		printk(KERN_ERR DEV_LABEL ": adummy_start() failed\n");
-		err = -ENODEV;
-		goto out_unregister;
-	}
-
-	list_add(&adummy_dev->entry, &adummy_devs);
-out:
-	return err;
-
-out_unregister:
-	atm_dev_deregister(atm_dev);
-out_kfree:
-	kfree(adummy_dev);
-	goto out;
-}
-
-static void __exit adummy_cleanup(void)
-{
-	struct adummy_dev *adummy_dev, *next;
-
-	list_for_each_entry_safe(adummy_dev, next, &adummy_devs, entry) {
-		atm_dev_deregister(adummy_dev->atm_dev);
-		kfree(adummy_dev);
-	}
-}
-
-module_init(adummy_init);
-module_exit(adummy_cleanup);
-
-MODULE_AUTHOR("chas williams <chas@cmf.nrl.navy.mil>");
-MODULE_DESCRIPTION("dummy ATM driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
deleted file mode 100644
index 96719851ae2a..000000000000
--- a/drivers/atm/atmtcp.c
+++ /dev/null
@@ -1,513 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* drivers/atm/atmtcp.c - ATM over TCP "device" driver */
-
-/* Written 1997-2000 by Werner Almesberger, EPFL LRC/ICA */
-
-
-#include <linux/module.h>
-#include <linux/wait.h>
-#include <linux/atmdev.h>
-#include <linux/atm_tcp.h>
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/atomic.h>
-
-
-extern int atm_init_aal5(struct atm_vcc *vcc); /* "raw" AAL5 transport */
-
-
-#define PRIV(dev) ((struct atmtcp_dev_data *) ((dev)->dev_data))
-
-
-struct atmtcp_dev_data {
-	struct atm_vcc *vcc;	/* control VCC; NULL if detached */
-	int persist;		/* non-zero if persistent */
-};
-
-
-#define DEV_LABEL    "atmtcp"
-
-#define MAX_VPI_BITS  8	/* simplifies life */
-#define MAX_VCI_BITS 16
-
-
-/*
- * Hairy code ahead: the control VCC may be closed while we're still
- * waiting for an answer, so we need to re-validate out_vcc every once
- * in a while.
- */
-
-
-static int atmtcp_send_control(struct atm_vcc *vcc,int type,
-    const struct atmtcp_control *msg,int flag)
-{
-	DECLARE_WAITQUEUE(wait,current);
-	struct atm_vcc *out_vcc;
-	struct sk_buff *skb;
-	struct atmtcp_control *new_msg;
-	int old_test;
-	int error = 0;
-
-	out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
-	if (!out_vcc) return -EUNATCH;
-	skb = alloc_skb(sizeof(*msg),GFP_KERNEL);
-	if (!skb) return -ENOMEM;
-	mb();
-	out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
-	if (!out_vcc) {
-		dev_kfree_skb(skb);
-		return -EUNATCH;
-	}
-	atm_force_charge(out_vcc,skb->truesize);
-	new_msg = skb_put(skb, sizeof(*new_msg));
-	*new_msg = *msg;
-	new_msg->hdr.length = ATMTCP_HDR_MAGIC;
-	new_msg->type = type;
-	memset(&new_msg->vcc,0,sizeof(atm_kptr_t));
-	*(struct atm_vcc **) &new_msg->vcc = vcc;
-	old_test = test_bit(flag,&vcc->flags);
-	out_vcc->push(out_vcc,skb);
-	add_wait_queue(sk_sleep(sk_atm(vcc)), &wait);
-	while (test_bit(flag,&vcc->flags) == old_test) {
-		mb();
-		out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
-		if (!out_vcc) {
-			error = -EUNATCH;
-			break;
-		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule();
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(sk_sleep(sk_atm(vcc)), &wait);
-	return error;
-}
-
-
-static int atmtcp_recv_control(const struct atmtcp_control *msg)
-{
-	struct atm_vcc *vcc = *(struct atm_vcc **) &msg->vcc;
-
-	vcc->vpi = msg->addr.sap_addr.vpi;
-	vcc->vci = msg->addr.sap_addr.vci;
-	vcc->qos = msg->qos;
-	sk_atm(vcc)->sk_err = -msg->result;
-	switch (msg->type) {
-	    case ATMTCP_CTRL_OPEN:
-		change_bit(ATM_VF_READY,&vcc->flags);
-		break;
-	    case ATMTCP_CTRL_CLOSE:
-		change_bit(ATM_VF_ADDR,&vcc->flags);
-		break;
-	    default:
-		printk(KERN_ERR "atmtcp_recv_control: unknown type %d\n",
-		    msg->type);
-		return -EINVAL;
-	}
-	wake_up(sk_sleep(sk_atm(vcc)));
-	return 0;
-}
-
-
-static void atmtcp_v_dev_close(struct atm_dev *dev)
-{
-	/* Nothing.... Isn't this simple :-)  -- REW */
-}
-
-
-static int atmtcp_v_open(struct atm_vcc *vcc)
-{
-	struct atmtcp_control msg;
-	int error;
-	short vpi = vcc->vpi;
-	int vci = vcc->vci;
-
-	memset(&msg,0,sizeof(msg));
-	msg.addr.sap_family = AF_ATMPVC;
-	msg.hdr.vpi = htons(vpi);
-	msg.addr.sap_addr.vpi = vpi;
-	msg.hdr.vci = htons(vci);
-	msg.addr.sap_addr.vci = vci;
-	if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) return 0;
-	msg.type = ATMTCP_CTRL_OPEN;
-	msg.qos = vcc->qos;
-	set_bit(ATM_VF_ADDR,&vcc->flags);
-	clear_bit(ATM_VF_READY,&vcc->flags); /* just in case ... */
-	error = atmtcp_send_control(vcc,ATMTCP_CTRL_OPEN,&msg,ATM_VF_READY);
-	if (error) return error;
-	return -sk_atm(vcc)->sk_err;
-}
-
-
-static void atmtcp_v_close(struct atm_vcc *vcc)
-{
-	struct atmtcp_control msg;
-
-	memset(&msg,0,sizeof(msg));
-	msg.addr.sap_family = AF_ATMPVC;
-	msg.addr.sap_addr.vpi = vcc->vpi;
-	msg.addr.sap_addr.vci = vcc->vci;
-	clear_bit(ATM_VF_READY,&vcc->flags);
-	(void) atmtcp_send_control(vcc,ATMTCP_CTRL_CLOSE,&msg,ATM_VF_ADDR);
-}
-
-
-static int atmtcp_v_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
-{
-	struct atm_cirange ci;
-	struct atm_vcc *vcc;
-	struct sock *s;
-	int i;
-
-	if (cmd != ATM_SETCIRANGE) return -ENOIOCTLCMD;
-	if (copy_from_user(&ci, arg,sizeof(ci))) return -EFAULT;
-	if (ci.vpi_bits == ATM_CI_MAX) ci.vpi_bits = MAX_VPI_BITS;
-	if (ci.vci_bits == ATM_CI_MAX) ci.vci_bits = MAX_VCI_BITS;
-	if (ci.vpi_bits > MAX_VPI_BITS || ci.vpi_bits < 0 ||
-	    ci.vci_bits > MAX_VCI_BITS || ci.vci_bits < 0) return -EINVAL;
-	read_lock(&vcc_sklist_lock);
-	for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
-		struct hlist_head *head = &vcc_hash[i];
-
-		sk_for_each(s, head) {
-			vcc = atm_sk(s);
-			if (vcc->dev != dev)
-				continue;
-			if ((vcc->vpi >> ci.vpi_bits) ||
-			    (vcc->vci >> ci.vci_bits)) {
-				read_unlock(&vcc_sklist_lock);
-				return -EBUSY;
-			}
-		}
-	}
-	read_unlock(&vcc_sklist_lock);
-	dev->ci_range = ci;
-	return 0;
-}
-
-
-static int atmtcp_v_send(struct atm_vcc *vcc,struct sk_buff *skb)
-{
-	struct atmtcp_dev_data *dev_data;
-	struct atm_vcc *out_vcc=NULL; /* Initializer quietens GCC warning */
-	struct sk_buff *new_skb;
-	struct atmtcp_hdr *hdr;
-	int size;
-
-	if (vcc->qos.txtp.traffic_class == ATM_NONE) {
-		if (vcc->pop) vcc->pop(vcc,skb);
-		else dev_kfree_skb(skb);
-		return -EINVAL;
-	}
-	dev_data = PRIV(vcc->dev);
-	if (dev_data) out_vcc = dev_data->vcc;
-	if (!dev_data || !out_vcc) {
-		if (vcc->pop) vcc->pop(vcc,skb);
-		else dev_kfree_skb(skb);
-		if (dev_data) return 0;
-		atomic_inc(&vcc->stats->tx_err);
-		return -ENOLINK;
-	}
-	size = skb->len+sizeof(struct atmtcp_hdr);
-	new_skb = atm_alloc_charge(out_vcc,size,GFP_ATOMIC);
-	if (!new_skb) {
-		if (vcc->pop) vcc->pop(vcc,skb);
-		else dev_kfree_skb(skb);
-		atomic_inc(&vcc->stats->tx_err);
-		return -ENOBUFS;
-	}
-	hdr = skb_put(new_skb, sizeof(struct atmtcp_hdr));
-	hdr->vpi = htons(vcc->vpi);
-	hdr->vci = htons(vcc->vci);
-	hdr->length = htonl(skb->len);
-	skb_copy_from_linear_data(skb, skb_put(new_skb, skb->len), skb->len);
-	if (vcc->pop) vcc->pop(vcc,skb);
-	else dev_kfree_skb(skb);
-	out_vcc->push(out_vcc,new_skb);
-	atomic_inc(&vcc->stats->tx);
-	atomic_inc(&out_vcc->stats->rx);
-	return 0;
-}
-
-
-static int atmtcp_v_proc(struct atm_dev *dev,loff_t *pos,char *page)
-{
-	struct atmtcp_dev_data *dev_data = PRIV(dev);
-
-	if (*pos) return 0;
-	if (!dev_data->persist) return sprintf(page,"ephemeral\n");
-	return sprintf(page,"persistent, %sconnected\n",
-	    dev_data->vcc ? "" : "dis");
-}
-
-
-static void atmtcp_c_close(struct atm_vcc *vcc)
-{
-	struct atm_dev *atmtcp_dev;
-	struct atmtcp_dev_data *dev_data;
-
-	atmtcp_dev = (struct atm_dev *) vcc->dev_data;
-	dev_data = PRIV(atmtcp_dev);
-	dev_data->vcc = NULL;
-	if (dev_data->persist) return;
-	atmtcp_dev->dev_data = NULL;
-	kfree(dev_data);
-	atm_dev_deregister(atmtcp_dev);
-	vcc->dev_data = NULL;
-	module_put(THIS_MODULE);
-}
-
-
-static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
-{
-        struct hlist_head *head;
-        struct atm_vcc *vcc;
-        struct sock *s;
-
-        head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)];
-
-	sk_for_each(s, head) {
-                vcc = atm_sk(s);
-                if (vcc->dev == dev &&
-                    vcc->vci == vci && vcc->vpi == vpi &&
-                    vcc->qos.rxtp.traffic_class != ATM_NONE) {
-                                return vcc;
-                }
-        }
-        return NULL;
-}
-
-static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	struct atmtcp_hdr *hdr;
-
-	if (skb->len < sizeof(struct atmtcp_hdr))
-		return -EINVAL;
-
-	hdr = (struct atmtcp_hdr *)skb->data;
-	if (hdr->length == ATMTCP_HDR_MAGIC)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
-{
-	struct atm_dev *dev;
-	struct atmtcp_hdr *hdr;
-	struct atm_vcc *out_vcc;
-	struct sk_buff *new_skb;
-	int result = 0;
-
-	dev = vcc->dev_data;
-	hdr = (struct atmtcp_hdr *) skb->data;
-	if (hdr->length == ATMTCP_HDR_MAGIC) {
-		result = atmtcp_recv_control(
-		    (struct atmtcp_control *) skb->data);
-		goto done;
-	}
-	read_lock(&vcc_sklist_lock);
-	out_vcc = find_vcc(dev, ntohs(hdr->vpi), ntohs(hdr->vci));
-	read_unlock(&vcc_sklist_lock);
-	if (!out_vcc) {
-		result = -EUNATCH;
-		atomic_inc(&vcc->stats->tx_err);
-		goto done;
-	}
-	skb_pull(skb,sizeof(struct atmtcp_hdr));
-	new_skb = atm_alloc_charge(out_vcc,skb->len,GFP_KERNEL);
-	if (!new_skb) {
-		result = -ENOBUFS;
-		goto done;
-	}
-	__net_timestamp(new_skb);
-	skb_copy_from_linear_data(skb, skb_put(new_skb, skb->len), skb->len);
-	out_vcc->push(out_vcc,new_skb);
-	atomic_inc(&vcc->stats->tx);
-	atomic_inc(&out_vcc->stats->rx);
-done:
-	if (vcc->pop) vcc->pop(vcc,skb);
-	else dev_kfree_skb(skb);
-	return result;
-}
-
-
-/*
- * Device operations for the virtual ATM devices created by ATMTCP.
- */
-
-
-static const struct atmdev_ops atmtcp_v_dev_ops = {
-	.dev_close	= atmtcp_v_dev_close,
-	.open		= atmtcp_v_open,
-	.close		= atmtcp_v_close,
-	.ioctl		= atmtcp_v_ioctl,
-	.send		= atmtcp_v_send,
-	.proc_read	= atmtcp_v_proc,
-	.owner		= THIS_MODULE
-};
-
-
-/*
- * Device operations for the ATMTCP control device.
- */
-
-
-static const struct atmdev_ops atmtcp_c_dev_ops = {
-	.close		= atmtcp_c_close,
-	.pre_send	= atmtcp_c_pre_send,
-	.send		= atmtcp_c_send
-};
-
-
-static struct atm_dev atmtcp_control_dev = {
-	.ops		= &atmtcp_c_dev_ops,
-	.type		= "atmtcp",
-	.number		= 999,
-	.lock		= __SPIN_LOCK_UNLOCKED(atmtcp_control_dev.lock)
-};
-
-
-static int atmtcp_create(int itf,int persist,struct atm_dev **result)
-{
-	struct atmtcp_dev_data *dev_data;
-	struct atm_dev *dev;
-
-	dev_data = kmalloc_obj(*dev_data);
-	if (!dev_data)
-		return -ENOMEM;
-
-	dev = atm_dev_register(DEV_LABEL,NULL,&atmtcp_v_dev_ops,itf,NULL);
-	if (!dev) {
-		kfree(dev_data);
-		return itf == -1 ? -ENOMEM : -EBUSY;
-	}
-	dev->ci_range.vpi_bits = MAX_VPI_BITS;
-	dev->ci_range.vci_bits = MAX_VCI_BITS;
-	dev->dev_data = dev_data;
-	PRIV(dev)->vcc = NULL;
-	PRIV(dev)->persist = persist;
-	if (result) *result = dev;
-	return 0;
-}
-
-
-static int atmtcp_attach(struct atm_vcc *vcc,int itf)
-{
-	struct atm_dev *dev;
-
-	dev = NULL;
-	if (itf != -1) dev = atm_dev_lookup(itf);
-	if (dev) {
-		if (dev->ops != &atmtcp_v_dev_ops) {
-			atm_dev_put(dev);
-			return -EMEDIUMTYPE;
-		}
-		if (PRIV(dev)->vcc) {
-			atm_dev_put(dev);
-			return -EBUSY;
-		}
-	}
-	else {
-		int error;
-
-		error = atmtcp_create(itf,0,&dev);
-		if (error) return error;
-	}
-	PRIV(dev)->vcc = vcc;
-	vcc->dev = &atmtcp_control_dev;
-	vcc_insert_socket(sk_atm(vcc));
-	set_bit(ATM_VF_META,&vcc->flags);
-	set_bit(ATM_VF_READY,&vcc->flags);
-	vcc->dev_data = dev;
-	(void) atm_init_aal5(vcc); /* @@@ losing AAL in transit ... */
-	vcc->stats = &atmtcp_control_dev.stats.aal5;
-	return dev->number;
-}
-
-
-static int atmtcp_create_persistent(int itf)
-{
-	return atmtcp_create(itf,1,NULL);
-}
-
-
-static int atmtcp_remove_persistent(int itf)
-{
-	struct atm_dev *dev;
-	struct atmtcp_dev_data *dev_data;
-
-	dev = atm_dev_lookup(itf);
-	if (!dev) return -ENODEV;
-	if (dev->ops != &atmtcp_v_dev_ops) {
-		atm_dev_put(dev);
-		return -EMEDIUMTYPE;
-	}
-	dev_data = PRIV(dev);
-	if (!dev_data->persist) {
-		atm_dev_put(dev);
-		return 0;
-	}
-	dev_data->persist = 0;
-	if (PRIV(dev)->vcc) {
-		atm_dev_put(dev);
-		return 0;
-	}
-	kfree(dev_data);
-	atm_dev_put(dev);
-	atm_dev_deregister(dev);
-	return 0;
-}
-
-static int atmtcp_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
-	int err = 0;
-	struct atm_vcc *vcc = ATM_SD(sock);
-
-	if (cmd != SIOCSIFATMTCP && cmd != ATMTCP_CREATE && cmd != ATMTCP_REMOVE)
-		return -ENOIOCTLCMD;
-
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
-	switch (cmd) {
-		case SIOCSIFATMTCP:
-			err = atmtcp_attach(vcc, (int) arg);
-			if (err >= 0) {
-				sock->state = SS_CONNECTED;
-				__module_get(THIS_MODULE);
-			}
-			break;
-		case ATMTCP_CREATE:
-			err = atmtcp_create_persistent((int) arg);
-			break;
-		case ATMTCP_REMOVE:
-			err = atmtcp_remove_persistent((int) arg);
-			break;
-	}
-	return err;
-}
-
-static struct atm_ioctl atmtcp_ioctl_ops = {
-	.owner 	= THIS_MODULE,
-	.ioctl	= atmtcp_ioctl,
-};
-
-static __init int atmtcp_init(void)
-{
-	register_atm_ioctl(&atmtcp_ioctl_ops);
-	return 0;
-}
-
-
-static void __exit atmtcp_exit(void)
-{
-	deregister_atm_ioctl(&atmtcp_ioctl_ops);
-}
-
-MODULE_DESCRIPTION("ATM over TCP");
-MODULE_LICENSE("GPL");
-module_init(atmtcp_init);
-module_exit(atmtcp_exit);
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
deleted file mode 100644
index 12cb3aa588bc..000000000000
--- a/drivers/atm/eni.c
+++ /dev/null
@@ -1,2321 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* drivers/atm/eni.c - Efficient Networks ENI155P device driver */
- 
-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
- 
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <linux/sonet.h>
-#include <linux/skbuff.h>
-#include <linux/time.h>
-#include <linux/delay.h>
-#include <linux/uio.h>
-#include <linux/init.h>
-#include <linux/atm_eni.h>
-#include <linux/bitops.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-#include <linux/uaccess.h>
-#include <asm/string.h>
-#include <asm/byteorder.h>
-
-#include "tonga.h"
-#include "midway.h"
-#include "suni.h"
-#include "eni.h"
-
-/*
- * TODO:
- *
- * Show stoppers
- *  none
- *
- * Minor
- *  - OAM support
- *  - fix bugs listed below
- */
-
-/*
- * KNOWN BUGS:
- *
- * - may run into JK-JK bug and deadlock
- * - should allocate UBR channel first
- * - buffer space allocation algorithm is stupid
- *   (RX: should be maxSDU+maxdelay*rate
- *    TX: should be maxSDU+min(maxSDU,maxdelay*rate) )
- * - doesn't support OAM cells
- * - eni_put_free may hang if not putting memory fragments that _complete_
- *   2^n block (never happens in real life, though)
- */
-
-
-#if 0
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
-
-#ifndef CONFIG_ATM_ENI_TUNE_BURST
-#define CONFIG_ATM_ENI_BURST_TX_8W
-#define CONFIG_ATM_ENI_BURST_RX_4W
-#endif
-
-
-#ifndef CONFIG_ATM_ENI_DEBUG
-
-
-#define NULLCHECK(x)
-
-#define EVENT(s,a,b)
-
-
-static void event_dump(void)
-{
-}
-
-
-#else
-
-
-/* 
- * NULL pointer checking
- */
-
-#define NULLCHECK(x) \
-	if ((unsigned long) (x) < 0x30) \
-		printk(KERN_CRIT #x "==0x%lx\n",(unsigned long) (x))
-
-/*
- * Very extensive activity logging. Greatly improves bug detection speed but
- * costs a few Mbps if enabled.
- */
-
-#define EV 64
-
-static const char *ev[EV];
-static unsigned long ev_a[EV],ev_b[EV];
-static int ec = 0;
-
-
-static void EVENT(const char *s,unsigned long a,unsigned long b)
-{
-	ev[ec] = s; 
-	ev_a[ec] = a;
-	ev_b[ec] = b;
-	ec = (ec+1) % EV;
-}
-
-
-static void event_dump(void)
-{
-	int n,i;
-
-	for (n = 0; n < EV; n++) {
-		i = (ec+n) % EV;
-		printk(KERN_NOTICE);
-		printk(ev[i] ? ev[i] : "(null)",ev_a[i],ev_b[i]);
-	}
-}
-
-
-#endif /* CONFIG_ATM_ENI_DEBUG */
-
-
-/*
- * NExx   must not be equal at end
- * EExx   may be equal at end
- * xxPJOK verify validity of pointer jumps
- * xxPMOK operating on a circular buffer of "c" words
- */
-
-#define NEPJOK(a0,a1,b) \
-    ((a0) < (a1) ? (b) <= (a0) || (b) > (a1) : (b) <= (a0) && (b) > (a1))
-#define EEPJOK(a0,a1,b) \
-    ((a0) < (a1) ? (b) < (a0) || (b) >= (a1) : (b) < (a0) && (b) >= (a1))
-#define NEPMOK(a0,d,b,c) NEPJOK(a0,(a0+d) & (c-1),b)
-#define EEPMOK(a0,d,b,c) EEPJOK(a0,(a0+d) & (c-1),b)
-
-
-static int tx_complete = 0,dma_complete = 0,queued = 0,requeued = 0,
-  backlogged = 0,rx_enqueued = 0,rx_dequeued = 0,pushed = 0,submitted = 0,
-  putting = 0;
-
-static struct atm_dev *eni_boards = NULL;
-
-/* Read/write registers on card */
-#define eni_in(r)	readl(eni_dev->reg+(r)*4)
-#define eni_out(v,r)	writel((v),eni_dev->reg+(r)*4)
-
-
-/*-------------------------------- utilities --------------------------------*/
-
-
-static void dump_mem(struct eni_dev *eni_dev)
-{
-	int i;
-
-	for (i = 0; i < eni_dev->free_len; i++)
-		printk(KERN_DEBUG "  %d: %p %d\n",i,
-		    eni_dev->free_list[i].start,
-		    1 << eni_dev->free_list[i].order);
-}
-
-
-static void dump(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-
-	int i;
-
-	eni_dev = ENI_DEV(dev);
-	printk(KERN_NOTICE "Free memory\n");
-	dump_mem(eni_dev);
-	printk(KERN_NOTICE "TX buffers\n");
-	for (i = 0; i < NR_CHAN; i++)
-		if (eni_dev->tx[i].send)
-			printk(KERN_NOTICE "  TX %d @ %p: %ld\n",i,
-			    eni_dev->tx[i].send,eni_dev->tx[i].words*4);
-	printk(KERN_NOTICE "RX buffers\n");
-	for (i = 0; i < 1024; i++)
-		if (eni_dev->rx_map[i] && ENI_VCC(eni_dev->rx_map[i])->rx)
-			printk(KERN_NOTICE "  RX %d @ %p: %ld\n",i,
-			    ENI_VCC(eni_dev->rx_map[i])->recv,
-			    ENI_VCC(eni_dev->rx_map[i])->words*4);
-	printk(KERN_NOTICE "----\n");
-}
-
-
-static void eni_put_free(struct eni_dev *eni_dev, void __iomem *start,
-    unsigned long size)
-{
-	struct eni_free *list;
-	int len,order;
-
-	DPRINTK("init 0x%lx+%ld(0x%lx)\n",start,size,size);
-	start += eni_dev->base_diff;
-	list = eni_dev->free_list;
-	len = eni_dev->free_len;
-	while (size) {
-		if (len >= eni_dev->free_list_size) {
-			printk(KERN_CRIT "eni_put_free overflow (%p,%ld)\n",
-			    start,size);
-			break;
-		}
-		for (order = 0; !(((unsigned long)start | size) & (1 << order)); order++);
-		if (MID_MIN_BUF_SIZE > (1 << order)) {
-			printk(KERN_CRIT "eni_put_free: order %d too small\n",
-			    order);
-			break;
-		}
-		list[len].start = (void __iomem *) start;
-		list[len].order = order;
-		len++;
-		start += 1 << order;
-		size -= 1 << order;
-	}
-	eni_dev->free_len = len;
-	/*dump_mem(eni_dev);*/
-}
-
-
-static void __iomem *eni_alloc_mem(struct eni_dev *eni_dev, unsigned long *size)
-{
-	struct eni_free *list;
-	void __iomem *start;
-	int len,i,order,best_order,index;
-
-	list = eni_dev->free_list;
-	len = eni_dev->free_len;
-	if (*size < MID_MIN_BUF_SIZE) *size = MID_MIN_BUF_SIZE;
-	if (*size > MID_MAX_BUF_SIZE) return NULL;
-	for (order = 0; (1 << order) < *size; order++)
-		;
-	DPRINTK("trying: %ld->%d\n",*size,order);
-	best_order = 65; /* we don't have more than 2^64 of anything ... */
-	index = 0; /* silence GCC */
-	for (i = 0; i < len; i++)
-		if (list[i].order == order) {
-			best_order = order;
-			index = i;
-			break;
-		}
-		else if (best_order > list[i].order && list[i].order > order) {
-				best_order = list[i].order;
-				index = i;
-			}
-	if (best_order == 65) return NULL;
-	start = list[index].start-eni_dev->base_diff;
-	list[index] = list[--len];
-	eni_dev->free_len = len;
-	*size = 1 << order;
-	eni_put_free(eni_dev,start+*size,(1 << best_order)-*size);
-	DPRINTK("%ld bytes (order %d) at 0x%lx\n",*size,order,start);
-	memset_io(start,0,*size);       /* never leak data */
-	/*dump_mem(eni_dev);*/
-	return start;
-}
-
-
-static void eni_free_mem(struct eni_dev *eni_dev, void __iomem *start,
-    unsigned long size)
-{
-	struct eni_free *list;
-	int len,i,order;
-
-	start += eni_dev->base_diff;
-	list = eni_dev->free_list;
-	len = eni_dev->free_len;
-	for (order = -1; size; order++) size >>= 1;
-	DPRINTK("eni_free_mem: %p+0x%lx (order %d)\n",start,size,order);
-	for (i = 0; i < len; i++)
-		if (((unsigned long) list[i].start) == ((unsigned long)start^(1 << order)) &&
-		    list[i].order == order) {
-			DPRINTK("match[%d]: 0x%lx/0x%lx(0x%x), %d/%d\n",i,
-			    list[i].start,start,1 << order,list[i].order,order);
-			list[i] = list[--len];
-			start = (void __iomem *) ((unsigned long) start & ~(unsigned long) (1 << order));
-			order++;
-			i = -1;
-			continue;
-		}
-	if (len >= eni_dev->free_list_size) {
-		printk(KERN_ALERT "eni_free_mem overflow (%p,%d)\n",start,
-		    order);
-		return;
-	}
-	list[len].start = start;
-	list[len].order = order;
-	eni_dev->free_len = len+1;
-	/*dump_mem(eni_dev);*/
-}
-
-
-/*----------------------------------- RX ------------------------------------*/
-
-
-#define ENI_VCC_NOS ((struct atm_vcc *) 1)
-
-
-static void rx_ident_err(struct atm_vcc *vcc)
-{
-	struct atm_dev *dev;
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-
-	dev = vcc->dev;
-	eni_dev = ENI_DEV(dev);
-	/* immediately halt adapter */
-	eni_out(eni_in(MID_MC_S) &
-	    ~(MID_DMA_ENABLE | MID_TX_ENABLE | MID_RX_ENABLE),MID_MC_S);
-	/* dump useful information */
-	eni_vcc = ENI_VCC(vcc);
-	printk(KERN_ALERT DEV_LABEL "(itf %d): driver error - RX ident "
-	    "mismatch\n",dev->number);
-	printk(KERN_ALERT "  VCI %d, rxing %d, words %ld\n",vcc->vci,
-	    eni_vcc->rxing,eni_vcc->words);
-	printk(KERN_ALERT "  host descr 0x%lx, rx pos 0x%lx, descr value "
-	    "0x%x\n",eni_vcc->descr,eni_vcc->rx_pos,
-	    (unsigned) readl(eni_vcc->recv+eni_vcc->descr*4));
-	printk(KERN_ALERT "  last %p, servicing %d\n",eni_vcc->last,
-	    eni_vcc->servicing);
-	EVENT("---dump ends here---\n",0,0);
-	printk(KERN_NOTICE "---recent events---\n");
-	event_dump();
-	ENI_DEV(dev)->fast = NULL; /* really stop it */
-	ENI_DEV(dev)->slow = NULL;
-	skb_queue_head_init(&ENI_DEV(dev)->rx_queue);
-}
-
-
-static int do_rx_dma(struct atm_vcc *vcc,struct sk_buff *skb,
-    unsigned long skip,unsigned long size,unsigned long eff)
-{
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-	u32 dma_rd,dma_wr;
-	u32 dma[RX_DMA_BUF*2];
-	dma_addr_t paddr;
-	unsigned long here;
-	int i,j;
-
-	eni_dev = ENI_DEV(vcc->dev);
-	eni_vcc = ENI_VCC(vcc);
-	paddr = 0; /* GCC, shut up */
-	if (skb) {
-		paddr = dma_map_single(&eni_dev->pci_dev->dev,skb->data,skb->len,
-				       DMA_FROM_DEVICE);
-		if (dma_mapping_error(&eni_dev->pci_dev->dev, paddr))
-			goto dma_map_error;
-		ENI_PRV_PADDR(skb) = paddr;
-		if (paddr & 3)
-			printk(KERN_CRIT DEV_LABEL "(itf %d): VCI %d has "
-			    "mis-aligned RX data (0x%lx)\n",vcc->dev->number,
-			    vcc->vci,(unsigned long) paddr);
-		ENI_PRV_SIZE(skb) = size+skip;
-		    /* PDU plus descriptor */
-		ATM_SKB(skb)->vcc = vcc;
-	}
-	j = 0;
-	if ((eff && skip) || 1) { /* @@@ actually, skip is always == 1 ... */
-		here = (eni_vcc->descr+skip) & (eni_vcc->words-1);
-		dma[j++] = (here << MID_DMA_COUNT_SHIFT) | (vcc->vci
-		    << MID_DMA_VCI_SHIFT) | MID_DT_JK;
-		dma[j++] = 0;
-	}
-	here = (eni_vcc->descr+size+skip) & (eni_vcc->words-1);
-	if (!eff) size += skip;
-	else {
-		unsigned long words;
-
-		if (!size) {
-			DPRINTK("strange things happen ...\n");
-			EVENT("strange things happen ... (skip=%ld,eff=%ld)\n",
-			    size,eff);
-		}
-		words = eff;
-		if (paddr & 15) {
-			unsigned long init;
-
-			init = 4-((paddr & 15) >> 2);
-			if (init > words) init = words;
-			dma[j++] = MID_DT_WORD | (init << MID_DMA_COUNT_SHIFT) |
-			    (vcc->vci << MID_DMA_VCI_SHIFT);
-			dma[j++] = paddr;
-			paddr += init << 2;
-			words -= init;
-		}
-#ifdef CONFIG_ATM_ENI_BURST_RX_16W /* may work with some PCI chipsets ... */
-		if (words & ~15) {
-			dma[j++] = MID_DT_16W | ((words >> 4) <<
-			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
-			    MID_DMA_VCI_SHIFT);
-			dma[j++] = paddr;
-			paddr += (words & ~15) << 2;
-			words &= 15;
-		}
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_RX_8W  /* works only with *some* PCI chipsets ... */
-		if (words & ~7) {
-			dma[j++] = MID_DT_8W | ((words >> 3) <<
-			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
-			    MID_DMA_VCI_SHIFT);
-			dma[j++] = paddr;
-			paddr += (words & ~7) << 2;
-			words &= 7;
-		}
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_RX_4W /* recommended */
-		if (words & ~3) {
-			dma[j++] = MID_DT_4W | ((words >> 2) <<
-			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
-			    MID_DMA_VCI_SHIFT);
-			dma[j++] = paddr;
-			paddr += (words & ~3) << 2;
-			words &= 3;
-		}
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_RX_2W /* probably useless if RX_4W, RX_8W, ... */
-		if (words & ~1) {
-			dma[j++] = MID_DT_2W | ((words >> 1) <<
-			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
-			    MID_DMA_VCI_SHIFT);
-			dma[j++] = paddr;
-			paddr += (words & ~1) << 2;
-			words &= 1;
-		}
-#endif
-		if (words) {
-			dma[j++] = MID_DT_WORD | (words << MID_DMA_COUNT_SHIFT)
-			    | (vcc->vci << MID_DMA_VCI_SHIFT);
-			dma[j++] = paddr;
-		}
-	}
-	if (size != eff) {
-		dma[j++] = (here << MID_DMA_COUNT_SHIFT) |
-		    (vcc->vci << MID_DMA_VCI_SHIFT) | MID_DT_JK;
-		dma[j++] = 0;
-	}
-	if (!j || j > 2*RX_DMA_BUF) {
-		printk(KERN_CRIT DEV_LABEL "!j or j too big!!!\n");
-		goto trouble;
-	}
-	dma[j-2] |= MID_DMA_END;
-	j = j >> 1;
-	dma_wr = eni_in(MID_DMA_WR_RX);
-	dma_rd = eni_in(MID_DMA_RD_RX);
-	/*
-	 * Can I move the dma_wr pointer by 2j+1 positions without overwriting
-	 * data that hasn't been read (position of dma_rd) yet ?
-	 */
-	if (!NEPMOK(dma_wr,j+j+1,dma_rd,NR_DMA_RX)) { /* @@@ +1 is ugly */
-		printk(KERN_WARNING DEV_LABEL "(itf %d): RX DMA full\n",
-		    vcc->dev->number);
-		goto trouble;
-	}
-        for (i = 0; i < j; i++) {
-		writel(dma[i*2],eni_dev->rx_dma+dma_wr*8);
-		writel(dma[i*2+1],eni_dev->rx_dma+dma_wr*8+4);
-		dma_wr = (dma_wr+1) & (NR_DMA_RX-1);
-        }
-	if (skb) {
-		ENI_PRV_POS(skb) = eni_vcc->descr+size+1;
-		skb_queue_tail(&eni_dev->rx_queue,skb);
-		eni_vcc->last = skb;
-		rx_enqueued++;
-	}
-	eni_vcc->descr = here;
-	eni_out(dma_wr,MID_DMA_WR_RX);
-	return 0;
-
-trouble:
-	if (paddr)
-		dma_unmap_single(&eni_dev->pci_dev->dev,paddr,skb->len,
-				 DMA_FROM_DEVICE);
-dma_map_error:
-	if (skb) dev_kfree_skb_irq(skb);
-	return -1;
-}
-
-
-static void discard(struct atm_vcc *vcc,unsigned long size)
-{
-	struct eni_vcc *eni_vcc;
-
-	eni_vcc = ENI_VCC(vcc);
-	EVENT("discard (size=%ld)\n",size,0);
-	while (do_rx_dma(vcc,NULL,1,size,0)) EVENT("BUSY LOOP",0,0);
-	    /* could do a full fallback, but that might be more expensive */
-	if (eni_vcc->rxing) ENI_PRV_POS(eni_vcc->last) += size+1;
-	else eni_vcc->rx_pos = (eni_vcc->rx_pos+size+1) & (eni_vcc->words-1);
-}
-
-
-/*
- * TODO: should check whether direct copies (without DMA setup, dequeuing on
- * interrupt, etc.) aren't much faster for AAL0
- */
-
-static int rx_aal0(struct atm_vcc *vcc)
-{
-	struct eni_vcc *eni_vcc;
-	unsigned long descr;
-	unsigned long length;
-	struct sk_buff *skb;
-
-	DPRINTK(">rx_aal0\n");
-	eni_vcc = ENI_VCC(vcc);
-	descr = readl(eni_vcc->recv+eni_vcc->descr*4);
-	if ((descr & MID_RED_IDEN) != (MID_RED_RX_ID << MID_RED_SHIFT)) {
-		rx_ident_err(vcc);
-		return 1;
-	}
-	if (descr & MID_RED_T) {
-		DPRINTK(DEV_LABEL "(itf %d): trashing empty cell\n",
-		    vcc->dev->number);
-		length = 0;
-		atomic_inc(&vcc->stats->rx_err);
-	}
-	else {
-		length = ATM_CELL_SIZE-1; /* no HEC */
-	}
-	skb = length ? atm_alloc_charge(vcc,length,GFP_ATOMIC) : NULL;
-	if (!skb) {
-		discard(vcc,length >> 2);
-		return 0;
-	}
-	skb_put(skb,length);
-	skb->tstamp = eni_vcc->timestamp;
-	DPRINTK("got len %ld\n",length);
-	if (do_rx_dma(vcc,skb,1,length >> 2,length >> 2)) return 1;
-	eni_vcc->rxing++;
-	return 0;
-}
-
-
-static int rx_aal5(struct atm_vcc *vcc)
-{
-	struct eni_vcc *eni_vcc;
-	unsigned long descr;
-	unsigned long size,eff,length;
-	struct sk_buff *skb;
-
-	EVENT("rx_aal5\n",0,0);
-	DPRINTK(">rx_aal5\n");
-	eni_vcc = ENI_VCC(vcc);
-	descr = readl(eni_vcc->recv+eni_vcc->descr*4);
-	if ((descr & MID_RED_IDEN) != (MID_RED_RX_ID << MID_RED_SHIFT)) {
-		rx_ident_err(vcc);
-		return 1;
-	}
-	if (descr & (MID_RED_T | MID_RED_CRC_ERR)) {
-		if (descr & MID_RED_T) {
-			EVENT("empty cell (descr=0x%lx)\n",descr,0);
-			DPRINTK(DEV_LABEL "(itf %d): trashing empty cell\n",
-			    vcc->dev->number);
-			size = 0;
-		}
-		else {
-			static unsigned long silence = 0;
-
-			if (time_after(jiffies, silence) || silence == 0) {
-				printk(KERN_WARNING DEV_LABEL "(itf %d): "
-				    "discarding PDU(s) with CRC error\n",
-				    vcc->dev->number);
-				silence = (jiffies+2*HZ)|1;
-			}
-			size = (descr & MID_RED_COUNT)*(ATM_CELL_PAYLOAD >> 2);
-			EVENT("CRC error (descr=0x%lx,size=%ld)\n",descr,
-			    size);
-		}
-		eff = length = 0;
-		atomic_inc(&vcc->stats->rx_err);
-	}
-	else {
-		size = (descr & MID_RED_COUNT)*(ATM_CELL_PAYLOAD >> 2);
-		DPRINTK("size=%ld\n",size);
-		length = readl(eni_vcc->recv+(((eni_vcc->descr+size-1) &
-		    (eni_vcc->words-1)))*4) & 0xffff;
-				/* -trailer(2)+header(1) */
-		if (length && length <= (size << 2)-8 && length <=
-		  ATM_MAX_AAL5_PDU) eff = (length+3) >> 2;
-		else {				 /* ^ trailer length (8) */
-			EVENT("bad PDU (descr=0x08%lx,length=%ld)\n",descr,
-			    length);
-			printk(KERN_ERR DEV_LABEL "(itf %d): bad AAL5 PDU "
-			    "(VCI=%d,length=%ld,size=%ld (descr 0x%lx))\n",
-			    vcc->dev->number,vcc->vci,length,size << 2,descr);
-			length = eff = 0;
-			atomic_inc(&vcc->stats->rx_err);
-		}
-	}
-	skb = eff ? atm_alloc_charge(vcc,eff << 2,GFP_ATOMIC) : NULL;
-	if (!skb) {
-		discard(vcc,size);
-		return 0;
-	}
-	skb_put(skb,length);
-	DPRINTK("got len %ld\n",length);
-	if (do_rx_dma(vcc,skb,1,size,eff)) return 1;
-	eni_vcc->rxing++;
-	return 0;
-}
-
-
-static inline int rx_vcc(struct atm_vcc *vcc)
-{
-	void __iomem *vci_dsc;
-	unsigned long tmp;
-	struct eni_vcc *eni_vcc;
-
-	eni_vcc = ENI_VCC(vcc);
-	vci_dsc = ENI_DEV(vcc->dev)->vci+vcc->vci*16;
-	EVENT("rx_vcc(1)\n",0,0);
-	while (eni_vcc->descr != (tmp = (readl(vci_dsc+4) & MID_VCI_DESCR) >>
-	    MID_VCI_DESCR_SHIFT)) {
-		EVENT("rx_vcc(2: host dsc=0x%lx, nic dsc=0x%lx)\n",
-		    eni_vcc->descr,tmp);
-		DPRINTK("CB_DESCR %ld REG_DESCR %d\n",ENI_VCC(vcc)->descr,
-		    (((unsigned) readl(vci_dsc+4) & MID_VCI_DESCR) >>
-		    MID_VCI_DESCR_SHIFT));
-		if (ENI_VCC(vcc)->rx(vcc)) return 1;
-	}
-	/* clear IN_SERVICE flag */
-	writel(readl(vci_dsc) & ~MID_VCI_IN_SERVICE,vci_dsc);
-	/*
-	 * If new data has arrived between evaluating the while condition and
-	 * clearing IN_SERVICE, we wouldn't be notified until additional data
-	 * follows. So we have to loop again to be sure.
-	 */
-	EVENT("rx_vcc(3)\n",0,0);
-	while (ENI_VCC(vcc)->descr != (tmp = (readl(vci_dsc+4) & MID_VCI_DESCR)
-	    >> MID_VCI_DESCR_SHIFT)) {
-		EVENT("rx_vcc(4: host dsc=0x%lx, nic dsc=0x%lx)\n",
-		    eni_vcc->descr,tmp);
-		DPRINTK("CB_DESCR %ld REG_DESCR %d\n",ENI_VCC(vcc)->descr,
-		    (((unsigned) readl(vci_dsc+4) & MID_VCI_DESCR) >>
-		    MID_VCI_DESCR_SHIFT));
-		if (ENI_VCC(vcc)->rx(vcc)) return 1;
-	}
-	return 0;
-}
-
-
-static void poll_rx(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-	struct atm_vcc *curr;
-
-	eni_dev = ENI_DEV(dev);
-	while ((curr = eni_dev->fast)) {
-		EVENT("poll_rx.fast\n",0,0);
-		if (rx_vcc(curr)) return;
-		eni_dev->fast = ENI_VCC(curr)->next;
-		ENI_VCC(curr)->next = ENI_VCC_NOS;
-		barrier();
-		ENI_VCC(curr)->servicing--;
-	}
-	while ((curr = eni_dev->slow)) {
-		EVENT("poll_rx.slow\n",0,0);
-		if (rx_vcc(curr)) return;
-		eni_dev->slow = ENI_VCC(curr)->next;
-		ENI_VCC(curr)->next = ENI_VCC_NOS;
-		barrier();
-		ENI_VCC(curr)->servicing--;
-	}
-}
-
-
-static void get_service(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-	struct atm_vcc *vcc;
-	unsigned long vci;
-
-	DPRINTK(">get_service\n");
-	eni_dev = ENI_DEV(dev);
-	while (eni_in(MID_SERV_WRITE) != eni_dev->serv_read) {
-		vci = readl(eni_dev->service+eni_dev->serv_read*4);
-		eni_dev->serv_read = (eni_dev->serv_read+1) & (NR_SERVICE-1);
-		vcc = eni_dev->rx_map[vci & 1023];
-		if (!vcc) {
-			printk(KERN_CRIT DEV_LABEL "(itf %d): VCI %ld not "
-			    "found\n",dev->number,vci);
-			continue; /* nasty but we try to go on anyway */
-			/* @@@ nope, doesn't work */
-		}
-		EVENT("getting from service\n",0,0);
-		if (ENI_VCC(vcc)->next != ENI_VCC_NOS) {
-			EVENT("double service\n",0,0);
-			DPRINTK("Grr, servicing VCC %ld twice\n",vci);
-			continue;
-		}
-		ENI_VCC(vcc)->timestamp = ktime_get_real();
-		ENI_VCC(vcc)->next = NULL;
-		if (vcc->qos.rxtp.traffic_class == ATM_CBR) {
-			if (eni_dev->fast)
-				ENI_VCC(eni_dev->last_fast)->next = vcc;
-			else eni_dev->fast = vcc;
-			eni_dev->last_fast = vcc;
-		}
-		else {
-			if (eni_dev->slow)
-				ENI_VCC(eni_dev->last_slow)->next = vcc;
-			else eni_dev->slow = vcc;
-			eni_dev->last_slow = vcc;
-		}
-		putting++;
-		ENI_VCC(vcc)->servicing++;
-	}
-}
-
-
-static void dequeue_rx(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-	struct atm_vcc *vcc;
-	struct sk_buff *skb;
-	void __iomem *vci_dsc;
-	int first;
-
-	eni_dev = ENI_DEV(dev);
-	first = 1;
-	while (1) {
-		skb = skb_dequeue(&eni_dev->rx_queue);
-		if (!skb) {
-			if (first) {
-				DPRINTK(DEV_LABEL "(itf %d): RX but not "
-				    "rxing\n",dev->number);
-				EVENT("nothing to dequeue\n",0,0);
-			}
-			break;
-		}
-		EVENT("dequeued (size=%ld,pos=0x%lx)\n",ENI_PRV_SIZE(skb),
-		    ENI_PRV_POS(skb));
-		rx_dequeued++;
-		vcc = ATM_SKB(skb)->vcc;
-		eni_vcc = ENI_VCC(vcc);
-		first = 0;
-		vci_dsc = eni_dev->vci+vcc->vci*16;
-		if (!EEPMOK(eni_vcc->rx_pos,ENI_PRV_SIZE(skb),
-		    (readl(vci_dsc+4) & MID_VCI_READ) >> MID_VCI_READ_SHIFT,
-		    eni_vcc->words)) {
-			EVENT("requeuing\n",0,0);
-			skb_queue_head(&eni_dev->rx_queue,skb);
-			break;
-		}
-		eni_vcc->rxing--;
-		eni_vcc->rx_pos = ENI_PRV_POS(skb) & (eni_vcc->words-1);
-		dma_unmap_single(&eni_dev->pci_dev->dev,ENI_PRV_PADDR(skb),skb->len,
-			         DMA_TO_DEVICE);
-		if (!skb->len) dev_kfree_skb_irq(skb);
-		else {
-			EVENT("pushing (len=%ld)\n",skb->len,0);
-			if (vcc->qos.aal == ATM_AAL0)
-				*(unsigned long *) skb->data =
-				    ntohl(*(unsigned long *) skb->data);
-			memset(skb->cb,0,sizeof(struct eni_skb_prv));
-			vcc->push(vcc,skb);
-			pushed++;
-		}
-		atomic_inc(&vcc->stats->rx);
-	}
-	wake_up(&eni_dev->rx_wait);
-}
-
-
-static int open_rx_first(struct atm_vcc *vcc)
-{
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-	unsigned long size;
-
-	DPRINTK("open_rx_first\n");
-	eni_dev = ENI_DEV(vcc->dev);
-	eni_vcc = ENI_VCC(vcc);
-	eni_vcc->rx = NULL;
-	if (vcc->qos.rxtp.traffic_class == ATM_NONE) return 0;
-	size = vcc->qos.rxtp.max_sdu*eni_dev->rx_mult/100;
-	if (size > MID_MAX_BUF_SIZE && vcc->qos.rxtp.max_sdu <=
-	    MID_MAX_BUF_SIZE)
-		size = MID_MAX_BUF_SIZE;
-	eni_vcc->recv = eni_alloc_mem(eni_dev,&size);
-	DPRINTK("rx at 0x%lx\n",eni_vcc->recv);
-	eni_vcc->words = size >> 2;
-	if (!eni_vcc->recv) return -ENOBUFS;
-	eni_vcc->rx = vcc->qos.aal == ATM_AAL5 ? rx_aal5 : rx_aal0;
-	eni_vcc->descr = 0;
-	eni_vcc->rx_pos = 0;
-	eni_vcc->rxing = 0;
-	eni_vcc->servicing = 0;
-	eni_vcc->next = ENI_VCC_NOS;
-	return 0;
-}
-
-
-static int open_rx_second(struct atm_vcc *vcc)
-{
-	void __iomem *here;
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-	unsigned long size;
-	int order;
-
-	DPRINTK("open_rx_second\n");
-	eni_dev = ENI_DEV(vcc->dev);
-	eni_vcc = ENI_VCC(vcc);
-	if (!eni_vcc->rx) return 0;
-	/* set up VCI descriptor */
-	here = eni_dev->vci+vcc->vci*16;
-	DPRINTK("loc 0x%x\n",(unsigned) (eni_vcc->recv-eni_dev->ram)/4);
-	size = eni_vcc->words >> 8;
-	for (order = -1; size; order++) size >>= 1;
-	writel(0,here+4); /* descr, read = 0 */
-	writel(0,here+8); /* write, state, count = 0 */
-	if (eni_dev->rx_map[vcc->vci])
-		printk(KERN_CRIT DEV_LABEL "(itf %d): BUG - VCI %d already "
-		    "in use\n",vcc->dev->number,vcc->vci);
-	eni_dev->rx_map[vcc->vci] = vcc; /* now it counts */
-	writel(((vcc->qos.aal != ATM_AAL5 ? MID_MODE_RAW : MID_MODE_AAL5) <<
-	    MID_VCI_MODE_SHIFT) | MID_VCI_PTI_MODE |
-	    (((eni_vcc->recv-eni_dev->ram) >> (MID_LOC_SKIP+2)) <<
-	    MID_VCI_LOCATION_SHIFT) | (order << MID_VCI_SIZE_SHIFT),here);
-	return 0;
-}
-
-
-static void close_rx(struct atm_vcc *vcc)
-{
-	DECLARE_WAITQUEUE(wait,current);
-	void __iomem *here;
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-
-	eni_vcc = ENI_VCC(vcc);
-	if (!eni_vcc->rx) return;
-	eni_dev = ENI_DEV(vcc->dev);
-	if (vcc->vpi != ATM_VPI_UNSPEC && vcc->vci != ATM_VCI_UNSPEC) {
-		here = eni_dev->vci+vcc->vci*16;
-		/* block receiver */
-		writel((readl(here) & ~MID_VCI_MODE) | (MID_MODE_TRASH <<
-		    MID_VCI_MODE_SHIFT),here);
-		/* wait for receiver to become idle */
-		udelay(27);
-		/* discard pending cell */
-		writel(readl(here) & ~MID_VCI_IN_SERVICE,here);
-		/* don't accept any new ones */
-		eni_dev->rx_map[vcc->vci] = NULL;
-		/* wait for RX queue to drain */
-		DPRINTK("eni_close: waiting for RX ...\n");
-		EVENT("RX closing\n",0,0);
-		add_wait_queue(&eni_dev->rx_wait,&wait);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		barrier();
-		for (;;) {
-			/* transition service->rx: rxing++, servicing-- */
-			if (!eni_vcc->servicing) {
-				barrier();
-				if (!eni_vcc->rxing) break;
-			}
-			EVENT("drain PDUs (rx %ld, serv %ld)\n",eni_vcc->rxing,
-			    eni_vcc->servicing);
-			printk(KERN_INFO "%d+%d RX left\n",eni_vcc->servicing,
-			    eni_vcc->rxing);
-			schedule();
-			set_current_state(TASK_UNINTERRUPTIBLE);
-		}
-		for (;;) {
-			int at_end;
-			u32 tmp;
-
-			tasklet_disable(&eni_dev->task);
-			tmp = readl(eni_dev->vci+vcc->vci*16+4) & MID_VCI_READ;
-			at_end = eni_vcc->rx_pos == tmp >> MID_VCI_READ_SHIFT;
-			tasklet_enable(&eni_dev->task);
-			if (at_end) break;
-			EVENT("drain discard (host 0x%lx, nic 0x%lx)\n",
-			    eni_vcc->rx_pos,tmp);
-			printk(KERN_INFO "draining RX: host 0x%lx, nic 0x%x\n",
-			    eni_vcc->rx_pos,tmp);
-			schedule();
-			set_current_state(TASK_UNINTERRUPTIBLE);
-		}
-		set_current_state(TASK_RUNNING);
-		remove_wait_queue(&eni_dev->rx_wait,&wait);
-	}
-	eni_free_mem(eni_dev,eni_vcc->recv,eni_vcc->words << 2);
-	eni_vcc->rx = NULL;
-}
-
-
-static int start_rx(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-
-	eni_dev = ENI_DEV(dev);
-	eni_dev->rx_map = (struct atm_vcc **) get_zeroed_page(GFP_KERNEL);
-	if (!eni_dev->rx_map) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): couldn't get free page\n",
-		    dev->number);
-		free_page((unsigned long) eni_dev->free_list);
-		return -ENOMEM;
-	}
-	eni_dev->rx_mult = DEFAULT_RX_MULT;
-	eni_dev->fast = eni_dev->last_fast = NULL;
-	eni_dev->slow = eni_dev->last_slow = NULL;
-	init_waitqueue_head(&eni_dev->rx_wait);
-	skb_queue_head_init(&eni_dev->rx_queue);
-	eni_dev->serv_read = eni_in(MID_SERV_WRITE);
-	eni_out(0,MID_DMA_WR_RX);
-	return 0;
-}
-
-
-/*----------------------------------- TX ------------------------------------*/
-
-
-enum enq_res { enq_ok,enq_next,enq_jam };
-
-
-static inline void put_dma(int chan,u32 *dma,int *j,dma_addr_t paddr,
-    u32 size)
-{
-	u32 init,words;
-
-	DPRINTK("put_dma: 0x%lx+0x%x\n",(unsigned long) paddr,size);
-	EVENT("put_dma: 0x%lx+0x%lx\n",(unsigned long) paddr,size);
-#if 0 /* don't complain anymore */
-	if (paddr & 3)
-		printk(KERN_ERR "put_dma: unaligned addr (0x%lx)\n",paddr);
-	if (size & 3)
-		printk(KERN_ERR "put_dma: unaligned size (0x%lx)\n",size);
-#endif
-	if (paddr & 3) {
-		init = 4-(paddr & 3);
-		if (init > size || size < 7) init = size;
-		DPRINTK("put_dma: %lx DMA: %d/%d bytes\n",
-		    (unsigned long) paddr,init,size);
-		dma[(*j)++] = MID_DT_BYTE | (init << MID_DMA_COUNT_SHIFT) |
-		    (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-		paddr += init;
-		size -= init;
-	}
-	words = size >> 2;
-	size &= 3;
-	if (words && (paddr & 31)) {
-		init = 8-((paddr & 31) >> 2);
-		if (init > words) init = words;
-		DPRINTK("put_dma: %lx DMA: %d/%d words\n",
-		    (unsigned long) paddr,init,words);
-		dma[(*j)++] = MID_DT_WORD | (init << MID_DMA_COUNT_SHIFT) |
-		    (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-		paddr += init << 2;
-		words -= init;
-	}
-#ifdef CONFIG_ATM_ENI_BURST_TX_16W /* may work with some PCI chipsets ... */
-	if (words & ~15) {
-		DPRINTK("put_dma: %lx DMA: %d*16/%d words\n",
-		    (unsigned long) paddr,words >> 4,words);
-		dma[(*j)++] = MID_DT_16W | ((words >> 4) << MID_DMA_COUNT_SHIFT)
-		    | (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-		paddr += (words & ~15) << 2;
-		words &= 15;
-	}
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_TX_8W /* recommended */
-	if (words & ~7) {
-		DPRINTK("put_dma: %lx DMA: %d*8/%d words\n",
-		    (unsigned long) paddr,words >> 3,words);
-		dma[(*j)++] = MID_DT_8W | ((words >> 3) << MID_DMA_COUNT_SHIFT)
-		    | (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-		paddr += (words & ~7) << 2;
-		words &= 7;
-	}
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_TX_4W /* probably useless if TX_8W or TX_16W */
-	if (words & ~3) {
-		DPRINTK("put_dma: %lx DMA: %d*4/%d words\n",
-		    (unsigned long) paddr,words >> 2,words);
-		dma[(*j)++] = MID_DT_4W | ((words >> 2) << MID_DMA_COUNT_SHIFT)
-		    | (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-		paddr += (words & ~3) << 2;
-		words &= 3;
-	}
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_TX_2W /* probably useless if TX_4W, TX_8W, ... */
-	if (words & ~1) {
-		DPRINTK("put_dma: %lx DMA: %d*2/%d words\n",
-		    (unsigned long) paddr,words >> 1,words);
-		dma[(*j)++] = MID_DT_2W | ((words >> 1) << MID_DMA_COUNT_SHIFT)
-		    | (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-		paddr += (words & ~1) << 2;
-		words &= 1;
-	}
-#endif
-	if (words) {
-		DPRINTK("put_dma: %lx DMA: %d words\n",(unsigned long) paddr,
-		    words);
-		dma[(*j)++] = MID_DT_WORD | (words << MID_DMA_COUNT_SHIFT) |
-		    (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-		paddr += words << 2;
-	}
-	if (size) {
-		DPRINTK("put_dma: %lx DMA: %d bytes\n",(unsigned long) paddr,
-		    size);
-		dma[(*j)++] = MID_DT_BYTE | (size << MID_DMA_COUNT_SHIFT) |
-		    (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-	}
-}
-
-
-static enum enq_res do_tx(struct sk_buff *skb)
-{
-	struct atm_vcc *vcc;
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-	struct eni_tx *tx;
-	dma_addr_t paddr;
-	u32 dma_rd,dma_wr;
-	u32 size; /* in words */
-	int aal5,dma_size,i,j;
-	unsigned char skb_data3;
-
-	DPRINTK(">do_tx\n");
-	NULLCHECK(skb);
-	EVENT("do_tx: skb=0x%lx, %ld bytes\n",(unsigned long) skb,skb->len);
-	vcc = ATM_SKB(skb)->vcc;
-	NULLCHECK(vcc);
-	eni_dev = ENI_DEV(vcc->dev);
-	NULLCHECK(eni_dev);
-	eni_vcc = ENI_VCC(vcc);
-	tx = eni_vcc->tx;
-	NULLCHECK(tx);
-#if 0 /* Enable this for testing with the "align" program */
-	{
-		unsigned int hack = *((char *) skb->data)-'0';
-
-		if (hack < 8) {
-			skb->data += hack;
-			skb->len -= hack;
-		}
-	}
-#endif
-#if 0 /* should work now */
-	if ((unsigned long) skb->data & 3)
-		printk(KERN_ERR DEV_LABEL "(itf %d): VCI %d has mis-aligned "
-		    "TX data\n",vcc->dev->number,vcc->vci);
-#endif
-	/*
-	 * Potential future IP speedup: make hard_header big enough to put
-	 * segmentation descriptor directly into PDU. Saves: 4 slave writes,
-	 * 1 DMA xfer & 2 DMA'ed bytes (protocol layering is for wimps :-)
-	 */
-
-	aal5 = vcc->qos.aal == ATM_AAL5;
-	/* check space in buffer */
-	if (!aal5)
-		size = (ATM_CELL_PAYLOAD >> 2)+TX_DESCR_SIZE;
-			/* cell without HEC plus segmentation header (includes
-			   four-byte cell header) */
-	else {
-		size = skb->len+4*AAL5_TRAILER+ATM_CELL_PAYLOAD-1;
-			/* add AAL5 trailer */
-		size = ((size-(size % ATM_CELL_PAYLOAD)) >> 2)+TX_DESCR_SIZE;
-						/* add segmentation header */
-	}
-	/*
-	 * Can I move tx_pos by size bytes without getting closer than TX_GAP
-	 * to the read pointer ? TX_GAP means to leave some space for what
-	 * the manual calls "too close".
-	 */
-	if (!NEPMOK(tx->tx_pos,size+TX_GAP,
-	    eni_in(MID_TX_RDPTR(tx->index)),tx->words)) {
-		DPRINTK(DEV_LABEL "(itf %d): TX full (size %d)\n",
-		    vcc->dev->number,size);
-		return enq_next;
-	}
-	/* check DMA */
-	dma_wr = eni_in(MID_DMA_WR_TX);
-	dma_rd = eni_in(MID_DMA_RD_TX);
-	dma_size = 3; /* JK for descriptor and final fill, plus final size
-			 mis-alignment fix */
-DPRINTK("iovcnt = %d\n",skb_shinfo(skb)->nr_frags);
-	if (!skb_shinfo(skb)->nr_frags) dma_size += 5;
-	else dma_size += 5*(skb_shinfo(skb)->nr_frags+1);
-	if (dma_size > TX_DMA_BUF) {
-		printk(KERN_CRIT DEV_LABEL "(itf %d): needs %d DMA entries "
-		    "(got only %d)\n",vcc->dev->number,dma_size,TX_DMA_BUF);
-	}
-	DPRINTK("dma_wr is %d, tx_pos is %ld\n",dma_wr,tx->tx_pos);
-	if (dma_wr != dma_rd && ((dma_rd+NR_DMA_TX-dma_wr) & (NR_DMA_TX-1)) <
-	     dma_size) {
-		printk(KERN_WARNING DEV_LABEL "(itf %d): TX DMA full\n",
-		    vcc->dev->number);
-		return enq_jam;
-	}
-	skb_data3 = skb->data[3];
-	paddr = dma_map_single(&eni_dev->pci_dev->dev,skb->data,skb->len,
-			       DMA_TO_DEVICE);
-	if (dma_mapping_error(&eni_dev->pci_dev->dev, paddr))
-		return enq_next;
-	ENI_PRV_PADDR(skb) = paddr;
-	/* prepare DMA queue entries */
-	j = 0;
-	eni_dev->dma[j++] = (((tx->tx_pos+TX_DESCR_SIZE) & (tx->words-1)) <<
-	     MID_DMA_COUNT_SHIFT) | (tx->index << MID_DMA_CHAN_SHIFT) |
-	     MID_DT_JK;
-	j++;
-	if (!skb_shinfo(skb)->nr_frags)
-		if (aal5) put_dma(tx->index,eni_dev->dma,&j,paddr,skb->len);
-		else put_dma(tx->index,eni_dev->dma,&j,paddr+4,skb->len-4);
-	else {
-DPRINTK("doing direct send\n"); /* @@@ well, this doesn't work anyway */
-		for (i = -1; i < skb_shinfo(skb)->nr_frags; i++)
-			if (i == -1)
-				put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
-				    skb->data,
-				    skb_headlen(skb));
-			else
-				put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
-				    skb_frag_page(&skb_shinfo(skb)->frags[i]) +
-					skb_frag_off(&skb_shinfo(skb)->frags[i]),
-				    skb_frag_size(&skb_shinfo(skb)->frags[i]));
-	}
-	if (skb->len & 3) {
-		put_dma(tx->index, eni_dev->dma, &j, eni_dev->zero.dma,
-			4 - (skb->len & 3));
-	}
-	/* JK for AAL5 trailer - AAL0 doesn't need it, but who cares ... */
-	eni_dev->dma[j++] = (((tx->tx_pos+size) & (tx->words-1)) <<
-	     MID_DMA_COUNT_SHIFT) | (tx->index << MID_DMA_CHAN_SHIFT) |
-	     MID_DMA_END | MID_DT_JK;
-	j++;
-	DPRINTK("DMA at end: %d\n",j);
-	/* store frame */
-	writel((MID_SEG_TX_ID << MID_SEG_ID_SHIFT) |
-	    (aal5 ? MID_SEG_AAL5 : 0) | (tx->prescaler << MID_SEG_PR_SHIFT) |
-	    (tx->resolution << MID_SEG_RATE_SHIFT) |
-	    (size/(ATM_CELL_PAYLOAD/4)),tx->send+tx->tx_pos*4);
-/*printk("dsc = 0x%08lx\n",(unsigned long) readl(tx->send+tx->tx_pos*4));*/
-	writel((vcc->vci << MID_SEG_VCI_SHIFT) |
-            (aal5 ? 0 : (skb_data3 & 0xf)) |
-	    (ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ? MID_SEG_CLP : 0),
-	    tx->send+((tx->tx_pos+1) & (tx->words-1))*4);
-	DPRINTK("size: %d, len:%d\n",size,skb->len);
-	if (aal5)
-		writel(skb->len,tx->send+
-                    ((tx->tx_pos+size-AAL5_TRAILER) & (tx->words-1))*4);
-	j = j >> 1;
-	for (i = 0; i < j; i++) {
-		writel(eni_dev->dma[i*2],eni_dev->tx_dma+dma_wr*8);
-		writel(eni_dev->dma[i*2+1],eni_dev->tx_dma+dma_wr*8+4);
-		dma_wr = (dma_wr+1) & (NR_DMA_TX-1);
-	}
-	ENI_PRV_POS(skb) = tx->tx_pos;
-	ENI_PRV_SIZE(skb) = size;
-	ENI_VCC(vcc)->txing += size;
-	tx->tx_pos = (tx->tx_pos+size) & (tx->words-1);
-	DPRINTK("dma_wr set to %d, tx_pos is now %ld\n",dma_wr,tx->tx_pos);
-	eni_out(dma_wr,MID_DMA_WR_TX);
-	skb_queue_tail(&eni_dev->tx_queue,skb);
-	queued++;
-	return enq_ok;
-}
-
-
-static void poll_tx(struct atm_dev *dev)
-{
-	struct eni_tx *tx;
-	struct sk_buff *skb;
-	enum enq_res res;
-	int i;
-
-	DPRINTK(">poll_tx\n");
-	for (i = NR_CHAN-1; i >= 0; i--) {
-		tx = &ENI_DEV(dev)->tx[i];
-		if (tx->send)
-			while ((skb = skb_dequeue(&tx->backlog))) {
-				res = do_tx(skb);
-				if (res == enq_ok) continue;
-				DPRINTK("re-queuing TX PDU\n");
-				skb_queue_head(&tx->backlog,skb);
-				requeued++;
-				if (res == enq_jam) return;
-				break;
-			}
-	}
-}
-
-
-static void dequeue_tx(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-	struct atm_vcc *vcc;
-	struct sk_buff *skb;
-	struct eni_tx *tx;
-
-	NULLCHECK(dev);
-	eni_dev = ENI_DEV(dev);
-	NULLCHECK(eni_dev);
-	while ((skb = skb_dequeue(&eni_dev->tx_queue))) {
-		vcc = ATM_SKB(skb)->vcc;
-		NULLCHECK(vcc);
-		tx = ENI_VCC(vcc)->tx;
-		NULLCHECK(ENI_VCC(vcc)->tx);
-		DPRINTK("dequeue_tx: next 0x%lx curr 0x%x\n",ENI_PRV_POS(skb),
-		    (unsigned) eni_in(MID_TX_DESCRSTART(tx->index)));
-		if (ENI_VCC(vcc)->txing < tx->words && ENI_PRV_POS(skb) ==
-		    eni_in(MID_TX_DESCRSTART(tx->index))) {
-			skb_queue_head(&eni_dev->tx_queue,skb);
-			break;
-		}
-		ENI_VCC(vcc)->txing -= ENI_PRV_SIZE(skb);
-		dma_unmap_single(&eni_dev->pci_dev->dev,ENI_PRV_PADDR(skb),skb->len,
-				 DMA_TO_DEVICE);
-		if (vcc->pop) vcc->pop(vcc,skb);
-		else dev_kfree_skb_irq(skb);
-		atomic_inc(&vcc->stats->tx);
-		wake_up(&eni_dev->tx_wait);
-		dma_complete++;
-	}
-}
-
-
-static struct eni_tx *alloc_tx(struct eni_dev *eni_dev,int ubr)
-{
-	int i;
-
-	for (i = !ubr; i < NR_CHAN; i++)
-		if (!eni_dev->tx[i].send) return eni_dev->tx+i;
-	return NULL;
-}
-
-
-static int comp_tx(struct eni_dev *eni_dev,int *pcr,int reserved,int *pre,
-    int *res,int unlimited)
-{
-	static const int pre_div[] = { 4,16,128,2048 };
-	    /* 2^(((x+2)^2-(x+2))/2+1) */
-
-	if (unlimited) *pre = *res = 0;
-	else {
-		if (*pcr > 0) {
-			int div;
-
-			for (*pre = 0; *pre < 3; (*pre)++)
-				if (TS_CLOCK/pre_div[*pre]/64 <= *pcr) break;
-			div = pre_div[*pre]**pcr;
-			DPRINTK("min div %d\n",div);
-			*res = TS_CLOCK/div-1;
-		}
-		else {
-			int div;
-
-			if (!*pcr) *pcr = eni_dev->tx_bw+reserved;
-			for (*pre = 3; *pre >= 0; (*pre)--)
-				if (TS_CLOCK/pre_div[*pre]/64 > -*pcr) break;
-			if (*pre < 3) (*pre)++; /* else fail later */
-			div = pre_div[*pre]*-*pcr;
-			DPRINTK("max div %d\n",div);
-			*res = DIV_ROUND_UP(TS_CLOCK, div)-1;
-		}
-		if (*res < 0) *res = 0;
-		if (*res > MID_SEG_MAX_RATE) *res = MID_SEG_MAX_RATE;
-	}
-	*pcr = TS_CLOCK/pre_div[*pre]/(*res+1);
-	DPRINTK("out pcr: %d (%d:%d)\n",*pcr,*pre,*res);
-	return 0;
-}
-
-
-static int reserve_or_set_tx(struct atm_vcc *vcc,struct atm_trafprm *txtp,
-    int set_rsv,int set_shp)
-{
-	struct eni_dev *eni_dev = ENI_DEV(vcc->dev);
-	struct eni_vcc *eni_vcc = ENI_VCC(vcc);
-	struct eni_tx *tx;
-	unsigned long size;
-	void __iomem *mem;
-	int rate,ubr,unlimited,new_tx;
-	int pre,res,order;
-	int error;
-
-	rate = atm_pcr_goal(txtp);
-	ubr = txtp->traffic_class == ATM_UBR;
-	unlimited = ubr && (!rate || rate <= -ATM_OC3_PCR ||
-	    rate >= ATM_OC3_PCR);
-	if (!unlimited) {
-		size = txtp->max_sdu*eni_dev->tx_mult/100;
-		if (size > MID_MAX_BUF_SIZE && txtp->max_sdu <=
-		    MID_MAX_BUF_SIZE)
-			size = MID_MAX_BUF_SIZE;
-	}
-	else {
-		if (eni_dev->ubr) {
-			eni_vcc->tx = eni_dev->ubr;
-			txtp->pcr = ATM_OC3_PCR;
-			return 0;
-		}
-		size = UBR_BUFFER;
-	}
-	new_tx = !eni_vcc->tx;
-	mem = NULL; /* for gcc */
-	if (!new_tx) tx = eni_vcc->tx;
-	else {
-		mem = eni_alloc_mem(eni_dev,&size);
-		if (!mem) return -ENOBUFS;
-		tx = alloc_tx(eni_dev,unlimited);
-		if (!tx) {
-			eni_free_mem(eni_dev,mem,size);
-			return -EBUSY;
-		}
-		DPRINTK("got chan %d\n",tx->index);
-		tx->reserved = tx->shaping = 0;
-		tx->send = mem;
-		tx->words = size >> 2;
-		skb_queue_head_init(&tx->backlog);
-		for (order = 0; size > (1 << (order+10)); order++);
-		eni_out((order << MID_SIZE_SHIFT) |
-		    ((tx->send-eni_dev->ram) >> (MID_LOC_SKIP+2)),
-		    MID_TX_PLACE(tx->index));
-		tx->tx_pos = eni_in(MID_TX_DESCRSTART(tx->index)) &
-		    MID_DESCR_START;
-	}
-	error = comp_tx(eni_dev,&rate,tx->reserved,&pre,&res,unlimited);
-	if (!error  && txtp->min_pcr > rate) error = -EINVAL;
-	if (!error && txtp->max_pcr && txtp->max_pcr != ATM_MAX_PCR &&
-	    txtp->max_pcr < rate) error = -EINVAL;
-	if (!error && !ubr && rate > eni_dev->tx_bw+tx->reserved)
-		error = -EINVAL;
-	if (!error && set_rsv && !set_shp && rate < tx->shaping)
-		error = -EINVAL;
-	if (!error && !set_rsv && rate > tx->reserved && !ubr)
-		error = -EINVAL;
-	if (error) {
-		if (new_tx) {
-			tx->send = NULL;
-			eni_free_mem(eni_dev,mem,size);
-		}
-		return error;
-	}
-	txtp->pcr = rate;
-	if (set_rsv && !ubr) {
-		eni_dev->tx_bw += tx->reserved;
-		tx->reserved = rate;
-		eni_dev->tx_bw -= rate;
-	}
-	if (set_shp || (unlimited && new_tx)) {
-		if (unlimited && new_tx) eni_dev->ubr = tx;
-		tx->prescaler = pre;
-		tx->resolution = res;
-		tx->shaping = rate;
-	}
-	if (set_shp) eni_vcc->tx = tx;
-	DPRINTK("rsv %d shp %d\n",tx->reserved,tx->shaping);
-	return 0;
-}
-
-
-static int open_tx_first(struct atm_vcc *vcc)
-{
-	ENI_VCC(vcc)->tx = NULL;
-	if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0;
-	ENI_VCC(vcc)->txing = 0;
-	return reserve_or_set_tx(vcc,&vcc->qos.txtp,1,1);
-}
-
-
-static int open_tx_second(struct atm_vcc *vcc)
-{
-	return 0; /* nothing to do */
-}
-
-
-static void close_tx(struct atm_vcc *vcc)
-{
-	DECLARE_WAITQUEUE(wait,current);
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-
-	eni_vcc = ENI_VCC(vcc);
-	if (!eni_vcc->tx) return;
-	eni_dev = ENI_DEV(vcc->dev);
-	/* wait for TX queue to drain */
-	DPRINTK("eni_close: waiting for TX ...\n");
-	add_wait_queue(&eni_dev->tx_wait,&wait);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	for (;;) {
-		int txing;
-
-		tasklet_disable(&eni_dev->task);
-		txing = skb_peek(&eni_vcc->tx->backlog) || eni_vcc->txing;
-		tasklet_enable(&eni_dev->task);
-		if (!txing) break;
-		DPRINTK("%d TX left\n",eni_vcc->txing);
-		schedule();
-		set_current_state(TASK_UNINTERRUPTIBLE);
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&eni_dev->tx_wait,&wait);
-	if (eni_vcc->tx != eni_dev->ubr) {
-		/*
-		 * Looping a few times in here is probably far cheaper than
-		 * keeping track of TX completions all the time, so let's poll
-		 * a bit ...
-		 */
-		while (eni_in(MID_TX_RDPTR(eni_vcc->tx->index)) !=
-		    eni_in(MID_TX_DESCRSTART(eni_vcc->tx->index)))
-			schedule();
-		eni_free_mem(eni_dev,eni_vcc->tx->send,eni_vcc->tx->words << 2);
-		eni_vcc->tx->send = NULL;
-		eni_dev->tx_bw += eni_vcc->tx->reserved;
-	}
-	eni_vcc->tx = NULL;
-}
-
-
-static int start_tx(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-	int i;
-
-	eni_dev = ENI_DEV(dev);
-	eni_dev->lost = 0;
-	eni_dev->tx_bw = ATM_OC3_PCR;
-	eni_dev->tx_mult = DEFAULT_TX_MULT;
-	init_waitqueue_head(&eni_dev->tx_wait);
-	eni_dev->ubr = NULL;
-	skb_queue_head_init(&eni_dev->tx_queue);
-	eni_out(0,MID_DMA_WR_TX);
-	for (i = 0; i < NR_CHAN; i++) {
-		eni_dev->tx[i].send = NULL;
-		eni_dev->tx[i].index = i;
-	}
-	return 0;
-}
-
-
-/*--------------------------------- common ----------------------------------*/
-
-
-#if 0 /* may become useful again when tuning things */
-
-static void foo(void)
-{
-printk(KERN_INFO
-  "tx_complete=%d,dma_complete=%d,queued=%d,requeued=%d,sub=%d,\n"
-  "backlogged=%d,rx_enqueued=%d,rx_dequeued=%d,putting=%d,pushed=%d\n",
-  tx_complete,dma_complete,queued,requeued,submitted,backlogged,
-  rx_enqueued,rx_dequeued,putting,pushed);
-if (eni_boards) printk(KERN_INFO "loss: %ld\n",ENI_DEV(eni_boards)->lost);
-}
-
-#endif
-
-
-static void bug_int(struct atm_dev *dev,unsigned long reason)
-{
-	DPRINTK(">bug_int\n");
-	if (reason & MID_DMA_ERR_ACK)
-		printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - DMA "
-		    "error\n",dev->number);
-	if (reason & MID_TX_IDENT_MISM)
-		printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - ident "
-		    "mismatch\n",dev->number);
-	if (reason & MID_TX_DMA_OVFL)
-		printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - DMA "
-		    "overflow\n",dev->number);
-	EVENT("---dump ends here---\n",0,0);
-	printk(KERN_NOTICE "---recent events---\n");
-	event_dump();
-}
-
-
-static irqreturn_t eni_int(int irq,void *dev_id)
-{
-	struct atm_dev *dev;
-	struct eni_dev *eni_dev;
-	u32 reason;
-
-	DPRINTK(">eni_int\n");
-	dev = dev_id;
-	eni_dev = ENI_DEV(dev);
-	reason = eni_in(MID_ISA);
-	DPRINTK(DEV_LABEL ": int 0x%lx\n",(unsigned long) reason);
-	/*
-	 * Must handle these two right now, because reading ISA doesn't clear
-	 * them, so they re-occur and we never make it to the tasklet. Since
-	 * they're rare, we don't mind the occasional invocation of eni_tasklet
-	 * with eni_dev->events == 0.
-	 */
-	if (reason & MID_STAT_OVFL) {
-		EVENT("stat overflow\n",0,0);
-		eni_dev->lost += eni_in(MID_STAT) & MID_OVFL_TRASH;
-	}
-	if (reason & MID_SUNI_INT) {
-		EVENT("SUNI int\n",0,0);
-		dev->phy->interrupt(dev);
-#if 0
-		foo();
-#endif
-	}
-	spin_lock(&eni_dev->lock);
-	eni_dev->events |= reason;
-	spin_unlock(&eni_dev->lock);
-	tasklet_schedule(&eni_dev->task);
-	return IRQ_HANDLED;
-}
-
-
-static void eni_tasklet(unsigned long data)
-{
-	struct atm_dev *dev = (struct atm_dev *) data;
-	struct eni_dev *eni_dev = ENI_DEV(dev);
-	unsigned long flags;
-	u32 events;
-
-	DPRINTK("eni_tasklet (dev %p)\n",dev);
-	spin_lock_irqsave(&eni_dev->lock,flags);
-	events = xchg(&eni_dev->events,0);
-	spin_unlock_irqrestore(&eni_dev->lock,flags);
-	if (events & MID_RX_DMA_COMPLETE) {
-		EVENT("INT: RX DMA complete, starting dequeue_rx\n",0,0);
-		dequeue_rx(dev);
-		EVENT("dequeue_rx done, starting poll_rx\n",0,0);
-		poll_rx(dev);
-		EVENT("poll_rx done\n",0,0);
-		/* poll_tx ? */
-	}
-	if (events & MID_SERVICE) {
-		EVENT("INT: service, starting get_service\n",0,0);
-		get_service(dev);
-		EVENT("get_service done, starting poll_rx\n",0,0);
-		poll_rx(dev);
-		EVENT("poll_rx done\n",0,0);
-	}
- 	if (events & MID_TX_DMA_COMPLETE) {
-		EVENT("INT: TX DMA COMPLETE\n",0,0);
-		dequeue_tx(dev);
-	}
-	if (events & MID_TX_COMPLETE) {
-		EVENT("INT: TX COMPLETE\n",0,0);
-		tx_complete++;
-		wake_up(&eni_dev->tx_wait);
-		/* poll_rx ? */
-	}
-	if (events & (MID_DMA_ERR_ACK | MID_TX_IDENT_MISM | MID_TX_DMA_OVFL)) {
-		EVENT("bug interrupt\n",0,0);
-		bug_int(dev,events);
-	}
-	poll_tx(dev);
-}
-
-
-/*--------------------------------- entries ---------------------------------*/
-
-
-static char * const media_name[] = {
-    "MMF", "SMF", "MMF", "03?", /*  0- 3 */
-    "UTP", "05?", "06?", "07?", /*  4- 7 */
-    "TAXI","09?", "10?", "11?", /*  8-11 */
-    "12?", "13?", "14?", "15?", /* 12-15 */
-    "MMF", "SMF", "18?", "19?", /* 16-19 */
-    "UTP", "21?", "22?", "23?", /* 20-23 */
-    "24?", "25?", "26?", "27?", /* 24-27 */
-    "28?", "29?", "30?", "31?"  /* 28-31 */
-};
-
-
-#define SET_SEPROM \
-  ({ if (!error && !pci_error) { \
-    pci_error = pci_write_config_byte(eni_dev->pci_dev,PCI_TONGA_CTRL,tonga); \
-    udelay(10); /* 10 usecs */ \
-  } })
-#define GET_SEPROM \
-  ({ if (!error && !pci_error) { \
-    pci_error = pci_read_config_byte(eni_dev->pci_dev,PCI_TONGA_CTRL,&tonga); \
-    udelay(10); /* 10 usecs */ \
-  } })
-
-
-static int get_esi_asic(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-	unsigned char tonga;
-	int error,failed,pci_error;
-	int address,i,j;
-
-	eni_dev = ENI_DEV(dev);
-	error = pci_error = 0;
-	tonga = SEPROM_MAGIC | SEPROM_DATA | SEPROM_CLK;
-	SET_SEPROM;
-	for (i = 0; i < ESI_LEN && !error && !pci_error; i++) {
-		/* start operation */
-		tonga |= SEPROM_DATA;
-		SET_SEPROM;
-		tonga |= SEPROM_CLK;
-		SET_SEPROM;
-		tonga &= ~SEPROM_DATA;
-		SET_SEPROM;
-		tonga &= ~SEPROM_CLK;
-		SET_SEPROM;
-		/* send address */
-		address = ((i+SEPROM_ESI_BASE) << 1)+1;
-		for (j = 7; j >= 0; j--) {
-			tonga = (address >> j) & 1 ? tonga | SEPROM_DATA :
-			    tonga & ~SEPROM_DATA;
-			SET_SEPROM;
-			tonga |= SEPROM_CLK;
-			SET_SEPROM;
-			tonga &= ~SEPROM_CLK;
-			SET_SEPROM;
-		}
-		/* get ack */
-		tonga |= SEPROM_DATA;
-		SET_SEPROM;
-		tonga |= SEPROM_CLK;
-		SET_SEPROM;
-		GET_SEPROM;
-		failed = tonga & SEPROM_DATA;
-		tonga &= ~SEPROM_CLK;
-		SET_SEPROM;
-		tonga |= SEPROM_DATA;
-		SET_SEPROM;
-		if (failed) error = -EIO;
-		else {
-			dev->esi[i] = 0;
-			for (j = 7; j >= 0; j--) {
-				dev->esi[i] <<= 1;
-				tonga |= SEPROM_DATA;
-				SET_SEPROM;
-				tonga |= SEPROM_CLK;
-				SET_SEPROM;
-				GET_SEPROM;
-				if (tonga & SEPROM_DATA) dev->esi[i] |= 1;
-				tonga &= ~SEPROM_CLK;
-				SET_SEPROM;
-				tonga |= SEPROM_DATA;
-				SET_SEPROM;
-			}
-			/* get ack */
-			tonga |= SEPROM_DATA;
-			SET_SEPROM;
-			tonga |= SEPROM_CLK;
-			SET_SEPROM;
-			GET_SEPROM;
-			if (!(tonga & SEPROM_DATA)) error = -EIO;
-			tonga &= ~SEPROM_CLK;
-			SET_SEPROM;
-			tonga |= SEPROM_DATA;
-			SET_SEPROM;
-		}
-		/* stop operation */
-		tonga &= ~SEPROM_DATA;
-		SET_SEPROM;
-		tonga |= SEPROM_CLK;
-		SET_SEPROM;
-		tonga |= SEPROM_DATA;
-		SET_SEPROM;
-	}
-	if (pci_error) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): error reading ESI "
-		    "(0x%02x)\n",dev->number,pci_error);
-		error = -EIO;
-	}
-	return error;
-}
-
-
-#undef SET_SEPROM
-#undef GET_SEPROM
-
-
-static int get_esi_fpga(struct atm_dev *dev, void __iomem *base)
-{
-	void __iomem *mac_base;
-	int i;
-
-	mac_base = base+EPROM_SIZE-sizeof(struct midway_eprom);
-	for (i = 0; i < ESI_LEN; i++) dev->esi[i] = readb(mac_base+(i^3));
-	return 0;
-}
-
-
-static int eni_do_init(struct atm_dev *dev)
-{
-	struct midway_eprom __iomem *eprom;
-	struct eni_dev *eni_dev;
-	struct pci_dev *pci_dev;
-	unsigned long real_base;
-	void __iomem *base;
-	int error,i,last;
-
-	DPRINTK(">eni_init\n");
-	dev->ci_range.vpi_bits = 0;
-	dev->ci_range.vci_bits = NR_VCI_LD;
-	dev->link_rate = ATM_OC3_PCR;
-	eni_dev = ENI_DEV(dev);
-	pci_dev = eni_dev->pci_dev;
-	real_base = pci_resource_start(pci_dev, 0);
-	eni_dev->irq = pci_dev->irq;
-	if ((error = pci_write_config_word(pci_dev,PCI_COMMAND,
-	    PCI_COMMAND_MEMORY |
-	    (eni_dev->asic ? PCI_COMMAND_PARITY | PCI_COMMAND_SERR : 0)))) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't enable memory "
-		    "(0x%02x)\n",dev->number,error);
-		return -EIO;
-	}
-	printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d,base=0x%lx,irq=%d,",
-	    dev->number,pci_dev->revision,real_base,eni_dev->irq);
-	if (!(base = ioremap(real_base,MAP_MAX_SIZE))) {
-		printk("\n");
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't set up page "
-		    "mapping\n",dev->number);
-		return -ENOMEM;
-	}
-	eni_dev->ioaddr = base;
-	eni_dev->base_diff = real_base - (unsigned long) base;
-	/* id may not be present in ASIC Tonga boards - check this @@@ */
-	if (!eni_dev->asic) {
-		eprom = (base+EPROM_SIZE-sizeof(struct midway_eprom));
-		if (readl(&eprom->magic) != ENI155_MAGIC) {
-			printk("\n");
-			printk(KERN_ERR DEV_LABEL
-			       "(itf %d): bad magic - expected 0x%x, got 0x%x\n",
-			       dev->number, ENI155_MAGIC,
-			       (unsigned)readl(&eprom->magic));
-			error = -EINVAL;
-			goto unmap;
-		}
-	}
-	eni_dev->phy = base+PHY_BASE;
-	eni_dev->reg = base+REG_BASE;
-	eni_dev->ram = base+RAM_BASE;
-	last = MAP_MAX_SIZE-RAM_BASE;
-	for (i = last-RAM_INCREMENT; i >= 0; i -= RAM_INCREMENT) {
-		writel(0x55555555,eni_dev->ram+i);
-		if (readl(eni_dev->ram+i) != 0x55555555) last = i;
-		else {
-			writel(0xAAAAAAAA,eni_dev->ram+i);
-			if (readl(eni_dev->ram+i) != 0xAAAAAAAA) last = i;
-			else writel(i,eni_dev->ram+i);
-		}
-	}
-	for (i = 0; i < last; i += RAM_INCREMENT)
-		if (readl(eni_dev->ram+i) != i) break;
-	eni_dev->mem = i;
-	memset_io(eni_dev->ram,0,eni_dev->mem);
-	/* TODO: should shrink allocation now */
-	printk("mem=%dkB (",eni_dev->mem >> 10);
-	/* TODO: check for non-SUNI, check for TAXI ? */
-	if (!(eni_in(MID_RES_ID_MCON) & 0x200) != !eni_dev->asic) {
-		printk(")\n");
-		printk(KERN_ERR DEV_LABEL "(itf %d): ERROR - wrong id 0x%x\n",
-		    dev->number,(unsigned) eni_in(MID_RES_ID_MCON));
-		error = -EINVAL;
-		goto unmap;
-	}
-	error = eni_dev->asic ? get_esi_asic(dev) : get_esi_fpga(dev,base);
-	if (error)
-		goto unmap;
-	for (i = 0; i < ESI_LEN; i++)
-		printk("%s%02X",i ? "-" : "",dev->esi[i]);
-	printk(")\n");
-	printk(KERN_NOTICE DEV_LABEL "(itf %d): %s,%s\n",dev->number,
-	    eni_in(MID_RES_ID_MCON) & 0x200 ? "ASIC" : "FPGA",
-	    media_name[eni_in(MID_RES_ID_MCON) & DAUGHTER_ID]);
-
-	error = suni_init(dev);
-	if (error)
-		goto unmap;
-out:
-	return error;
-unmap:
-	iounmap(base);
-	goto out;
-}
-
-static void eni_do_release(struct atm_dev *dev)
-{
-	struct eni_dev *ed = ENI_DEV(dev);
-
-	dev->phy->stop(dev);
-	dev->phy = NULL;
-	iounmap(ed->ioaddr);
-}
-
-static int eni_start(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-	
-	void __iomem *buf;
-	unsigned long buffer_mem;
-	int error;
-
-	DPRINTK(">eni_start\n");
-	eni_dev = ENI_DEV(dev);
-	if (request_irq(eni_dev->irq,&eni_int,IRQF_SHARED,DEV_LABEL,dev)) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",
-		    dev->number,eni_dev->irq);
-		error = -EAGAIN;
-		goto out;
-	}
-	pci_set_master(eni_dev->pci_dev);
-	if ((error = pci_write_config_word(eni_dev->pci_dev,PCI_COMMAND,
-	    PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
-	    (eni_dev->asic ? PCI_COMMAND_PARITY | PCI_COMMAND_SERR : 0)))) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't enable memory+"
-		    "master (0x%02x)\n",dev->number,error);
-		goto free_irq;
-	}
-	if ((error = pci_write_config_byte(eni_dev->pci_dev,PCI_TONGA_CTRL,
-	    END_SWAP_DMA))) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't set endian swap "
-		    "(0x%02x)\n",dev->number,error);
-		goto free_irq;
-	}
-	/* determine addresses of internal tables */
-	eni_dev->vci = eni_dev->ram;
-	eni_dev->rx_dma = eni_dev->ram+NR_VCI*16;
-	eni_dev->tx_dma = eni_dev->rx_dma+NR_DMA_RX*8;
-	eni_dev->service = eni_dev->tx_dma+NR_DMA_TX*8;
-	buf = eni_dev->service+NR_SERVICE*4;
-	DPRINTK("vci 0x%lx,rx 0x%lx, tx 0x%lx,srv 0x%lx,buf 0x%lx\n",
-	     eni_dev->vci,eni_dev->rx_dma,eni_dev->tx_dma,
-	     eni_dev->service,buf);
-	spin_lock_init(&eni_dev->lock);
-	tasklet_init(&eni_dev->task,eni_tasklet,(unsigned long) dev);
-	eni_dev->events = 0;
-	/* initialize memory management */
-	buffer_mem = eni_dev->mem - (buf - eni_dev->ram);
-	eni_dev->free_list_size = buffer_mem/MID_MIN_BUF_SIZE/2;
-	eni_dev->free_list = kmalloc_objs(*eni_dev->free_list,
-					  eni_dev->free_list_size + 1);
-	if (!eni_dev->free_list) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): couldn't get free page\n",
-		    dev->number);
-		error = -ENOMEM;
-		goto free_irq;
-	}
-	eni_dev->free_len = 0;
-	eni_put_free(eni_dev,buf,buffer_mem);
-	memset_io(eni_dev->vci,0,16*NR_VCI); /* clear VCI table */
-	/*
-	 * byte_addr  free (k)
-	 * 0x00000000     512  VCI table
-	 * 0x00004000	  496  RX DMA
-	 * 0x00005000	  492  TX DMA
-	 * 0x00006000	  488  service list
-	 * 0x00007000	  484  buffers
-	 * 0x00080000	    0  end (512kB)
-	 */
-	eni_out(0xffffffff,MID_IE);
-	error = start_tx(dev);
-	if (error) goto free_list;
-	error = start_rx(dev);
-	if (error) goto free_list;
-	error = dev->phy->start(dev);
-	if (error) goto free_list;
-	eni_out(eni_in(MID_MC_S) | (1 << MID_INT_SEL_SHIFT) |
-	    MID_TX_LOCK_MODE | MID_DMA_ENABLE | MID_TX_ENABLE | MID_RX_ENABLE,
-	    MID_MC_S);
-	    /* Tonga uses SBus INTReq1 */
-	(void) eni_in(MID_ISA); /* clear Midway interrupts */
-	return 0;
-
-free_list:
-	kfree(eni_dev->free_list);
-
-free_irq:
-	free_irq(eni_dev->irq, dev);
-
-out:
-	return error;
-}
-
-
-static void eni_close(struct atm_vcc *vcc)
-{
-	DPRINTK(">eni_close\n");
-	if (!ENI_VCC(vcc)) return;
-	clear_bit(ATM_VF_READY,&vcc->flags);
-	close_rx(vcc);
-	close_tx(vcc);
-	DPRINTK("eni_close: done waiting\n");
-	/* deallocate memory */
-	kfree(ENI_VCC(vcc));
-	vcc->dev_data = NULL;
-	clear_bit(ATM_VF_ADDR,&vcc->flags);
-	/*foo();*/
-}
-
-
-static int eni_open(struct atm_vcc *vcc)
-{
-	struct eni_vcc *eni_vcc;
-	int error;
-	short vpi = vcc->vpi;
-	int vci = vcc->vci;
-
-	DPRINTK(">eni_open\n");
-	EVENT("eni_open\n",0,0);
-	if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))
-		vcc->dev_data = NULL;
-	if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
-		set_bit(ATM_VF_ADDR,&vcc->flags);
-	if (vcc->qos.aal != ATM_AAL0 && vcc->qos.aal != ATM_AAL5)
-		return -EINVAL;
-	DPRINTK(DEV_LABEL "(itf %d): open %d.%d\n",vcc->dev->number,vcc->vpi,
-	    vcc->vci);
-	if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) {
-		eni_vcc = kmalloc_obj(struct eni_vcc);
-		if (!eni_vcc) return -ENOMEM;
-		vcc->dev_data = eni_vcc;
-		eni_vcc->tx = NULL; /* for eni_close after open_rx */
-		if ((error = open_rx_first(vcc))) {
-			eni_close(vcc);
-			return error;
-		}
-		if ((error = open_tx_first(vcc))) {
-			eni_close(vcc);
-			return error;
-		}
-	}
-	if (vci == ATM_VPI_UNSPEC || vpi == ATM_VCI_UNSPEC) return 0;
-	if ((error = open_rx_second(vcc))) {
-		eni_close(vcc);
-		return error;
-	}
-	if ((error = open_tx_second(vcc))) {
-		eni_close(vcc);
-		return error;
-	}
-	set_bit(ATM_VF_READY,&vcc->flags);
-	/* should power down SUNI while !ref_count @@@ */
-	return 0;
-}
-
-
-static int eni_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flgs)
-{
-	struct eni_dev *eni_dev = ENI_DEV(vcc->dev);
-	struct eni_tx *tx = ENI_VCC(vcc)->tx;
-	struct sk_buff *skb;
-	int error,rate,rsv,shp;
-
-	if (qos->txtp.traffic_class == ATM_NONE) return 0;
-	if (tx == eni_dev->ubr) return -EBADFD;
-	rate = atm_pcr_goal(&qos->txtp);
-	if (rate < 0) rate = -rate;
-	rsv = shp = 0;
-	if ((flgs & ATM_MF_DEC_RSV) && rate && rate < tx->reserved) rsv = 1;
-	if ((flgs & ATM_MF_INC_RSV) && (!rate || rate > tx->reserved)) rsv = 1;
-	if ((flgs & ATM_MF_DEC_SHP) && rate && rate < tx->shaping) shp = 1;
-	if ((flgs & ATM_MF_INC_SHP) && (!rate || rate > tx->shaping)) shp = 1;
-	if (!rsv && !shp) return 0;
-	error = reserve_or_set_tx(vcc,&qos->txtp,rsv,shp);
-	if (error) return error;
-	if (shp && !(flgs & ATM_MF_IMMED)) return 0;
-	/*
-	 * Walk through the send buffer and patch the rate information in all
-	 * segmentation buffer descriptors of this VCC.
-	 */
-	tasklet_disable(&eni_dev->task);
-	skb_queue_walk(&eni_dev->tx_queue, skb) {
-		void __iomem *dsc;
-
-		if (ATM_SKB(skb)->vcc != vcc) continue;
-		dsc = tx->send+ENI_PRV_POS(skb)*4;
-		writel((readl(dsc) & ~(MID_SEG_RATE | MID_SEG_PR)) |
-		    (tx->prescaler << MID_SEG_PR_SHIFT) |
-		    (tx->resolution << MID_SEG_RATE_SHIFT), dsc);
-	}
-	tasklet_enable(&eni_dev->task);
-	return 0;
-}
-
-
-static int eni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
-{
-	struct eni_dev *eni_dev = ENI_DEV(dev);
-
-	if (cmd == ENI_MEMDUMP) {
-		if (!capable(CAP_NET_ADMIN)) return -EPERM;
-		printk(KERN_WARNING "Please use /proc/atm/" DEV_LABEL ":%d "
-		    "instead of obsolete ioctl ENI_MEMDUMP\n",dev->number);
-		dump(dev);
-		return 0;
-	}
-	if (cmd == ENI_SETMULT) {
-		struct eni_multipliers mult;
-
-		if (!capable(CAP_NET_ADMIN)) return -EPERM;
-		if (copy_from_user(&mult, arg,
-		    sizeof(struct eni_multipliers)))
-			return -EFAULT;
-		if ((mult.tx && mult.tx <= 100) || (mult.rx &&mult.rx <= 100) ||
-		    mult.tx > 65536 || mult.rx > 65536)
-			return -EINVAL;
-		if (mult.tx) eni_dev->tx_mult = mult.tx;
-		if (mult.rx) eni_dev->rx_mult = mult.rx;
-		return 0;
-	}
-	if (cmd == ATM_SETCIRANGE) {
-		struct atm_cirange ci;
-
-		if (copy_from_user(&ci, arg,sizeof(struct atm_cirange)))
-			return -EFAULT;
-		if ((ci.vpi_bits == 0 || ci.vpi_bits == ATM_CI_MAX) &&
-		    (ci.vci_bits == NR_VCI_LD || ci.vpi_bits == ATM_CI_MAX))
-		    return 0;
-		return -EINVAL;
-	}
-	if (!dev->phy->ioctl) return -ENOIOCTLCMD;
-	return dev->phy->ioctl(dev,cmd,arg);
-}
-
-static int eni_send(struct atm_vcc *vcc,struct sk_buff *skb)
-{
-	enum enq_res res;
-
-	DPRINTK(">eni_send\n");
-	if (!ENI_VCC(vcc)->tx) {
-		if (vcc->pop) vcc->pop(vcc,skb);
-		else dev_kfree_skb(skb);
-		return -EINVAL;
-	}
-	if (!skb) {
-		printk(KERN_CRIT "!skb in eni_send ?\n");
-		if (vcc->pop) vcc->pop(vcc,skb);
-		return -EINVAL;
-	}
-	if (vcc->qos.aal == ATM_AAL0) {
-		if (skb->len != ATM_CELL_SIZE-1) {
-			if (vcc->pop) vcc->pop(vcc,skb);
-			else dev_kfree_skb(skb);
-			return -EINVAL;
-		}
-		*(u32 *) skb->data = htonl(*(u32 *) skb->data);
-	}
-	submitted++;
-	ATM_SKB(skb)->vcc = vcc;
-	tasklet_disable_in_atomic(&ENI_DEV(vcc->dev)->task);
-	res = do_tx(skb);
-	tasklet_enable(&ENI_DEV(vcc->dev)->task);
-	if (res == enq_ok) return 0;
-	skb_queue_tail(&ENI_VCC(vcc)->tx->backlog,skb);
-	backlogged++;
-	tasklet_schedule(&ENI_DEV(vcc->dev)->task);
-	return 0;
-}
-
-static void eni_phy_put(struct atm_dev *dev,unsigned char value,
-    unsigned long addr)
-{
-	writel(value,ENI_DEV(dev)->phy+addr*4);
-}
-
-
-
-static unsigned char eni_phy_get(struct atm_dev *dev,unsigned long addr)
-{
-	return readl(ENI_DEV(dev)->phy+addr*4);
-}
-
-
-static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
-{
-	struct sock *s;
-	static const char *signal[] = { "LOST","unknown","okay" };
-	struct eni_dev *eni_dev = ENI_DEV(dev);
-	struct atm_vcc *vcc;
-	int left,i;
-
-	left = *pos;
-	if (!left)
-		return sprintf(page,DEV_LABEL "(itf %d) signal %s, %dkB, "
-		    "%d cps remaining\n",dev->number,signal[(int) dev->signal],
-		    eni_dev->mem >> 10,eni_dev->tx_bw);
-	if (!--left)
-		return sprintf(page,"%4sBursts: TX"
-#if !defined(CONFIG_ATM_ENI_BURST_TX_16W) && \
-    !defined(CONFIG_ATM_ENI_BURST_TX_8W) && \
-    !defined(CONFIG_ATM_ENI_BURST_TX_4W) && \
-    !defined(CONFIG_ATM_ENI_BURST_TX_2W)
-		    " none"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_TX_16W
-		    " 16W"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_TX_8W
-		    " 8W"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_TX_4W
-		    " 4W"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_TX_2W
-		    " 2W"
-#endif
-		    ", RX"
-#if !defined(CONFIG_ATM_ENI_BURST_RX_16W) && \
-    !defined(CONFIG_ATM_ENI_BURST_RX_8W) && \
-    !defined(CONFIG_ATM_ENI_BURST_RX_4W) && \
-    !defined(CONFIG_ATM_ENI_BURST_RX_2W)
-		    " none"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_RX_16W
-		    " 16W"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_RX_8W
-		    " 8W"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_RX_4W
-		    " 4W"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_RX_2W
-		    " 2W"
-#endif
-#ifndef CONFIG_ATM_ENI_TUNE_BURST
-		    " (default)"
-#endif
-		    "\n","");
-	if (!--left) 
-		return sprintf(page,"%4sBuffer multipliers: tx %d%%, rx %d%%\n",
-		    "",eni_dev->tx_mult,eni_dev->rx_mult);
-	for (i = 0; i < NR_CHAN; i++) {
-		struct eni_tx *tx = eni_dev->tx+i;
-
-		if (!tx->send) continue;
-		if (!--left) {
-			return sprintf(page, "tx[%d]:    0x%lx-0x%lx "
-			    "(%6ld bytes), rsv %d cps, shp %d cps%s\n",i,
-			    (unsigned long) (tx->send - eni_dev->ram),
-			    tx->send-eni_dev->ram+tx->words*4-1,tx->words*4,
-			    tx->reserved,tx->shaping,
-			    tx == eni_dev->ubr ? " (UBR)" : "");
-		}
-		if (--left) continue;
-		return sprintf(page,"%10sbacklog %u packets\n","",
-		    skb_queue_len(&tx->backlog));
-	}
-	read_lock(&vcc_sklist_lock);
-	for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
-		struct hlist_head *head = &vcc_hash[i];
-
-		sk_for_each(s, head) {
-			struct eni_vcc *eni_vcc;
-			int length;
-
-			vcc = atm_sk(s);
-			if (vcc->dev != dev)
-				continue;
-			eni_vcc = ENI_VCC(vcc);
-			if (--left) continue;
-			length = sprintf(page,"vcc %4d: ",vcc->vci);
-			if (eni_vcc->rx) {
-				length += sprintf(page+length, "0x%lx-0x%lx "
-				    "(%6ld bytes)",
-				    (unsigned long) (eni_vcc->recv - eni_dev->ram),
-				    eni_vcc->recv-eni_dev->ram+eni_vcc->words*4-1,
-				    eni_vcc->words*4);
-				if (eni_vcc->tx) length += sprintf(page+length,", ");
-			}
-			if (eni_vcc->tx)
-				length += sprintf(page+length,"tx[%d], txing %d bytes",
-				    eni_vcc->tx->index,eni_vcc->txing);
-			page[length] = '\n';
-			read_unlock(&vcc_sklist_lock);
-			return length+1;
-		}
-	}
-	read_unlock(&vcc_sklist_lock);
-	for (i = 0; i < eni_dev->free_len; i++) {
-		struct eni_free *fe = eni_dev->free_list+i;
-		unsigned long offset;
-
-		if (--left) continue;
-		offset = (unsigned long) eni_dev->ram+eni_dev->base_diff;
-		return sprintf(page,"free      %p-%p (%6d bytes)\n",
-		    fe->start-offset,fe->start-offset+(1 << fe->order)-1,
-		    1 << fe->order);
-	}
-	return 0;
-}
-
-
-static const struct atmdev_ops ops = {
-	.open		= eni_open,
-	.close		= eni_close,
-	.ioctl		= eni_ioctl,
-	.send		= eni_send,
-	.phy_put	= eni_phy_put,
-	.phy_get	= eni_phy_get,
-	.change_qos	= eni_change_qos,
-	.proc_read	= eni_proc_read
-};
-
-
-static int eni_init_one(struct pci_dev *pci_dev,
-			const struct pci_device_id *ent)
-{
-	struct atm_dev *dev;
-	struct eni_dev *eni_dev;
-	struct eni_zero *zero;
-	int rc;
-
-	rc = pci_enable_device(pci_dev);
-	if (rc < 0)
-		goto out;
-
-	rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32));
-	if (rc < 0)
-		goto err_disable;
-
-	rc = -ENOMEM;
-	eni_dev = kmalloc_obj(struct eni_dev);
-	if (!eni_dev)
-		goto err_disable;
-
-	zero = &eni_dev->zero;
-	zero->addr = dma_alloc_coherent(&pci_dev->dev,
-					ENI_ZEROES_SIZE, &zero->dma, GFP_KERNEL);
-	if (!zero->addr)
-		goto err_kfree;
-
-	dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
-	if (!dev)
-		goto err_free_consistent;
-
-	dev->dev_data = eni_dev;
-	pci_set_drvdata(pci_dev, dev);
-	eni_dev->pci_dev = pci_dev;
-	eni_dev->asic = ent->driver_data;
-
-	rc = eni_do_init(dev);
-	if (rc < 0)
-		goto err_unregister;
-
-	rc = eni_start(dev);
-	if (rc < 0)
-		goto err_eni_release;
-
-	eni_dev->more = eni_boards;
-	eni_boards = dev;
-out:
-	return rc;
-
-err_eni_release:
-	dev->phy = NULL;
-	iounmap(ENI_DEV(dev)->ioaddr);
-err_unregister:
-	atm_dev_deregister(dev);
-err_free_consistent:
-	dma_free_coherent(&pci_dev->dev, ENI_ZEROES_SIZE, zero->addr, zero->dma);
-err_kfree:
-	kfree(eni_dev);
-err_disable:
-	pci_disable_device(pci_dev);
-	goto out;
-}
-
-
-static const struct pci_device_id eni_pci_tbl[] = {
-	{ PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_FPGA), 0 /* FPGA */ },
-	{ PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_ASIC), 1 /* ASIC */ },
-	{ 0, }
-};
-MODULE_DEVICE_TABLE(pci,eni_pci_tbl);
-
-
-static void eni_remove_one(struct pci_dev *pdev)
-{
-	struct atm_dev *dev = pci_get_drvdata(pdev);
-	struct eni_dev *ed = ENI_DEV(dev);
-	struct eni_zero *zero = &ed->zero;
-
-	eni_do_release(dev);
-	atm_dev_deregister(dev);
-	dma_free_coherent(&pdev->dev, ENI_ZEROES_SIZE, zero->addr, zero->dma);
-	kfree(ed);
-	pci_disable_device(pdev);
-}
-
-
-static struct pci_driver eni_driver = {
-	.name		= DEV_LABEL,
-	.id_table	= eni_pci_tbl,
-	.probe		= eni_init_one,
-	.remove		= eni_remove_one,
-};
-
-
-static int __init eni_init(void)
-{
-	struct sk_buff *skb; /* dummy for sizeof */
-
-	BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct eni_skb_prv));
-	return pci_register_driver(&eni_driver);
-}
-
-
-module_init(eni_init);
-/* @@@ since exit routine not defined, this module can not be unloaded */
-
-MODULE_DESCRIPTION("Efficient Networks ENI155P ATM NIC driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
deleted file mode 100644
index 2423eed506c1..000000000000
--- a/drivers/atm/fore200e.c
+++ /dev/null
@@ -1,3012 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
-  A FORE Systems 200E-series driver for ATM on Linux.
-  Christophe Lizzi (lizzi@cnam.fr), October 1999-March 2003.
-
-  Based on the PCA-200E driver from Uwe Dannowski (Uwe.Dannowski@inf.tu-dresden.de).
-
-  This driver simultaneously supports PCA-200E and SBA-200E adapters
-  on i386, alpha (untested), powerpc, sparc and sparc64 architectures.
-
-*/
-
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/capability.h>
-#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/atmdev.h>
-#include <linux/sonet.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/pgtable.h>
-#include <asm/io.h>
-#include <asm/string.h>
-#include <asm/page.h>
-#include <asm/irq.h>
-#include <asm/dma.h>
-#include <asm/byteorder.h>
-#include <linux/uaccess.h>
-#include <linux/atomic.h>
-
-#ifdef CONFIG_SBUS
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <asm/idprom.h>
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-#endif
-
-#if defined(CONFIG_ATM_FORE200E_USE_TASKLET) /* defer interrupt work to a tasklet */
-#define FORE200E_USE_TASKLET
-#endif
-
-#if 0 /* enable the debugging code of the buffer supply queues */
-#define FORE200E_BSQ_DEBUG
-#endif
-
-#if 1 /* ensure correct handling of 52-byte AAL0 SDUs expected by atmdump-like apps */
-#define FORE200E_52BYTE_AAL0_SDU
-#endif
-
-#include "fore200e.h"
-#include "suni.h"
-
-#define FORE200E_VERSION "0.3e"
-
-#define FORE200E         "fore200e: "
-
-#if 0 /* override .config */
-#define CONFIG_ATM_FORE200E_DEBUG 1
-#endif
-#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG > 0)
-#define DPRINTK(level, format, args...)  do { if (CONFIG_ATM_FORE200E_DEBUG >= (level)) \
-                                                  printk(FORE200E format, ##args); } while (0)
-#else
-#define DPRINTK(level, format, args...)  do {} while (0)
-#endif
-
-
-#define FORE200E_ALIGN(addr, alignment) \
-        ((((unsigned long)(addr) + (alignment - 1)) & ~(alignment - 1)) - (unsigned long)(addr))
-
-#define FORE200E_DMA_INDEX(dma_addr, type, index)  ((dma_addr) + (index) * sizeof(type))
-
-#define FORE200E_INDEX(virt_addr, type, index)     (&((type *)(virt_addr))[ index ])
-
-#define FORE200E_NEXT_ENTRY(index, modulo)         (index = ((index) + 1) % (modulo))
-
-#if 1
-#define ASSERT(expr)     if (!(expr)) { \
-			     printk(FORE200E "assertion failed! %s[%d]: %s\n", \
-				    __func__, __LINE__, #expr); \
-			     panic(FORE200E "%s", __func__); \
-			 }
-#else
-#define ASSERT(expr)     do {} while (0)
-#endif
-
-
-static const struct atmdev_ops   fore200e_ops;
-
-MODULE_AUTHOR("Christophe Lizzi - credits to Uwe Dannowski and Heikki Vatiainen");
-MODULE_DESCRIPTION("FORE Systems 200E-series ATM driver - version " FORE200E_VERSION);
-
-static const int fore200e_rx_buf_nbr[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = {
-    { BUFFER_S1_NBR, BUFFER_L1_NBR },
-    { BUFFER_S2_NBR, BUFFER_L2_NBR }
-};
-
-static const int fore200e_rx_buf_size[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = {
-    { BUFFER_S1_SIZE, BUFFER_L1_SIZE },
-    { BUFFER_S2_SIZE, BUFFER_L2_SIZE }
-};
-
-
-#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG > 0)
-static const char* fore200e_traffic_class[] = { "NONE", "UBR", "CBR", "VBR", "ABR", "ANY" };
-#endif
-
-
-#if 0 /* currently unused */
-static int 
-fore200e_fore2atm_aal(enum fore200e_aal aal)
-{
-    switch(aal) {
-    case FORE200E_AAL0:  return ATM_AAL0;
-    case FORE200E_AAL34: return ATM_AAL34;
-    case FORE200E_AAL5:  return ATM_AAL5;
-    }
-
-    return -EINVAL;
-}
-#endif
-
-
-static enum fore200e_aal
-fore200e_atm2fore_aal(int aal)
-{
-    switch(aal) {
-    case ATM_AAL0:  return FORE200E_AAL0;
-    case ATM_AAL34: return FORE200E_AAL34;
-    case ATM_AAL1:
-    case ATM_AAL2:
-    case ATM_AAL5:  return FORE200E_AAL5;
-    }
-
-    return -EINVAL;
-}
-
-
-static char*
-fore200e_irq_itoa(int irq)
-{
-    static char str[8];
-    sprintf(str, "%d", irq);
-    return str;
-}
-
-
-/* allocate and align a chunk of memory intended to hold the data behing exchanged
-   between the driver and the adapter (using streaming DVMA) */
-
-static int
-fore200e_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int alignment, int direction)
-{
-    unsigned long offset = 0;
-
-    if (alignment <= sizeof(int))
-	alignment = 0;
-
-    chunk->alloc_size = size + alignment;
-    chunk->direction  = direction;
-
-    chunk->alloc_addr = kzalloc(chunk->alloc_size, GFP_KERNEL);
-    if (chunk->alloc_addr == NULL)
-	return -ENOMEM;
-
-    if (alignment > 0)
-	offset = FORE200E_ALIGN(chunk->alloc_addr, alignment); 
-    
-    chunk->align_addr = chunk->alloc_addr + offset;
-
-    chunk->dma_addr = dma_map_single(fore200e->dev, chunk->align_addr,
-				     size, direction);
-    if (dma_mapping_error(fore200e->dev, chunk->dma_addr)) {
-	kfree(chunk->alloc_addr);
-	return -ENOMEM;
-    }
-    return 0;
-}
-
-
-/* free a chunk of memory */
-
-static void
-fore200e_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
-{
-    dma_unmap_single(fore200e->dev, chunk->dma_addr, chunk->dma_size,
-		     chunk->direction);
-    kfree(chunk->alloc_addr);
-}
-
-/*
- * Allocate a DMA consistent chunk of memory intended to act as a communication
- * mechanism (to hold descriptors, status, queues, etc.) shared by the driver
- * and the adapter.
- */
-static int
-fore200e_dma_chunk_alloc(struct fore200e *fore200e, struct chunk *chunk,
-		int size, int nbr, int alignment)
-{
-	/* returned chunks are page-aligned */
-	chunk->alloc_size = size * nbr;
-	chunk->alloc_addr = dma_alloc_coherent(fore200e->dev, chunk->alloc_size,
-					       &chunk->dma_addr, GFP_KERNEL);
-	if (!chunk->alloc_addr)
-		return -ENOMEM;
-	chunk->align_addr = chunk->alloc_addr;
-	return 0;
-}
-
-/*
- * Free a DMA consistent chunk of memory.
- */
-static void
-fore200e_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
-{
-	dma_free_coherent(fore200e->dev, chunk->alloc_size, chunk->alloc_addr,
-			  chunk->dma_addr);
-}
-
-static void
-fore200e_spin(int msecs)
-{
-    unsigned long timeout = jiffies + msecs_to_jiffies(msecs);
-    while (time_before(jiffies, timeout));
-}
-
-
-static int
-fore200e_poll(struct fore200e* fore200e, volatile u32* addr, u32 val, int msecs)
-{
-    unsigned long timeout = jiffies + msecs_to_jiffies(msecs);
-    int           ok;
-
-    mb();
-    do {
-	if ((ok = (*addr == val)) || (*addr & STATUS_ERROR))
-	    break;
-
-    } while (time_before(jiffies, timeout));
-
-#if 1
-    if (!ok) {
-	printk(FORE200E "cmd polling failed, got status 0x%08x, expected 0x%08x\n",
-	       *addr, val);
-    }
-#endif
-
-    return ok;
-}
-
-
-static int
-fore200e_io_poll(struct fore200e* fore200e, volatile u32 __iomem *addr, u32 val, int msecs)
-{
-    unsigned long timeout = jiffies + msecs_to_jiffies(msecs);
-    int           ok;
-
-    do {
-	if ((ok = (fore200e->bus->read(addr) == val)))
-	    break;
-
-    } while (time_before(jiffies, timeout));
-
-#if 1
-    if (!ok) {
-	printk(FORE200E "I/O polling failed, got status 0x%08x, expected 0x%08x\n",
-	       fore200e->bus->read(addr), val);
-    }
-#endif
-
-    return ok;
-}
-
-
-static void
-fore200e_free_rx_buf(struct fore200e* fore200e)
-{
-    int scheme, magn, nbr;
-    struct buffer* buffer;
-
-    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
-	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
-
-	    if ((buffer = fore200e->host_bsq[ scheme ][ magn ].buffer) != NULL) {
-
-		for (nbr = 0; nbr < fore200e_rx_buf_nbr[ scheme ][ magn ]; nbr++) {
-
-		    struct chunk* data = &buffer[ nbr ].data;
-
-		    if (data->alloc_addr != NULL)
-			fore200e_chunk_free(fore200e, data);
-		}
-	    }
-	}
-    }
-}
-
-
-static void
-fore200e_uninit_bs_queue(struct fore200e* fore200e)
-{
-    int scheme, magn;
-    
-    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
-	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
-
-	    struct chunk* status    = &fore200e->host_bsq[ scheme ][ magn ].status;
-	    struct chunk* rbd_block = &fore200e->host_bsq[ scheme ][ magn ].rbd_block;
-	    
-	    if (status->alloc_addr)
-		fore200e_dma_chunk_free(fore200e, status);
-	    
-	    if (rbd_block->alloc_addr)
-		fore200e_dma_chunk_free(fore200e, rbd_block);
-	}
-    }
-}
-
-
-static int
-fore200e_reset(struct fore200e* fore200e, int diag)
-{
-    int ok;
-
-    fore200e->cp_monitor = fore200e->virt_base + FORE200E_CP_MONITOR_OFFSET;
-    
-    fore200e->bus->write(BSTAT_COLD_START, &fore200e->cp_monitor->bstat);
-
-    fore200e->bus->reset(fore200e);
-
-    if (diag) {
-	ok = fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_SELFTEST_OK, 1000);
-	if (ok == 0) {
-	    
-	    printk(FORE200E "device %s self-test failed\n", fore200e->name);
-	    return -ENODEV;
-	}
-
-	printk(FORE200E "device %s self-test passed\n", fore200e->name);
-	
-	fore200e->state = FORE200E_STATE_RESET;
-    }
-
-    return 0;
-}
-
-
-static void
-fore200e_shutdown(struct fore200e* fore200e)
-{
-    printk(FORE200E "removing device %s at 0x%lx, IRQ %s\n",
-	   fore200e->name, fore200e->phys_base, 
-	   fore200e_irq_itoa(fore200e->irq));
-    
-    if (fore200e->state > FORE200E_STATE_RESET) {
-	/* first, reset the board to prevent further interrupts or data transfers */
-	fore200e_reset(fore200e, 0);
-    }
-    
-    /* then, release all allocated resources */
-    switch(fore200e->state) {
-
-    case FORE200E_STATE_COMPLETE:
-	kfree(fore200e->stats);
-
-	fallthrough;
-    case FORE200E_STATE_IRQ:
-	free_irq(fore200e->irq, fore200e->atm_dev);
-#ifdef FORE200E_USE_TASKLET
-	tasklet_kill(&fore200e->tx_tasklet);
-	tasklet_kill(&fore200e->rx_tasklet);
-#endif
-
-	fallthrough;
-    case FORE200E_STATE_ALLOC_BUF:
-	fore200e_free_rx_buf(fore200e);
-
-	fallthrough;
-    case FORE200E_STATE_INIT_BSQ:
-	fore200e_uninit_bs_queue(fore200e);
-
-	fallthrough;
-    case FORE200E_STATE_INIT_RXQ:
-	fore200e_dma_chunk_free(fore200e, &fore200e->host_rxq.status);
-	fore200e_dma_chunk_free(fore200e, &fore200e->host_rxq.rpd);
-
-	fallthrough;
-    case FORE200E_STATE_INIT_TXQ:
-	fore200e_dma_chunk_free(fore200e, &fore200e->host_txq.status);
-	fore200e_dma_chunk_free(fore200e, &fore200e->host_txq.tpd);
-
-	fallthrough;
-    case FORE200E_STATE_INIT_CMDQ:
-	fore200e_dma_chunk_free(fore200e, &fore200e->host_cmdq.status);
-
-	fallthrough;
-    case FORE200E_STATE_INITIALIZE:
-	/* nothing to do for that state */
-
-    case FORE200E_STATE_START_FW:
-	/* nothing to do for that state */
-
-    case FORE200E_STATE_RESET:
-	/* nothing to do for that state */
-
-    case FORE200E_STATE_MAP:
-	fore200e->bus->unmap(fore200e);
-
-	fallthrough;
-    case FORE200E_STATE_CONFIGURE:
-	/* nothing to do for that state */
-
-    case FORE200E_STATE_REGISTER:
-	/* XXX shouldn't we *start* by deregistering the device? */
-	atm_dev_deregister(fore200e->atm_dev);
-
-	fallthrough;
-    case FORE200E_STATE_BLANK:
-	/* nothing to do for that state */
-	break;
-    }
-}
-
-
-#ifdef CONFIG_PCI
-
-static u32 fore200e_pca_read(volatile u32 __iomem *addr)
-{
-    /* on big-endian hosts, the board is configured to convert
-       the endianess of slave RAM accesses  */
-    return le32_to_cpu(readl(addr));
-}
-
-
-static void fore200e_pca_write(u32 val, volatile u32 __iomem *addr)
-{
-    /* on big-endian hosts, the board is configured to convert
-       the endianess of slave RAM accesses  */
-    writel(cpu_to_le32(val), addr);
-}
-
-static int
-fore200e_pca_irq_check(struct fore200e* fore200e)
-{
-    /* this is a 1 bit register */
-    int irq_posted = readl(fore200e->regs.pca.psr);
-
-#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG == 2)
-    if (irq_posted && (readl(fore200e->regs.pca.hcr) & PCA200E_HCR_OUTFULL)) {
-	DPRINTK(2,"FIFO OUT full, device %d\n", fore200e->atm_dev->number);
-    }
-#endif
-
-    return irq_posted;
-}
-
-
-static void
-fore200e_pca_irq_ack(struct fore200e* fore200e)
-{
-    writel(PCA200E_HCR_CLRINTR, fore200e->regs.pca.hcr);
-}
-
-
-static void
-fore200e_pca_reset(struct fore200e* fore200e)
-{
-    writel(PCA200E_HCR_RESET, fore200e->regs.pca.hcr);
-    fore200e_spin(10);
-    writel(0, fore200e->regs.pca.hcr);
-}
-
-
-static int fore200e_pca_map(struct fore200e* fore200e)
-{
-    DPRINTK(2, "device %s being mapped in memory\n", fore200e->name);
-
-    fore200e->virt_base = ioremap(fore200e->phys_base, PCA200E_IOSPACE_LENGTH);
-    
-    if (fore200e->virt_base == NULL) {
-	printk(FORE200E "can't map device %s\n", fore200e->name);
-	return -EFAULT;
-    }
-
-    DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
-
-    /* gain access to the PCA specific registers  */
-    fore200e->regs.pca.hcr = fore200e->virt_base + PCA200E_HCR_OFFSET;
-    fore200e->regs.pca.imr = fore200e->virt_base + PCA200E_IMR_OFFSET;
-    fore200e->regs.pca.psr = fore200e->virt_base + PCA200E_PSR_OFFSET;
-
-    fore200e->state = FORE200E_STATE_MAP;
-    return 0;
-}
-
-
-static void
-fore200e_pca_unmap(struct fore200e* fore200e)
-{
-    DPRINTK(2, "device %s being unmapped from memory\n", fore200e->name);
-
-    if (fore200e->virt_base != NULL)
-	iounmap(fore200e->virt_base);
-}
-
-
-static int fore200e_pca_configure(struct fore200e *fore200e)
-{
-    struct pci_dev *pci_dev = to_pci_dev(fore200e->dev);
-    u8              master_ctrl, latency;
-
-    DPRINTK(2, "device %s being configured\n", fore200e->name);
-
-    if ((pci_dev->irq == 0) || (pci_dev->irq == 0xFF)) {
-	printk(FORE200E "incorrect IRQ setting - misconfigured PCI-PCI bridge?\n");
-	return -EIO;
-    }
-
-    pci_read_config_byte(pci_dev, PCA200E_PCI_MASTER_CTRL, &master_ctrl);
-
-    master_ctrl = master_ctrl
-#if defined(__BIG_ENDIAN)
-	/* request the PCA board to convert the endianess of slave RAM accesses */
-	| PCA200E_CTRL_CONVERT_ENDIAN
-#endif
-#if 0
-        | PCA200E_CTRL_DIS_CACHE_RD
-        | PCA200E_CTRL_DIS_WRT_INVAL
-        | PCA200E_CTRL_ENA_CONT_REQ_MODE
-        | PCA200E_CTRL_2_CACHE_WRT_INVAL
-#endif
-	| PCA200E_CTRL_LARGE_PCI_BURSTS;
-    
-    pci_write_config_byte(pci_dev, PCA200E_PCI_MASTER_CTRL, master_ctrl);
-
-    /* raise latency from 32 (default) to 192, as this seems to prevent NIC
-       lockups (under heavy rx loads) due to continuous 'FIFO OUT full' condition.
-       this may impact the performances of other PCI devices on the same bus, though */
-    latency = 192;
-    pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
-
-    fore200e->state = FORE200E_STATE_CONFIGURE;
-    return 0;
-}
-
-
-static int __init
-fore200e_pca_prom_read(struct fore200e* fore200e, struct prom_data* prom)
-{
-    struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
-    struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
-    struct prom_opcode      opcode;
-    int                     ok;
-    u32                     prom_dma;
-
-    FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
-
-    opcode.opcode = OPCODE_GET_PROM;
-    opcode.pad    = 0;
-
-    prom_dma = dma_map_single(fore200e->dev, prom, sizeof(struct prom_data),
-			      DMA_FROM_DEVICE);
-    if (dma_mapping_error(fore200e->dev, prom_dma))
-	return -ENOMEM;
-
-    fore200e->bus->write(prom_dma, &entry->cp_entry->cmd.prom_block.prom_haddr);
-    
-    *entry->status = STATUS_PENDING;
-
-    fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.prom_block.opcode);
-
-    ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
-
-    *entry->status = STATUS_FREE;
-
-    dma_unmap_single(fore200e->dev, prom_dma, sizeof(struct prom_data), DMA_FROM_DEVICE);
-
-    if (ok == 0) {
-	printk(FORE200E "unable to get PROM data from device %s\n", fore200e->name);
-	return -EIO;
-    }
-
-#if defined(__BIG_ENDIAN)
-    
-#define swap_here(addr) (*((u32*)(addr)) = swab32( *((u32*)(addr)) ))
-
-    /* MAC address is stored as little-endian */
-    swap_here(&prom->mac_addr[0]);
-    swap_here(&prom->mac_addr[4]);
-#endif
-    
-    return 0;
-}
-
-
-static int
-fore200e_pca_proc_read(struct fore200e* fore200e, char *page)
-{
-    struct pci_dev *pci_dev = to_pci_dev(fore200e->dev);
-
-    return sprintf(page, "   PCI bus/slot/function:\t%d/%d/%d\n",
-		   pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn));
-}
-
-static const struct fore200e_bus fore200e_pci_ops = {
-	.model_name		= "PCA-200E",
-	.proc_name		= "pca200e",
-	.descr_alignment	= 32,
-	.buffer_alignment	= 4,
-	.status_alignment	= 32,
-	.read			= fore200e_pca_read,
-	.write			= fore200e_pca_write,
-	.configure		= fore200e_pca_configure,
-	.map			= fore200e_pca_map,
-	.reset			= fore200e_pca_reset,
-	.prom_read		= fore200e_pca_prom_read,
-	.unmap			= fore200e_pca_unmap,
-	.irq_check		= fore200e_pca_irq_check,
-	.irq_ack		= fore200e_pca_irq_ack,
-	.proc_read		= fore200e_pca_proc_read,
-};
-#endif /* CONFIG_PCI */
-
-#ifdef CONFIG_SBUS
-
-static u32 fore200e_sba_read(volatile u32 __iomem *addr)
-{
-    return sbus_readl(addr);
-}
-
-static void fore200e_sba_write(u32 val, volatile u32 __iomem *addr)
-{
-    sbus_writel(val, addr);
-}
-
-static void fore200e_sba_irq_enable(struct fore200e *fore200e)
-{
-	u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
-	fore200e->bus->write(hcr | SBA200E_HCR_INTR_ENA, fore200e->regs.sba.hcr);
-}
-
-static int fore200e_sba_irq_check(struct fore200e *fore200e)
-{
-	return fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_INTR_REQ;
-}
-
-static void fore200e_sba_irq_ack(struct fore200e *fore200e)
-{
-	u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
-	fore200e->bus->write(hcr | SBA200E_HCR_INTR_CLR, fore200e->regs.sba.hcr);
-}
-
-static void fore200e_sba_reset(struct fore200e *fore200e)
-{
-	fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr);
-	fore200e_spin(10);
-	fore200e->bus->write(0, fore200e->regs.sba.hcr);
-}
-
-static int __init fore200e_sba_map(struct fore200e *fore200e)
-{
-	struct platform_device *op = to_platform_device(fore200e->dev);
-	unsigned int bursts;
-
-	/* gain access to the SBA specific registers  */
-	fore200e->regs.sba.hcr = of_ioremap(&op->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR");
-	fore200e->regs.sba.bsr = of_ioremap(&op->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR");
-	fore200e->regs.sba.isr = of_ioremap(&op->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR");
-	fore200e->virt_base    = of_ioremap(&op->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM");
-
-	if (!fore200e->virt_base) {
-		printk(FORE200E "unable to map RAM of device %s\n", fore200e->name);
-		return -EFAULT;
-	}
-
-	DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
-    
-	fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */
-
-	/* get the supported DVMA burst sizes */
-	bursts = of_getintprop_default(op->dev.of_node->parent, "burst-sizes", 0x00);
-
-	if (sbus_can_dma_64bit())
-		sbus_set_sbus64(&op->dev, bursts);
-
-	fore200e->state = FORE200E_STATE_MAP;
-	return 0;
-}
-
-static void fore200e_sba_unmap(struct fore200e *fore200e)
-{
-	struct platform_device *op = to_platform_device(fore200e->dev);
-
-	of_iounmap(&op->resource[0], fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH);
-	of_iounmap(&op->resource[1], fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH);
-	of_iounmap(&op->resource[2], fore200e->regs.sba.isr, SBA200E_ISR_LENGTH);
-	of_iounmap(&op->resource[3], fore200e->virt_base,    SBA200E_RAM_LENGTH);
-}
-
-static int __init fore200e_sba_configure(struct fore200e *fore200e)
-{
-	fore200e->state = FORE200E_STATE_CONFIGURE;
-	return 0;
-}
-
-static int __init fore200e_sba_prom_read(struct fore200e *fore200e, struct prom_data *prom)
-{
-	struct platform_device *op = to_platform_device(fore200e->dev);
-	const u8 *prop;
-	int len;
-
-	prop = of_get_property(op->dev.of_node, "madaddrlo2", &len);
-	if (!prop)
-		return -ENODEV;
-	memcpy(&prom->mac_addr[4], prop, 4);
-
-	prop = of_get_property(op->dev.of_node, "madaddrhi4", &len);
-	if (!prop)
-		return -ENODEV;
-	memcpy(&prom->mac_addr[2], prop, 4);
-
-	prom->serial_number = of_getintprop_default(op->dev.of_node,
-						    "serialnumber", 0);
-	prom->hw_revision = of_getintprop_default(op->dev.of_node,
-						  "promversion", 0);
-    
-	return 0;
-}
-
-static int fore200e_sba_proc_read(struct fore200e *fore200e, char *page)
-{
-	struct platform_device *op = to_platform_device(fore200e->dev);
-	const struct linux_prom_registers *regs;
-
-	regs = of_get_property(op->dev.of_node, "reg", NULL);
-
-	return sprintf(page, "   SBUS slot/device:\t\t%d/'%pOFn'\n",
-		       (regs ? regs->which_io : 0), op->dev.of_node);
-}
-
-static const struct fore200e_bus fore200e_sbus_ops = {
-	.model_name		= "SBA-200E",
-	.proc_name		= "sba200e",
-	.descr_alignment	= 32,
-	.buffer_alignment	= 64,
-	.status_alignment	= 32,
-	.read			= fore200e_sba_read,
-	.write			= fore200e_sba_write,
-	.configure		= fore200e_sba_configure,
-	.map			= fore200e_sba_map,
-	.reset			= fore200e_sba_reset,
-	.prom_read		= fore200e_sba_prom_read,
-	.unmap			= fore200e_sba_unmap,
-	.irq_enable		= fore200e_sba_irq_enable,
-	.irq_check		= fore200e_sba_irq_check,
-	.irq_ack		= fore200e_sba_irq_ack,
-	.proc_read		= fore200e_sba_proc_read,
-};
-#endif /* CONFIG_SBUS */
-
-static void
-fore200e_tx_irq(struct fore200e* fore200e)
-{
-    struct host_txq*        txq = &fore200e->host_txq;
-    struct host_txq_entry*  entry;
-    struct atm_vcc*         vcc;
-    struct fore200e_vc_map* vc_map;
-
-    if (fore200e->host_txq.txing == 0)
-	return;
-
-    for (;;) {
-	
-	entry = &txq->host_entry[ txq->tail ];
-
-        if ((*entry->status & STATUS_COMPLETE) == 0) {
-	    break;
-	}
-
-	DPRINTK(3, "TX COMPLETED: entry = %p [tail = %d], vc_map = %p, skb = %p\n", 
-		entry, txq->tail, entry->vc_map, entry->skb);
-
-	/* free copy of misaligned data */
-	kfree(entry->data);
-	
-	/* remove DMA mapping */
-	dma_unmap_single(fore200e->dev, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length,
-				 DMA_TO_DEVICE);
-
-	vc_map = entry->vc_map;
-
-	/* vcc closed since the time the entry was submitted for tx? */
-	if ((vc_map->vcc == NULL) ||
-	    (test_bit(ATM_VF_READY, &vc_map->vcc->flags) == 0)) {
-
-	    DPRINTK(1, "no ready vcc found for PDU sent on device %d\n",
-		    fore200e->atm_dev->number);
-
-	    dev_kfree_skb_any(entry->skb);
-	}
-	else {
-	    ASSERT(vc_map->vcc);
-
-	    /* vcc closed then immediately re-opened? */
-	    if (vc_map->incarn != entry->incarn) {
-
-		/* when a vcc is closed, some PDUs may be still pending in the tx queue.
-		   if the same vcc is immediately re-opened, those pending PDUs must
-		   not be popped after the completion of their emission, as they refer
-		   to the prior incarnation of that vcc. otherwise, sk_atm(vcc)->sk_wmem_alloc
-		   would be decremented by the size of the (unrelated) skb, possibly
-		   leading to a negative sk->sk_wmem_alloc count, ultimately freezing the vcc.
-		   we thus bind the tx entry to the current incarnation of the vcc
-		   when the entry is submitted for tx. When the tx later completes,
-		   if the incarnation number of the tx entry does not match the one
-		   of the vcc, then this implies that the vcc has been closed then re-opened.
-		   we thus just drop the skb here. */
-
-		DPRINTK(1, "vcc closed-then-re-opened; dropping PDU sent on device %d\n",
-			fore200e->atm_dev->number);
-
-		dev_kfree_skb_any(entry->skb);
-	    }
-	    else {
-		vcc = vc_map->vcc;
-		ASSERT(vcc);
-
-		/* notify tx completion */
-		if (vcc->pop) {
-		    vcc->pop(vcc, entry->skb);
-		}
-		else {
-		    dev_kfree_skb_any(entry->skb);
-		}
-
-		/* check error condition */
-		if (*entry->status & STATUS_ERROR)
-		    atomic_inc(&vcc->stats->tx_err);
-		else
-		    atomic_inc(&vcc->stats->tx);
-	    }
-	}
-
-	*entry->status = STATUS_FREE;
-
-	fore200e->host_txq.txing--;
-
-	FORE200E_NEXT_ENTRY(txq->tail, QUEUE_SIZE_TX);
-    }
-}
-
-
-#ifdef FORE200E_BSQ_DEBUG
-int bsq_audit(int where, struct host_bsq* bsq, int scheme, int magn)
-{
-    struct buffer* buffer;
-    int count = 0;
-
-    buffer = bsq->freebuf;
-    while (buffer) {
-
-	if (buffer->supplied) {
-	    printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld supplied but in free list!\n",
-		   where, scheme, magn, buffer->index);
-	}
-
-	if (buffer->magn != magn) {
-	    printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld, unexpected magn = %d\n",
-		   where, scheme, magn, buffer->index, buffer->magn);
-	}
-
-	if (buffer->scheme != scheme) {
-	    printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld, unexpected scheme = %d\n",
-		   where, scheme, magn, buffer->index, buffer->scheme);
-	}
-
-	if ((buffer->index < 0) || (buffer->index >= fore200e_rx_buf_nbr[ scheme ][ magn ])) {
-	    printk(FORE200E "bsq_audit(%d): queue %d.%d, out of range buffer index = %ld !\n",
-		   where, scheme, magn, buffer->index);
-	}
-
-	count++;
-	buffer = buffer->next;
-    }
-
-    if (count != bsq->freebuf_count) {
-	printk(FORE200E "bsq_audit(%d): queue %d.%d, %d bufs in free list, but freebuf_count = %d\n",
-	       where, scheme, magn, count, bsq->freebuf_count);
-    }
-    return 0;
-}
-#endif
-
-
-static void
-fore200e_supply(struct fore200e* fore200e)
-{
-    int  scheme, magn, i;
-
-    struct host_bsq*       bsq;
-    struct host_bsq_entry* entry;
-    struct buffer*         buffer;
-
-    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
-	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
-
-	    bsq = &fore200e->host_bsq[ scheme ][ magn ];
-
-#ifdef FORE200E_BSQ_DEBUG
-	    bsq_audit(1, bsq, scheme, magn);
-#endif
-	    while (bsq->freebuf_count >= RBD_BLK_SIZE) {
-
-		DPRINTK(2, "supplying %d rx buffers to queue %d / %d, freebuf_count = %d\n",
-			RBD_BLK_SIZE, scheme, magn, bsq->freebuf_count);
-
-		entry = &bsq->host_entry[ bsq->head ];
-
-		for (i = 0; i < RBD_BLK_SIZE; i++) {
-
-		    /* take the first buffer in the free buffer list */
-		    buffer = bsq->freebuf;
-		    if (!buffer) {
-			printk(FORE200E "no more free bufs in queue %d.%d, but freebuf_count = %d\n",
-			       scheme, magn, bsq->freebuf_count);
-			return;
-		    }
-		    bsq->freebuf = buffer->next;
-		    
-#ifdef FORE200E_BSQ_DEBUG
-		    if (buffer->supplied)
-			printk(FORE200E "queue %d.%d, buffer %lu already supplied\n",
-			       scheme, magn, buffer->index);
-		    buffer->supplied = 1;
-#endif
-		    entry->rbd_block->rbd[ i ].buffer_haddr = buffer->data.dma_addr;
-		    entry->rbd_block->rbd[ i ].handle       = FORE200E_BUF2HDL(buffer);
-		}
-
-		FORE200E_NEXT_ENTRY(bsq->head, QUEUE_SIZE_BS);
-
- 		/* decrease accordingly the number of free rx buffers */
-		bsq->freebuf_count -= RBD_BLK_SIZE;
-
-		*entry->status = STATUS_PENDING;
-		fore200e->bus->write(entry->rbd_block_dma, &entry->cp_entry->rbd_block_haddr);
-	    }
-	}
-    }
-}
-
-
-static int
-fore200e_push_rpd(struct fore200e* fore200e, struct atm_vcc* vcc, struct rpd* rpd)
-{
-    struct sk_buff*      skb;
-    struct buffer*       buffer;
-    struct fore200e_vcc* fore200e_vcc;
-    int                  i, pdu_len = 0;
-#ifdef FORE200E_52BYTE_AAL0_SDU
-    u32                  cell_header = 0;
-#endif
-
-    ASSERT(vcc);
-    
-    fore200e_vcc = FORE200E_VCC(vcc);
-    ASSERT(fore200e_vcc);
-
-#ifdef FORE200E_52BYTE_AAL0_SDU
-    if ((vcc->qos.aal == ATM_AAL0) && (vcc->qos.rxtp.max_sdu == ATM_AAL0_SDU)) {
-
-	cell_header = (rpd->atm_header.gfc << ATM_HDR_GFC_SHIFT) |
-	              (rpd->atm_header.vpi << ATM_HDR_VPI_SHIFT) |
-                      (rpd->atm_header.vci << ATM_HDR_VCI_SHIFT) |
-                      (rpd->atm_header.plt << ATM_HDR_PTI_SHIFT) | 
-                       rpd->atm_header.clp;
-	pdu_len = 4;
-    }
-#endif
-    
-    /* compute total PDU length */
-    for (i = 0; i < rpd->nseg; i++)
-	pdu_len += rpd->rsd[ i ].length;
-    
-    skb = alloc_skb(pdu_len, GFP_ATOMIC);
-    if (skb == NULL) {
-	DPRINTK(2, "unable to alloc new skb, rx PDU length = %d\n", pdu_len);
-
-	atomic_inc(&vcc->stats->rx_drop);
-	return -ENOMEM;
-    } 
-
-    __net_timestamp(skb);
-    
-#ifdef FORE200E_52BYTE_AAL0_SDU
-    if (cell_header) {
-	*((u32*)skb_put(skb, 4)) = cell_header;
-    }
-#endif
-
-    /* reassemble segments */
-    for (i = 0; i < rpd->nseg; i++) {
-	
-	/* rebuild rx buffer address from rsd handle */
-	buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle);
-	
-	/* Make device DMA transfer visible to CPU.  */
-	dma_sync_single_for_cpu(fore200e->dev, buffer->data.dma_addr,
-				rpd->rsd[i].length, DMA_FROM_DEVICE);
-	
-	skb_put_data(skb, buffer->data.align_addr, rpd->rsd[i].length);
-
-	/* Now let the device get at it again.  */
-	dma_sync_single_for_device(fore200e->dev, buffer->data.dma_addr,
-				   rpd->rsd[i].length, DMA_FROM_DEVICE);
-    }
-
-    DPRINTK(3, "rx skb: len = %d, truesize = %d\n", skb->len, skb->truesize);
-    
-    if (pdu_len < fore200e_vcc->rx_min_pdu)
-	fore200e_vcc->rx_min_pdu = pdu_len;
-    if (pdu_len > fore200e_vcc->rx_max_pdu)
-	fore200e_vcc->rx_max_pdu = pdu_len;
-    fore200e_vcc->rx_pdu++;
-
-    /* push PDU */
-    if (atm_charge(vcc, skb->truesize) == 0) {
-
-	DPRINTK(2, "receive buffers saturated for %d.%d.%d - PDU dropped\n",
-		vcc->itf, vcc->vpi, vcc->vci);
-
-	dev_kfree_skb_any(skb);
-
-	atomic_inc(&vcc->stats->rx_drop);
-	return -ENOMEM;
-    }
-
-    vcc->push(vcc, skb);
-    atomic_inc(&vcc->stats->rx);
-
-    return 0;
-}
-
-
-static void
-fore200e_collect_rpd(struct fore200e* fore200e, struct rpd* rpd)
-{
-    struct host_bsq* bsq;
-    struct buffer*   buffer;
-    int              i;
-    
-    for (i = 0; i < rpd->nseg; i++) {
-
-	/* rebuild rx buffer address from rsd handle */
-	buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle);
-
-	bsq = &fore200e->host_bsq[ buffer->scheme ][ buffer->magn ];
-
-#ifdef FORE200E_BSQ_DEBUG
-	bsq_audit(2, bsq, buffer->scheme, buffer->magn);
-
-	if (buffer->supplied == 0)
-	    printk(FORE200E "queue %d.%d, buffer %ld was not supplied\n",
-		   buffer->scheme, buffer->magn, buffer->index);
-	buffer->supplied = 0;
-#endif
-
-	/* re-insert the buffer into the free buffer list */
-	buffer->next = bsq->freebuf;
-	bsq->freebuf = buffer;
-
-	/* then increment the number of free rx buffers */
-	bsq->freebuf_count++;
-    }
-}
-
-
-static void
-fore200e_rx_irq(struct fore200e* fore200e)
-{
-    struct host_rxq*        rxq = &fore200e->host_rxq;
-    struct host_rxq_entry*  entry;
-    struct atm_vcc*         vcc;
-    struct fore200e_vc_map* vc_map;
-
-    for (;;) {
-	
-	entry = &rxq->host_entry[ rxq->head ];
-
-	/* no more received PDUs */
-	if ((*entry->status & STATUS_COMPLETE) == 0)
-	    break;
-
-	vc_map = FORE200E_VC_MAP(fore200e, entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
-
-	if ((vc_map->vcc == NULL) ||
-	    (test_bit(ATM_VF_READY, &vc_map->vcc->flags) == 0)) {
-
-	    DPRINTK(1, "no ready VC found for PDU received on %d.%d.%d\n",
-		    fore200e->atm_dev->number,
-		    entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
-	}
-	else {
-	    vcc = vc_map->vcc;
-	    ASSERT(vcc);
-
-	    if ((*entry->status & STATUS_ERROR) == 0) {
-
-		fore200e_push_rpd(fore200e, vcc, entry->rpd);
-	    }
-	    else {
-		DPRINTK(2, "damaged PDU on %d.%d.%d\n",
-			fore200e->atm_dev->number,
-			entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
-		atomic_inc(&vcc->stats->rx_err);
-	    }
-	}
-
-	FORE200E_NEXT_ENTRY(rxq->head, QUEUE_SIZE_RX);
-
-	fore200e_collect_rpd(fore200e, entry->rpd);
-
-	/* rewrite the rpd address to ack the received PDU */
-	fore200e->bus->write(entry->rpd_dma, &entry->cp_entry->rpd_haddr);
-	*entry->status = STATUS_FREE;
-
-	fore200e_supply(fore200e);
-    }
-}
-
-
-#ifndef FORE200E_USE_TASKLET
-static void
-fore200e_irq(struct fore200e* fore200e)
-{
-    unsigned long flags;
-
-    spin_lock_irqsave(&fore200e->q_lock, flags);
-    fore200e_rx_irq(fore200e);
-    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-
-    spin_lock_irqsave(&fore200e->q_lock, flags);
-    fore200e_tx_irq(fore200e);
-    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-}
-#endif
-
-
-static irqreturn_t
-fore200e_interrupt(int irq, void* dev)
-{
-    struct fore200e* fore200e = FORE200E_DEV((struct atm_dev*)dev);
-
-    if (fore200e->bus->irq_check(fore200e) == 0) {
-	
-	DPRINTK(3, "interrupt NOT triggered by device %d\n", fore200e->atm_dev->number);
-	return IRQ_NONE;
-    }
-    DPRINTK(3, "interrupt triggered by device %d\n", fore200e->atm_dev->number);
-
-#ifdef FORE200E_USE_TASKLET
-    tasklet_schedule(&fore200e->tx_tasklet);
-    tasklet_schedule(&fore200e->rx_tasklet);
-#else
-    fore200e_irq(fore200e);
-#endif
-    
-    fore200e->bus->irq_ack(fore200e);
-    return IRQ_HANDLED;
-}
-
-
-#ifdef FORE200E_USE_TASKLET
-static void
-fore200e_tx_tasklet(unsigned long data)
-{
-    struct fore200e* fore200e = (struct fore200e*) data;
-    unsigned long flags;
-
-    DPRINTK(3, "tx tasklet scheduled for device %d\n", fore200e->atm_dev->number);
-
-    spin_lock_irqsave(&fore200e->q_lock, flags);
-    fore200e_tx_irq(fore200e);
-    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-}
-
-
-static void
-fore200e_rx_tasklet(unsigned long data)
-{
-    struct fore200e* fore200e = (struct fore200e*) data;
-    unsigned long    flags;
-
-    DPRINTK(3, "rx tasklet scheduled for device %d\n", fore200e->atm_dev->number);
-
-    spin_lock_irqsave(&fore200e->q_lock, flags);
-    fore200e_rx_irq((struct fore200e*) data);
-    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-}
-#endif
-
-
-static int
-fore200e_select_scheme(struct atm_vcc* vcc)
-{
-    /* fairly balance the VCs over (identical) buffer schemes */
-    int scheme = vcc->vci % 2 ? BUFFER_SCHEME_ONE : BUFFER_SCHEME_TWO;
-
-    DPRINTK(1, "VC %d.%d.%d uses buffer scheme %d\n",
-	    vcc->itf, vcc->vpi, vcc->vci, scheme);
-
-    return scheme;
-}
-
-
-static int 
-fore200e_activate_vcin(struct fore200e* fore200e, int activate, struct atm_vcc* vcc, int mtu)
-{
-    struct host_cmdq*        cmdq  = &fore200e->host_cmdq;
-    struct host_cmdq_entry*  entry = &cmdq->host_entry[ cmdq->head ];
-    struct activate_opcode   activ_opcode;
-    struct deactivate_opcode deactiv_opcode;
-    struct vpvc              vpvc;
-    int                      ok;
-    enum fore200e_aal        aal = fore200e_atm2fore_aal(vcc->qos.aal);
-
-    FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
-    
-    if (activate) {
-	FORE200E_VCC(vcc)->scheme = fore200e_select_scheme(vcc);
-	
-	activ_opcode.opcode = OPCODE_ACTIVATE_VCIN;
-	activ_opcode.aal    = aal;
-	activ_opcode.scheme = FORE200E_VCC(vcc)->scheme;
-	activ_opcode.pad    = 0;
-    }
-    else {
-	deactiv_opcode.opcode = OPCODE_DEACTIVATE_VCIN;
-	deactiv_opcode.pad    = 0;
-    }
-
-    vpvc.vci = vcc->vci;
-    vpvc.vpi = vcc->vpi;
-
-    *entry->status = STATUS_PENDING;
-
-    if (activate) {
-
-#ifdef FORE200E_52BYTE_AAL0_SDU
-	mtu = 48;
-#endif
-	/* the MTU is not used by the cp, except in the case of AAL0 */
-	fore200e->bus->write(mtu,                        &entry->cp_entry->cmd.activate_block.mtu);
-	fore200e->bus->write(*(u32*)&vpvc,         (u32 __iomem *)&entry->cp_entry->cmd.activate_block.vpvc);
-	fore200e->bus->write(*(u32*)&activ_opcode, (u32 __iomem *)&entry->cp_entry->cmd.activate_block.opcode);
-    }
-    else {
-	fore200e->bus->write(*(u32*)&vpvc,         (u32 __iomem *)&entry->cp_entry->cmd.deactivate_block.vpvc);
-	fore200e->bus->write(*(u32*)&deactiv_opcode, (u32 __iomem *)&entry->cp_entry->cmd.deactivate_block.opcode);
-    }
-
-    ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
-
-    *entry->status = STATUS_FREE;
-
-    if (ok == 0) {
-	printk(FORE200E "unable to %s VC %d.%d.%d\n",
-	       activate ? "open" : "close", vcc->itf, vcc->vpi, vcc->vci);
-	return -EIO;
-    }
-
-    DPRINTK(1, "VC %d.%d.%d %sed\n", vcc->itf, vcc->vpi, vcc->vci, 
-	    activate ? "open" : "clos");
-
-    return 0;
-}
-
-
-#define FORE200E_MAX_BACK2BACK_CELLS 255    /* XXX depends on CDVT */
-
-static void
-fore200e_rate_ctrl(struct atm_qos* qos, struct tpd_rate* rate)
-{
-    if (qos->txtp.max_pcr < ATM_OC3_PCR) {
-    
-	/* compute the data cells to idle cells ratio from the tx PCR */
-	rate->data_cells = qos->txtp.max_pcr * FORE200E_MAX_BACK2BACK_CELLS / ATM_OC3_PCR;
-	rate->idle_cells = FORE200E_MAX_BACK2BACK_CELLS - rate->data_cells;
-    }
-    else {
-	/* disable rate control */
-	rate->data_cells = rate->idle_cells = 0;
-    }
-}
-
-
-static int
-fore200e_open(struct atm_vcc *vcc)
-{
-    struct fore200e*        fore200e = FORE200E_DEV(vcc->dev);
-    struct fore200e_vcc*    fore200e_vcc;
-    struct fore200e_vc_map* vc_map;
-    unsigned long	    flags;
-    int			    vci = vcc->vci;
-    short		    vpi = vcc->vpi;
-
-    ASSERT((vpi >= 0) && (vpi < 1<<FORE200E_VPI_BITS));
-    ASSERT((vci >= 0) && (vci < 1<<FORE200E_VCI_BITS));
-
-    spin_lock_irqsave(&fore200e->q_lock, flags);
-
-    vc_map = FORE200E_VC_MAP(fore200e, vpi, vci);
-    if (vc_map->vcc) {
-
-	spin_unlock_irqrestore(&fore200e->q_lock, flags);
-
-	printk(FORE200E "VC %d.%d.%d already in use\n",
-	       fore200e->atm_dev->number, vpi, vci);
-
-	return -EINVAL;
-    }
-
-    vc_map->vcc = vcc;
-
-    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-
-    fore200e_vcc = kzalloc_obj(struct fore200e_vcc, GFP_ATOMIC);
-    if (fore200e_vcc == NULL) {
-	vc_map->vcc = NULL;
-	return -ENOMEM;
-    }
-
-    DPRINTK(2, "opening %d.%d.%d:%d QoS = (tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; "
-	    "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d)\n",
-	    vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
-	    fore200e_traffic_class[ vcc->qos.txtp.traffic_class ],
-	    vcc->qos.txtp.min_pcr, vcc->qos.txtp.max_pcr, vcc->qos.txtp.max_cdv, vcc->qos.txtp.max_sdu,
-	    fore200e_traffic_class[ vcc->qos.rxtp.traffic_class ],
-	    vcc->qos.rxtp.min_pcr, vcc->qos.rxtp.max_pcr, vcc->qos.rxtp.max_cdv, vcc->qos.rxtp.max_sdu);
-    
-    /* pseudo-CBR bandwidth requested? */
-    if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
-	
-	mutex_lock(&fore200e->rate_mtx);
-	if (fore200e->available_cell_rate < vcc->qos.txtp.max_pcr) {
-	    mutex_unlock(&fore200e->rate_mtx);
-
-	    kfree(fore200e_vcc);
-	    vc_map->vcc = NULL;
-	    return -EAGAIN;
-	}
-
-	/* reserve bandwidth */
-	fore200e->available_cell_rate -= vcc->qos.txtp.max_pcr;
-	mutex_unlock(&fore200e->rate_mtx);
-    }
-    
-    vcc->itf = vcc->dev->number;
-
-    set_bit(ATM_VF_PARTIAL,&vcc->flags);
-    set_bit(ATM_VF_ADDR, &vcc->flags);
-
-    vcc->dev_data = fore200e_vcc;
-    
-    if (fore200e_activate_vcin(fore200e, 1, vcc, vcc->qos.rxtp.max_sdu) < 0) {
-
-	vc_map->vcc = NULL;
-
-	clear_bit(ATM_VF_ADDR, &vcc->flags);
-	clear_bit(ATM_VF_PARTIAL,&vcc->flags);
-
-	vcc->dev_data = NULL;
-
-	mutex_lock(&fore200e->rate_mtx);
-	fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
-	mutex_unlock(&fore200e->rate_mtx);
-
-	kfree(fore200e_vcc);
-	return -EINVAL;
-    }
-    
-    /* compute rate control parameters */
-    if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
-	
-	fore200e_rate_ctrl(&vcc->qos, &fore200e_vcc->rate);
-	set_bit(ATM_VF_HASQOS, &vcc->flags);
-
-	DPRINTK(3, "tx on %d.%d.%d:%d, tx PCR = %d, rx PCR = %d, data_cells = %u, idle_cells = %u\n",
-		vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
-		vcc->qos.txtp.max_pcr, vcc->qos.rxtp.max_pcr, 
-		fore200e_vcc->rate.data_cells, fore200e_vcc->rate.idle_cells);
-    }
-    
-    fore200e_vcc->tx_min_pdu = fore200e_vcc->rx_min_pdu = MAX_PDU_SIZE + 1;
-    fore200e_vcc->tx_max_pdu = fore200e_vcc->rx_max_pdu = 0;
-    fore200e_vcc->tx_pdu     = fore200e_vcc->rx_pdu     = 0;
-
-    /* new incarnation of the vcc */
-    vc_map->incarn = ++fore200e->incarn_count;
-
-    /* VC unusable before this flag is set */
-    set_bit(ATM_VF_READY, &vcc->flags);
-
-    return 0;
-}
-
-
-static void
-fore200e_close(struct atm_vcc* vcc)
-{
-    struct fore200e_vcc*    fore200e_vcc;
-    struct fore200e*        fore200e;
-    struct fore200e_vc_map* vc_map;
-    unsigned long           flags;
-
-    ASSERT(vcc);
-    fore200e = FORE200E_DEV(vcc->dev);
-
-    ASSERT((vcc->vpi >= 0) && (vcc->vpi < 1<<FORE200E_VPI_BITS));
-    ASSERT((vcc->vci >= 0) && (vcc->vci < 1<<FORE200E_VCI_BITS));
-
-    DPRINTK(2, "closing %d.%d.%d:%d\n", vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal));
-
-    clear_bit(ATM_VF_READY, &vcc->flags);
-
-    fore200e_activate_vcin(fore200e, 0, vcc, 0);
-
-    spin_lock_irqsave(&fore200e->q_lock, flags);
-
-    vc_map = FORE200E_VC_MAP(fore200e, vcc->vpi, vcc->vci);
-
-    /* the vc is no longer considered as "in use" by fore200e_open() */
-    vc_map->vcc = NULL;
-
-    vcc->itf = vcc->vci = vcc->vpi = 0;
-
-    fore200e_vcc = FORE200E_VCC(vcc);
-    vcc->dev_data = NULL;
-
-    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-
-    /* release reserved bandwidth, if any */
-    if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
-
-	mutex_lock(&fore200e->rate_mtx);
-	fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
-	mutex_unlock(&fore200e->rate_mtx);
-
-	clear_bit(ATM_VF_HASQOS, &vcc->flags);
-    }
-
-    clear_bit(ATM_VF_ADDR, &vcc->flags);
-    clear_bit(ATM_VF_PARTIAL,&vcc->flags);
-
-    ASSERT(fore200e_vcc);
-    kfree(fore200e_vcc);
-}
-
-
-static int
-fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-    struct fore200e*        fore200e;
-    struct fore200e_vcc*    fore200e_vcc;
-    struct fore200e_vc_map* vc_map;
-    struct host_txq*        txq;
-    struct host_txq_entry*  entry;
-    struct tpd*             tpd;
-    struct tpd_haddr        tpd_haddr;
-    int                     retry        = CONFIG_ATM_FORE200E_TX_RETRY;
-    int                     tx_copy      = 0;
-    int                     tx_len       = skb->len;
-    u32*                    cell_header  = NULL;
-    unsigned char*          skb_data;
-    int                     skb_len;
-    unsigned char*          data;
-    unsigned long           flags;
-
-    if (!vcc)
-        return -EINVAL;
-
-    fore200e = FORE200E_DEV(vcc->dev);
-    fore200e_vcc = FORE200E_VCC(vcc);
-
-    if (!fore200e)
-        return -EINVAL;
-
-    txq = &fore200e->host_txq;
-    if (!fore200e_vcc)
-        return -EINVAL;
-
-    if (!test_bit(ATM_VF_READY, &vcc->flags)) {
-	DPRINTK(1, "VC %d.%d.%d not ready for tx\n", vcc->itf, vcc->vpi, vcc->vpi);
-	dev_kfree_skb_any(skb);
-	return -EINVAL;
-    }
-
-#ifdef FORE200E_52BYTE_AAL0_SDU
-    if ((vcc->qos.aal == ATM_AAL0) && (vcc->qos.txtp.max_sdu == ATM_AAL0_SDU)) {
-	cell_header = (u32*) skb->data;
-	skb_data    = skb->data + 4;    /* skip 4-byte cell header */
-	skb_len     = tx_len = skb->len  - 4;
-
-	DPRINTK(3, "user-supplied cell header = 0x%08x\n", *cell_header);
-    }
-    else 
-#endif
-    {
-	skb_data = skb->data;
-	skb_len  = skb->len;
-    }
-    
-    if (((unsigned long)skb_data) & 0x3) {
-
-	DPRINTK(2, "misaligned tx PDU on device %s\n", fore200e->name);
-	tx_copy = 1;
-	tx_len  = skb_len;
-    }
-
-    if ((vcc->qos.aal == ATM_AAL0) && (skb_len % ATM_CELL_PAYLOAD)) {
-
-        /* this simply NUKES the PCA board */
-	DPRINTK(2, "incomplete tx AAL0 PDU on device %s\n", fore200e->name);
-	tx_copy = 1;
-	tx_len  = ((skb_len / ATM_CELL_PAYLOAD) + 1) * ATM_CELL_PAYLOAD;
-    }
-    
-    if (tx_copy) {
-	data = kmalloc(tx_len, GFP_ATOMIC);
-	if (data == NULL) {
-	    if (vcc->pop) {
-		vcc->pop(vcc, skb);
-	    }
-	    else {
-		dev_kfree_skb_any(skb);
-	    }
-	    return -ENOMEM;
-	}
-
-	memcpy(data, skb_data, skb_len);
-	if (skb_len < tx_len)
-	    memset(data + skb_len, 0x00, tx_len - skb_len);
-    }
-    else {
-	data = skb_data;
-    }
-
-    vc_map = FORE200E_VC_MAP(fore200e, vcc->vpi, vcc->vci);
-    ASSERT(vc_map->vcc == vcc);
-
-  retry_here:
-
-    spin_lock_irqsave(&fore200e->q_lock, flags);
-
-    entry = &txq->host_entry[ txq->head ];
-
-    if ((*entry->status != STATUS_FREE) || (txq->txing >= QUEUE_SIZE_TX - 2)) {
-
-	/* try to free completed tx queue entries */
-	fore200e_tx_irq(fore200e);
-
-	if (*entry->status != STATUS_FREE) {
-
-	    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-
-	    /* retry once again? */
-	    if (--retry > 0) {
-		udelay(50);
-		goto retry_here;
-	    }
-
-	    atomic_inc(&vcc->stats->tx_err);
-
-	    fore200e->tx_sat++;
-	    DPRINTK(2, "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n",
-		    fore200e->name, fore200e->cp_queues->heartbeat);
-	    if (vcc->pop) {
-		vcc->pop(vcc, skb);
-	    }
-	    else {
-		dev_kfree_skb_any(skb);
-	    }
-
-	    if (tx_copy)
-		kfree(data);
-
-	    return -ENOBUFS;
-	}
-    }
-
-    entry->incarn = vc_map->incarn;
-    entry->vc_map = vc_map;
-    entry->skb    = skb;
-    entry->data   = tx_copy ? data : NULL;
-
-    tpd = entry->tpd;
-    tpd->tsd[ 0 ].buffer = dma_map_single(fore200e->dev, data, tx_len,
-					  DMA_TO_DEVICE);
-    if (dma_mapping_error(fore200e->dev, tpd->tsd[0].buffer)) {
-	if (tx_copy)
-	    kfree(data);
-	spin_unlock_irqrestore(&fore200e->q_lock, flags);
-	return -ENOMEM;
-    }
-    tpd->tsd[ 0 ].length = tx_len;
-
-    FORE200E_NEXT_ENTRY(txq->head, QUEUE_SIZE_TX);
-    txq->txing++;
-
-    /* The dma_map call above implies a dma_sync so the device can use it,
-     * thus no explicit dma_sync call is necessary here.
-     */
-    
-    DPRINTK(3, "tx on %d.%d.%d:%d, len = %u (%u)\n", 
-	    vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
-	    tpd->tsd[0].length, skb_len);
-
-    if (skb_len < fore200e_vcc->tx_min_pdu)
-	fore200e_vcc->tx_min_pdu = skb_len;
-    if (skb_len > fore200e_vcc->tx_max_pdu)
-	fore200e_vcc->tx_max_pdu = skb_len;
-    fore200e_vcc->tx_pdu++;
-
-    /* set tx rate control information */
-    tpd->rate.data_cells = fore200e_vcc->rate.data_cells;
-    tpd->rate.idle_cells = fore200e_vcc->rate.idle_cells;
-
-    if (cell_header) {
-	tpd->atm_header.clp = (*cell_header & ATM_HDR_CLP);
-	tpd->atm_header.plt = (*cell_header & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT;
-	tpd->atm_header.vci = (*cell_header & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT;
-	tpd->atm_header.vpi = (*cell_header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT;
-	tpd->atm_header.gfc = (*cell_header & ATM_HDR_GFC_MASK) >> ATM_HDR_GFC_SHIFT;
-    }
-    else {
-	/* set the ATM header, common to all cells conveying the PDU */
-	tpd->atm_header.clp = 0;
-	tpd->atm_header.plt = 0;
-	tpd->atm_header.vci = vcc->vci;
-	tpd->atm_header.vpi = vcc->vpi;
-	tpd->atm_header.gfc = 0;
-    }
-
-    tpd->spec.length = tx_len;
-    tpd->spec.nseg   = 1;
-    tpd->spec.aal    = fore200e_atm2fore_aal(vcc->qos.aal);
-    tpd->spec.intr   = 1;
-
-    tpd_haddr.size  = sizeof(struct tpd) / (1<<TPD_HADDR_SHIFT);  /* size is expressed in 32 byte blocks */
-    tpd_haddr.pad   = 0;
-    tpd_haddr.haddr = entry->tpd_dma >> TPD_HADDR_SHIFT;          /* shift the address, as we are in a bitfield */
-
-    *entry->status = STATUS_PENDING;
-    fore200e->bus->write(*(u32*)&tpd_haddr, (u32 __iomem *)&entry->cp_entry->tpd_haddr);
-
-    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-
-    return 0;
-}
-
-
-static int
-fore200e_getstats(struct fore200e* fore200e)
-{
-    struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
-    struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
-    struct stats_opcode     opcode;
-    int                     ok;
-    u32                     stats_dma_addr;
-
-    if (fore200e->stats == NULL) {
-	fore200e->stats = kzalloc_obj(struct stats);
-	if (fore200e->stats == NULL)
-	    return -ENOMEM;
-    }
-    
-    stats_dma_addr = dma_map_single(fore200e->dev, fore200e->stats,
-				    sizeof(struct stats), DMA_FROM_DEVICE);
-    if (dma_mapping_error(fore200e->dev, stats_dma_addr))
-    	return -ENOMEM;
-    
-    FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
-
-    opcode.opcode = OPCODE_GET_STATS;
-    opcode.pad    = 0;
-
-    fore200e->bus->write(stats_dma_addr, &entry->cp_entry->cmd.stats_block.stats_haddr);
-    
-    *entry->status = STATUS_PENDING;
-
-    fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.stats_block.opcode);
-
-    ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
-
-    *entry->status = STATUS_FREE;
-
-    dma_unmap_single(fore200e->dev, stats_dma_addr, sizeof(struct stats), DMA_FROM_DEVICE);
-    
-    if (ok == 0) {
-	printk(FORE200E "unable to get statistics from device %s\n", fore200e->name);
-	return -EIO;
-    }
-
-    return 0;
-}
-
-#if 0 /* currently unused */
-static int
-fore200e_get_oc3(struct fore200e* fore200e, struct oc3_regs* regs)
-{
-    struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
-    struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
-    struct oc3_opcode       opcode;
-    int                     ok;
-    u32                     oc3_regs_dma_addr;
-
-    oc3_regs_dma_addr = fore200e->bus->dma_map(fore200e, regs, sizeof(struct oc3_regs), DMA_FROM_DEVICE);
-
-    FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
-
-    opcode.opcode = OPCODE_GET_OC3;
-    opcode.reg    = 0;
-    opcode.value  = 0;
-    opcode.mask   = 0;
-
-    fore200e->bus->write(oc3_regs_dma_addr, &entry->cp_entry->cmd.oc3_block.regs_haddr);
-    
-    *entry->status = STATUS_PENDING;
-
-    fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.oc3_block.opcode);
-
-    ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
-
-    *entry->status = STATUS_FREE;
-
-    fore200e->bus->dma_unmap(fore200e, oc3_regs_dma_addr, sizeof(struct oc3_regs), DMA_FROM_DEVICE);
-    
-    if (ok == 0) {
-	printk(FORE200E "unable to get OC-3 regs of device %s\n", fore200e->name);
-	return -EIO;
-    }
-
-    return 0;
-}
-#endif
-
-
-static int
-fore200e_set_oc3(struct fore200e* fore200e, u32 reg, u32 value, u32 mask)
-{
-    struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
-    struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
-    struct oc3_opcode       opcode;
-    int                     ok;
-
-    DPRINTK(2, "set OC-3 reg = 0x%02x, value = 0x%02x, mask = 0x%02x\n", reg, value, mask);
-
-    FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
-
-    opcode.opcode = OPCODE_SET_OC3;
-    opcode.reg    = reg;
-    opcode.value  = value;
-    opcode.mask   = mask;
-
-    fore200e->bus->write(0, &entry->cp_entry->cmd.oc3_block.regs_haddr);
-    
-    *entry->status = STATUS_PENDING;
-
-    fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.oc3_block.opcode);
-
-    ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
-
-    *entry->status = STATUS_FREE;
-
-    if (ok == 0) {
-	printk(FORE200E "unable to set OC-3 reg 0x%02x of device %s\n", reg, fore200e->name);
-	return -EIO;
-    }
-
-    return 0;
-}
-
-
-static int
-fore200e_setloop(struct fore200e* fore200e, int loop_mode)
-{
-    u32 mct_value, mct_mask;
-    int error;
-
-    if (!capable(CAP_NET_ADMIN))
-	return -EPERM;
-    
-    switch (loop_mode) {
-
-    case ATM_LM_NONE:
-	mct_value = 0; 
-	mct_mask  = SUNI_MCT_DLE | SUNI_MCT_LLE;
-	break;
-	
-    case ATM_LM_LOC_PHY:
-	mct_value = mct_mask = SUNI_MCT_DLE;
-	break;
-
-    case ATM_LM_RMT_PHY:
-	mct_value = mct_mask = SUNI_MCT_LLE;
-	break;
-
-    default:
-	return -EINVAL;
-    }
-
-    error = fore200e_set_oc3(fore200e, SUNI_MCT, mct_value, mct_mask);
-    if (error == 0)
-	fore200e->loop_mode = loop_mode;
-
-    return error;
-}
-
-
-static int
-fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats __user *arg)
-{
-    struct sonet_stats tmp;
-
-    if (fore200e_getstats(fore200e) < 0)
-	return -EIO;
-
-    tmp.section_bip = be32_to_cpu(fore200e->stats->oc3.section_bip8_errors);
-    tmp.line_bip    = be32_to_cpu(fore200e->stats->oc3.line_bip24_errors);
-    tmp.path_bip    = be32_to_cpu(fore200e->stats->oc3.path_bip8_errors);
-    tmp.line_febe   = be32_to_cpu(fore200e->stats->oc3.line_febe_errors);
-    tmp.path_febe   = be32_to_cpu(fore200e->stats->oc3.path_febe_errors);
-    tmp.corr_hcs    = be32_to_cpu(fore200e->stats->oc3.corr_hcs_errors);
-    tmp.uncorr_hcs  = be32_to_cpu(fore200e->stats->oc3.ucorr_hcs_errors);
-    tmp.tx_cells    = be32_to_cpu(fore200e->stats->aal0.cells_transmitted)  +
-	              be32_to_cpu(fore200e->stats->aal34.cells_transmitted) +
-	              be32_to_cpu(fore200e->stats->aal5.cells_transmitted);
-    tmp.rx_cells    = be32_to_cpu(fore200e->stats->aal0.cells_received)     +
-	              be32_to_cpu(fore200e->stats->aal34.cells_received)    +
-	              be32_to_cpu(fore200e->stats->aal5.cells_received);
-
-    if (arg)
-	return copy_to_user(arg, &tmp, sizeof(struct sonet_stats)) ? -EFAULT : 0;	
-    
-    return 0;
-}
-
-
-static int
-fore200e_ioctl(struct atm_dev* dev, unsigned int cmd, void __user * arg)
-{
-    struct fore200e* fore200e = FORE200E_DEV(dev);
-    
-    DPRINTK(2, "ioctl cmd = 0x%x (%u), arg = 0x%p (%lu)\n", cmd, cmd, arg, (unsigned long)arg);
-
-    switch (cmd) {
-
-    case SONET_GETSTAT:
-	return fore200e_fetch_stats(fore200e, (struct sonet_stats __user *)arg);
-
-    case SONET_GETDIAG:
-	return put_user(0, (int __user *)arg) ? -EFAULT : 0;
-
-    case ATM_SETLOOP:
-	return fore200e_setloop(fore200e, (int)(unsigned long)arg);
-
-    case ATM_GETLOOP:
-	return put_user(fore200e->loop_mode, (int __user *)arg) ? -EFAULT : 0;
-
-    case ATM_QUERYLOOP:
-	return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY, (int __user *)arg) ? -EFAULT : 0;
-    }
-
-    return -ENOSYS; /* not implemented */
-}
-
-
-static int
-fore200e_change_qos(struct atm_vcc* vcc,struct atm_qos* qos, int flags)
-{
-    struct fore200e_vcc* fore200e_vcc = FORE200E_VCC(vcc);
-    struct fore200e*     fore200e     = FORE200E_DEV(vcc->dev);
-
-    if (!test_bit(ATM_VF_READY, &vcc->flags)) {
-	DPRINTK(1, "VC %d.%d.%d not ready for QoS change\n", vcc->itf, vcc->vpi, vcc->vpi);
-	return -EINVAL;
-    }
-
-    DPRINTK(2, "change_qos %d.%d.%d, "
-	    "(tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; "
-	    "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d), flags = 0x%x\n"
-	    "available_cell_rate = %u",
-	    vcc->itf, vcc->vpi, vcc->vci,
-	    fore200e_traffic_class[ qos->txtp.traffic_class ],
-	    qos->txtp.min_pcr, qos->txtp.max_pcr, qos->txtp.max_cdv, qos->txtp.max_sdu,
-	    fore200e_traffic_class[ qos->rxtp.traffic_class ],
-	    qos->rxtp.min_pcr, qos->rxtp.max_pcr, qos->rxtp.max_cdv, qos->rxtp.max_sdu,
-	    flags, fore200e->available_cell_rate);
-
-    if ((qos->txtp.traffic_class == ATM_CBR) && (qos->txtp.max_pcr > 0)) {
-
-	mutex_lock(&fore200e->rate_mtx);
-	if (fore200e->available_cell_rate + vcc->qos.txtp.max_pcr < qos->txtp.max_pcr) {
-	    mutex_unlock(&fore200e->rate_mtx);
-	    return -EAGAIN;
-	}
-
-	fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
-	fore200e->available_cell_rate -= qos->txtp.max_pcr;
-
-	mutex_unlock(&fore200e->rate_mtx);
-	
-	memcpy(&vcc->qos, qos, sizeof(struct atm_qos));
-	
-	/* update rate control parameters */
-	fore200e_rate_ctrl(qos, &fore200e_vcc->rate);
-
-	set_bit(ATM_VF_HASQOS, &vcc->flags);
-
-	return 0;
-    }
-    
-    return -EINVAL;
-}
-    
-
-static int fore200e_irq_request(struct fore200e *fore200e)
-{
-    if (request_irq(fore200e->irq, fore200e_interrupt, IRQF_SHARED, fore200e->name, fore200e->atm_dev) < 0) {
-
-	printk(FORE200E "unable to reserve IRQ %s for device %s\n",
-	       fore200e_irq_itoa(fore200e->irq), fore200e->name);
-	return -EBUSY;
-    }
-
-    printk(FORE200E "IRQ %s reserved for device %s\n",
-	   fore200e_irq_itoa(fore200e->irq), fore200e->name);
-
-#ifdef FORE200E_USE_TASKLET
-    tasklet_init(&fore200e->tx_tasklet, fore200e_tx_tasklet, (unsigned long)fore200e);
-    tasklet_init(&fore200e->rx_tasklet, fore200e_rx_tasklet, (unsigned long)fore200e);
-#endif
-
-    fore200e->state = FORE200E_STATE_IRQ;
-    return 0;
-}
-
-
-static int fore200e_get_esi(struct fore200e *fore200e)
-{
-    struct prom_data* prom = kzalloc_obj(struct prom_data);
-    int ok, i;
-
-    if (!prom)
-	return -ENOMEM;
-
-    ok = fore200e->bus->prom_read(fore200e, prom);
-    if (ok < 0) {
-	kfree(prom);
-	return -EBUSY;
-    }
-	
-    printk(FORE200E "device %s, rev. %c, S/N: %d, ESI: %pM\n",
-	   fore200e->name, 
-	   (prom->hw_revision & 0xFF) + '@',    /* probably meaningless with SBA boards */
-	   prom->serial_number & 0xFFFF, &prom->mac_addr[2]);
-	
-    for (i = 0; i < ESI_LEN; i++) {
-	fore200e->esi[ i ] = fore200e->atm_dev->esi[ i ] = prom->mac_addr[ i + 2 ];
-    }
-    
-    kfree(prom);
-
-    return 0;
-}
-
-
-static int fore200e_alloc_rx_buf(struct fore200e *fore200e)
-{
-    int scheme, magn, nbr, size, i;
-
-    struct host_bsq* bsq;
-    struct buffer*   buffer;
-
-    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
-	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
-
-	    bsq = &fore200e->host_bsq[ scheme ][ magn ];
-
-	    nbr  = fore200e_rx_buf_nbr[ scheme ][ magn ];
-	    size = fore200e_rx_buf_size[ scheme ][ magn ];
-
-	    DPRINTK(2, "rx buffers %d / %d are being allocated\n", scheme, magn);
-
-	    /* allocate the array of receive buffers */
-	    buffer = bsq->buffer = kzalloc_objs(struct buffer, nbr);
-
-	    if (buffer == NULL)
-		return -ENOMEM;
-
-	    bsq->freebuf = NULL;
-
-	    for (i = 0; i < nbr; i++) {
-
-		buffer[ i ].scheme = scheme;
-		buffer[ i ].magn   = magn;
-#ifdef FORE200E_BSQ_DEBUG
-		buffer[ i ].index  = i;
-		buffer[ i ].supplied = 0;
-#endif
-
-		/* allocate the receive buffer body */
-		if (fore200e_chunk_alloc(fore200e,
-					 &buffer[ i ].data, size, fore200e->bus->buffer_alignment,
-					 DMA_FROM_DEVICE) < 0) {
-		    
-		    while (i > 0)
-			fore200e_chunk_free(fore200e, &buffer[ --i ].data);
-		    kfree(buffer);
-		    
-		    return -ENOMEM;
-		}
-
-		/* insert the buffer into the free buffer list */
-		buffer[ i ].next = bsq->freebuf;
-		bsq->freebuf = &buffer[ i ];
-	    }
-	    /* all the buffers are free, initially */
-	    bsq->freebuf_count = nbr;
-
-#ifdef FORE200E_BSQ_DEBUG
-	    bsq_audit(3, bsq, scheme, magn);
-#endif
-	}
-    }
-
-    fore200e->state = FORE200E_STATE_ALLOC_BUF;
-    return 0;
-}
-
-
-static int fore200e_init_bs_queue(struct fore200e *fore200e)
-{
-    int scheme, magn, i;
-
-    struct host_bsq*     bsq;
-    struct cp_bsq_entry __iomem * cp_entry;
-
-    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
-	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
-
-	    DPRINTK(2, "buffer supply queue %d / %d is being initialized\n", scheme, magn);
-
-	    bsq = &fore200e->host_bsq[ scheme ][ magn ];
-
-	    /* allocate and align the array of status words */
-	    if (fore200e_dma_chunk_alloc(fore200e,
-					       &bsq->status,
-					       sizeof(enum status), 
-					       QUEUE_SIZE_BS,
-					       fore200e->bus->status_alignment) < 0) {
-		return -ENOMEM;
-	    }
-
-	    /* allocate and align the array of receive buffer descriptors */
-	    if (fore200e_dma_chunk_alloc(fore200e,
-					       &bsq->rbd_block,
-					       sizeof(struct rbd_block),
-					       QUEUE_SIZE_BS,
-					       fore200e->bus->descr_alignment) < 0) {
-		
-		fore200e_dma_chunk_free(fore200e, &bsq->status);
-		return -ENOMEM;
-	    }
-	    
-	    /* get the base address of the cp resident buffer supply queue entries */
-	    cp_entry = fore200e->virt_base + 
-		       fore200e->bus->read(&fore200e->cp_queues->cp_bsq[ scheme ][ magn ]);
-	    
-	    /* fill the host resident and cp resident buffer supply queue entries */
-	    for (i = 0; i < QUEUE_SIZE_BS; i++) {
-		
-		bsq->host_entry[ i ].status = 
-		                     FORE200E_INDEX(bsq->status.align_addr, enum status, i);
-	        bsq->host_entry[ i ].rbd_block =
-		                     FORE200E_INDEX(bsq->rbd_block.align_addr, struct rbd_block, i);
-		bsq->host_entry[ i ].rbd_block_dma =
-		                     FORE200E_DMA_INDEX(bsq->rbd_block.dma_addr, struct rbd_block, i);
-		bsq->host_entry[ i ].cp_entry = &cp_entry[ i ];
-		
-		*bsq->host_entry[ i ].status = STATUS_FREE;
-		
-		fore200e->bus->write(FORE200E_DMA_INDEX(bsq->status.dma_addr, enum status, i), 
-				     &cp_entry[ i ].status_haddr);
-	    }
-	}
-    }
-
-    fore200e->state = FORE200E_STATE_INIT_BSQ;
-    return 0;
-}
-
-
-static int fore200e_init_rx_queue(struct fore200e *fore200e)
-{
-    struct host_rxq*     rxq =  &fore200e->host_rxq;
-    struct cp_rxq_entry __iomem * cp_entry;
-    int i;
-
-    DPRINTK(2, "receive queue is being initialized\n");
-
-    /* allocate and align the array of status words */
-    if (fore200e_dma_chunk_alloc(fore200e,
-				       &rxq->status,
-				       sizeof(enum status), 
-				       QUEUE_SIZE_RX,
-				       fore200e->bus->status_alignment) < 0) {
-	return -ENOMEM;
-    }
-
-    /* allocate and align the array of receive PDU descriptors */
-    if (fore200e_dma_chunk_alloc(fore200e,
-				       &rxq->rpd,
-				       sizeof(struct rpd), 
-				       QUEUE_SIZE_RX,
-				       fore200e->bus->descr_alignment) < 0) {
-	
-	fore200e_dma_chunk_free(fore200e, &rxq->status);
-	return -ENOMEM;
-    }
-
-    /* get the base address of the cp resident rx queue entries */
-    cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_rxq);
-
-    /* fill the host resident and cp resident rx entries */
-    for (i=0; i < QUEUE_SIZE_RX; i++) {
-	
-	rxq->host_entry[ i ].status = 
-	                     FORE200E_INDEX(rxq->status.align_addr, enum status, i);
-	rxq->host_entry[ i ].rpd = 
-	                     FORE200E_INDEX(rxq->rpd.align_addr, struct rpd, i);
-	rxq->host_entry[ i ].rpd_dma = 
-	                     FORE200E_DMA_INDEX(rxq->rpd.dma_addr, struct rpd, i);
-	rxq->host_entry[ i ].cp_entry = &cp_entry[ i ];
-
-	*rxq->host_entry[ i ].status = STATUS_FREE;
-
-	fore200e->bus->write(FORE200E_DMA_INDEX(rxq->status.dma_addr, enum status, i), 
-			     &cp_entry[ i ].status_haddr);
-
-	fore200e->bus->write(FORE200E_DMA_INDEX(rxq->rpd.dma_addr, struct rpd, i),
-			     &cp_entry[ i ].rpd_haddr);
-    }
-
-    /* set the head entry of the queue */
-    rxq->head = 0;
-
-    fore200e->state = FORE200E_STATE_INIT_RXQ;
-    return 0;
-}
-
-
-static int fore200e_init_tx_queue(struct fore200e *fore200e)
-{
-    struct host_txq*     txq =  &fore200e->host_txq;
-    struct cp_txq_entry __iomem * cp_entry;
-    int i;
-
-    DPRINTK(2, "transmit queue is being initialized\n");
-
-    /* allocate and align the array of status words */
-    if (fore200e_dma_chunk_alloc(fore200e,
-				       &txq->status,
-				       sizeof(enum status), 
-				       QUEUE_SIZE_TX,
-				       fore200e->bus->status_alignment) < 0) {
-	return -ENOMEM;
-    }
-
-    /* allocate and align the array of transmit PDU descriptors */
-    if (fore200e_dma_chunk_alloc(fore200e,
-				       &txq->tpd,
-				       sizeof(struct tpd), 
-				       QUEUE_SIZE_TX,
-				       fore200e->bus->descr_alignment) < 0) {
-	
-	fore200e_dma_chunk_free(fore200e, &txq->status);
-	return -ENOMEM;
-    }
-
-    /* get the base address of the cp resident tx queue entries */
-    cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_txq);
-
-    /* fill the host resident and cp resident tx entries */
-    for (i=0; i < QUEUE_SIZE_TX; i++) {
-	
-	txq->host_entry[ i ].status = 
-	                     FORE200E_INDEX(txq->status.align_addr, enum status, i);
-	txq->host_entry[ i ].tpd = 
-	                     FORE200E_INDEX(txq->tpd.align_addr, struct tpd, i);
-	txq->host_entry[ i ].tpd_dma  = 
-                             FORE200E_DMA_INDEX(txq->tpd.dma_addr, struct tpd, i);
-	txq->host_entry[ i ].cp_entry = &cp_entry[ i ];
-
-	*txq->host_entry[ i ].status = STATUS_FREE;
-	
-	fore200e->bus->write(FORE200E_DMA_INDEX(txq->status.dma_addr, enum status, i), 
-			     &cp_entry[ i ].status_haddr);
-	
-        /* although there is a one-to-one mapping of tx queue entries and tpds,
-	   we do not write here the DMA (physical) base address of each tpd into
-	   the related cp resident entry, because the cp relies on this write
-	   operation to detect that a new pdu has been submitted for tx */
-    }
-
-    /* set the head and tail entries of the queue */
-    txq->head = 0;
-    txq->tail = 0;
-
-    fore200e->state = FORE200E_STATE_INIT_TXQ;
-    return 0;
-}
-
-
-static int fore200e_init_cmd_queue(struct fore200e *fore200e)
-{
-    struct host_cmdq*     cmdq =  &fore200e->host_cmdq;
-    struct cp_cmdq_entry __iomem * cp_entry;
-    int i;
-
-    DPRINTK(2, "command queue is being initialized\n");
-
-    /* allocate and align the array of status words */
-    if (fore200e_dma_chunk_alloc(fore200e,
-				       &cmdq->status,
-				       sizeof(enum status), 
-				       QUEUE_SIZE_CMD,
-				       fore200e->bus->status_alignment) < 0) {
-	return -ENOMEM;
-    }
-    
-    /* get the base address of the cp resident cmd queue entries */
-    cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_cmdq);
-
-    /* fill the host resident and cp resident cmd entries */
-    for (i=0; i < QUEUE_SIZE_CMD; i++) {
-	
-	cmdq->host_entry[ i ].status   = 
-                              FORE200E_INDEX(cmdq->status.align_addr, enum status, i);
-	cmdq->host_entry[ i ].cp_entry = &cp_entry[ i ];
-
-	*cmdq->host_entry[ i ].status = STATUS_FREE;
-
-	fore200e->bus->write(FORE200E_DMA_INDEX(cmdq->status.dma_addr, enum status, i), 
-                             &cp_entry[ i ].status_haddr);
-    }
-
-    /* set the head entry of the queue */
-    cmdq->head = 0;
-
-    fore200e->state = FORE200E_STATE_INIT_CMDQ;
-    return 0;
-}
-
-
-static void fore200e_param_bs_queue(struct fore200e *fore200e,
-				    enum buffer_scheme scheme,
-				    enum buffer_magn magn, int queue_length,
-				    int pool_size, int supply_blksize)
-{
-    struct bs_spec __iomem * bs_spec = &fore200e->cp_queues->init.bs_spec[ scheme ][ magn ];
-
-    fore200e->bus->write(queue_length,                           &bs_spec->queue_length);
-    fore200e->bus->write(fore200e_rx_buf_size[ scheme ][ magn ], &bs_spec->buffer_size);
-    fore200e->bus->write(pool_size,                              &bs_spec->pool_size);
-    fore200e->bus->write(supply_blksize,                         &bs_spec->supply_blksize);
-}
-
-
-static int fore200e_initialize(struct fore200e *fore200e)
-{
-    struct cp_queues __iomem * cpq;
-    int               ok, scheme, magn;
-
-    DPRINTK(2, "device %s being initialized\n", fore200e->name);
-
-    mutex_init(&fore200e->rate_mtx);
-    spin_lock_init(&fore200e->q_lock);
-
-    cpq = fore200e->cp_queues = fore200e->virt_base + FORE200E_CP_QUEUES_OFFSET;
-
-    /* enable cp to host interrupts */
-    fore200e->bus->write(1, &cpq->imask);
-
-    if (fore200e->bus->irq_enable)
-	fore200e->bus->irq_enable(fore200e);
-    
-    fore200e->bus->write(NBR_CONNECT, &cpq->init.num_connect);
-
-    fore200e->bus->write(QUEUE_SIZE_CMD, &cpq->init.cmd_queue_len);
-    fore200e->bus->write(QUEUE_SIZE_RX,  &cpq->init.rx_queue_len);
-    fore200e->bus->write(QUEUE_SIZE_TX,  &cpq->init.tx_queue_len);
-
-    fore200e->bus->write(RSD_EXTENSION,  &cpq->init.rsd_extension);
-    fore200e->bus->write(TSD_EXTENSION,  &cpq->init.tsd_extension);
-
-    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++)
-	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++)
-	    fore200e_param_bs_queue(fore200e, scheme, magn,
-				    QUEUE_SIZE_BS, 
-				    fore200e_rx_buf_nbr[ scheme ][ magn ],
-				    RBD_BLK_SIZE);
-
-    /* issue the initialize command */
-    fore200e->bus->write(STATUS_PENDING,    &cpq->init.status);
-    fore200e->bus->write(OPCODE_INITIALIZE, &cpq->init.opcode);
-
-    ok = fore200e_io_poll(fore200e, &cpq->init.status, STATUS_COMPLETE, 3000);
-    if (ok == 0) {
-	printk(FORE200E "device %s initialization failed\n", fore200e->name);
-	return -ENODEV;
-    }
-
-    printk(FORE200E "device %s initialized\n", fore200e->name);
-
-    fore200e->state = FORE200E_STATE_INITIALIZE;
-    return 0;
-}
-
-
-static void fore200e_monitor_putc(struct fore200e *fore200e, char c)
-{
-    struct cp_monitor __iomem * monitor = fore200e->cp_monitor;
-
-#if 0
-    printk("%c", c);
-#endif
-    fore200e->bus->write(((u32) c) | FORE200E_CP_MONITOR_UART_AVAIL, &monitor->soft_uart.send);
-}
-
-
-static int fore200e_monitor_getc(struct fore200e *fore200e)
-{
-    struct cp_monitor __iomem * monitor = fore200e->cp_monitor;
-    unsigned long      timeout = jiffies + msecs_to_jiffies(50);
-    int                c;
-
-    while (time_before(jiffies, timeout)) {
-
-	c = (int) fore200e->bus->read(&monitor->soft_uart.recv);
-
-	if (c & FORE200E_CP_MONITOR_UART_AVAIL) {
-
-	    fore200e->bus->write(FORE200E_CP_MONITOR_UART_FREE, &monitor->soft_uart.recv);
-#if 0
-	    printk("%c", c & 0xFF);
-#endif
-	    return c & 0xFF;
-	}
-    }
-
-    return -1;
-}
-
-
-static void fore200e_monitor_puts(struct fore200e *fore200e, char *str)
-{
-    while (*str) {
-
-	/* the i960 monitor doesn't accept any new character if it has something to say */
-	while (fore200e_monitor_getc(fore200e) >= 0);
-	
-	fore200e_monitor_putc(fore200e, *str++);
-    }
-
-    while (fore200e_monitor_getc(fore200e) >= 0);
-}
-
-#ifdef __LITTLE_ENDIAN
-#define FW_EXT ".bin"
-#else
-#define FW_EXT "_ecd.bin2"
-#endif
-
-static int fore200e_load_and_start_fw(struct fore200e *fore200e)
-{
-    const struct firmware *firmware;
-    const struct fw_header *fw_header;
-    const __le32 *fw_data;
-    u32 fw_size;
-    u32 __iomem *load_addr;
-    char buf[48];
-    int err;
-
-    sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT);
-    if ((err = request_firmware(&firmware, buf, fore200e->dev)) < 0) {
-	printk(FORE200E "problem loading firmware image %s\n", fore200e->bus->model_name);
-	return err;
-    }
-
-    fw_data = (const __le32 *)firmware->data;
-    fw_size = firmware->size / sizeof(u32);
-    fw_header = (const struct fw_header *)firmware->data;
-    load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset);
-
-    DPRINTK(2, "device %s firmware being loaded at 0x%p (%d words)\n",
-	    fore200e->name, load_addr, fw_size);
-
-    if (le32_to_cpu(fw_header->magic) != FW_HEADER_MAGIC) {
-	printk(FORE200E "corrupted %s firmware image\n", fore200e->bus->model_name);
-	goto release;
-    }
-
-    for (; fw_size--; fw_data++, load_addr++)
-	fore200e->bus->write(le32_to_cpu(*fw_data), load_addr);
-
-    DPRINTK(2, "device %s firmware being started\n", fore200e->name);
-
-#if defined(__sparc_v9__)
-    /* reported to be required by SBA cards on some sparc64 hosts */
-    fore200e_spin(100);
-#endif
-
-    sprintf(buf, "\rgo %x\r", le32_to_cpu(fw_header->start_offset));
-    fore200e_monitor_puts(fore200e, buf);
-
-    if (fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_CP_RUNNING, 1000) == 0) {
-	printk(FORE200E "device %s firmware didn't start\n", fore200e->name);
-	goto release;
-    }
-
-    printk(FORE200E "device %s firmware started\n", fore200e->name);
-
-    fore200e->state = FORE200E_STATE_START_FW;
-    err = 0;
-
-release:
-    release_firmware(firmware);
-    return err;
-}
-
-
-static int fore200e_register(struct fore200e *fore200e, struct device *parent)
-{
-    struct atm_dev* atm_dev;
-
-    DPRINTK(2, "device %s being registered\n", fore200e->name);
-
-    atm_dev = atm_dev_register(fore200e->bus->proc_name, parent, &fore200e_ops,
-                               -1, NULL);
-    if (atm_dev == NULL) {
-	printk(FORE200E "unable to register device %s\n", fore200e->name);
-	return -ENODEV;
-    }
-
-    atm_dev->dev_data = fore200e;
-    fore200e->atm_dev = atm_dev;
-
-    atm_dev->ci_range.vpi_bits = FORE200E_VPI_BITS;
-    atm_dev->ci_range.vci_bits = FORE200E_VCI_BITS;
-
-    fore200e->available_cell_rate = ATM_OC3_PCR;
-
-    fore200e->state = FORE200E_STATE_REGISTER;
-    return 0;
-}
-
-
-static int fore200e_init(struct fore200e *fore200e, struct device *parent)
-{
-    if (fore200e_register(fore200e, parent) < 0)
-	return -ENODEV;
-    
-    if (fore200e->bus->configure(fore200e) < 0)
-	return -ENODEV;
-
-    if (fore200e->bus->map(fore200e) < 0)
-	return -ENODEV;
-
-    if (fore200e_reset(fore200e, 1) < 0)
-	return -ENODEV;
-
-    if (fore200e_load_and_start_fw(fore200e) < 0)
-	return -ENODEV;
-
-    if (fore200e_initialize(fore200e) < 0)
-	return -ENODEV;
-
-    if (fore200e_init_cmd_queue(fore200e) < 0)
-	return -ENOMEM;
-
-    if (fore200e_init_tx_queue(fore200e) < 0)
-	return -ENOMEM;
-
-    if (fore200e_init_rx_queue(fore200e) < 0)
-	return -ENOMEM;
-
-    if (fore200e_init_bs_queue(fore200e) < 0)
-	return -ENOMEM;
-
-    if (fore200e_alloc_rx_buf(fore200e) < 0)
-	return -ENOMEM;
-
-    if (fore200e_get_esi(fore200e) < 0)
-	return -EIO;
-
-    if (fore200e_irq_request(fore200e) < 0)
-	return -EBUSY;
-
-    fore200e_supply(fore200e);
-
-    /* all done, board initialization is now complete */
-    fore200e->state = FORE200E_STATE_COMPLETE;
-    return 0;
-}
-
-#ifdef CONFIG_SBUS
-static int fore200e_sba_probe(struct platform_device *op)
-{
-	struct fore200e *fore200e;
-	static int index = 0;
-	int err;
-
-	fore200e = kzalloc_obj(struct fore200e);
-	if (!fore200e)
-		return -ENOMEM;
-
-	fore200e->bus = &fore200e_sbus_ops;
-	fore200e->dev = &op->dev;
-	fore200e->irq = op->archdata.irqs[0];
-	fore200e->phys_base = op->resource[0].start;
-
-	sprintf(fore200e->name, "SBA-200E-%d", index);
-
-	err = fore200e_init(fore200e, &op->dev);
-	if (err < 0) {
-		fore200e_shutdown(fore200e);
-		kfree(fore200e);
-		return err;
-	}
-
-	index++;
-	dev_set_drvdata(&op->dev, fore200e);
-
-	return 0;
-}
-
-static void fore200e_sba_remove(struct platform_device *op)
-{
-	struct fore200e *fore200e = dev_get_drvdata(&op->dev);
-
-	fore200e_shutdown(fore200e);
-	kfree(fore200e);
-}
-
-static const struct of_device_id fore200e_sba_match[] = {
-	{
-		.name = SBA200E_PROM_NAME,
-	},
-	{},
-};
-MODULE_DEVICE_TABLE(of, fore200e_sba_match);
-
-static struct platform_driver fore200e_sba_driver = {
-	.driver = {
-		.name = "fore_200e",
-		.of_match_table = fore200e_sba_match,
-	},
-	.probe		= fore200e_sba_probe,
-	.remove		= fore200e_sba_remove,
-};
-#endif
-
-#ifdef CONFIG_PCI
-static int fore200e_pca_detect(struct pci_dev *pci_dev,
-			       const struct pci_device_id *pci_ent)
-{
-    struct fore200e* fore200e;
-    int err = 0;
-    static int index = 0;
-
-    if (pci_enable_device(pci_dev)) {
-	err = -EINVAL;
-	goto out;
-    }
-
-    if (dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32))) {
-	err = -EINVAL;
-	goto out;
-    }
-    
-    fore200e = kzalloc_obj(struct fore200e);
-    if (fore200e == NULL) {
-	err = -ENOMEM;
-	goto out_disable;
-    }
-
-    fore200e->bus       = &fore200e_pci_ops;
-    fore200e->dev	= &pci_dev->dev;
-    fore200e->irq       = pci_dev->irq;
-    fore200e->phys_base = pci_resource_start(pci_dev, 0);
-
-    sprintf(fore200e->name, "PCA-200E-%d", index - 1);
-
-    pci_set_master(pci_dev);
-
-    printk(FORE200E "device PCA-200E found at 0x%lx, IRQ %s\n",
-	   fore200e->phys_base, fore200e_irq_itoa(fore200e->irq));
-
-    sprintf(fore200e->name, "PCA-200E-%d", index);
-
-    err = fore200e_init(fore200e, &pci_dev->dev);
-    if (err < 0) {
-	fore200e_shutdown(fore200e);
-	goto out_free;
-    }
-
-    ++index;
-    pci_set_drvdata(pci_dev, fore200e);
-
-out:
-    return err;
-
-out_free:
-    kfree(fore200e);
-out_disable:
-    pci_disable_device(pci_dev);
-    goto out;
-}
-
-
-static void fore200e_pca_remove_one(struct pci_dev *pci_dev)
-{
-    struct fore200e *fore200e;
-
-    fore200e = pci_get_drvdata(pci_dev);
-
-    fore200e_shutdown(fore200e);
-    kfree(fore200e);
-    pci_disable_device(pci_dev);
-}
-
-
-static const struct pci_device_id fore200e_pca_tbl[] = {
-    { PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_PCA200E, PCI_ANY_ID, PCI_ANY_ID },
-    { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, fore200e_pca_tbl);
-
-static struct pci_driver fore200e_pca_driver = {
-    .name =     "fore_200e",
-    .probe =    fore200e_pca_detect,
-    .remove =   fore200e_pca_remove_one,
-    .id_table = fore200e_pca_tbl,
-};
-#endif
-
-static int __init fore200e_module_init(void)
-{
-	int err = 0;
-
-	printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n");
-
-#ifdef CONFIG_SBUS
-	err = platform_driver_register(&fore200e_sba_driver);
-	if (err)
-		return err;
-#endif
-
-#ifdef CONFIG_PCI
-	err = pci_register_driver(&fore200e_pca_driver);
-#endif
-
-#ifdef CONFIG_SBUS
-	if (err)
-		platform_driver_unregister(&fore200e_sba_driver);
-#endif
-
-	return err;
-}
-
-static void __exit fore200e_module_cleanup(void)
-{
-#ifdef CONFIG_PCI
-	pci_unregister_driver(&fore200e_pca_driver);
-#endif
-#ifdef CONFIG_SBUS
-	platform_driver_unregister(&fore200e_sba_driver);
-#endif
-}
-
-static int
-fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
-{
-    struct fore200e*     fore200e  = FORE200E_DEV(dev);
-    struct fore200e_vcc* fore200e_vcc;
-    struct atm_vcc*      vcc;
-    int                  i, len, left = *pos;
-    unsigned long        flags;
-
-    if (!left--) {
-
-	if (fore200e_getstats(fore200e) < 0)
-	    return -EIO;
-
-	len = sprintf(page,"\n"
-		       " device:\n"
-		       "   internal name:\t\t%s\n", fore200e->name);
-
-	/* print bus-specific information */
-	if (fore200e->bus->proc_read)
-	    len += fore200e->bus->proc_read(fore200e, page + len);
-	
-	len += sprintf(page + len,
-		"   interrupt line:\t\t%s\n"
-		"   physical base address:\t0x%p\n"
-		"   virtual base address:\t0x%p\n"
-		"   factory address (ESI):\t%pM\n"
-		"   board serial number:\t\t%d\n\n",
-		fore200e_irq_itoa(fore200e->irq),
-		(void*)fore200e->phys_base,
-		fore200e->virt_base,
-		fore200e->esi,
-		fore200e->esi[4] * 256 + fore200e->esi[5]);
-
-	return len;
-    }
-
-    if (!left--)
-	return sprintf(page,
-		       "   free small bufs, scheme 1:\t%d\n"
-		       "   free large bufs, scheme 1:\t%d\n"
-		       "   free small bufs, scheme 2:\t%d\n"
-		       "   free large bufs, scheme 2:\t%d\n",
-		       fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_SMALL ].freebuf_count,
-		       fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_LARGE ].freebuf_count,
-		       fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_SMALL ].freebuf_count,
-		       fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_LARGE ].freebuf_count);
-
-    if (!left--) {
-	u32 hb = fore200e->bus->read(&fore200e->cp_queues->heartbeat);
-
-	len = sprintf(page,"\n\n"
-		      " cell processor:\n"
-		      "   heartbeat state:\t\t");
-	
-	if (hb >> 16 != 0xDEAD)
-	    len += sprintf(page + len, "0x%08x\n", hb);
-	else
-	    len += sprintf(page + len, "*** FATAL ERROR %04x ***\n", hb & 0xFFFF);
-
-	return len;
-    }
-
-    if (!left--) {
-	static const char* media_name[] = {
-	    "unshielded twisted pair",
-	    "multimode optical fiber ST",
-	    "multimode optical fiber SC",
-	    "single-mode optical fiber ST",
-	    "single-mode optical fiber SC",
-	    "unknown"
-	};
-
-	static const char* oc3_mode[] = {
-	    "normal operation",
-	    "diagnostic loopback",
-	    "line loopback",
-	    "unknown"
-	};
-
-	u32 fw_release     = fore200e->bus->read(&fore200e->cp_queues->fw_release);
-	u32 mon960_release = fore200e->bus->read(&fore200e->cp_queues->mon960_release);
-	u32 oc3_revision   = fore200e->bus->read(&fore200e->cp_queues->oc3_revision);
-	u32 media_index    = FORE200E_MEDIA_INDEX(fore200e->bus->read(&fore200e->cp_queues->media_type));
-	u32 oc3_index;
-
-	if (media_index > 4)
-		media_index = 5;
-	
-	switch (fore200e->loop_mode) {
-	    case ATM_LM_NONE:    oc3_index = 0;
-		                 break;
-	    case ATM_LM_LOC_PHY: oc3_index = 1;
-		                 break;
-	    case ATM_LM_RMT_PHY: oc3_index = 2;
-		                 break;
-	    default:             oc3_index = 3;
-	}
-
-	return sprintf(page,
-		       "   firmware release:\t\t%d.%d.%d\n"
-		       "   monitor release:\t\t%d.%d\n"
-		       "   media type:\t\t\t%s\n"
-		       "   OC-3 revision:\t\t0x%x\n"
-                       "   OC-3 mode:\t\t\t%s",
-		       fw_release >> 16, fw_release << 16 >> 24,  fw_release << 24 >> 24,
-		       mon960_release >> 16, mon960_release << 16 >> 16,
-		       media_name[ media_index ],
-		       oc3_revision,
-		       oc3_mode[ oc3_index ]);
-    }
-
-    if (!left--) {
-	struct cp_monitor __iomem * cp_monitor = fore200e->cp_monitor;
-
-	return sprintf(page,
-		       "\n\n"
-		       " monitor:\n"
-		       "   version number:\t\t%d\n"
-		       "   boot status word:\t\t0x%08x\n",
-		       fore200e->bus->read(&cp_monitor->mon_version),
-		       fore200e->bus->read(&cp_monitor->bstat));
-    }
-
-    if (!left--)
-	return sprintf(page,
-		       "\n"
-		       " device statistics:\n"
-		       "  4b5b:\n"
-		       "     crc_header_errors:\t\t%10u\n"
-		       "     framing_errors:\t\t%10u\n",
-		       be32_to_cpu(fore200e->stats->phy.crc_header_errors),
-		       be32_to_cpu(fore200e->stats->phy.framing_errors));
-    
-    if (!left--)
-	return sprintf(page, "\n"
-		       "  OC-3:\n"
-		       "     section_bip8_errors:\t%10u\n"
-		       "     path_bip8_errors:\t\t%10u\n"
-		       "     line_bip24_errors:\t\t%10u\n"
-		       "     line_febe_errors:\t\t%10u\n"
-		       "     path_febe_errors:\t\t%10u\n"
-		       "     corr_hcs_errors:\t\t%10u\n"
-		       "     ucorr_hcs_errors:\t\t%10u\n",
-		       be32_to_cpu(fore200e->stats->oc3.section_bip8_errors),
-		       be32_to_cpu(fore200e->stats->oc3.path_bip8_errors),
-		       be32_to_cpu(fore200e->stats->oc3.line_bip24_errors),
-		       be32_to_cpu(fore200e->stats->oc3.line_febe_errors),
-		       be32_to_cpu(fore200e->stats->oc3.path_febe_errors),
-		       be32_to_cpu(fore200e->stats->oc3.corr_hcs_errors),
-		       be32_to_cpu(fore200e->stats->oc3.ucorr_hcs_errors));
-
-    if (!left--)
-	return sprintf(page,"\n"
-		       "   ATM:\t\t\t\t     cells\n"
-		       "     TX:\t\t\t%10u\n"
-		       "     RX:\t\t\t%10u\n"
-		       "     vpi out of range:\t\t%10u\n"
-		       "     vpi no conn:\t\t%10u\n"
-		       "     vci out of range:\t\t%10u\n"
-		       "     vci no conn:\t\t%10u\n",
-		       be32_to_cpu(fore200e->stats->atm.cells_transmitted),
-		       be32_to_cpu(fore200e->stats->atm.cells_received),
-		       be32_to_cpu(fore200e->stats->atm.vpi_bad_range),
-		       be32_to_cpu(fore200e->stats->atm.vpi_no_conn),
-		       be32_to_cpu(fore200e->stats->atm.vci_bad_range),
-		       be32_to_cpu(fore200e->stats->atm.vci_no_conn));
-    
-    if (!left--)
-	return sprintf(page,"\n"
-		       "   AAL0:\t\t\t     cells\n"
-		       "     TX:\t\t\t%10u\n"
-		       "     RX:\t\t\t%10u\n"
-		       "     dropped:\t\t\t%10u\n",
-		       be32_to_cpu(fore200e->stats->aal0.cells_transmitted),
-		       be32_to_cpu(fore200e->stats->aal0.cells_received),
-		       be32_to_cpu(fore200e->stats->aal0.cells_dropped));
-    
-    if (!left--)
-	return sprintf(page,"\n"
-		       "   AAL3/4:\n"
-		       "     SAR sublayer:\t\t     cells\n"
-		       "       TX:\t\t\t%10u\n"
-		       "       RX:\t\t\t%10u\n"
-		       "       dropped:\t\t\t%10u\n"
-		       "       CRC errors:\t\t%10u\n"
-		       "       protocol errors:\t\t%10u\n\n"
-		       "     CS  sublayer:\t\t      PDUs\n"
-		       "       TX:\t\t\t%10u\n"
-		       "       RX:\t\t\t%10u\n"
-		       "       dropped:\t\t\t%10u\n"
-		       "       protocol errors:\t\t%10u\n",
-		       be32_to_cpu(fore200e->stats->aal34.cells_transmitted),
-		       be32_to_cpu(fore200e->stats->aal34.cells_received),
-		       be32_to_cpu(fore200e->stats->aal34.cells_dropped),
-		       be32_to_cpu(fore200e->stats->aal34.cells_crc_errors),
-		       be32_to_cpu(fore200e->stats->aal34.cells_protocol_errors),
-		       be32_to_cpu(fore200e->stats->aal34.cspdus_transmitted),
-		       be32_to_cpu(fore200e->stats->aal34.cspdus_received),
-		       be32_to_cpu(fore200e->stats->aal34.cspdus_dropped),
-		       be32_to_cpu(fore200e->stats->aal34.cspdus_protocol_errors));
-    
-    if (!left--)
-	return sprintf(page,"\n"
-		       "   AAL5:\n"
-		       "     SAR sublayer:\t\t     cells\n"
-		       "       TX:\t\t\t%10u\n"
-		       "       RX:\t\t\t%10u\n"
-		       "       dropped:\t\t\t%10u\n"
-		       "       congestions:\t\t%10u\n\n"
-		       "     CS  sublayer:\t\t      PDUs\n"
-		       "       TX:\t\t\t%10u\n"
-		       "       RX:\t\t\t%10u\n"
-		       "       dropped:\t\t\t%10u\n"
-		       "       CRC errors:\t\t%10u\n"
-		       "       protocol errors:\t\t%10u\n",
-		       be32_to_cpu(fore200e->stats->aal5.cells_transmitted),
-		       be32_to_cpu(fore200e->stats->aal5.cells_received),
-		       be32_to_cpu(fore200e->stats->aal5.cells_dropped),
-		       be32_to_cpu(fore200e->stats->aal5.congestion_experienced),
-		       be32_to_cpu(fore200e->stats->aal5.cspdus_transmitted),
-		       be32_to_cpu(fore200e->stats->aal5.cspdus_received),
-		       be32_to_cpu(fore200e->stats->aal5.cspdus_dropped),
-		       be32_to_cpu(fore200e->stats->aal5.cspdus_crc_errors),
-		       be32_to_cpu(fore200e->stats->aal5.cspdus_protocol_errors));
-    
-    if (!left--)
-	return sprintf(page,"\n"
-		       "   AUX:\t\t       allocation failures\n"
-		       "     small b1:\t\t\t%10u\n"
-		       "     large b1:\t\t\t%10u\n"
-		       "     small b2:\t\t\t%10u\n"
-		       "     large b2:\t\t\t%10u\n"
-		       "     RX PDUs:\t\t\t%10u\n"
-		       "     TX PDUs:\t\t\t%10lu\n",
-		       be32_to_cpu(fore200e->stats->aux.small_b1_failed),
-		       be32_to_cpu(fore200e->stats->aux.large_b1_failed),
-		       be32_to_cpu(fore200e->stats->aux.small_b2_failed),
-		       be32_to_cpu(fore200e->stats->aux.large_b2_failed),
-		       be32_to_cpu(fore200e->stats->aux.rpd_alloc_failed),
-		       fore200e->tx_sat);
-    
-    if (!left--)
-	return sprintf(page,"\n"
-		       " receive carrier:\t\t\t%s\n",
-		       fore200e->stats->aux.receive_carrier ? "ON" : "OFF!");
-    
-    if (!left--) {
-        return sprintf(page,"\n"
-		       " VCCs:\n  address   VPI VCI   AAL "
-		       "TX PDUs   TX min/max size  RX PDUs   RX min/max size\n");
-    }
-
-    for (i = 0; i < NBR_CONNECT; i++) {
-
-	vcc = fore200e->vc_map[i].vcc;
-
-	if (vcc == NULL)
-	    continue;
-
-	spin_lock_irqsave(&fore200e->q_lock, flags);
-
-	if (vcc && test_bit(ATM_VF_READY, &vcc->flags) && !left--) {
-
-	    fore200e_vcc = FORE200E_VCC(vcc);
-	    ASSERT(fore200e_vcc);
-
-	    len = sprintf(page,
-			  "  %pK  %03d %05d %1d   %09lu %05d/%05d      %09lu %05d/%05d\n",
-			  vcc,
-			  vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
-			  fore200e_vcc->tx_pdu,
-			  fore200e_vcc->tx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->tx_min_pdu,
-			  fore200e_vcc->tx_max_pdu,
-			  fore200e_vcc->rx_pdu,
-			  fore200e_vcc->rx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->rx_min_pdu,
-			  fore200e_vcc->rx_max_pdu);
-
-	    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-	    return len;
-	}
-
-	spin_unlock_irqrestore(&fore200e->q_lock, flags);
-    }
-    
-    return 0;
-}
-
-module_init(fore200e_module_init);
-module_exit(fore200e_module_cleanup);
-
-
-static const struct atmdev_ops fore200e_ops = {
-	.open       = fore200e_open,
-	.close      = fore200e_close,
-	.ioctl      = fore200e_ioctl,
-	.send       = fore200e_send,
-	.change_qos = fore200e_change_qos,
-	.proc_read  = fore200e_proc_read,
-	.owner      = THIS_MODULE
-};
-
-MODULE_LICENSE("GPL");
-#ifdef CONFIG_PCI
-#ifdef __LITTLE_ENDIAN__
-MODULE_FIRMWARE("pca200e.bin");
-#else
-MODULE_FIRMWARE("pca200e_ecd.bin2");
-#endif
-#endif /* CONFIG_PCI */
-#ifdef CONFIG_SBUS
-MODULE_FIRMWARE("sba200e_ecd.bin2");
-#endif
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
deleted file mode 100644
index bb9cb00f9585..000000000000
--- a/drivers/atm/he.c
+++ /dev/null
@@ -1,2861 +0,0 @@
-/*
-
-  he.c
-
-  ForeRunnerHE ATM Adapter driver for ATM on Linux
-  Copyright (C) 1999-2001  Naval Research Laboratory
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-
-/*
-
-  he.c
-
-  ForeRunnerHE ATM Adapter driver for ATM on Linux
-  Copyright (C) 1999-2001  Naval Research Laboratory
-
-  Permission to use, copy, modify and distribute this software and its
-  documentation is hereby granted, provided that both the copyright
-  notice and this permission notice appear in all copies of the software,
-  derivative works or modified versions, and any portions thereof, and
-  that both notices appear in supporting documentation.
-
-  NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
-  DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
-  RESULTING FROM THE USE OF THIS SOFTWARE.
-
-  This driver was written using the "Programmer's Reference Manual for
-  ForeRunnerHE(tm)", MANU0361-01 - Rev. A, 08/21/98.
-
-  AUTHORS:
-	chas williams <chas@cmf.nrl.navy.mil>
-	eric kinzie <ekinzie@cmf.nrl.navy.mil>
-
-  NOTES:
-	4096 supported 'connections'
-	group 0 is used for all traffic
-	interrupt queue 0 is used for all interrupts
-	aal0 support (based on work from ulrich.u.muller@nokia.com)
-
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
-#include <linux/bitmap.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-#include <linux/uaccess.h>
-
-#include <linux/atmdev.h>
-#include <linux/atm.h>
-#include <linux/sonet.h>
-
-#undef USE_SCATTERGATHER
-#undef USE_CHECKSUM_HW			/* still confused about this */
-/* #undef HE_DEBUG */
-
-#include "he.h"
-#include "suni.h"
-#include <linux/atm_he.h>
-
-#define hprintk(fmt,args...)	printk(KERN_ERR DEV_LABEL "%d: " fmt, he_dev->number , ##args)
-
-#ifdef HE_DEBUG
-#define HPRINTK(fmt,args...)	printk(KERN_DEBUG DEV_LABEL "%d: " fmt, he_dev->number , ##args)
-#else /* !HE_DEBUG */
-#define HPRINTK(fmt,args...)	do { } while (0)
-#endif /* HE_DEBUG */
-
-/* declarations */
-
-static int he_open(struct atm_vcc *vcc);
-static void he_close(struct atm_vcc *vcc);
-static int he_send(struct atm_vcc *vcc, struct sk_buff *skb);
-static int he_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg);
-static irqreturn_t he_irq_handler(int irq, void *dev_id);
-static void he_tasklet(unsigned long data);
-static int he_proc_read(struct atm_dev *dev,loff_t *pos,char *page);
-static int he_start(struct atm_dev *dev);
-static void he_stop(struct he_dev *dev);
-static void he_phy_put(struct atm_dev *, unsigned char, unsigned long);
-static unsigned char he_phy_get(struct atm_dev *, unsigned long);
-
-static u8 read_prom_byte(struct he_dev *he_dev, int addr);
-
-/* globals */
-
-static struct he_dev *he_devs;
-static bool disable64;
-static short nvpibits = -1;
-static short nvcibits = -1;
-static short rx_skb_reserve = 16;
-static bool irq_coalesce = true;
-static bool sdh;
-
-/* Read from EEPROM = 0000 0011b */
-static unsigned int readtab[] = {
-	CS_HIGH | CLK_HIGH,
-	CS_LOW | CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW | SI_HIGH,
-	CLK_HIGH | SI_HIGH,     /* 1 */
-	CLK_LOW | SI_HIGH,
-	CLK_HIGH | SI_HIGH      /* 1 */
-};     
- 
-/* Clock to read from/write to the EEPROM */
-static unsigned int clocktab[] = {
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW
-};     
-
-static const struct atmdev_ops he_ops =
-{
-	.open =		he_open,
-	.close =	he_close,	
-	.ioctl =	he_ioctl,	
-	.send =		he_send,
-	.phy_put =	he_phy_put,
-	.phy_get =	he_phy_get,
-	.proc_read =	he_proc_read,
-	.owner =	THIS_MODULE
-};
-
-#define he_writel(dev, val, reg)	do { writel(val, (dev)->membase + (reg)); wmb(); } while (0)
-#define he_readl(dev, reg)		readl((dev)->membase + (reg))
-
-/* section 2.12 connection memory access */
-
-static __inline__ void
-he_writel_internal(struct he_dev *he_dev, unsigned val, unsigned addr,
-								unsigned flags)
-{
-	he_writel(he_dev, val, CON_DAT);
-	(void) he_readl(he_dev, CON_DAT);		/* flush posted writes */
-	he_writel(he_dev, flags | CON_CTL_WRITE | CON_CTL_ADDR(addr), CON_CTL);
-	while (he_readl(he_dev, CON_CTL) & CON_CTL_BUSY);
-}
-
-#define he_writel_rcm(dev, val, reg) 				\
-			he_writel_internal(dev, val, reg, CON_CTL_RCM)
-
-#define he_writel_tcm(dev, val, reg) 				\
-			he_writel_internal(dev, val, reg, CON_CTL_TCM)
-
-#define he_writel_mbox(dev, val, reg) 				\
-			he_writel_internal(dev, val, reg, CON_CTL_MBOX)
-
-static unsigned
-he_readl_internal(struct he_dev *he_dev, unsigned addr, unsigned flags)
-{
-	he_writel(he_dev, flags | CON_CTL_READ | CON_CTL_ADDR(addr), CON_CTL);
-	while (he_readl(he_dev, CON_CTL) & CON_CTL_BUSY);
-	return he_readl(he_dev, CON_DAT);
-}
-
-#define he_readl_rcm(dev, reg) \
-			he_readl_internal(dev, reg, CON_CTL_RCM)
-
-#define he_readl_tcm(dev, reg) \
-			he_readl_internal(dev, reg, CON_CTL_TCM)
-
-#define he_readl_mbox(dev, reg) \
-			he_readl_internal(dev, reg, CON_CTL_MBOX)
-
-
-/* figure 2.2 connection id */
-
-#define he_mkcid(dev, vpi, vci)		(((vpi << (dev)->vcibits) | vci) & 0x1fff)
-
-/* 2.5.1 per connection transmit state registers */
-
-#define he_writel_tsr0(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 0)
-#define he_readl_tsr0(dev, cid) \
-		he_readl_tcm(dev, CONFIG_TSRA | (cid << 3) | 0)
-
-#define he_writel_tsr1(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 1)
-
-#define he_writel_tsr2(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 2)
-
-#define he_writel_tsr3(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 3)
-
-#define he_writel_tsr4(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 4)
-
-	/* from page 2-20
-	 *
-	 * NOTE While the transmit connection is active, bits 23 through 0
-	 *      of this register must not be written by the host.  Byte
-	 *      enables should be used during normal operation when writing
-	 *      the most significant byte.
-	 */
-
-#define he_writel_tsr4_upper(dev, val, cid) \
-		he_writel_internal(dev, val, CONFIG_TSRA | (cid << 3) | 4, \
-							CON_CTL_TCM \
-							| CON_BYTE_DISABLE_2 \
-							| CON_BYTE_DISABLE_1 \
-							| CON_BYTE_DISABLE_0)
-
-#define he_readl_tsr4(dev, cid) \
-		he_readl_tcm(dev, CONFIG_TSRA | (cid << 3) | 4)
-
-#define he_writel_tsr5(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 5)
-
-#define he_writel_tsr6(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 6)
-
-#define he_writel_tsr7(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 7)
-
-
-#define he_writel_tsr8(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 0)
-
-#define he_writel_tsr9(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 1)
-
-#define he_writel_tsr10(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 2)
-
-#define he_writel_tsr11(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 3)
-
-
-#define he_writel_tsr12(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRC | (cid << 1) | 0)
-
-#define he_writel_tsr13(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRC | (cid << 1) | 1)
-
-
-#define he_writel_tsr14(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRD | cid)
-
-#define he_writel_tsr14_upper(dev, val, cid) \
-		he_writel_internal(dev, val, CONFIG_TSRD | cid, \
-							CON_CTL_TCM \
-							| CON_BYTE_DISABLE_2 \
-							| CON_BYTE_DISABLE_1 \
-							| CON_BYTE_DISABLE_0)
-
-/* 2.7.1 per connection receive state registers */
-
-#define he_writel_rsr0(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 0)
-#define he_readl_rsr0(dev, cid) \
-		he_readl_rcm(dev, 0x00000 | (cid << 3) | 0)
-
-#define he_writel_rsr1(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 1)
-
-#define he_writel_rsr2(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 2)
-
-#define he_writel_rsr3(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 3)
-
-#define he_writel_rsr4(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 4)
-
-#define he_writel_rsr5(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 5)
-
-#define he_writel_rsr6(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 6)
-
-#define he_writel_rsr7(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 7)
-
-static __inline__ struct atm_vcc*
-__find_vcc(struct he_dev *he_dev, unsigned cid)
-{
-	struct hlist_head *head;
-	struct atm_vcc *vcc;
-	struct sock *s;
-	short vpi;
-	int vci;
-
-	vpi = cid >> he_dev->vcibits;
-	vci = cid & ((1 << he_dev->vcibits) - 1);
-	head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)];
-
-	sk_for_each(s, head) {
-		vcc = atm_sk(s);
-		if (vcc->dev == he_dev->atm_dev &&
-		    vcc->vci == vci && vcc->vpi == vpi &&
-		    vcc->qos.rxtp.traffic_class != ATM_NONE) {
-				return vcc;
-		}
-	}
-	return NULL;
-}
-
-static int he_init_one(struct pci_dev *pci_dev,
-		       const struct pci_device_id *pci_ent)
-{
-	struct atm_dev *atm_dev = NULL;
-	struct he_dev *he_dev = NULL;
-	int err = 0;
-
-	printk(KERN_INFO "ATM he driver\n");
-
-	if (pci_enable_device(pci_dev))
-		return -EIO;
-	if (dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32)) != 0) {
-		printk(KERN_WARNING "he: no suitable dma available\n");
-		err = -EIO;
-		goto init_one_failure;
-	}
-
-	atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &he_ops, -1, NULL);
-	if (!atm_dev) {
-		err = -ENODEV;
-		goto init_one_failure;
-	}
-	pci_set_drvdata(pci_dev, atm_dev);
-
-	he_dev = kzalloc_obj(struct he_dev);
-	if (!he_dev) {
-		err = -ENOMEM;
-		goto init_one_failure;
-	}
-	he_dev->pci_dev = pci_dev;
-	he_dev->atm_dev = atm_dev;
-	he_dev->atm_dev->dev_data = he_dev;
-	atm_dev->dev_data = he_dev;
-	he_dev->number = atm_dev->number;
-	tasklet_init(&he_dev->tasklet, he_tasklet, (unsigned long) he_dev);
-	spin_lock_init(&he_dev->global_lock);
-
-	if (he_start(atm_dev)) {
-		he_stop(he_dev);
-		err = -ENODEV;
-		goto init_one_failure;
-	}
-	he_dev->next = NULL;
-	if (he_devs)
-		he_dev->next = he_devs;
-	he_devs = he_dev;
-	return 0;
-
-init_one_failure:
-	if (atm_dev)
-		atm_dev_deregister(atm_dev);
-	kfree(he_dev);
-	pci_disable_device(pci_dev);
-	return err;
-}
-
-static void he_remove_one(struct pci_dev *pci_dev)
-{
-	struct atm_dev *atm_dev;
-	struct he_dev *he_dev;
-
-	atm_dev = pci_get_drvdata(pci_dev);
-	he_dev = HE_DEV(atm_dev);
-
-	/* need to remove from he_devs */
-
-	he_stop(he_dev);
-	atm_dev_deregister(atm_dev);
-	kfree(he_dev);
-
-	pci_disable_device(pci_dev);
-}
-
-
-static unsigned
-rate_to_atmf(unsigned rate)		/* cps to atm forum format */
-{
-#define NONZERO (1 << 14)
-
-	unsigned exp = 0;
-
-	if (rate == 0)
-		return 0;
-
-	rate <<= 9;
-	while (rate > 0x3ff) {
-		++exp;
-		rate >>= 1;
-	}
-
-	return (NONZERO | (exp << 9) | (rate & 0x1ff));
-}
-
-static void he_init_rx_lbfp0(struct he_dev *he_dev)
-{
-	unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
-	unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
-	unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
-	unsigned row_offset = he_dev->r0_startrow * he_dev->bytes_per_row;
-	
-	lbufd_index = 0;
-	lbm_offset = he_readl(he_dev, RCMLBM_BA);
-
-	he_writel(he_dev, lbufd_index, RLBF0_H);
-
-	for (i = 0, lbuf_count = 0; i < he_dev->r0_numbuffs; ++i) {
-		lbufd_index += 2;
-		lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
-
-		he_writel_rcm(he_dev, lbuf_addr, lbm_offset);
-		he_writel_rcm(he_dev, lbufd_index, lbm_offset + 1);
-
-		if (++lbuf_count == lbufs_per_row) {
-			lbuf_count = 0;
-			row_offset += he_dev->bytes_per_row;
-		}
-		lbm_offset += 4;
-	}
-		
-	he_writel(he_dev, lbufd_index - 2, RLBF0_T);
-	he_writel(he_dev, he_dev->r0_numbuffs, RLBF0_C);
-}
-
-static void he_init_rx_lbfp1(struct he_dev *he_dev)
-{
-	unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
-	unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
-	unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
-	unsigned row_offset = he_dev->r1_startrow * he_dev->bytes_per_row;
-	
-	lbufd_index = 1;
-	lbm_offset = he_readl(he_dev, RCMLBM_BA) + (2 * lbufd_index);
-
-	he_writel(he_dev, lbufd_index, RLBF1_H);
-
-	for (i = 0, lbuf_count = 0; i < he_dev->r1_numbuffs; ++i) {
-		lbufd_index += 2;
-		lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
-
-		he_writel_rcm(he_dev, lbuf_addr, lbm_offset);
-		he_writel_rcm(he_dev, lbufd_index, lbm_offset + 1);
-
-		if (++lbuf_count == lbufs_per_row) {
-			lbuf_count = 0;
-			row_offset += he_dev->bytes_per_row;
-		}
-		lbm_offset += 4;
-	}
-		
-	he_writel(he_dev, lbufd_index - 2, RLBF1_T);
-	he_writel(he_dev, he_dev->r1_numbuffs, RLBF1_C);
-}
-
-static void he_init_tx_lbfp(struct he_dev *he_dev)
-{
-	unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
-	unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
-	unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
-	unsigned row_offset = he_dev->tx_startrow * he_dev->bytes_per_row;
-	
-	lbufd_index = he_dev->r0_numbuffs + he_dev->r1_numbuffs;
-	lbm_offset = he_readl(he_dev, RCMLBM_BA) + (2 * lbufd_index);
-
-	he_writel(he_dev, lbufd_index, TLBF_H);
-
-	for (i = 0, lbuf_count = 0; i < he_dev->tx_numbuffs; ++i) {
-		lbufd_index += 1;
-		lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
-
-		he_writel_rcm(he_dev, lbuf_addr, lbm_offset);
-		he_writel_rcm(he_dev, lbufd_index, lbm_offset + 1);
-
-		if (++lbuf_count == lbufs_per_row) {
-			lbuf_count = 0;
-			row_offset += he_dev->bytes_per_row;
-		}
-		lbm_offset += 2;
-	}
-		
-	he_writel(he_dev, lbufd_index - 1, TLBF_T);
-}
-
-static int he_init_tpdrq(struct he_dev *he_dev)
-{
-	he_dev->tpdrq_base = dma_alloc_coherent(&he_dev->pci_dev->dev,
-						CONFIG_TPDRQ_SIZE * sizeof(struct he_tpdrq),
-						&he_dev->tpdrq_phys,
-						GFP_KERNEL);
-	if (he_dev->tpdrq_base == NULL) {
-		hprintk("failed to alloc tpdrq\n");
-		return -ENOMEM;
-	}
-
-	he_dev->tpdrq_tail = he_dev->tpdrq_base;
-	he_dev->tpdrq_head = he_dev->tpdrq_base;
-
-	he_writel(he_dev, he_dev->tpdrq_phys, TPDRQ_B_H);
-	he_writel(he_dev, 0, TPDRQ_T);	
-	he_writel(he_dev, CONFIG_TPDRQ_SIZE - 1, TPDRQ_S);
-
-	return 0;
-}
-
-static void he_init_cs_block(struct he_dev *he_dev)
-{
-	unsigned clock, rate, delta;
-	int reg;
-
-	/* 5.1.7 cs block initialization */
-
-	for (reg = 0; reg < 0x20; ++reg)
-		he_writel_mbox(he_dev, 0x0, CS_STTIM0 + reg);
-
-	/* rate grid timer reload values */
-
-	clock = he_is622(he_dev) ? 66667000 : 50000000;
-	rate = he_dev->atm_dev->link_rate;
-	delta = rate / 16 / 2;
-
-	for (reg = 0; reg < 0x10; ++reg) {
-		/* 2.4 internal transmit function
-		 *
-	 	 * we initialize the first row in the rate grid.
-		 * values are period (in clock cycles) of timer
-		 */
-		unsigned period = clock / rate;
-
-		he_writel_mbox(he_dev, period, CS_TGRLD0 + reg);
-		rate -= delta;
-	}
-
-	if (he_is622(he_dev)) {
-		/* table 5.2 (4 cells per lbuf) */
-		he_writel_mbox(he_dev, 0x000800fa, CS_ERTHR0);
-		he_writel_mbox(he_dev, 0x000c33cb, CS_ERTHR1);
-		he_writel_mbox(he_dev, 0x0010101b, CS_ERTHR2);
-		he_writel_mbox(he_dev, 0x00181dac, CS_ERTHR3);
-		he_writel_mbox(he_dev, 0x00280600, CS_ERTHR4);
-
-		/* table 5.3, 5.4, 5.5, 5.6, 5.7 */
-		he_writel_mbox(he_dev, 0x023de8b3, CS_ERCTL0);
-		he_writel_mbox(he_dev, 0x1801, CS_ERCTL1);
-		he_writel_mbox(he_dev, 0x68b3, CS_ERCTL2);
-		he_writel_mbox(he_dev, 0x1280, CS_ERSTAT0);
-		he_writel_mbox(he_dev, 0x68b3, CS_ERSTAT1);
-		he_writel_mbox(he_dev, 0x14585, CS_RTFWR);
-
-		he_writel_mbox(he_dev, 0x4680, CS_RTATR);
-
-		/* table 5.8 */
-		he_writel_mbox(he_dev, 0x00159ece, CS_TFBSET);
-		he_writel_mbox(he_dev, 0x68b3, CS_WCRMAX);
-		he_writel_mbox(he_dev, 0x5eb3, CS_WCRMIN);
-		he_writel_mbox(he_dev, 0xe8b3, CS_WCRINC);
-		he_writel_mbox(he_dev, 0xdeb3, CS_WCRDEC);
-		he_writel_mbox(he_dev, 0x68b3, CS_WCRCEIL);
-
-		/* table 5.9 */
-		he_writel_mbox(he_dev, 0x5, CS_OTPPER);
-		he_writel_mbox(he_dev, 0x14, CS_OTWPER);
-	} else {
-		/* table 5.1 (4 cells per lbuf) */
-		he_writel_mbox(he_dev, 0x000400ea, CS_ERTHR0);
-		he_writel_mbox(he_dev, 0x00063388, CS_ERTHR1);
-		he_writel_mbox(he_dev, 0x00081018, CS_ERTHR2);
-		he_writel_mbox(he_dev, 0x000c1dac, CS_ERTHR3);
-		he_writel_mbox(he_dev, 0x0014051a, CS_ERTHR4);
-
-		/* table 5.3, 5.4, 5.5, 5.6, 5.7 */
-		he_writel_mbox(he_dev, 0x0235e4b1, CS_ERCTL0);
-		he_writel_mbox(he_dev, 0x4701, CS_ERCTL1);
-		he_writel_mbox(he_dev, 0x64b1, CS_ERCTL2);
-		he_writel_mbox(he_dev, 0x1280, CS_ERSTAT0);
-		he_writel_mbox(he_dev, 0x64b1, CS_ERSTAT1);
-		he_writel_mbox(he_dev, 0xf424, CS_RTFWR);
-
-		he_writel_mbox(he_dev, 0x4680, CS_RTATR);
-
-		/* table 5.8 */
-		he_writel_mbox(he_dev, 0x000563b7, CS_TFBSET);
-		he_writel_mbox(he_dev, 0x64b1, CS_WCRMAX);
-		he_writel_mbox(he_dev, 0x5ab1, CS_WCRMIN);
-		he_writel_mbox(he_dev, 0xe4b1, CS_WCRINC);
-		he_writel_mbox(he_dev, 0xdab1, CS_WCRDEC);
-		he_writel_mbox(he_dev, 0x64b1, CS_WCRCEIL);
-
-		/* table 5.9 */
-		he_writel_mbox(he_dev, 0x6, CS_OTPPER);
-		he_writel_mbox(he_dev, 0x1e, CS_OTWPER);
-	}
-
-	he_writel_mbox(he_dev, 0x8, CS_OTTLIM);
-
-	for (reg = 0; reg < 0x8; ++reg)
-		he_writel_mbox(he_dev, 0x0, CS_HGRRT0 + reg);
-
-}
-
-static int he_init_cs_block_rcm(struct he_dev *he_dev)
-{
-	unsigned (*rategrid)[16][16];
-	unsigned rate, delta;
-	int i, j, reg;
-
-	unsigned rate_atmf, exp, man;
-	unsigned long long rate_cps;
-	int mult, buf, buf_limit = 4;
-
-	rategrid = kmalloc( sizeof(unsigned) * 16 * 16, GFP_KERNEL);
-	if (!rategrid)
-		return -ENOMEM;
-
-	/* initialize rate grid group table */
-
-	for (reg = 0x0; reg < 0xff; ++reg)
-		he_writel_rcm(he_dev, 0x0, CONFIG_RCMABR + reg);
-
-	/* initialize rate controller groups */
-
-	for (reg = 0x100; reg < 0x1ff; ++reg)
-		he_writel_rcm(he_dev, 0x0, CONFIG_RCMABR + reg);
-	
-	/* initialize tNrm lookup table */
-
-	/* the manual makes reference to a routine in a sample driver
-	   for proper configuration; fortunately, we only need this
-	   in order to support abr connection */
-	
-	/* initialize rate to group table */
-
-	rate = he_dev->atm_dev->link_rate;
-	delta = rate / 32;
-
-	/*
-	 * 2.4 transmit internal functions
-	 * 
-	 * we construct a copy of the rate grid used by the scheduler
-	 * in order to construct the rate to group table below
-	 */
-
-	for (j = 0; j < 16; j++) {
-		(*rategrid)[0][j] = rate;
-		rate -= delta;
-	}
-
-	for (i = 1; i < 16; i++)
-		for (j = 0; j < 16; j++)
-			if (i > 14)
-				(*rategrid)[i][j] = (*rategrid)[i - 1][j] / 4;
-			else
-				(*rategrid)[i][j] = (*rategrid)[i - 1][j] / 2;
-
-	/*
-	 * 2.4 transmit internal function
-	 *
-	 * this table maps the upper 5 bits of exponent and mantissa
-	 * of the atm forum representation of the rate into an index
-	 * on rate grid  
-	 */
-
-	rate_atmf = 0;
-	while (rate_atmf < 0x400) {
-		man = (rate_atmf & 0x1f) << 4;
-		exp = rate_atmf >> 5;
-
-		/* 
-			instead of '/ 512', use '>> 9' to prevent a call
-			to divdu3 on x86 platforms
-		*/
-		rate_cps = (unsigned long long) (1UL << exp) * (man + 512) >> 9;
-
-		if (rate_cps < 10)
-			rate_cps = 10;	/* 2.2.1 minimum payload rate is 10 cps */
-
-		for (i = 255; i > 0; i--)
-			if ((*rategrid)[i/16][i%16] >= rate_cps)
-				break;	 /* pick nearest rate instead? */
-
-		/*
-		 * each table entry is 16 bits: (rate grid index (8 bits)
-		 * and a buffer limit (8 bits)
-		 * there are two table entries in each 32-bit register
-		 */
-
-#ifdef notdef
-		buf = rate_cps * he_dev->tx_numbuffs /
-				(he_dev->atm_dev->link_rate * 2);
-#else
-		/* this is pretty, but avoids _divdu3 and is mostly correct */
-		mult = he_dev->atm_dev->link_rate / ATM_OC3_PCR;
-		if (rate_cps > (272ULL * mult))
-			buf = 4;
-		else if (rate_cps > (204ULL * mult))
-			buf = 3;
-		else if (rate_cps > (136ULL * mult))
-			buf = 2;
-		else if (rate_cps > (68ULL * mult))
-			buf = 1;
-		else
-			buf = 0;
-#endif
-		if (buf > buf_limit)
-			buf = buf_limit;
-		reg = (reg << 16) | ((i << 8) | buf);
-
-#define RTGTBL_OFFSET 0x400
-	  
-		if (rate_atmf & 0x1)
-			he_writel_rcm(he_dev, reg,
-				CONFIG_RCMABR + RTGTBL_OFFSET + (rate_atmf >> 1));
-
-		++rate_atmf;
-	}
-
-	kfree(rategrid);
-	return 0;
-}
-
-static int he_init_group(struct he_dev *he_dev, int group)
-{
-	struct he_buff *heb, *next;
-	dma_addr_t mapping;
-	int i;
-
-	he_writel(he_dev, 0x0, G0_RBPS_S + (group * 32));
-	he_writel(he_dev, 0x0, G0_RBPS_T + (group * 32));
-	he_writel(he_dev, 0x0, G0_RBPS_QI + (group * 32));
-	he_writel(he_dev, RBP_THRESH(0x1) | RBP_QSIZE(0x0),
-		  G0_RBPS_BS + (group * 32));
-
-	/* bitmap table */
-	he_dev->rbpl_table = bitmap_zalloc(RBPL_TABLE_SIZE, GFP_KERNEL);
-	if (!he_dev->rbpl_table) {
-		hprintk("unable to allocate rbpl bitmap table\n");
-		return -ENOMEM;
-	}
-
-	/* rbpl_virt 64-bit pointers */
-	he_dev->rbpl_virt = kmalloc_objs(*he_dev->rbpl_virt, RBPL_TABLE_SIZE);
-	if (!he_dev->rbpl_virt) {
-		hprintk("unable to allocate rbpl virt table\n");
-		goto out_free_rbpl_table;
-	}
-
-	/* large buffer pool */
-	he_dev->rbpl_pool = dma_pool_create("rbpl", &he_dev->pci_dev->dev,
-					    CONFIG_RBPL_BUFSIZE, 64, 0);
-	if (he_dev->rbpl_pool == NULL) {
-		hprintk("unable to create rbpl pool\n");
-		goto out_free_rbpl_virt;
-	}
-
-	he_dev->rbpl_base = dma_alloc_coherent(&he_dev->pci_dev->dev,
-					       CONFIG_RBPL_SIZE * sizeof(struct he_rbp),
-					       &he_dev->rbpl_phys, GFP_KERNEL);
-	if (he_dev->rbpl_base == NULL) {
-		hprintk("failed to alloc rbpl_base\n");
-		goto out_destroy_rbpl_pool;
-	}
-
-	INIT_LIST_HEAD(&he_dev->rbpl_outstanding);
-
-	for (i = 0; i < CONFIG_RBPL_SIZE; ++i) {
-
-		heb = dma_pool_alloc(he_dev->rbpl_pool, GFP_KERNEL, &mapping);
-		if (!heb)
-			goto out_free_rbpl;
-		heb->mapping = mapping;
-		list_add(&heb->entry, &he_dev->rbpl_outstanding);
-
-		set_bit(i, he_dev->rbpl_table);
-		he_dev->rbpl_virt[i] = heb;
-		he_dev->rbpl_hint = i + 1;
-		he_dev->rbpl_base[i].idx =  i << RBP_IDX_OFFSET;
-		he_dev->rbpl_base[i].phys = mapping + offsetof(struct he_buff, data);
-	}
-	he_dev->rbpl_tail = &he_dev->rbpl_base[CONFIG_RBPL_SIZE - 1];
-
-	he_writel(he_dev, he_dev->rbpl_phys, G0_RBPL_S + (group * 32));
-	he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail),
-						G0_RBPL_T + (group * 32));
-	he_writel(he_dev, (CONFIG_RBPL_BUFSIZE - sizeof(struct he_buff))/4,
-						G0_RBPL_BS + (group * 32));
-	he_writel(he_dev,
-			RBP_THRESH(CONFIG_RBPL_THRESH) |
-			RBP_QSIZE(CONFIG_RBPL_SIZE - 1) |
-			RBP_INT_ENB,
-						G0_RBPL_QI + (group * 32));
-
-	/* rx buffer ready queue */
-
-	he_dev->rbrq_base = dma_alloc_coherent(&he_dev->pci_dev->dev,
-					       CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq),
-					       &he_dev->rbrq_phys, GFP_KERNEL);
-	if (he_dev->rbrq_base == NULL) {
-		hprintk("failed to allocate rbrq\n");
-		goto out_free_rbpl;
-	}
-
-	he_dev->rbrq_head = he_dev->rbrq_base;
-	he_writel(he_dev, he_dev->rbrq_phys, G0_RBRQ_ST + (group * 16));
-	he_writel(he_dev, 0, G0_RBRQ_H + (group * 16));
-	he_writel(he_dev,
-		RBRQ_THRESH(CONFIG_RBRQ_THRESH) | RBRQ_SIZE(CONFIG_RBRQ_SIZE - 1),
-						G0_RBRQ_Q + (group * 16));
-	if (irq_coalesce) {
-		hprintk("coalescing interrupts\n");
-		he_writel(he_dev, RBRQ_TIME(768) | RBRQ_COUNT(7),
-						G0_RBRQ_I + (group * 16));
-	} else
-		he_writel(he_dev, RBRQ_TIME(0) | RBRQ_COUNT(1),
-						G0_RBRQ_I + (group * 16));
-
-	/* tx buffer ready queue */
-
-	he_dev->tbrq_base = dma_alloc_coherent(&he_dev->pci_dev->dev,
-					       CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq),
-					       &he_dev->tbrq_phys, GFP_KERNEL);
-	if (he_dev->tbrq_base == NULL) {
-		hprintk("failed to allocate tbrq\n");
-		goto out_free_rbpq_base;
-	}
-
-	he_dev->tbrq_head = he_dev->tbrq_base;
-
-	he_writel(he_dev, he_dev->tbrq_phys, G0_TBRQ_B_T + (group * 16));
-	he_writel(he_dev, 0, G0_TBRQ_H + (group * 16));
-	he_writel(he_dev, CONFIG_TBRQ_SIZE - 1, G0_TBRQ_S + (group * 16));
-	he_writel(he_dev, CONFIG_TBRQ_THRESH, G0_TBRQ_THRESH + (group * 16));
-
-	return 0;
-
-out_free_rbpq_base:
-	dma_free_coherent(&he_dev->pci_dev->dev, CONFIG_RBRQ_SIZE *
-			  sizeof(struct he_rbrq), he_dev->rbrq_base,
-			  he_dev->rbrq_phys);
-out_free_rbpl:
-	list_for_each_entry_safe(heb, next, &he_dev->rbpl_outstanding, entry)
-		dma_pool_free(he_dev->rbpl_pool, heb, heb->mapping);
-
-	dma_free_coherent(&he_dev->pci_dev->dev, CONFIG_RBPL_SIZE *
-			  sizeof(struct he_rbp), he_dev->rbpl_base,
-			  he_dev->rbpl_phys);
-out_destroy_rbpl_pool:
-	dma_pool_destroy(he_dev->rbpl_pool);
-out_free_rbpl_virt:
-	kfree(he_dev->rbpl_virt);
-out_free_rbpl_table:
-	bitmap_free(he_dev->rbpl_table);
-
-	return -ENOMEM;
-}
-
-static int he_init_irq(struct he_dev *he_dev)
-{
-	int i;
-
-	/* 2.9.3.5  tail offset for each interrupt queue is located after the
-		    end of the interrupt queue */
-
-	he_dev->irq_base = dma_alloc_coherent(&he_dev->pci_dev->dev,
-					      (CONFIG_IRQ_SIZE + 1) * sizeof(struct he_irq),
-					      &he_dev->irq_phys, GFP_KERNEL);
-	if (he_dev->irq_base == NULL) {
-		hprintk("failed to allocate irq\n");
-		return -ENOMEM;
-	}
-	he_dev->irq_tailoffset = (unsigned *)
-					&he_dev->irq_base[CONFIG_IRQ_SIZE];
-	*he_dev->irq_tailoffset = 0;
-	he_dev->irq_head = he_dev->irq_base;
-	he_dev->irq_tail = he_dev->irq_base;
-
-	for (i = 0; i < CONFIG_IRQ_SIZE; ++i)
-		he_dev->irq_base[i].isw = ITYPE_INVALID;
-
-	he_writel(he_dev, he_dev->irq_phys, IRQ0_BASE);
-	he_writel(he_dev,
-		IRQ_SIZE(CONFIG_IRQ_SIZE) | IRQ_THRESH(CONFIG_IRQ_THRESH),
-								IRQ0_HEAD);
-	he_writel(he_dev, IRQ_INT_A | IRQ_TYPE_LINE, IRQ0_CNTL);
-	he_writel(he_dev, 0x0, IRQ0_DATA);
-
-	he_writel(he_dev, 0x0, IRQ1_BASE);
-	he_writel(he_dev, 0x0, IRQ1_HEAD);
-	he_writel(he_dev, 0x0, IRQ1_CNTL);
-	he_writel(he_dev, 0x0, IRQ1_DATA);
-
-	he_writel(he_dev, 0x0, IRQ2_BASE);
-	he_writel(he_dev, 0x0, IRQ2_HEAD);
-	he_writel(he_dev, 0x0, IRQ2_CNTL);
-	he_writel(he_dev, 0x0, IRQ2_DATA);
-
-	he_writel(he_dev, 0x0, IRQ3_BASE);
-	he_writel(he_dev, 0x0, IRQ3_HEAD);
-	he_writel(he_dev, 0x0, IRQ3_CNTL);
-	he_writel(he_dev, 0x0, IRQ3_DATA);
-
-	/* 2.9.3.2 interrupt queue mapping registers */
-
-	he_writel(he_dev, 0x0, GRP_10_MAP);
-	he_writel(he_dev, 0x0, GRP_32_MAP);
-	he_writel(he_dev, 0x0, GRP_54_MAP);
-	he_writel(he_dev, 0x0, GRP_76_MAP);
-
-	if (request_irq(he_dev->pci_dev->irq,
-			he_irq_handler, IRQF_SHARED, DEV_LABEL, he_dev)) {
-		hprintk("irq %d already in use\n", he_dev->pci_dev->irq);
-		return -EINVAL;
-	}   
-
-	he_dev->irq = he_dev->pci_dev->irq;
-
-	return 0;
-}
-
-static int he_start(struct atm_dev *dev)
-{
-	struct he_dev *he_dev;
-	struct pci_dev *pci_dev;
-	unsigned long membase;
-
-	u16 command;
-	u32 gen_cntl_0, host_cntl, lb_swap;
-	u8 cache_size, timer;
-	
-	unsigned err;
-	unsigned int status, reg;
-	int i, group;
-
-	he_dev = HE_DEV(dev);
-	pci_dev = he_dev->pci_dev;
-
-	membase = pci_resource_start(pci_dev, 0);
-	HPRINTK("membase = 0x%lx  irq = %d.\n", membase, pci_dev->irq);
-
-	/*
-	 * pci bus controller initialization 
-	 */
-
-	/* 4.3 pci bus controller-specific initialization */
-	if (pci_read_config_dword(pci_dev, GEN_CNTL_0, &gen_cntl_0) != 0) {
-		hprintk("can't read GEN_CNTL_0\n");
-		return -EINVAL;
-	}
-	gen_cntl_0 |= (MRL_ENB | MRM_ENB | IGNORE_TIMEOUT);
-	if (pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0) != 0) {
-		hprintk("can't write GEN_CNTL_0.\n");
-		return -EINVAL;
-	}
-
-	if (pci_read_config_word(pci_dev, PCI_COMMAND, &command) != 0) {
-		hprintk("can't read PCI_COMMAND.\n");
-		return -EINVAL;
-	}
-
-	command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE);
-	if (pci_write_config_word(pci_dev, PCI_COMMAND, command) != 0) {
-		hprintk("can't enable memory.\n");
-		return -EINVAL;
-	}
-
-	if (pci_read_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, &cache_size)) {
-		hprintk("can't read cache line size?\n");
-		return -EINVAL;
-	}
-
-	if (cache_size < 16) {
-		cache_size = 16;
-		if (pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, cache_size))
-			hprintk("can't set cache line size to %d\n", cache_size);
-	}
-
-	if (pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &timer)) {
-		hprintk("can't read latency timer?\n");
-		return -EINVAL;
-	}
-
-	/* from table 3.9
-	 *
-	 * LAT_TIMER = 1 + AVG_LAT + BURST_SIZE/BUS_SIZE
-	 * 
-	 * AVG_LAT: The average first data read/write latency [maximum 16 clock cycles]
-	 * BURST_SIZE: 1536 bytes (read) for 622, 768 bytes (read) for 155 [192 clock cycles]
-	 *
-	 */ 
-#define LAT_TIMER 209
-	if (timer < LAT_TIMER) {
-		HPRINTK("latency timer was %d, setting to %d\n", timer, LAT_TIMER);
-		timer = LAT_TIMER;
-		if (pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, timer))
-			hprintk("can't set latency timer to %d\n", timer);
-	}
-
-	if (!(he_dev->membase = ioremap(membase, HE_REGMAP_SIZE))) {
-		hprintk("can't set up page mapping\n");
-		return -EINVAL;
-	}
-
-	/* 4.4 card reset */
-	he_writel(he_dev, 0x0, RESET_CNTL);
-	he_writel(he_dev, 0xff, RESET_CNTL);
-
-	msleep(16);	/* 16 ms */
-	status = he_readl(he_dev, RESET_CNTL);
-	if ((status & BOARD_RST_STATUS) == 0) {
-		hprintk("reset failed\n");
-		return -EINVAL;
-	}
-
-	/* 4.5 set bus width */
-	host_cntl = he_readl(he_dev, HOST_CNTL);
-	if (host_cntl & PCI_BUS_SIZE64)
-		gen_cntl_0 |= ENBL_64;
-	else
-		gen_cntl_0 &= ~ENBL_64;
-
-	if (disable64 == 1) {
-		hprintk("disabling 64-bit pci bus transfers\n");
-		gen_cntl_0 &= ~ENBL_64;
-	}
-
-	if (gen_cntl_0 & ENBL_64)
-		hprintk("64-bit transfers enabled\n");
-
-	pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0);
-
-	/* 4.7 read prom contents */
-	for (i = 0; i < PROD_ID_LEN; ++i)
-		he_dev->prod_id[i] = read_prom_byte(he_dev, PROD_ID + i);
-
-	he_dev->media = read_prom_byte(he_dev, MEDIA);
-
-	for (i = 0; i < 6; ++i)
-		dev->esi[i] = read_prom_byte(he_dev, MAC_ADDR + i);
-
-	hprintk("%s%s, %pM\n", he_dev->prod_id,
-		he_dev->media & 0x40 ? "SM" : "MM", dev->esi);
-	he_dev->atm_dev->link_rate = he_is622(he_dev) ?
-						ATM_OC12_PCR : ATM_OC3_PCR;
-
-	/* 4.6 set host endianess */
-	lb_swap = he_readl(he_dev, LB_SWAP);
-	if (he_is622(he_dev))
-		lb_swap &= ~XFER_SIZE;		/* 4 cells */
-	else
-		lb_swap |= XFER_SIZE;		/* 8 cells */
-#ifdef __BIG_ENDIAN
-	lb_swap |= DESC_WR_SWAP | INTR_SWAP | BIG_ENDIAN_HOST;
-#else
-	lb_swap &= ~(DESC_WR_SWAP | INTR_SWAP | BIG_ENDIAN_HOST |
-			DATA_WR_SWAP | DATA_RD_SWAP | DESC_RD_SWAP);
-#endif /* __BIG_ENDIAN */
-	he_writel(he_dev, lb_swap, LB_SWAP);
-
-	/* 4.8 sdram controller initialization */
-	he_writel(he_dev, he_is622(he_dev) ? LB_64_ENB : 0x0, SDRAM_CTL);
-
-	/* 4.9 initialize rnum value */
-	lb_swap |= SWAP_RNUM_MAX(0xf);
-	he_writel(he_dev, lb_swap, LB_SWAP);
-
-	/* 4.10 initialize the interrupt queues */
-	if ((err = he_init_irq(he_dev)) != 0)
-		return err;
-
-	/* 4.11 enable pci bus controller state machines */
-	host_cntl |= (OUTFF_ENB | CMDFF_ENB |
-				QUICK_RD_RETRY | QUICK_WR_RETRY | PERR_INT_ENB);
-	he_writel(he_dev, host_cntl, HOST_CNTL);
-
-	gen_cntl_0 |= INT_PROC_ENBL|INIT_ENB;
-	pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0);
-
-	/*
-	 * atm network controller initialization
-	 */
-
-	/* 5.1.1 generic configuration state */
-
-	/*
-	 *		local (cell) buffer memory map
-	 *                    
-	 *             HE155                          HE622
-	 *                                                      
-	 *        0 ____________1023 bytes  0 _______________________2047 bytes
-	 *         |            |            |                   |   |
-	 *         |  utility   |            |        rx0        |   |
-	 *        5|____________|         255|___________________| u |
-	 *        6|            |         256|                   | t |
-	 *         |            |            |                   | i |
-	 *         |    rx0     |     row    |        tx         | l |
-	 *         |            |            |                   | i |
-	 *         |            |         767|___________________| t |
-	 *      517|____________|         768|                   | y |
-	 * row  518|            |            |        rx1        |   |
-	 *         |            |        1023|___________________|___|
-	 *         |            |
-	 *         |    tx      |
-	 *         |            |
-	 *         |            |
-	 *     1535|____________|
-	 *     1536|            |
-	 *         |    rx1     |
-	 *     2047|____________|
-	 *
-	 */
-
-	/* total 4096 connections */
-	he_dev->vcibits = CONFIG_DEFAULT_VCIBITS;
-	he_dev->vpibits = CONFIG_DEFAULT_VPIBITS;
-
-	if (nvpibits != -1 && nvcibits != -1 && nvpibits+nvcibits != HE_MAXCIDBITS) {
-		hprintk("nvpibits + nvcibits != %d\n", HE_MAXCIDBITS);
-		return -ENODEV;
-	}
-
-	if (nvpibits != -1) {
-		he_dev->vpibits = nvpibits;
-		he_dev->vcibits = HE_MAXCIDBITS - nvpibits;
-	}
-
-	if (nvcibits != -1) {
-		he_dev->vcibits = nvcibits;
-		he_dev->vpibits = HE_MAXCIDBITS - nvcibits;
-	}
-
-
-	if (he_is622(he_dev)) {
-		he_dev->cells_per_row = 40;
-		he_dev->bytes_per_row = 2048;
-		he_dev->r0_numrows = 256;
-		he_dev->tx_numrows = 512;
-		he_dev->r1_numrows = 256;
-		he_dev->r0_startrow = 0;
-		he_dev->tx_startrow = 256;
-		he_dev->r1_startrow = 768;
-	} else {
-		he_dev->cells_per_row = 20;
-		he_dev->bytes_per_row = 1024;
-		he_dev->r0_numrows = 512;
-		he_dev->tx_numrows = 1018;
-		he_dev->r1_numrows = 512;
-		he_dev->r0_startrow = 6;
-		he_dev->tx_startrow = 518;
-		he_dev->r1_startrow = 1536;
-	}
-
-	he_dev->cells_per_lbuf = 4;
-	he_dev->buffer_limit = 4;
-	he_dev->r0_numbuffs = he_dev->r0_numrows *
-				he_dev->cells_per_row / he_dev->cells_per_lbuf;
-	if (he_dev->r0_numbuffs > 2560)
-		he_dev->r0_numbuffs = 2560;
-
-	he_dev->r1_numbuffs = he_dev->r1_numrows *
-				he_dev->cells_per_row / he_dev->cells_per_lbuf;
-	if (he_dev->r1_numbuffs > 2560)
-		he_dev->r1_numbuffs = 2560;
-
-	he_dev->tx_numbuffs = he_dev->tx_numrows *
-				he_dev->cells_per_row / he_dev->cells_per_lbuf;
-	if (he_dev->tx_numbuffs > 5120)
-		he_dev->tx_numbuffs = 5120;
-
-	/* 5.1.2 configure hardware dependent registers */
-
-	he_writel(he_dev, 
-		SLICE_X(0x2) | ARB_RNUM_MAX(0xf) | TH_PRTY(0x3) |
-		RH_PRTY(0x3) | TL_PRTY(0x2) | RL_PRTY(0x1) |
-		(he_is622(he_dev) ? BUS_MULTI(0x28) : BUS_MULTI(0x46)) |
-		(he_is622(he_dev) ? NET_PREF(0x50) : NET_PREF(0x8c)),
-								LBARB);
-
-	he_writel(he_dev, BANK_ON |
-		(he_is622(he_dev) ? (REF_RATE(0x384) | WIDE_DATA) : REF_RATE(0x150)),
-								SDRAMCON);
-
-	he_writel(he_dev,
-		(he_is622(he_dev) ? RM_BANK_WAIT(1) : RM_BANK_WAIT(0)) |
-						RM_RW_WAIT(1), RCMCONFIG);
-	he_writel(he_dev,
-		(he_is622(he_dev) ? TM_BANK_WAIT(2) : TM_BANK_WAIT(1)) |
-						TM_RW_WAIT(1), TCMCONFIG);
-
-	he_writel(he_dev, he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD, LB_CONFIG);
-
-	he_writel(he_dev, 
-		(he_is622(he_dev) ? UT_RD_DELAY(8) : UT_RD_DELAY(0)) |
-		(he_is622(he_dev) ? RC_UT_MODE(0) : RC_UT_MODE(1)) |
-		RX_VALVP(he_dev->vpibits) |
-		RX_VALVC(he_dev->vcibits),			 RC_CONFIG);
-
-	he_writel(he_dev, DRF_THRESH(0x20) |
-		(he_is622(he_dev) ? TX_UT_MODE(0) : TX_UT_MODE(1)) |
-		TX_VCI_MASK(he_dev->vcibits) |
-		LBFREE_CNT(he_dev->tx_numbuffs), 		TX_CONFIG);
-
-	he_writel(he_dev, 0x0, TXAAL5_PROTO);
-
-	he_writel(he_dev, PHY_INT_ENB |
-		(he_is622(he_dev) ? PTMR_PRE(67 - 1) : PTMR_PRE(50 - 1)),
-								RH_CONFIG);
-
-	/* 5.1.3 initialize connection memory */
-
-	for (i = 0; i < TCM_MEM_SIZE; ++i)
-		he_writel_tcm(he_dev, 0, i);
-
-	for (i = 0; i < RCM_MEM_SIZE; ++i)
-		he_writel_rcm(he_dev, 0, i);
-
-	/*
-	 *	transmit connection memory map
-	 *
-	 *                  tx memory
-	 *          0x0 ___________________
-	 *             |                   |
-	 *             |                   |
-	 *             |       TSRa        |
-	 *             |                   |
-	 *             |                   |
-	 *       0x8000|___________________|
-	 *             |                   |
-	 *             |       TSRb        |
-	 *       0xc000|___________________|
-	 *             |                   |
-	 *             |       TSRc        |
-	 *       0xe000|___________________|
-	 *             |       TSRd        |
-	 *       0xf000|___________________|
-	 *             |       tmABR       |
-	 *      0x10000|___________________|
-	 *             |                   |
-	 *             |       tmTPD       |
-	 *             |___________________|
-	 *             |                   |
-	 *                      ....
-	 *      0x1ffff|___________________|
-	 *
-	 *
-	 */
-
-	he_writel(he_dev, CONFIG_TSRB, TSRB_BA);
-	he_writel(he_dev, CONFIG_TSRC, TSRC_BA);
-	he_writel(he_dev, CONFIG_TSRD, TSRD_BA);
-	he_writel(he_dev, CONFIG_TMABR, TMABR_BA);
-	he_writel(he_dev, CONFIG_TPDBA, TPD_BA);
-
-
-	/*
-	 *	receive connection memory map
-	 *
-	 *          0x0 ___________________
-	 *             |                   |
-	 *             |                   |
-	 *             |       RSRa        |
-	 *             |                   |
-	 *             |                   |
-	 *       0x8000|___________________|
-	 *             |                   |
-	 *             |             rx0/1 |
-	 *             |       LBM         |   link lists of local
-	 *             |             tx    |   buffer memory 
-	 *             |                   |
-	 *       0xd000|___________________|
-	 *             |                   |
-	 *             |      rmABR        |
-	 *       0xe000|___________________|
-	 *             |                   |
-	 *             |       RSRb        |
-	 *             |___________________|
-	 *             |                   |
-	 *                      ....
-	 *       0xffff|___________________|
-	 */
-
-	he_writel(he_dev, 0x08000, RCMLBM_BA);
-	he_writel(he_dev, 0x0e000, RCMRSRB_BA);
-	he_writel(he_dev, 0x0d800, RCMABR_BA);
-
-	/* 5.1.4 initialize local buffer free pools linked lists */
-
-	he_init_rx_lbfp0(he_dev);
-	he_init_rx_lbfp1(he_dev);
-
-	he_writel(he_dev, 0x0, RLBC_H);
-	he_writel(he_dev, 0x0, RLBC_T);
-	he_writel(he_dev, 0x0, RLBC_H2);
-
-	he_writel(he_dev, 512, RXTHRSH);	/* 10% of r0+r1 buffers */
-	he_writel(he_dev, 256, LITHRSH); 	/* 5% of r0+r1 buffers */
-
-	he_init_tx_lbfp(he_dev);
-
-	he_writel(he_dev, he_is622(he_dev) ? 0x104780 : 0x800, UBUFF_BA);
-
-	/* 5.1.5 initialize intermediate receive queues */
-
-	if (he_is622(he_dev)) {
-		he_writel(he_dev, 0x000f, G0_INMQ_S);
-		he_writel(he_dev, 0x200f, G0_INMQ_L);
-
-		he_writel(he_dev, 0x001f, G1_INMQ_S);
-		he_writel(he_dev, 0x201f, G1_INMQ_L);
-
-		he_writel(he_dev, 0x002f, G2_INMQ_S);
-		he_writel(he_dev, 0x202f, G2_INMQ_L);
-
-		he_writel(he_dev, 0x003f, G3_INMQ_S);
-		he_writel(he_dev, 0x203f, G3_INMQ_L);
-
-		he_writel(he_dev, 0x004f, G4_INMQ_S);
-		he_writel(he_dev, 0x204f, G4_INMQ_L);
-
-		he_writel(he_dev, 0x005f, G5_INMQ_S);
-		he_writel(he_dev, 0x205f, G5_INMQ_L);
-
-		he_writel(he_dev, 0x006f, G6_INMQ_S);
-		he_writel(he_dev, 0x206f, G6_INMQ_L);
-
-		he_writel(he_dev, 0x007f, G7_INMQ_S);
-		he_writel(he_dev, 0x207f, G7_INMQ_L);
-	} else {
-		he_writel(he_dev, 0x0000, G0_INMQ_S);
-		he_writel(he_dev, 0x0008, G0_INMQ_L);
-
-		he_writel(he_dev, 0x0001, G1_INMQ_S);
-		he_writel(he_dev, 0x0009, G1_INMQ_L);
-
-		he_writel(he_dev, 0x0002, G2_INMQ_S);
-		he_writel(he_dev, 0x000a, G2_INMQ_L);
-
-		he_writel(he_dev, 0x0003, G3_INMQ_S);
-		he_writel(he_dev, 0x000b, G3_INMQ_L);
-
-		he_writel(he_dev, 0x0004, G4_INMQ_S);
-		he_writel(he_dev, 0x000c, G4_INMQ_L);
-
-		he_writel(he_dev, 0x0005, G5_INMQ_S);
-		he_writel(he_dev, 0x000d, G5_INMQ_L);
-
-		he_writel(he_dev, 0x0006, G6_INMQ_S);
-		he_writel(he_dev, 0x000e, G6_INMQ_L);
-
-		he_writel(he_dev, 0x0007, G7_INMQ_S);
-		he_writel(he_dev, 0x000f, G7_INMQ_L);
-	}
-
-	/* 5.1.6 application tunable parameters */
-
-	he_writel(he_dev, 0x0, MCC);
-	he_writel(he_dev, 0x0, OEC);
-	he_writel(he_dev, 0x0, DCC);
-	he_writel(he_dev, 0x0, CEC);
-	
-	/* 5.1.7 cs block initialization */
-
-	he_init_cs_block(he_dev);
-
-	/* 5.1.8 cs block connection memory initialization */
-	
-	if (he_init_cs_block_rcm(he_dev) < 0)
-		return -ENOMEM;
-
-	/* 5.1.10 initialize host structures */
-
-	he_init_tpdrq(he_dev);
-
-	he_dev->tpd_pool = dma_pool_create("tpd", &he_dev->pci_dev->dev,
-					   sizeof(struct he_tpd), TPD_ALIGNMENT, 0);
-	if (he_dev->tpd_pool == NULL) {
-		hprintk("unable to create tpd dma_pool\n");
-		return -ENOMEM;         
-	}
-
-	INIT_LIST_HEAD(&he_dev->outstanding_tpds);
-
-	if (he_init_group(he_dev, 0) != 0)
-		return -ENOMEM;
-
-	for (group = 1; group < HE_NUM_GROUPS; ++group) {
-		he_writel(he_dev, 0x0, G0_RBPS_S + (group * 32));
-		he_writel(he_dev, 0x0, G0_RBPS_T + (group * 32));
-		he_writel(he_dev, 0x0, G0_RBPS_QI + (group * 32));
-		he_writel(he_dev, RBP_THRESH(0x1) | RBP_QSIZE(0x0),
-						G0_RBPS_BS + (group * 32));
-
-		he_writel(he_dev, 0x0, G0_RBPL_S + (group * 32));
-		he_writel(he_dev, 0x0, G0_RBPL_T + (group * 32));
-		he_writel(he_dev, RBP_THRESH(0x1) | RBP_QSIZE(0x0),
-						G0_RBPL_QI + (group * 32));
-		he_writel(he_dev, 0x0, G0_RBPL_BS + (group * 32));
-
-		he_writel(he_dev, 0x0, G0_RBRQ_ST + (group * 16));
-		he_writel(he_dev, 0x0, G0_RBRQ_H + (group * 16));
-		he_writel(he_dev, RBRQ_THRESH(0x1) | RBRQ_SIZE(0x0),
-						G0_RBRQ_Q + (group * 16));
-		he_writel(he_dev, 0x0, G0_RBRQ_I + (group * 16));
-
-		he_writel(he_dev, 0x0, G0_TBRQ_B_T + (group * 16));
-		he_writel(he_dev, 0x0, G0_TBRQ_H + (group * 16));
-		he_writel(he_dev, TBRQ_THRESH(0x1),
-						G0_TBRQ_THRESH + (group * 16));
-		he_writel(he_dev, 0x0, G0_TBRQ_S + (group * 16));
-	}
-
-	/* host status page */
-
-	he_dev->hsp = dma_alloc_coherent(&he_dev->pci_dev->dev,
-					 sizeof(struct he_hsp),
-					 &he_dev->hsp_phys, GFP_KERNEL);
-	if (he_dev->hsp == NULL) {
-		hprintk("failed to allocate host status page\n");
-		return -ENOMEM;
-	}
-	he_writel(he_dev, he_dev->hsp_phys, HSP_BA);
-
-	/* initialize framer */
-
-#ifdef CONFIG_ATM_HE_USE_SUNI
-	if (he_isMM(he_dev))
-		suni_init(he_dev->atm_dev);
-	if (he_dev->atm_dev->phy && he_dev->atm_dev->phy->start)
-		he_dev->atm_dev->phy->start(he_dev->atm_dev);
-#endif /* CONFIG_ATM_HE_USE_SUNI */
-
-	if (sdh) {
-		/* this really should be in suni.c but for now... */
-		int val;
-
-		val = he_phy_get(he_dev->atm_dev, SUNI_TPOP_APM);
-		val = (val & ~SUNI_TPOP_APM_S) | (SUNI_TPOP_S_SDH << SUNI_TPOP_APM_S_SHIFT);
-		he_phy_put(he_dev->atm_dev, val, SUNI_TPOP_APM);
-		he_phy_put(he_dev->atm_dev, SUNI_TACP_IUCHP_CLP, SUNI_TACP_IUCHP);
-	}
-
-	/* 5.1.12 enable transmit and receive */
-
-	reg = he_readl_mbox(he_dev, CS_ERCTL0);
-	reg |= TX_ENABLE|ER_ENABLE;
-	he_writel_mbox(he_dev, reg, CS_ERCTL0);
-
-	reg = he_readl(he_dev, RC_CONFIG);
-	reg |= RX_ENABLE;
-	he_writel(he_dev, reg, RC_CONFIG);
-
-	for (i = 0; i < HE_NUM_CS_STPER; ++i) {
-		he_dev->cs_stper[i].inuse = 0;
-		he_dev->cs_stper[i].pcr = -1;
-	}
-	he_dev->total_bw = 0;
-
-
-	/* atm linux initialization */
-
-	he_dev->atm_dev->ci_range.vpi_bits = he_dev->vpibits;
-	he_dev->atm_dev->ci_range.vci_bits = he_dev->vcibits;
-
-	he_dev->irq_peak = 0;
-	he_dev->rbrq_peak = 0;
-	he_dev->rbpl_peak = 0;
-	he_dev->tbrq_peak = 0;
-
-	HPRINTK("hell bent for leather!\n");
-
-	return 0;
-}
-
-static void
-he_stop(struct he_dev *he_dev)
-{
-	struct he_buff *heb, *next;
-	struct pci_dev *pci_dev;
-	u32 gen_cntl_0, reg;
-	u16 command;
-
-	pci_dev = he_dev->pci_dev;
-
-	/* disable interrupts */
-
-	if (he_dev->membase) {
-		pci_read_config_dword(pci_dev, GEN_CNTL_0, &gen_cntl_0);
-		gen_cntl_0 &= ~(INT_PROC_ENBL | INIT_ENB);
-		pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0);
-
-		tasklet_disable(&he_dev->tasklet);
-
-		/* disable recv and transmit */
-
-		reg = he_readl_mbox(he_dev, CS_ERCTL0);
-		reg &= ~(TX_ENABLE|ER_ENABLE);
-		he_writel_mbox(he_dev, reg, CS_ERCTL0);
-
-		reg = he_readl(he_dev, RC_CONFIG);
-		reg &= ~(RX_ENABLE);
-		he_writel(he_dev, reg, RC_CONFIG);
-	}
-
-#ifdef CONFIG_ATM_HE_USE_SUNI
-	if (he_dev->atm_dev->phy && he_dev->atm_dev->phy->stop)
-		he_dev->atm_dev->phy->stop(he_dev->atm_dev);
-#endif /* CONFIG_ATM_HE_USE_SUNI */
-
-	if (he_dev->irq)
-		free_irq(he_dev->irq, he_dev);
-
-	if (he_dev->irq_base)
-		dma_free_coherent(&he_dev->pci_dev->dev, (CONFIG_IRQ_SIZE + 1)
-				  * sizeof(struct he_irq), he_dev->irq_base, he_dev->irq_phys);
-
-	if (he_dev->hsp)
-		dma_free_coherent(&he_dev->pci_dev->dev, sizeof(struct he_hsp),
-				  he_dev->hsp, he_dev->hsp_phys);
-
-	if (he_dev->rbpl_base) {
-		list_for_each_entry_safe(heb, next, &he_dev->rbpl_outstanding, entry)
-			dma_pool_free(he_dev->rbpl_pool, heb, heb->mapping);
-
-		dma_free_coherent(&he_dev->pci_dev->dev, CONFIG_RBPL_SIZE
-				  * sizeof(struct he_rbp), he_dev->rbpl_base, he_dev->rbpl_phys);
-	}
-
-	kfree(he_dev->rbpl_virt);
-	bitmap_free(he_dev->rbpl_table);
-	dma_pool_destroy(he_dev->rbpl_pool);
-
-	if (he_dev->rbrq_base)
-		dma_free_coherent(&he_dev->pci_dev->dev, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq),
-				  he_dev->rbrq_base, he_dev->rbrq_phys);
-
-	if (he_dev->tbrq_base)
-		dma_free_coherent(&he_dev->pci_dev->dev, CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq),
-				  he_dev->tbrq_base, he_dev->tbrq_phys);
-
-	if (he_dev->tpdrq_base)
-		dma_free_coherent(&he_dev->pci_dev->dev,
-				  CONFIG_TPDRQ_SIZE * sizeof(struct he_tpdrq),
-				  he_dev->tpdrq_base, he_dev->tpdrq_phys);
-
-	dma_pool_destroy(he_dev->tpd_pool);
-
-	if (he_dev->pci_dev) {
-		pci_read_config_word(he_dev->pci_dev, PCI_COMMAND, &command);
-		command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-		pci_write_config_word(he_dev->pci_dev, PCI_COMMAND, command);
-	}
-	
-	if (he_dev->membase)
-		iounmap(he_dev->membase);
-}
-
-static struct he_tpd *
-__alloc_tpd(struct he_dev *he_dev)
-{
-	struct he_tpd *tpd;
-	dma_addr_t mapping;
-
-	tpd = dma_pool_alloc(he_dev->tpd_pool, GFP_ATOMIC, &mapping);
-	if (tpd == NULL)
-		return NULL;
-			
-	tpd->status = TPD_ADDR(mapping);
-	tpd->reserved = 0; 
-	tpd->iovec[0].addr = 0; tpd->iovec[0].len = 0;
-	tpd->iovec[1].addr = 0; tpd->iovec[1].len = 0;
-	tpd->iovec[2].addr = 0; tpd->iovec[2].len = 0;
-
-	return tpd;
-}
-
-#define AAL5_LEN(buf,len) 						\
-			((((unsigned char *)(buf))[(len)-6] << 8) |	\
-				(((unsigned char *)(buf))[(len)-5]))
-
-/* 2.10.1.2 receive
- *
- * aal5 packets can optionally return the tcp checksum in the lower
- * 16 bits of the crc (RSR0_TCP_CKSUM)
- */
-
-#define TCP_CKSUM(buf,len) 						\
-			((((unsigned char *)(buf))[(len)-2] << 8) |	\
-				(((unsigned char *)(buf))[(len-1)]))
-
-static int
-he_service_rbrq(struct he_dev *he_dev, int group)
-{
-	struct he_rbrq *rbrq_tail = (struct he_rbrq *)
-				((unsigned long)he_dev->rbrq_base |
-					he_dev->hsp->group[group].rbrq_tail);
-	unsigned cid, lastcid = -1;
-	struct sk_buff *skb;
-	struct atm_vcc *vcc = NULL;
-	struct he_vcc *he_vcc;
-	struct he_buff *heb, *next;
-	int i;
-	int pdus_assembled = 0;
-	int updated = 0;
-
-	read_lock(&vcc_sklist_lock);
-	while (he_dev->rbrq_head != rbrq_tail) {
-		++updated;
-
-		HPRINTK("%p rbrq%d 0x%x len=%d cid=0x%x %s%s%s%s%s%s\n",
-			he_dev->rbrq_head, group,
-			RBRQ_ADDR(he_dev->rbrq_head),
-			RBRQ_BUFLEN(he_dev->rbrq_head),
-			RBRQ_CID(he_dev->rbrq_head),
-			RBRQ_CRC_ERR(he_dev->rbrq_head) ? " CRC_ERR" : "",
-			RBRQ_LEN_ERR(he_dev->rbrq_head) ? " LEN_ERR" : "",
-			RBRQ_END_PDU(he_dev->rbrq_head) ? " END_PDU" : "",
-			RBRQ_AAL5_PROT(he_dev->rbrq_head) ? " AAL5_PROT" : "",
-			RBRQ_CON_CLOSED(he_dev->rbrq_head) ? " CON_CLOSED" : "",
-			RBRQ_HBUF_ERR(he_dev->rbrq_head) ? " HBUF_ERR" : "");
-
-		i = RBRQ_ADDR(he_dev->rbrq_head) >> RBP_IDX_OFFSET;
-		heb = he_dev->rbpl_virt[i];
-
-		cid = RBRQ_CID(he_dev->rbrq_head);
-		if (cid != lastcid)
-			vcc = __find_vcc(he_dev, cid);
-		lastcid = cid;
-
-		if (vcc == NULL || (he_vcc = HE_VCC(vcc)) == NULL) {
-			hprintk("vcc/he_vcc == NULL  (cid 0x%x)\n", cid);
-			if (!RBRQ_HBUF_ERR(he_dev->rbrq_head)) {
-				clear_bit(i, he_dev->rbpl_table);
-				list_del(&heb->entry);
-				dma_pool_free(he_dev->rbpl_pool, heb, heb->mapping);
-			}
-					
-			goto next_rbrq_entry;
-		}
-
-		if (RBRQ_HBUF_ERR(he_dev->rbrq_head)) {
-			hprintk("HBUF_ERR!  (cid 0x%x)\n", cid);
-			atomic_inc(&vcc->stats->rx_drop);
-			goto return_host_buffers;
-		}
-
-		heb->len = RBRQ_BUFLEN(he_dev->rbrq_head) * 4;
-		clear_bit(i, he_dev->rbpl_table);
-		list_move_tail(&heb->entry, &he_vcc->buffers);
-		he_vcc->pdu_len += heb->len;
-
-		if (RBRQ_CON_CLOSED(he_dev->rbrq_head)) {
-			lastcid = -1;
-			HPRINTK("wake_up rx_waitq  (cid 0x%x)\n", cid);
-			wake_up(&he_vcc->rx_waitq);
-			goto return_host_buffers;
-		}
-
-		if (!RBRQ_END_PDU(he_dev->rbrq_head))
-			goto next_rbrq_entry;
-
-		if (RBRQ_LEN_ERR(he_dev->rbrq_head)
-				|| RBRQ_CRC_ERR(he_dev->rbrq_head)) {
-			HPRINTK("%s%s (%d.%d)\n",
-				RBRQ_CRC_ERR(he_dev->rbrq_head)
-							? "CRC_ERR " : "",
-				RBRQ_LEN_ERR(he_dev->rbrq_head)
-							? "LEN_ERR" : "",
-							vcc->vpi, vcc->vci);
-			atomic_inc(&vcc->stats->rx_err);
-			goto return_host_buffers;
-		}
-
-		skb = atm_alloc_charge(vcc, he_vcc->pdu_len + rx_skb_reserve,
-							GFP_ATOMIC);
-		if (!skb) {
-			HPRINTK("charge failed (%d.%d)\n", vcc->vpi, vcc->vci);
-			goto return_host_buffers;
-		}
-
-		if (rx_skb_reserve > 0)
-			skb_reserve(skb, rx_skb_reserve);
-
-		__net_timestamp(skb);
-
-		list_for_each_entry(heb, &he_vcc->buffers, entry)
-			skb_put_data(skb, &heb->data, heb->len);
-
-		switch (vcc->qos.aal) {
-			case ATM_AAL0:
-				/* 2.10.1.5 raw cell receive */
-				skb->len = ATM_AAL0_SDU;
-				skb_set_tail_pointer(skb, skb->len);
-				break;
-			case ATM_AAL5:
-				/* 2.10.1.2 aal5 receive */
-
-				skb->len = AAL5_LEN(skb->data, he_vcc->pdu_len);
-				skb_set_tail_pointer(skb, skb->len);
-#ifdef USE_CHECKSUM_HW
-				if (vcc->vpi == 0 && vcc->vci >= ATM_NOT_RSV_VCI) {
-					skb->ip_summed = CHECKSUM_COMPLETE;
-					skb->csum = TCP_CKSUM(skb->data,
-							he_vcc->pdu_len);
-				}
-#endif
-				break;
-		}
-
-#ifdef should_never_happen
-		if (skb->len > vcc->qos.rxtp.max_sdu)
-			hprintk("pdu_len (%d) > vcc->qos.rxtp.max_sdu (%d)!  cid 0x%x\n", skb->len, vcc->qos.rxtp.max_sdu, cid);
-#endif
-
-#ifdef notdef
-		ATM_SKB(skb)->vcc = vcc;
-#endif
-		spin_unlock(&he_dev->global_lock);
-		vcc->push(vcc, skb);
-		spin_lock(&he_dev->global_lock);
-
-		atomic_inc(&vcc->stats->rx);
-
-return_host_buffers:
-		++pdus_assembled;
-
-		list_for_each_entry_safe(heb, next, &he_vcc->buffers, entry)
-			dma_pool_free(he_dev->rbpl_pool, heb, heb->mapping);
-		INIT_LIST_HEAD(&he_vcc->buffers);
-		he_vcc->pdu_len = 0;
-
-next_rbrq_entry:
-		he_dev->rbrq_head = (struct he_rbrq *)
-				((unsigned long) he_dev->rbrq_base |
-					RBRQ_MASK(he_dev->rbrq_head + 1));
-
-	}
-	read_unlock(&vcc_sklist_lock);
-
-	if (updated) {
-		if (updated > he_dev->rbrq_peak)
-			he_dev->rbrq_peak = updated;
-
-		he_writel(he_dev, RBRQ_MASK(he_dev->rbrq_head),
-						G0_RBRQ_H + (group * 16));
-	}
-
-	return pdus_assembled;
-}
-
-static void
-he_service_tbrq(struct he_dev *he_dev, int group)
-{
-	struct he_tbrq *tbrq_tail = (struct he_tbrq *)
-				((unsigned long)he_dev->tbrq_base |
-					he_dev->hsp->group[group].tbrq_tail);
-	struct he_tpd *tpd;
-	int slot, updated = 0;
-	struct he_tpd *__tpd;
-
-	/* 2.1.6 transmit buffer return queue */
-
-	while (he_dev->tbrq_head != tbrq_tail) {
-		++updated;
-
-		HPRINTK("tbrq%d 0x%x%s%s\n",
-			group,
-			TBRQ_TPD(he_dev->tbrq_head), 
-			TBRQ_EOS(he_dev->tbrq_head) ? " EOS" : "",
-			TBRQ_MULTIPLE(he_dev->tbrq_head) ? " MULTIPLE" : "");
-		tpd = NULL;
-		list_for_each_entry(__tpd, &he_dev->outstanding_tpds, entry) {
-			if (TPD_ADDR(__tpd->status) == TBRQ_TPD(he_dev->tbrq_head)) {
-				tpd = __tpd;
-				list_del(&__tpd->entry);
-				break;
-			}
-		}
-
-		if (tpd == NULL) {
-			hprintk("unable to locate tpd for dma buffer %x\n",
-						TBRQ_TPD(he_dev->tbrq_head));
-			goto next_tbrq_entry;
-		}
-
-		if (TBRQ_EOS(he_dev->tbrq_head)) {
-			HPRINTK("wake_up(tx_waitq) cid 0x%x\n",
-				he_mkcid(he_dev, tpd->vcc->vpi, tpd->vcc->vci));
-			if (tpd->vcc)
-				wake_up(&HE_VCC(tpd->vcc)->tx_waitq);
-
-			goto next_tbrq_entry;
-		}
-
-		for (slot = 0; slot < TPD_MAXIOV; ++slot) {
-			if (tpd->iovec[slot].addr)
-				dma_unmap_single(&he_dev->pci_dev->dev,
-					tpd->iovec[slot].addr,
-					tpd->iovec[slot].len & TPD_LEN_MASK,
-							DMA_TO_DEVICE);
-			if (tpd->iovec[slot].len & TPD_LST)
-				break;
-				
-		}
-
-		if (tpd->skb) {	/* && !TBRQ_MULTIPLE(he_dev->tbrq_head) */
-			if (tpd->vcc && tpd->vcc->pop)
-				tpd->vcc->pop(tpd->vcc, tpd->skb);
-			else
-				dev_kfree_skb_any(tpd->skb);
-		}
-
-next_tbrq_entry:
-		if (tpd)
-			dma_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
-		he_dev->tbrq_head = (struct he_tbrq *)
-				((unsigned long) he_dev->tbrq_base |
-					TBRQ_MASK(he_dev->tbrq_head + 1));
-	}
-
-	if (updated) {
-		if (updated > he_dev->tbrq_peak)
-			he_dev->tbrq_peak = updated;
-
-		he_writel(he_dev, TBRQ_MASK(he_dev->tbrq_head),
-						G0_TBRQ_H + (group * 16));
-	}
-}
-
-static void
-he_service_rbpl(struct he_dev *he_dev, int group)
-{
-	struct he_rbp *new_tail;
-	struct he_rbp *rbpl_head;
-	struct he_buff *heb;
-	dma_addr_t mapping;
-	int i;
-	int moved = 0;
-
-	rbpl_head = (struct he_rbp *) ((unsigned long)he_dev->rbpl_base |
-					RBPL_MASK(he_readl(he_dev, G0_RBPL_S)));
-
-	for (;;) {
-		new_tail = (struct he_rbp *) ((unsigned long)he_dev->rbpl_base |
-						RBPL_MASK(he_dev->rbpl_tail+1));
-
-		/* table 3.42 -- rbpl_tail should never be set to rbpl_head */
-		if (new_tail == rbpl_head)
-			break;
-
-		i = find_next_zero_bit(he_dev->rbpl_table, RBPL_TABLE_SIZE, he_dev->rbpl_hint);
-		if (i > (RBPL_TABLE_SIZE - 1)) {
-			i = find_first_zero_bit(he_dev->rbpl_table, RBPL_TABLE_SIZE);
-			if (i > (RBPL_TABLE_SIZE - 1))
-				break;
-		}
-		he_dev->rbpl_hint = i + 1;
-
-		heb = dma_pool_alloc(he_dev->rbpl_pool, GFP_ATOMIC, &mapping);
-		if (!heb)
-			break;
-		heb->mapping = mapping;
-		list_add(&heb->entry, &he_dev->rbpl_outstanding);
-		he_dev->rbpl_virt[i] = heb;
-		set_bit(i, he_dev->rbpl_table);
-		new_tail->idx = i << RBP_IDX_OFFSET;
-		new_tail->phys = mapping + offsetof(struct he_buff, data);
-
-		he_dev->rbpl_tail = new_tail;
-		++moved;
-	} 
-
-	if (moved)
-		he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail), G0_RBPL_T);
-}
-
-static void
-he_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	struct he_dev *he_dev = (struct he_dev *) data;
-	int group, type;
-	int updated = 0;
-
-	HPRINTK("tasklet (0x%lx)\n", data);
-	spin_lock_irqsave(&he_dev->global_lock, flags);
-
-	while (he_dev->irq_head != he_dev->irq_tail) {
-		++updated;
-
-		type = ITYPE_TYPE(he_dev->irq_head->isw);
-		group = ITYPE_GROUP(he_dev->irq_head->isw);
-
-		switch (type) {
-			case ITYPE_RBRQ_THRESH:
-				HPRINTK("rbrq%d threshold\n", group);
-				fallthrough;
-			case ITYPE_RBRQ_TIMER:
-				if (he_service_rbrq(he_dev, group))
-					he_service_rbpl(he_dev, group);
-				break;
-			case ITYPE_TBRQ_THRESH:
-				HPRINTK("tbrq%d threshold\n", group);
-				fallthrough;
-			case ITYPE_TPD_COMPLETE:
-				he_service_tbrq(he_dev, group);
-				break;
-			case ITYPE_RBPL_THRESH:
-				he_service_rbpl(he_dev, group);
-				break;
-			case ITYPE_RBPS_THRESH:
-				/* shouldn't happen unless small buffers enabled */
-				break;
-			case ITYPE_PHY:
-				HPRINTK("phy interrupt\n");
-#ifdef CONFIG_ATM_HE_USE_SUNI
-				spin_unlock_irqrestore(&he_dev->global_lock, flags);
-				if (he_dev->atm_dev->phy && he_dev->atm_dev->phy->interrupt)
-					he_dev->atm_dev->phy->interrupt(he_dev->atm_dev);
-				spin_lock_irqsave(&he_dev->global_lock, flags);
-#endif
-				break;
-			case ITYPE_OTHER:
-				switch (type|group) {
-					case ITYPE_PARITY:
-						hprintk("parity error\n");
-						break;
-					case ITYPE_ABORT:
-						hprintk("abort 0x%x\n", he_readl(he_dev, ABORT_ADDR));
-						break;
-				}
-				break;
-			case ITYPE_TYPE(ITYPE_INVALID):
-				/* see 8.1.1 -- check all queues */
-
-				HPRINTK("isw not updated 0x%x\n", he_dev->irq_head->isw);
-
-				he_service_rbrq(he_dev, 0);
-				he_service_rbpl(he_dev, 0);
-				he_service_tbrq(he_dev, 0);
-				break;
-			default:
-				hprintk("bad isw 0x%x?\n", he_dev->irq_head->isw);
-		}
-
-		he_dev->irq_head->isw = ITYPE_INVALID;
-
-		he_dev->irq_head = (struct he_irq *) NEXT_ENTRY(he_dev->irq_base, he_dev->irq_head, IRQ_MASK);
-	}
-
-	if (updated) {
-		if (updated > he_dev->irq_peak)
-			he_dev->irq_peak = updated;
-
-		he_writel(he_dev,
-			IRQ_SIZE(CONFIG_IRQ_SIZE) |
-			IRQ_THRESH(CONFIG_IRQ_THRESH) |
-			IRQ_TAIL(he_dev->irq_tail), IRQ0_HEAD);
-		(void) he_readl(he_dev, INT_FIFO); /* 8.1.2 controller errata; flush posted writes */
-	}
-	spin_unlock_irqrestore(&he_dev->global_lock, flags);
-}
-
-static irqreturn_t
-he_irq_handler(int irq, void *dev_id)
-{
-	unsigned long flags;
-	struct he_dev *he_dev = (struct he_dev * )dev_id;
-	int handled = 0;
-
-	if (he_dev == NULL)
-		return IRQ_NONE;
-
-	spin_lock_irqsave(&he_dev->global_lock, flags);
-
-	he_dev->irq_tail = (struct he_irq *) (((unsigned long)he_dev->irq_base) |
-						(*he_dev->irq_tailoffset << 2));
-
-	if (he_dev->irq_tail == he_dev->irq_head) {
-		HPRINTK("tailoffset not updated?\n");
-		he_dev->irq_tail = (struct he_irq *) ((unsigned long)he_dev->irq_base |
-			((he_readl(he_dev, IRQ0_BASE) & IRQ_MASK) << 2));
-		(void) he_readl(he_dev, INT_FIFO);	/* 8.1.2 controller errata */
-	}
-
-#ifdef DEBUG
-	if (he_dev->irq_head == he_dev->irq_tail /* && !IRQ_PENDING */)
-		hprintk("spurious (or shared) interrupt?\n");
-#endif
-
-	if (he_dev->irq_head != he_dev->irq_tail) {
-		handled = 1;
-		tasklet_schedule(&he_dev->tasklet);
-		he_writel(he_dev, INT_CLEAR_A, INT_FIFO);	/* clear interrupt */
-		(void) he_readl(he_dev, INT_FIFO);		/* flush posted writes */
-	}
-	spin_unlock_irqrestore(&he_dev->global_lock, flags);
-	return IRQ_RETVAL(handled);
-
-}
-
-static __inline__ void
-__enqueue_tpd(struct he_dev *he_dev, struct he_tpd *tpd, unsigned cid)
-{
-	struct he_tpdrq *new_tail;
-
-	HPRINTK("tpdrq %p cid 0x%x -> tpdrq_tail %p\n",
-					tpd, cid, he_dev->tpdrq_tail);
-
-	/* new_tail = he_dev->tpdrq_tail; */
-	new_tail = (struct he_tpdrq *) ((unsigned long) he_dev->tpdrq_base |
-					TPDRQ_MASK(he_dev->tpdrq_tail+1));
-
-	/*
-	 * check to see if we are about to set the tail == head
-	 * if true, update the head pointer from the adapter
-	 * to see if this is really the case (reading the queue
-	 * head for every enqueue would be unnecessarily slow)
-	 */
-
-	if (new_tail == he_dev->tpdrq_head) {
-		he_dev->tpdrq_head = (struct he_tpdrq *)
-			(((unsigned long)he_dev->tpdrq_base) |
-				TPDRQ_MASK(he_readl(he_dev, TPDRQ_B_H)));
-
-		if (new_tail == he_dev->tpdrq_head) {
-			int slot;
-
-			hprintk("tpdrq full (cid 0x%x)\n", cid);
-			/*
-			 * FIXME
-			 * push tpd onto a transmit backlog queue
-			 * after service_tbrq, service the backlog
-			 * for now, we just drop the pdu
-			 */
-			for (slot = 0; slot < TPD_MAXIOV; ++slot) {
-				if (tpd->iovec[slot].addr)
-					dma_unmap_single(&he_dev->pci_dev->dev,
-						tpd->iovec[slot].addr,
-						tpd->iovec[slot].len & TPD_LEN_MASK,
-								DMA_TO_DEVICE);
-			}
-			if (tpd->skb) {
-				if (tpd->vcc->pop)
-					tpd->vcc->pop(tpd->vcc, tpd->skb);
-				else
-					dev_kfree_skb_any(tpd->skb);
-				atomic_inc(&tpd->vcc->stats->tx_err);
-			}
-			dma_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
-			return;
-		}
-	}
-
-	/* 2.1.5 transmit packet descriptor ready queue */
-	list_add_tail(&tpd->entry, &he_dev->outstanding_tpds);
-	he_dev->tpdrq_tail->tpd = TPD_ADDR(tpd->status);
-	he_dev->tpdrq_tail->cid = cid;
-	wmb();
-
-	he_dev->tpdrq_tail = new_tail;
-
-	he_writel(he_dev, TPDRQ_MASK(he_dev->tpdrq_tail), TPDRQ_T);
-	(void) he_readl(he_dev, TPDRQ_T);		/* flush posted writes */
-}
-
-static int
-he_open(struct atm_vcc *vcc)
-{
-	unsigned long flags;
-	struct he_dev *he_dev = HE_DEV(vcc->dev);
-	struct he_vcc *he_vcc;
-	int err = 0;
-	unsigned cid, rsr0, rsr1, rsr4, tsr0, tsr0_aal, tsr4, period, reg, clock;
-	short vpi = vcc->vpi;
-	int vci = vcc->vci;
-
-	if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
-		return 0;
-
-	HPRINTK("open vcc %p %d.%d\n", vcc, vpi, vci);
-
-	set_bit(ATM_VF_ADDR, &vcc->flags);
-
-	cid = he_mkcid(he_dev, vpi, vci);
-
-	he_vcc = kmalloc_obj(struct he_vcc, GFP_ATOMIC);
-	if (he_vcc == NULL) {
-		hprintk("unable to allocate he_vcc during open\n");
-		return -ENOMEM;
-	}
-
-	INIT_LIST_HEAD(&he_vcc->buffers);
-	he_vcc->pdu_len = 0;
-	he_vcc->rc_index = -1;
-
-	init_waitqueue_head(&he_vcc->rx_waitq);
-	init_waitqueue_head(&he_vcc->tx_waitq);
-
-	vcc->dev_data = he_vcc;
-
-	if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-		int pcr_goal;
-
-		pcr_goal = atm_pcr_goal(&vcc->qos.txtp);
-		if (pcr_goal == 0)
-			pcr_goal = he_dev->atm_dev->link_rate;
-		if (pcr_goal < 0)	/* means round down, technically */
-			pcr_goal = -pcr_goal;
-
-		HPRINTK("open tx cid 0x%x pcr_goal %d\n", cid, pcr_goal);
-
-		switch (vcc->qos.aal) {
-			case ATM_AAL5:
-				tsr0_aal = TSR0_AAL5;
-				tsr4 = TSR4_AAL5;
-				break;
-			case ATM_AAL0:
-				tsr0_aal = TSR0_AAL0_SDU;
-				tsr4 = TSR4_AAL0_SDU;
-				break;
-			default:
-				err = -EINVAL;
-				goto open_failed;
-		}
-
-		spin_lock_irqsave(&he_dev->global_lock, flags);
-		tsr0 = he_readl_tsr0(he_dev, cid);
-		spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-		if (TSR0_CONN_STATE(tsr0) != 0) {
-			hprintk("cid 0x%x not idle (tsr0 = 0x%x)\n", cid, tsr0);
-			err = -EBUSY;
-			goto open_failed;
-		}
-
-		switch (vcc->qos.txtp.traffic_class) {
-			case ATM_UBR:
-				/* 2.3.3.1 open connection ubr */
-
-				tsr0 = TSR0_UBR | TSR0_GROUP(0) | tsr0_aal |
-					TSR0_USE_WMIN | TSR0_UPDATE_GER;
-				break;
-
-			case ATM_CBR:
-				/* 2.3.3.2 open connection cbr */
-
-				/* 8.2.3 cbr scheduler wrap problem -- limit to 90% total link rate */
-				if ((he_dev->total_bw + pcr_goal)
-					> (he_dev->atm_dev->link_rate * 9 / 10))
-				{
-					err = -EBUSY;
-					goto open_failed;
-				}
-
-				spin_lock_irqsave(&he_dev->global_lock, flags);			/* also protects he_dev->cs_stper[] */
-
-				/* find an unused cs_stper register */
-				for (reg = 0; reg < HE_NUM_CS_STPER; ++reg)
-					if (he_dev->cs_stper[reg].inuse == 0 || 
-					    he_dev->cs_stper[reg].pcr == pcr_goal)
-							break;
-
-				if (reg == HE_NUM_CS_STPER) {
-					err = -EBUSY;
-					spin_unlock_irqrestore(&he_dev->global_lock, flags);
-					goto open_failed;
-				}
-
-				he_dev->total_bw += pcr_goal;
-
-				he_vcc->rc_index = reg;
-				++he_dev->cs_stper[reg].inuse;
-				he_dev->cs_stper[reg].pcr = pcr_goal;
-
-				clock = he_is622(he_dev) ? 66667000 : 50000000;
-				period = clock / pcr_goal;
-				
-				HPRINTK("rc_index = %d period = %d\n",
-								reg, period);
-
-				he_writel_mbox(he_dev, rate_to_atmf(period/2),
-							CS_STPER0 + reg);
-				spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-				tsr0 = TSR0_CBR | TSR0_GROUP(0) | tsr0_aal |
-							TSR0_RC_INDEX(reg);
-
-				break;
-			default:
-				err = -EINVAL;
-				goto open_failed;
-		}
-
-		spin_lock_irqsave(&he_dev->global_lock, flags);
-
-		he_writel_tsr0(he_dev, tsr0, cid);
-		he_writel_tsr4(he_dev, tsr4 | 1, cid);
-		he_writel_tsr1(he_dev, TSR1_MCR(rate_to_atmf(0)) |
-					TSR1_PCR(rate_to_atmf(pcr_goal)), cid);
-		he_writel_tsr2(he_dev, TSR2_ACR(rate_to_atmf(pcr_goal)), cid);
-		he_writel_tsr9(he_dev, TSR9_OPEN_CONN, cid);
-
-		he_writel_tsr3(he_dev, 0x0, cid);
-		he_writel_tsr5(he_dev, 0x0, cid);
-		he_writel_tsr6(he_dev, 0x0, cid);
-		he_writel_tsr7(he_dev, 0x0, cid);
-		he_writel_tsr8(he_dev, 0x0, cid);
-		he_writel_tsr10(he_dev, 0x0, cid);
-		he_writel_tsr11(he_dev, 0x0, cid);
-		he_writel_tsr12(he_dev, 0x0, cid);
-		he_writel_tsr13(he_dev, 0x0, cid);
-		he_writel_tsr14(he_dev, 0x0, cid);
-		(void) he_readl_tsr0(he_dev, cid);		/* flush posted writes */
-		spin_unlock_irqrestore(&he_dev->global_lock, flags);
-	}
-
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
-		unsigned aal;
-
-		HPRINTK("open rx cid 0x%x (rx_waitq %p)\n", cid,
-		 				&HE_VCC(vcc)->rx_waitq);
-
-		switch (vcc->qos.aal) {
-			case ATM_AAL5:
-				aal = RSR0_AAL5;
-				break;
-			case ATM_AAL0:
-				aal = RSR0_RAWCELL;
-				break;
-			default:
-				err = -EINVAL;
-				goto open_failed;
-		}
-
-		spin_lock_irqsave(&he_dev->global_lock, flags);
-
-		rsr0 = he_readl_rsr0(he_dev, cid);
-		if (rsr0 & RSR0_OPEN_CONN) {
-			spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-			hprintk("cid 0x%x not idle (rsr0 = 0x%x)\n", cid, rsr0);
-			err = -EBUSY;
-			goto open_failed;
-		}
-
-		rsr1 = RSR1_GROUP(0) | RSR1_RBPL_ONLY;
-		rsr4 = RSR4_GROUP(0) | RSR4_RBPL_ONLY;
-		rsr0 = vcc->qos.rxtp.traffic_class == ATM_UBR ? 
-				(RSR0_EPD_ENABLE|RSR0_PPD_ENABLE) : 0;
-
-#ifdef USE_CHECKSUM_HW
-		if (vpi == 0 && vci >= ATM_NOT_RSV_VCI)
-			rsr0 |= RSR0_TCP_CKSUM;
-#endif
-
-		he_writel_rsr4(he_dev, rsr4, cid);
-		he_writel_rsr1(he_dev, rsr1, cid);
-		/* 5.1.11 last parameter initialized should be
-			  the open/closed indication in rsr0 */
-		he_writel_rsr0(he_dev,
-			rsr0 | RSR0_START_PDU | RSR0_OPEN_CONN | aal, cid);
-		(void) he_readl_rsr0(he_dev, cid);		/* flush posted writes */
-
-		spin_unlock_irqrestore(&he_dev->global_lock, flags);
-	}
-
-open_failed:
-
-	if (err) {
-		kfree(he_vcc);
-		clear_bit(ATM_VF_ADDR, &vcc->flags);
-	}
-	else
-		set_bit(ATM_VF_READY, &vcc->flags);
-
-	return err;
-}
-
-static void
-he_close(struct atm_vcc *vcc)
-{
-	unsigned long flags;
-	DECLARE_WAITQUEUE(wait, current);
-	struct he_dev *he_dev = HE_DEV(vcc->dev);
-	struct he_tpd *tpd;
-	unsigned cid;
-	struct he_vcc *he_vcc = HE_VCC(vcc);
-#define MAX_RETRY 30
-	int retry = 0, sleep = 1, tx_inuse;
-
-	HPRINTK("close vcc %p %d.%d\n", vcc, vcc->vpi, vcc->vci);
-
-	clear_bit(ATM_VF_READY, &vcc->flags);
-	cid = he_mkcid(he_dev, vcc->vpi, vcc->vci);
-
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
-		int timeout;
-
-		HPRINTK("close rx cid 0x%x\n", cid);
-
-		/* 2.7.2.2 close receive operation */
-
-		/* wait for previous close (if any) to finish */
-
-		spin_lock_irqsave(&he_dev->global_lock, flags);
-		while (he_readl(he_dev, RCC_STAT) & RCC_BUSY) {
-			HPRINTK("close cid 0x%x RCC_BUSY\n", cid);
-			udelay(250);
-		}
-
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		add_wait_queue(&he_vcc->rx_waitq, &wait);
-
-		he_writel_rsr0(he_dev, RSR0_CLOSE_CONN, cid);
-		(void) he_readl_rsr0(he_dev, cid);		/* flush posted writes */
-		he_writel_mbox(he_dev, cid, RXCON_CLOSE);
-		spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-		timeout = schedule_timeout(30*HZ);
-
-		remove_wait_queue(&he_vcc->rx_waitq, &wait);
-		set_current_state(TASK_RUNNING);
-
-		if (timeout == 0)
-			hprintk("close rx timeout cid 0x%x\n", cid);
-
-		HPRINTK("close rx cid 0x%x complete\n", cid);
-
-	}
-
-	if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-		volatile unsigned tsr4, tsr0;
-		int timeout;
-
-		HPRINTK("close tx cid 0x%x\n", cid);
-		
-		/* 2.1.2
-		 *
-		 * ... the host must first stop queueing packets to the TPDRQ
-		 * on the connection to be closed, then wait for all outstanding
-		 * packets to be transmitted and their buffers returned to the
-		 * TBRQ. When the last packet on the connection arrives in the
-		 * TBRQ, the host issues the close command to the adapter.
-		 */
-
-		while (((tx_inuse = refcount_read(&sk_atm(vcc)->sk_wmem_alloc)) > 1) &&
-		       (retry < MAX_RETRY)) {
-			msleep(sleep);
-			if (sleep < 250)
-				sleep = sleep * 2;
-
-			++retry;
-		}
-
-		if (tx_inuse > 1)
-			hprintk("close tx cid 0x%x tx_inuse = %d\n", cid, tx_inuse);
-
-		/* 2.3.1.1 generic close operations with flush */
-
-		spin_lock_irqsave(&he_dev->global_lock, flags);
-		he_writel_tsr4_upper(he_dev, TSR4_FLUSH_CONN, cid);
-					/* also clears TSR4_SESSION_ENDED */
-
-		switch (vcc->qos.txtp.traffic_class) {
-			case ATM_UBR:
-				he_writel_tsr1(he_dev, 
-					TSR1_MCR(rate_to_atmf(200000))
-					| TSR1_PCR(0), cid);
-				break;
-			case ATM_CBR:
-				he_writel_tsr14_upper(he_dev, TSR14_DELETE, cid);
-				break;
-		}
-		(void) he_readl_tsr4(he_dev, cid);		/* flush posted writes */
-
-		tpd = __alloc_tpd(he_dev);
-		if (tpd == NULL) {
-			hprintk("close tx he_alloc_tpd failed cid 0x%x\n", cid);
-			goto close_tx_incomplete;
-		}
-		tpd->status |= TPD_EOS | TPD_INT;
-		tpd->skb = NULL;
-		tpd->vcc = vcc;
-		wmb();
-
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		add_wait_queue(&he_vcc->tx_waitq, &wait);
-		__enqueue_tpd(he_dev, tpd, cid);
-		spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-		timeout = schedule_timeout(30*HZ);
-
-		remove_wait_queue(&he_vcc->tx_waitq, &wait);
-		set_current_state(TASK_RUNNING);
-
-		spin_lock_irqsave(&he_dev->global_lock, flags);
-
-		if (timeout == 0) {
-			hprintk("close tx timeout cid 0x%x\n", cid);
-			goto close_tx_incomplete;
-		}
-
-		while (!((tsr4 = he_readl_tsr4(he_dev, cid)) & TSR4_SESSION_ENDED)) {
-			HPRINTK("close tx cid 0x%x !TSR4_SESSION_ENDED (tsr4 = 0x%x)\n", cid, tsr4);
-			udelay(250);
-		}
-
-		while (TSR0_CONN_STATE(tsr0 = he_readl_tsr0(he_dev, cid)) != 0) {
-			HPRINTK("close tx cid 0x%x TSR0_CONN_STATE != 0 (tsr0 = 0x%x)\n", cid, tsr0);
-			udelay(250);
-		}
-
-close_tx_incomplete:
-
-		if (vcc->qos.txtp.traffic_class == ATM_CBR) {
-			int reg = he_vcc->rc_index;
-
-			HPRINTK("cs_stper reg = %d\n", reg);
-
-			if (he_dev->cs_stper[reg].inuse == 0)
-				hprintk("cs_stper[%d].inuse = 0!\n", reg);
-			else
-				--he_dev->cs_stper[reg].inuse;
-
-			he_dev->total_bw -= he_dev->cs_stper[reg].pcr;
-		}
-		spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-		HPRINTK("close tx cid 0x%x complete\n", cid);
-	}
-
-	kfree(he_vcc);
-
-	clear_bit(ATM_VF_ADDR, &vcc->flags);
-}
-
-static int
-he_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	unsigned long flags;
-	struct he_dev *he_dev = HE_DEV(vcc->dev);
-	unsigned cid = he_mkcid(he_dev, vcc->vpi, vcc->vci);
-	struct he_tpd *tpd;
-#ifdef USE_SCATTERGATHER
-	int i, slot = 0;
-#endif
-
-#define HE_TPD_BUFSIZE 0xffff
-
-	HPRINTK("send %d.%d\n", vcc->vpi, vcc->vci);
-
-	if ((skb->len > HE_TPD_BUFSIZE) ||
-	    ((vcc->qos.aal == ATM_AAL0) && (skb->len != ATM_AAL0_SDU))) {
-		hprintk("buffer too large (or small) -- %d bytes\n", skb->len );
-		if (vcc->pop)
-			vcc->pop(vcc, skb);
-		else
-			dev_kfree_skb_any(skb);
-		atomic_inc(&vcc->stats->tx_err);
-		return -EINVAL;
-	}
-
-#ifndef USE_SCATTERGATHER
-	if (skb_shinfo(skb)->nr_frags) {
-		hprintk("no scatter/gather support\n");
-		if (vcc->pop)
-			vcc->pop(vcc, skb);
-		else
-			dev_kfree_skb_any(skb);
-		atomic_inc(&vcc->stats->tx_err);
-		return -EINVAL;
-	}
-#endif
-	spin_lock_irqsave(&he_dev->global_lock, flags);
-
-	tpd = __alloc_tpd(he_dev);
-	if (tpd == NULL) {
-		if (vcc->pop)
-			vcc->pop(vcc, skb);
-		else
-			dev_kfree_skb_any(skb);
-		atomic_inc(&vcc->stats->tx_err);
-		spin_unlock_irqrestore(&he_dev->global_lock, flags);
-		return -ENOMEM;
-	}
-
-	if (vcc->qos.aal == ATM_AAL5)
-		tpd->status |= TPD_CELLTYPE(TPD_USERCELL);
-	else {
-		char *pti_clp = (void *) (skb->data + 3);
-		int clp, pti;
-
-		pti = (*pti_clp & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT; 
-		clp = (*pti_clp & ATM_HDR_CLP);
-		tpd->status |= TPD_CELLTYPE(pti);
-		if (clp)
-			tpd->status |= TPD_CLP;
-
-		skb_pull(skb, ATM_AAL0_SDU - ATM_CELL_PAYLOAD);
-	}
-
-#ifdef USE_SCATTERGATHER
-	tpd->iovec[slot].addr = dma_map_single(&he_dev->pci_dev->dev, skb->data,
-				skb_headlen(skb), DMA_TO_DEVICE);
-	tpd->iovec[slot].len = skb_headlen(skb);
-	++slot;
-
-	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-
-		if (slot == TPD_MAXIOV) {	/* queue tpd; start new tpd */
-			tpd->vcc = vcc;
-			tpd->skb = NULL;	/* not the last fragment
-						   so dont ->push() yet */
-			wmb();
-
-			__enqueue_tpd(he_dev, tpd, cid);
-			tpd = __alloc_tpd(he_dev);
-			if (tpd == NULL) {
-				if (vcc->pop)
-					vcc->pop(vcc, skb);
-				else
-					dev_kfree_skb_any(skb);
-				atomic_inc(&vcc->stats->tx_err);
-				spin_unlock_irqrestore(&he_dev->global_lock, flags);
-				return -ENOMEM;
-			}
-			tpd->status |= TPD_USERCELL;
-			slot = 0;
-		}
-
-		tpd->iovec[slot].addr = skb_frag_dma_map(&he_dev->pci_dev->dev,
-				frag, 0, skb_frag_size(frag), DMA_TO_DEVICE);
-		tpd->iovec[slot].len = skb_frag_size(frag);
-		++slot;
-
-	}
-
-	tpd->iovec[slot - 1].len |= TPD_LST;
-#else
-	tpd->address0 = dma_map_single(&he_dev->pci_dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
-	tpd->length0 = skb->len | TPD_LST;
-#endif
-	tpd->status |= TPD_INT;
-
-	tpd->vcc = vcc;
-	tpd->skb = skb;
-	wmb();
-	ATM_SKB(skb)->vcc = vcc;
-
-	__enqueue_tpd(he_dev, tpd, cid);
-	spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-	atomic_inc(&vcc->stats->tx);
-
-	return 0;
-}
-
-static int
-he_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void __user *arg)
-{
-	unsigned long flags;
-	struct he_dev *he_dev = HE_DEV(atm_dev);
-	struct he_ioctl_reg reg;
-	int err = 0;
-
-	switch (cmd) {
-		case HE_GET_REG:
-			if (!capable(CAP_NET_ADMIN))
-				return -EPERM;
-
-			if (copy_from_user(&reg, arg,
-					   sizeof(struct he_ioctl_reg)))
-				return -EFAULT;
-
-			spin_lock_irqsave(&he_dev->global_lock, flags);
-			switch (reg.type) {
-				case HE_REGTYPE_PCI:
-					if (reg.addr >= HE_REGMAP_SIZE) {
-						err = -EINVAL;
-						break;
-					}
-
-					reg.val = he_readl(he_dev, reg.addr);
-					break;
-				case HE_REGTYPE_RCM:
-					reg.val =
-						he_readl_rcm(he_dev, reg.addr);
-					break;
-				case HE_REGTYPE_TCM:
-					reg.val =
-						he_readl_tcm(he_dev, reg.addr);
-					break;
-				case HE_REGTYPE_MBOX:
-					reg.val =
-						he_readl_mbox(he_dev, reg.addr);
-					break;
-				default:
-					err = -EINVAL;
-					break;
-			}
-			spin_unlock_irqrestore(&he_dev->global_lock, flags);
-			if (err == 0)
-				if (copy_to_user(arg, &reg,
-							sizeof(struct he_ioctl_reg)))
-					return -EFAULT;
-			break;
-		default:
-#ifdef CONFIG_ATM_HE_USE_SUNI
-			if (atm_dev->phy && atm_dev->phy->ioctl)
-				err = atm_dev->phy->ioctl(atm_dev, cmd, arg);
-#else /* CONFIG_ATM_HE_USE_SUNI */
-			err = -EINVAL;
-#endif /* CONFIG_ATM_HE_USE_SUNI */
-			break;
-	}
-
-	return err;
-}
-
-static void
-he_phy_put(struct atm_dev *atm_dev, unsigned char val, unsigned long addr)
-{
-	unsigned long flags;
-	struct he_dev *he_dev = HE_DEV(atm_dev);
-
-	HPRINTK("phy_put(val 0x%x, addr 0x%lx)\n", val, addr);
-
-	spin_lock_irqsave(&he_dev->global_lock, flags);
-	he_writel(he_dev, val, FRAMER + (addr*4));
-	(void) he_readl(he_dev, FRAMER + (addr*4));		/* flush posted writes */
-	spin_unlock_irqrestore(&he_dev->global_lock, flags);
-}
- 
-	
-static unsigned char
-he_phy_get(struct atm_dev *atm_dev, unsigned long addr)
-{ 
-	unsigned long flags;
-	struct he_dev *he_dev = HE_DEV(atm_dev);
-	unsigned reg;
-
-	spin_lock_irqsave(&he_dev->global_lock, flags);
-	reg = he_readl(he_dev, FRAMER + (addr*4));
-	spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-	HPRINTK("phy_get(addr 0x%lx) =0x%x\n", addr, reg);
-	return reg;
-}
-
-static int
-he_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
-{
-	unsigned long flags;
-	struct he_dev *he_dev = HE_DEV(dev);
-	int left, i;
-#ifdef notdef
-	struct he_rbrq *rbrq_tail;
-	struct he_tpdrq *tpdrq_head;
-	int rbpl_head, rbpl_tail;
-#endif
-	static long mcc = 0, oec = 0, dcc = 0, cec = 0;
-
-
-	left = *pos;
-	if (!left--)
-		return sprintf(page, "ATM he driver\n");
-
-	if (!left--)
-		return sprintf(page, "%s%s\n\n",
-			he_dev->prod_id, he_dev->media & 0x40 ? "SM" : "MM");
-
-	if (!left--)
-		return sprintf(page, "Mismatched Cells  VPI/VCI Not Open  Dropped Cells  RCM Dropped Cells\n");
-
-	spin_lock_irqsave(&he_dev->global_lock, flags);
-	mcc += he_readl(he_dev, MCC);
-	oec += he_readl(he_dev, OEC);
-	dcc += he_readl(he_dev, DCC);
-	cec += he_readl(he_dev, CEC);
-	spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-	if (!left--)
-		return sprintf(page, "%16ld  %16ld  %13ld  %17ld\n\n", 
-							mcc, oec, dcc, cec);
-
-	if (!left--)
-		return sprintf(page, "irq_size = %d  inuse = ?  peak = %d\n",
-				CONFIG_IRQ_SIZE, he_dev->irq_peak);
-
-	if (!left--)
-		return sprintf(page, "tpdrq_size = %d  inuse = ?\n",
-						CONFIG_TPDRQ_SIZE);
-
-	if (!left--)
-		return sprintf(page, "rbrq_size = %d  inuse = ?  peak = %d\n",
-				CONFIG_RBRQ_SIZE, he_dev->rbrq_peak);
-
-	if (!left--)
-		return sprintf(page, "tbrq_size = %d  peak = %d\n",
-					CONFIG_TBRQ_SIZE, he_dev->tbrq_peak);
-
-
-#ifdef notdef
-	rbpl_head = RBPL_MASK(he_readl(he_dev, G0_RBPL_S));
-	rbpl_tail = RBPL_MASK(he_readl(he_dev, G0_RBPL_T));
-
-	inuse = rbpl_head - rbpl_tail;
-	if (inuse < 0)
-		inuse += CONFIG_RBPL_SIZE * sizeof(struct he_rbp);
-	inuse /= sizeof(struct he_rbp);
-
-	if (!left--)
-		return sprintf(page, "rbpl_size = %d  inuse = %d\n\n",
-						CONFIG_RBPL_SIZE, inuse);
-#endif
-
-	if (!left--)
-		return sprintf(page, "rate controller periods (cbr)\n                 pcr  #vc\n");
-
-	for (i = 0; i < HE_NUM_CS_STPER; ++i)
-		if (!left--)
-			return sprintf(page, "cs_stper%-2d  %8ld  %3d\n", i,
-						he_dev->cs_stper[i].pcr,
-						he_dev->cs_stper[i].inuse);
-
-	if (!left--)
-		return sprintf(page, "total bw (cbr): %d  (limit %d)\n",
-			he_dev->total_bw, he_dev->atm_dev->link_rate * 10 / 9);
-
-	return 0;
-}
-
-/* eeprom routines  -- see 4.7 */
-
-static u8 read_prom_byte(struct he_dev *he_dev, int addr)
-{
-	u32 val = 0, tmp_read = 0;
-	int i, j = 0;
-	u8 byte_read = 0;
-
-	val = readl(he_dev->membase + HOST_CNTL);
-	val &= 0xFFFFE0FF;
-       
-	/* Turn on write enable */
-	val |= 0x800;
-	he_writel(he_dev, val, HOST_CNTL);
-       
-	/* Send READ instruction */
-	for (i = 0; i < ARRAY_SIZE(readtab); i++) {
-		he_writel(he_dev, val | readtab[i], HOST_CNTL);
-		udelay(EEPROM_DELAY);
-	}
-       
-	/* Next, we need to send the byte address to read from */
-	for (i = 7; i >= 0; i--) {
-		he_writel(he_dev, val | clocktab[j++] | (((addr >> i) & 1) << 9), HOST_CNTL);
-		udelay(EEPROM_DELAY);
-		he_writel(he_dev, val | clocktab[j++] | (((addr >> i) & 1) << 9), HOST_CNTL);
-		udelay(EEPROM_DELAY);
-	}
-       
-	j = 0;
-
-	val &= 0xFFFFF7FF;      /* Turn off write enable */
-	he_writel(he_dev, val, HOST_CNTL);
-       
-	/* Now, we can read data from the EEPROM by clocking it in */
-	for (i = 7; i >= 0; i--) {
-		he_writel(he_dev, val | clocktab[j++], HOST_CNTL);
-		udelay(EEPROM_DELAY);
-		tmp_read = he_readl(he_dev, HOST_CNTL);
-		byte_read |= (unsigned char)
-			   ((tmp_read & ID_DOUT) >> ID_DOFFSET << i);
-		he_writel(he_dev, val | clocktab[j++], HOST_CNTL);
-		udelay(EEPROM_DELAY);
-	}
-       
-	he_writel(he_dev, val | ID_CS, HOST_CNTL);
-	udelay(EEPROM_DELAY);
-
-	return byte_read;
-}
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("chas williams <chas@cmf.nrl.navy.mil>");
-MODULE_DESCRIPTION("ForeRunnerHE ATM Adapter driver");
-module_param(disable64, bool, 0);
-MODULE_PARM_DESC(disable64, "disable 64-bit pci bus transfers");
-module_param(nvpibits, short, 0);
-MODULE_PARM_DESC(nvpibits, "numbers of bits for vpi (default 0)");
-module_param(nvcibits, short, 0);
-MODULE_PARM_DESC(nvcibits, "numbers of bits for vci (default 12)");
-module_param(rx_skb_reserve, short, 0);
-MODULE_PARM_DESC(rx_skb_reserve, "padding for receive skb (default 16)");
-module_param(irq_coalesce, bool, 0);
-MODULE_PARM_DESC(irq_coalesce, "use interrupt coalescing (default 1)");
-module_param(sdh, bool, 0);
-MODULE_PARM_DESC(sdh, "use SDH framing (default 0)");
-
-static const struct pci_device_id he_pci_tbl[] = {
-	{ PCI_VDEVICE(FORE, PCI_DEVICE_ID_FORE_HE), 0 },
-	{ 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, he_pci_tbl);
-
-static struct pci_driver he_driver = {
-	.name =		"he",
-	.probe =	he_init_one,
-	.remove =	he_remove_one,
-	.id_table =	he_pci_tbl,
-};
-
-module_pci_driver(he_driver);
diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c
deleted file mode 100644
index 4bbcca7f77c8..000000000000
--- a/drivers/atm/idt77105.c
+++ /dev/null
@@ -1,376 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* drivers/atm/idt77105.c - IDT77105 (PHY) driver */
- 
-/* Written 1999 by Greg Banks, NEC Australia <gnb@linuxfan.com>. Based on suni.c */
-
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/atmdev.h>
-#include <linux/sonet.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/capability.h>
-#include <linux/atm_idt77105.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <asm/param.h>
-#include <linux/uaccess.h>
-
-#include "idt77105.h"
-
-#undef GENERAL_DEBUG
-
-#ifdef GENERAL_DEBUG
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
-
-struct idt77105_priv {
-	struct idt77105_stats stats;    /* link diagnostics */
-	struct atm_dev *dev;		/* device back-pointer */
-	struct idt77105_priv *next;
-        int loop_mode;
-        unsigned char old_mcr;          /* storage of MCR reg while signal lost */
-};
-
-static DEFINE_SPINLOCK(idt77105_priv_lock);
-
-#define PRIV(dev) ((struct idt77105_priv *) dev->phy_data)
-
-#define PUT(val,reg) dev->ops->phy_put(dev,val,IDT77105_##reg)
-#define GET(reg) dev->ops->phy_get(dev,IDT77105_##reg)
-
-static void idt77105_stats_timer_func(struct timer_list *);
-static void idt77105_restart_timer_func(struct timer_list *);
-
-
-static DEFINE_TIMER(stats_timer, idt77105_stats_timer_func);
-static DEFINE_TIMER(restart_timer, idt77105_restart_timer_func);
-static int start_timer = 1;
-static struct idt77105_priv *idt77105_all = NULL;
-
-/*
- * Retrieve the value of one of the IDT77105's counters.
- * `counter' is one of the IDT77105_CTRSEL_* constants.
- */
-static u16 get_counter(struct atm_dev *dev, int counter)
-{
-        u16 val;
-        
-        /* write the counter bit into PHY register 6 */
-        PUT(counter, CTRSEL);
-        /* read the low 8 bits from register 4 */
-        val = GET(CTRLO);
-        /* read the high 8 bits from register 5 */
-        val |= GET(CTRHI)<<8;
-        
-        return val;
-}
-
-/*
- * Timer function called every second to gather statistics
- * from the 77105. This is done because the h/w registers
- * will overflow if not read at least once per second. The
- * kernel's stats are much higher precision. Also, having
- * a separate copy of the stats allows implementation of
- * an ioctl which gathers the stats *without* zero'ing them.
- */
-static void idt77105_stats_timer_func(struct timer_list *unused)
-{
-	struct idt77105_priv *walk;
-	struct atm_dev *dev;
-	struct idt77105_stats *stats;
-
-        DPRINTK("IDT77105 gathering statistics\n");
-	for (walk = idt77105_all; walk; walk = walk->next) {
-		dev = walk->dev;
-                
-		stats = &walk->stats;
-                stats->symbol_errors += get_counter(dev, IDT77105_CTRSEL_SEC);
-                stats->tx_cells += get_counter(dev, IDT77105_CTRSEL_TCC);
-                stats->rx_cells += get_counter(dev, IDT77105_CTRSEL_RCC);
-                stats->rx_hec_errors += get_counter(dev, IDT77105_CTRSEL_RHEC);
-	}
-        if (!start_timer) mod_timer(&stats_timer,jiffies+IDT77105_STATS_TIMER_PERIOD);
-}
-
-
-/*
- * A separate timer func which handles restarting PHY chips which
- * have had the cable re-inserted after being pulled out. This is
- * done by polling the Good Signal Bit in the Interrupt Status
- * register every 5 seconds. The other technique (checking Good
- * Signal Bit in the interrupt handler) cannot be used because PHY
- * interrupts need to be disabled when the cable is pulled out
- * to avoid lots of spurious cell error interrupts.
- */
-static void idt77105_restart_timer_func(struct timer_list *unused)
-{
-	struct idt77105_priv *walk;
-	struct atm_dev *dev;
-        unsigned char istat;
-
-        DPRINTK("IDT77105 checking for cable re-insertion\n");
-	for (walk = idt77105_all; walk; walk = walk->next) {
-		dev = walk->dev;
-                
-                if (dev->signal != ATM_PHY_SIG_LOST)
-                    continue;
-                    
-                istat = GET(ISTAT); /* side effect: clears all interrupt status bits */
-                if (istat & IDT77105_ISTAT_GOODSIG) {
-                    /* Found signal again */
-                    atm_dev_signal_change(dev, ATM_PHY_SIG_FOUND);
-	            printk(KERN_NOTICE "%s(itf %d): signal detected again\n",
-                        dev->type,dev->number);
-                    /* flush the receive FIFO */
-                    PUT( GET(DIAG) | IDT77105_DIAG_RFLUSH, DIAG);
-                    /* re-enable interrupts */
-	            PUT( walk->old_mcr ,MCR);
-                }
-	}
-        if (!start_timer) mod_timer(&restart_timer,jiffies+IDT77105_RESTART_TIMER_PERIOD);
-}
-
-
-static int fetch_stats(struct atm_dev *dev,struct idt77105_stats __user *arg,int zero)
-{
-	unsigned long flags;
-	struct idt77105_stats stats;
-
-	spin_lock_irqsave(&idt77105_priv_lock, flags);
-	memcpy(&stats, &PRIV(dev)->stats, sizeof(struct idt77105_stats));
-	if (zero)
-		memset(&PRIV(dev)->stats, 0, sizeof(struct idt77105_stats));
-	spin_unlock_irqrestore(&idt77105_priv_lock, flags);
-	if (arg == NULL)
-		return 0;
-	return copy_to_user(arg, &stats,
-		    sizeof(struct idt77105_stats)) ? -EFAULT : 0;
-}
-
-
-static int set_loopback(struct atm_dev *dev,int mode)
-{
-	int diag;
-
-	diag = GET(DIAG) & ~IDT77105_DIAG_LCMASK;
-	switch (mode) {
-		case ATM_LM_NONE:
-			break;
-		case ATM_LM_LOC_ATM:
-			diag |= IDT77105_DIAG_LC_PHY_LOOPBACK;
-			break;
-		case ATM_LM_RMT_ATM:
-			diag |= IDT77105_DIAG_LC_LINE_LOOPBACK;
-			break;
-		default:
-			return -EINVAL;
-	}
-	PUT(diag,DIAG);
-	printk(KERN_NOTICE "%s(%d) Loopback mode is: %s\n", dev->type,
-	    dev->number,
-	    (mode == ATM_LM_NONE ? "NONE" : 
-	      (mode == ATM_LM_LOC_ATM ? "DIAG (local)" :
-		(mode == IDT77105_DIAG_LC_LINE_LOOPBACK ? "LOOP (remote)" :
-		  "unknown")))
-		    );
-	PRIV(dev)->loop_mode = mode;
-	return 0;
-}
-
-
-static int idt77105_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
-{
-        printk(KERN_NOTICE "%s(%d) idt77105_ioctl() called\n",dev->type,dev->number);
-	switch (cmd) {
-		case IDT77105_GETSTATZ:
-			if (!capable(CAP_NET_ADMIN)) return -EPERM;
-			fallthrough;
-		case IDT77105_GETSTAT:
-			return fetch_stats(dev, arg, cmd == IDT77105_GETSTATZ);
-		case ATM_SETLOOP:
-			return set_loopback(dev,(int)(unsigned long) arg);
-		case ATM_GETLOOP:
-			return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ?
-			    -EFAULT : 0;
-		case ATM_QUERYLOOP:
-			return put_user(ATM_LM_LOC_ATM | ATM_LM_RMT_ATM,
-			    (int __user *) arg) ? -EFAULT : 0;
-		default:
-			return -ENOIOCTLCMD;
-	}
-}
-
-
-
-static void idt77105_int(struct atm_dev *dev)
-{
-        unsigned char istat;
-        
-        istat = GET(ISTAT); /* side effect: clears all interrupt status bits */
-     
-        DPRINTK("IDT77105 generated an interrupt, istat=%02x\n", (unsigned)istat);
-                
-        if (istat & IDT77105_ISTAT_RSCC) {
-            /* Rx Signal Condition Change - line went up or down */
-            if (istat & IDT77105_ISTAT_GOODSIG) {   /* signal detected again */
-                /* This should not happen (restart timer does it) but JIC */
-		atm_dev_signal_change(dev, ATM_PHY_SIG_FOUND);
-            } else {    /* signal lost */
-                /*
-                 * Disable interrupts and stop all transmission and
-                 * reception - the restart timer will restore these.
-                 */
-                PRIV(dev)->old_mcr = GET(MCR);
-	        PUT(
-                    (PRIV(dev)->old_mcr|
-                    IDT77105_MCR_DREC|
-                    IDT77105_MCR_DRIC|
-                    IDT77105_MCR_HALTTX
-                    ) & ~IDT77105_MCR_EIP, MCR);
-		atm_dev_signal_change(dev, ATM_PHY_SIG_LOST);
-	        printk(KERN_NOTICE "%s(itf %d): signal lost\n",
-                    dev->type,dev->number);
-            }
-        }
-        
-        if (istat & IDT77105_ISTAT_RFO) {
-            /* Rx FIFO Overrun -- perform a FIFO flush */
-            PUT( GET(DIAG) | IDT77105_DIAG_RFLUSH, DIAG);
-	    printk(KERN_NOTICE "%s(itf %d): receive FIFO overrun\n",
-                dev->type,dev->number);
-        }
-#ifdef GENERAL_DEBUG
-        if (istat & (IDT77105_ISTAT_HECERR | IDT77105_ISTAT_SCR |
-                     IDT77105_ISTAT_RSE)) {
-            /* normally don't care - just report in stats */
-	    printk(KERN_NOTICE "%s(itf %d): received cell with error\n",
-                dev->type,dev->number);
-        }
-#endif
-}
-
-
-static int idt77105_start(struct atm_dev *dev)
-{
-	unsigned long flags;
-
-	if (!(dev->phy_data = kmalloc_obj(struct idt77105_priv)))
-		return -ENOMEM;
-	PRIV(dev)->dev = dev;
-	spin_lock_irqsave(&idt77105_priv_lock, flags);
-	PRIV(dev)->next = idt77105_all;
-	idt77105_all = PRIV(dev);
-	spin_unlock_irqrestore(&idt77105_priv_lock, flags);
-	memset(&PRIV(dev)->stats,0,sizeof(struct idt77105_stats));
-        
-        /* initialise dev->signal from Good Signal Bit */
-	atm_dev_signal_change(dev,
-		GET(ISTAT) & IDT77105_ISTAT_GOODSIG ?
-		ATM_PHY_SIG_FOUND : ATM_PHY_SIG_LOST);
-	if (dev->signal == ATM_PHY_SIG_LOST)
-		printk(KERN_WARNING "%s(itf %d): no signal\n",dev->type,
-		    dev->number);
-
-        /* initialise loop mode from hardware */
-        switch ( GET(DIAG) & IDT77105_DIAG_LCMASK ) {
-        case IDT77105_DIAG_LC_NORMAL:
-            PRIV(dev)->loop_mode = ATM_LM_NONE;
-            break;
-        case IDT77105_DIAG_LC_PHY_LOOPBACK:
-            PRIV(dev)->loop_mode = ATM_LM_LOC_ATM;
-            break;
-        case IDT77105_DIAG_LC_LINE_LOOPBACK:
-            PRIV(dev)->loop_mode = ATM_LM_RMT_ATM;
-            break;
-        }
-        
-        /* enable interrupts, e.g. on loss of signal */
-        PRIV(dev)->old_mcr = GET(MCR);
-        if (dev->signal == ATM_PHY_SIG_FOUND) {
-            PRIV(dev)->old_mcr |= IDT77105_MCR_EIP;
-	    PUT(PRIV(dev)->old_mcr, MCR);
-        }
-
-                    
-	idt77105_stats_timer_func(0); /* clear 77105 counters */
-	(void) fetch_stats(dev,NULL,1); /* clear kernel counters */
-        
-	spin_lock_irqsave(&idt77105_priv_lock, flags);
-	if (start_timer) {
-		start_timer = 0;
-                
-		stats_timer.expires = jiffies+IDT77105_STATS_TIMER_PERIOD;
-		add_timer(&stats_timer);
-                
-		restart_timer.expires = jiffies+IDT77105_RESTART_TIMER_PERIOD;
-		add_timer(&restart_timer);
-	}
-	spin_unlock_irqrestore(&idt77105_priv_lock, flags);
-	return 0;
-}
-
-
-static int idt77105_stop(struct atm_dev *dev)
-{
-	struct idt77105_priv *walk, *prev;
-
-        DPRINTK("%s(itf %d): stopping IDT77105\n",dev->type,dev->number);
-        
-        /* disable interrupts */
-	PUT( GET(MCR) & ~IDT77105_MCR_EIP, MCR );
-        
-        /* detach private struct from atm_dev & free */
-	for (prev = NULL, walk = idt77105_all ;
-             walk != NULL;
-             prev = walk, walk = walk->next) {
-            if (walk->dev == dev) {
-                if (prev != NULL)
-                    prev->next = walk->next;
-                else
-                    idt77105_all = walk->next;
-	        dev->phy = NULL;
-                dev->phy_data = NULL;
-                kfree(walk);
-                break;
-            }
-        }
-
-	return 0;
-}
-
-
-static const struct atmphy_ops idt77105_ops = {
-	.start = 	idt77105_start,
-	.ioctl =	idt77105_ioctl,
-	.interrupt =	idt77105_int,
-	.stop =		idt77105_stop,
-};
-
-
-int idt77105_init(struct atm_dev *dev)
-{
-	dev->phy = &idt77105_ops;
-	return 0;
-}
-
-EXPORT_SYMBOL(idt77105_init);
-
-static void __exit idt77105_exit(void)
-{
-	/* turn off timers */
-	timer_delete_sync(&stats_timer);
-	timer_delete_sync(&restart_timer);
-}
-
-module_exit(idt77105_exit);
-
-MODULE_DESCRIPTION("IDT77105 PHY driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
deleted file mode 100644
index 7f8aaf5e6e43..000000000000
--- a/drivers/atm/idt77252.c
+++ /dev/null
@@ -1,3797 +0,0 @@
-/******************************************************************* 
- *
- * Copyright (c) 2000 ATecoM GmbH 
- *
- * The author may be reached at ecd@atecom.com.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *******************************************************************/
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/poison.h>
-#include <linux/skbuff.h>
-#include <linux/kernel.h>
-#include <linux/vmalloc.h>
-#include <linux/netdevice.h>
-#include <linux/atmdev.h>
-#include <linux/atm.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <linux/wait.h>
-#include <linux/jiffies.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-
-#include <asm/io.h>
-#include <linux/uaccess.h>
-#include <linux/atomic.h>
-#include <asm/byteorder.h>
-
-#ifdef CONFIG_ATM_IDT77252_USE_SUNI
-#include "suni.h"
-#endif /* CONFIG_ATM_IDT77252_USE_SUNI */
-
-
-#include "idt77252.h"
-#include "idt77252_tables.h"
-
-static unsigned int vpibits = 1;
-
-
-#define ATM_IDT77252_SEND_IDLE 1
-
-
-/*
- * Debug HACKs.
- */
-#define DEBUG_MODULE 1
-#undef HAVE_EEPROM	/* does not work, yet. */
-
-#ifdef CONFIG_ATM_IDT77252_DEBUG
-static unsigned long debug = DBG_GENERAL;
-#endif
-
-
-#define SAR_RX_DELAY	(SAR_CFG_RXINT_NODELAY)
-
-
-/*
- * SCQ Handling.
- */
-static struct scq_info *alloc_scq(struct idt77252_dev *, int);
-static void free_scq(struct idt77252_dev *, struct scq_info *);
-static int queue_skb(struct idt77252_dev *, struct vc_map *,
-		     struct sk_buff *, int oam);
-static void drain_scq(struct idt77252_dev *, struct vc_map *);
-static unsigned long get_free_scd(struct idt77252_dev *, struct vc_map *);
-static void fill_scd(struct idt77252_dev *, struct scq_info *, int);
-
-/*
- * FBQ Handling.
- */
-static int push_rx_skb(struct idt77252_dev *,
-		       struct sk_buff *, int queue);
-static void recycle_rx_skb(struct idt77252_dev *, struct sk_buff *);
-static void flush_rx_pool(struct idt77252_dev *, struct rx_pool *);
-static void recycle_rx_pool_skb(struct idt77252_dev *,
-				struct rx_pool *);
-static void add_rx_skb(struct idt77252_dev *, int queue,
-		       unsigned int size, unsigned int count);
-
-/*
- * RSQ Handling.
- */
-static int init_rsq(struct idt77252_dev *);
-static void deinit_rsq(struct idt77252_dev *);
-static void idt77252_rx(struct idt77252_dev *);
-
-/*
- * TSQ handling.
- */
-static int init_tsq(struct idt77252_dev *);
-static void deinit_tsq(struct idt77252_dev *);
-static void idt77252_tx(struct idt77252_dev *);
-
-
-/*
- * ATM Interface.
- */
-static void idt77252_dev_close(struct atm_dev *dev);
-static int idt77252_open(struct atm_vcc *vcc);
-static void idt77252_close(struct atm_vcc *vcc);
-static int idt77252_send(struct atm_vcc *vcc, struct sk_buff *skb);
-static int idt77252_send_oam(struct atm_vcc *vcc, void *cell,
-			     int flags);
-static void idt77252_phy_put(struct atm_dev *dev, unsigned char value,
-			     unsigned long addr);
-static unsigned char idt77252_phy_get(struct atm_dev *dev, unsigned long addr);
-static int idt77252_change_qos(struct atm_vcc *vcc, struct atm_qos *qos,
-			       int flags);
-static int idt77252_proc_read(struct atm_dev *dev, loff_t * pos,
-			      char *page);
-static void idt77252_softint(struct work_struct *work);
-
-
-static const struct atmdev_ops idt77252_ops =
-{
-	.dev_close	= idt77252_dev_close,
-	.open		= idt77252_open,
-	.close		= idt77252_close,
-	.send		= idt77252_send,
-	.send_oam	= idt77252_send_oam,
-	.phy_put	= idt77252_phy_put,
-	.phy_get	= idt77252_phy_get,
-	.change_qos	= idt77252_change_qos,
-	.proc_read	= idt77252_proc_read,
-	.owner		= THIS_MODULE
-};
-
-static struct idt77252_dev *idt77252_chain = NULL;
-static unsigned int idt77252_sram_write_errors = 0;
-
-/*****************************************************************************/
-/*                                                                           */
-/* I/O and Utility Bus                                                       */
-/*                                                                           */
-/*****************************************************************************/
-
-static void
-waitfor_idle(struct idt77252_dev *card)
-{
-	u32 stat;
-
-	stat = readl(SAR_REG_STAT);
-	while (stat & SAR_STAT_CMDBZ)
-		stat = readl(SAR_REG_STAT);
-}
-
-static u32
-read_sram(struct idt77252_dev *card, unsigned long addr)
-{
-	unsigned long flags;
-	u32 value;
-
-	spin_lock_irqsave(&card->cmd_lock, flags);
-	writel(SAR_CMD_READ_SRAM | (addr << 2), SAR_REG_CMD);
-	waitfor_idle(card);
-	value = readl(SAR_REG_DR0);
-	spin_unlock_irqrestore(&card->cmd_lock, flags);
-	return value;
-}
-
-static void
-write_sram(struct idt77252_dev *card, unsigned long addr, u32 value)
-{
-	unsigned long flags;
-
-	if ((idt77252_sram_write_errors == 0) &&
-	    (((addr > card->tst[0] + card->tst_size - 2) &&
-	      (addr < card->tst[0] + card->tst_size)) ||
-	     ((addr > card->tst[1] + card->tst_size - 2) &&
-	      (addr < card->tst[1] + card->tst_size)))) {
-		printk("%s: ERROR: TST JMP section at %08lx written: %08x\n",
-		       card->name, addr, value);
-	}
-
-	spin_lock_irqsave(&card->cmd_lock, flags);
-	writel(value, SAR_REG_DR0);
-	writel(SAR_CMD_WRITE_SRAM | (addr << 2), SAR_REG_CMD);
-	waitfor_idle(card);
-	spin_unlock_irqrestore(&card->cmd_lock, flags);
-}
-
-static u8
-read_utility(void *dev, unsigned long ubus_addr)
-{
-	struct idt77252_dev *card = dev;
-	unsigned long flags;
-	u8 value;
-
-	if (!card) {
-		printk("Error: No such device.\n");
-		return -1;
-	}
-
-	spin_lock_irqsave(&card->cmd_lock, flags);
-	writel(SAR_CMD_READ_UTILITY + ubus_addr, SAR_REG_CMD);
-	waitfor_idle(card);
-	value = readl(SAR_REG_DR0);
-	spin_unlock_irqrestore(&card->cmd_lock, flags);
-	return value;
-}
-
-static void
-write_utility(void *dev, unsigned long ubus_addr, u8 value)
-{
-	struct idt77252_dev *card = dev;
-	unsigned long flags;
-
-	if (!card) {
-		printk("Error: No such device.\n");
-		return;
-	}
-
-	spin_lock_irqsave(&card->cmd_lock, flags);
-	writel((u32) value, SAR_REG_DR0);
-	writel(SAR_CMD_WRITE_UTILITY + ubus_addr, SAR_REG_CMD);
-	waitfor_idle(card);
-	spin_unlock_irqrestore(&card->cmd_lock, flags);
-}
-
-#ifdef HAVE_EEPROM
-static u32 rdsrtab[] =
-{
-	SAR_GP_EECS | SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	SAR_GP_EEDO,
-	SAR_GP_EESCLK | SAR_GP_EEDO,	/* 1 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	SAR_GP_EEDO,
-	SAR_GP_EESCLK | SAR_GP_EEDO	/* 1 */
-};
-
-static u32 wrentab[] =
-{
-	SAR_GP_EECS | SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	SAR_GP_EEDO,
-	SAR_GP_EESCLK | SAR_GP_EEDO,	/* 1 */
-	SAR_GP_EEDO,
-	SAR_GP_EESCLK | SAR_GP_EEDO,	/* 1 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK			/* 0 */
-};
-
-static u32 rdtab[] =
-{
-	SAR_GP_EECS | SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	SAR_GP_EEDO,
-	SAR_GP_EESCLK | SAR_GP_EEDO,	/* 1 */
-	SAR_GP_EEDO,
-	SAR_GP_EESCLK | SAR_GP_EEDO	/* 1 */
-};
-
-static u32 wrtab[] =
-{
-	SAR_GP_EECS | SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	SAR_GP_EEDO,
-	SAR_GP_EESCLK | SAR_GP_EEDO,	/* 1 */
-	0,
-	SAR_GP_EESCLK			/* 0 */
-};
-
-static u32 clktab[] =
-{
-	0,
-	SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,
-	0
-};
-
-static u32
-idt77252_read_gp(struct idt77252_dev *card)
-{
-	u32 gp;
-
-	gp = readl(SAR_REG_GP);
-#if 0
-	printk("RD: %s\n", gp & SAR_GP_EEDI ? "1" : "0");
-#endif
-	return gp;
-}
-
-static void
-idt77252_write_gp(struct idt77252_dev *card, u32 value)
-{
-	unsigned long flags;
-
-#if 0
-	printk("WR: %s %s %s\n", value & SAR_GP_EECS ? "   " : "/CS",
-	       value & SAR_GP_EESCLK ? "HIGH" : "LOW ",
-	       value & SAR_GP_EEDO   ? "1" : "0");
-#endif
-
-	spin_lock_irqsave(&card->cmd_lock, flags);
-	waitfor_idle(card);
-	writel(value, SAR_REG_GP);
-	spin_unlock_irqrestore(&card->cmd_lock, flags);
-}
-
-static u8
-idt77252_eeprom_read_status(struct idt77252_dev *card)
-{
-	u8 byte;
-	u32 gp;
-	int i, j;
-
-	gp = idt77252_read_gp(card) & ~(SAR_GP_EESCLK|SAR_GP_EECS|SAR_GP_EEDO);
-
-	for (i = 0; i < ARRAY_SIZE(rdsrtab); i++) {
-		idt77252_write_gp(card, gp | rdsrtab[i]);
-		udelay(5);
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	byte = 0;
-	for (i = 0, j = 0; i < 8; i++) {
-		byte <<= 1;
-
-		idt77252_write_gp(card, gp | clktab[j++]);
-		udelay(5);
-
-		byte |= idt77252_read_gp(card) & SAR_GP_EEDI ? 1 : 0;
-
-		idt77252_write_gp(card, gp | clktab[j++]);
-		udelay(5);
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	return byte;
-}
-
-static u8
-idt77252_eeprom_read_byte(struct idt77252_dev *card, u8 offset)
-{
-	u8 byte;
-	u32 gp;
-	int i, j;
-
-	gp = idt77252_read_gp(card) & ~(SAR_GP_EESCLK|SAR_GP_EECS|SAR_GP_EEDO);
-
-	for (i = 0; i < ARRAY_SIZE(rdtab); i++) {
-		idt77252_write_gp(card, gp | rdtab[i]);
-		udelay(5);
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	for (i = 0, j = 0; i < 8; i++) {
-		idt77252_write_gp(card, gp | clktab[j++] |
-					(offset & 1 ? SAR_GP_EEDO : 0));
-		udelay(5);
-
-		idt77252_write_gp(card, gp | clktab[j++] |
-					(offset & 1 ? SAR_GP_EEDO : 0));
-		udelay(5);
-
-		offset >>= 1;
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	byte = 0;
-	for (i = 0, j = 0; i < 8; i++) {
-		byte <<= 1;
-
-		idt77252_write_gp(card, gp | clktab[j++]);
-		udelay(5);
-
-		byte |= idt77252_read_gp(card) & SAR_GP_EEDI ? 1 : 0;
-
-		idt77252_write_gp(card, gp | clktab[j++]);
-		udelay(5);
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	return byte;
-}
-
-static void
-idt77252_eeprom_write_byte(struct idt77252_dev *card, u8 offset, u8 data)
-{
-	u32 gp;
-	int i, j;
-
-	gp = idt77252_read_gp(card) & ~(SAR_GP_EESCLK|SAR_GP_EECS|SAR_GP_EEDO);
-
-	for (i = 0; i < ARRAY_SIZE(wrentab); i++) {
-		idt77252_write_gp(card, gp | wrentab[i]);
-		udelay(5);
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	for (i = 0; i < ARRAY_SIZE(wrtab); i++) {
-		idt77252_write_gp(card, gp | wrtab[i]);
-		udelay(5);
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	for (i = 0, j = 0; i < 8; i++) {
-		idt77252_write_gp(card, gp | clktab[j++] |
-					(offset & 1 ? SAR_GP_EEDO : 0));
-		udelay(5);
-
-		idt77252_write_gp(card, gp | clktab[j++] |
-					(offset & 1 ? SAR_GP_EEDO : 0));
-		udelay(5);
-
-		offset >>= 1;
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	for (i = 0, j = 0; i < 8; i++) {
-		idt77252_write_gp(card, gp | clktab[j++] |
-					(data & 1 ? SAR_GP_EEDO : 0));
-		udelay(5);
-
-		idt77252_write_gp(card, gp | clktab[j++] |
-					(data & 1 ? SAR_GP_EEDO : 0));
-		udelay(5);
-
-		data >>= 1;
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-}
-
-static void
-idt77252_eeprom_init(struct idt77252_dev *card)
-{
-	u32 gp;
-
-	gp = idt77252_read_gp(card) & ~(SAR_GP_EESCLK|SAR_GP_EECS|SAR_GP_EEDO);
-
-	idt77252_write_gp(card, gp | SAR_GP_EECS | SAR_GP_EESCLK);
-	udelay(5);
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-	idt77252_write_gp(card, gp | SAR_GP_EECS | SAR_GP_EESCLK);
-	udelay(5);
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-}
-#endif /* HAVE_EEPROM */
-
-
-#ifdef CONFIG_ATM_IDT77252_DEBUG
-static void
-dump_tct(struct idt77252_dev *card, int index)
-{
-	unsigned long tct;
-	int i;
-
-	tct = (unsigned long) (card->tct_base + index * SAR_SRAM_TCT_SIZE);
-
-	printk("%s: TCT %x:", card->name, index);
-	for (i = 0; i < 8; i++) {
-		printk(" %08x", read_sram(card, tct + i));
-	}
-	printk("\n");
-}
-
-static void
-idt77252_tx_dump(struct idt77252_dev *card)
-{
-	struct atm_vcc *vcc;
-	struct vc_map *vc;
-	int i;
-
-	printk("%s\n", __func__);
-	for (i = 0; i < card->tct_size; i++) {
-		vc = card->vcs[i];
-		if (!vc)
-			continue;
-
-		vcc = NULL;
-		if (vc->rx_vcc)
-			vcc = vc->rx_vcc;
-		else if (vc->tx_vcc)
-			vcc = vc->tx_vcc;
-
-		if (!vcc)
-			continue;
-
-		printk("%s: Connection %d:\n", card->name, vc->index);
-		dump_tct(card, vc->index);
-	}
-}
-#endif
-
-
-/*****************************************************************************/
-/*                                                                           */
-/* SCQ Handling                                                              */
-/*                                                                           */
-/*****************************************************************************/
-
-static int
-sb_pool_add(struct idt77252_dev *card, struct sk_buff *skb, int queue)
-{
-	struct sb_pool *pool = &card->sbpool[queue];
-	int index;
-
-	index = pool->index;
-	while (pool->skb[index]) {
-		index = (index + 1) & FBQ_MASK;
-		if (index == pool->index)
-			return -ENOBUFS;
-	}
-
-	pool->skb[index] = skb;
-	IDT77252_PRV_POOL(skb) = POOL_HANDLE(queue, index);
-
-	pool->index = (index + 1) & FBQ_MASK;
-	return 0;
-}
-
-static void
-sb_pool_remove(struct idt77252_dev *card, struct sk_buff *skb)
-{
-	unsigned int queue, index;
-	u32 handle;
-
-	handle = IDT77252_PRV_POOL(skb);
-
-	queue = POOL_QUEUE(handle);
-	if (queue > 3)
-		return;
-
-	index = POOL_INDEX(handle);
-	if (index > FBQ_SIZE - 1)
-		return;
-
-	card->sbpool[queue].skb[index] = NULL;
-}
-
-static struct sk_buff *
-sb_pool_skb(struct idt77252_dev *card, u32 handle)
-{
-	unsigned int queue, index;
-
-	queue = POOL_QUEUE(handle);
-	if (queue > 3)
-		return NULL;
-
-	index = POOL_INDEX(handle);
-	if (index > FBQ_SIZE - 1)
-		return NULL;
-
-	return card->sbpool[queue].skb[index];
-}
-
-static struct scq_info *
-alloc_scq(struct idt77252_dev *card, int class)
-{
-	struct scq_info *scq;
-
-	scq = kzalloc_obj(struct scq_info);
-	if (!scq)
-		return NULL;
-	scq->base = dma_alloc_coherent(&card->pcidev->dev, SCQ_SIZE,
-				       &scq->paddr, GFP_KERNEL);
-	if (scq->base == NULL) {
-		kfree(scq);
-		return NULL;
-	}
-
-	scq->next = scq->base;
-	scq->last = scq->base + (SCQ_ENTRIES - 1);
-	atomic_set(&scq->used, 0);
-
-	spin_lock_init(&scq->lock);
-	spin_lock_init(&scq->skblock);
-
-	skb_queue_head_init(&scq->transmit);
-	skb_queue_head_init(&scq->pending);
-
-	TXPRINTK("idt77252: SCQ: base 0x%p, next 0x%p, last 0x%p, paddr %08llx\n",
-		 scq->base, scq->next, scq->last, (unsigned long long)scq->paddr);
-
-	return scq;
-}
-
-static void
-free_scq(struct idt77252_dev *card, struct scq_info *scq)
-{
-	struct sk_buff *skb;
-	struct atm_vcc *vcc;
-
-	dma_free_coherent(&card->pcidev->dev, SCQ_SIZE,
-			  scq->base, scq->paddr);
-
-	while ((skb = skb_dequeue(&scq->transmit))) {
-		dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-				 skb->len, DMA_TO_DEVICE);
-
-		vcc = ATM_SKB(skb)->vcc;
-		if (vcc->pop)
-			vcc->pop(vcc, skb);
-		else
-			dev_kfree_skb(skb);
-	}
-
-	while ((skb = skb_dequeue(&scq->pending))) {
-		dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-				 skb->len, DMA_TO_DEVICE);
-
-		vcc = ATM_SKB(skb)->vcc;
-		if (vcc->pop)
-			vcc->pop(vcc, skb);
-		else
-			dev_kfree_skb(skb);
-	}
-
-	kfree(scq);
-}
-
-
-static int
-push_on_scq(struct idt77252_dev *card, struct vc_map *vc, struct sk_buff *skb)
-{
-	struct scq_info *scq = vc->scq;
-	unsigned long flags;
-	struct scqe *tbd;
-	int entries;
-
-	TXPRINTK("%s: SCQ: next 0x%p\n", card->name, scq->next);
-
-	atomic_inc(&scq->used);
-	entries = atomic_read(&scq->used);
-	if (entries > (SCQ_ENTRIES - 1)) {
-		atomic_dec(&scq->used);
-		goto out;
-	}
-
-	skb_queue_tail(&scq->transmit, skb);
-
-	spin_lock_irqsave(&vc->lock, flags);
-	if (vc->estimator) {
-		struct atm_vcc *vcc = vc->tx_vcc;
-		struct sock *sk = sk_atm(vcc);
-
-		vc->estimator->cells += (skb->len + 47) / 48;
-		if (refcount_read(&sk->sk_wmem_alloc) >
-		    (sk->sk_sndbuf >> 1)) {
-			u32 cps = vc->estimator->maxcps;
-
-			vc->estimator->cps = cps;
-			vc->estimator->avcps = cps << 5;
-			if (vc->lacr < vc->init_er) {
-				vc->lacr = vc->init_er;
-				writel(TCMDQ_LACR | (vc->lacr << 16) |
-				       vc->index, SAR_REG_TCMDQ);
-			}
-		}
-	}
-	spin_unlock_irqrestore(&vc->lock, flags);
-
-	tbd = &IDT77252_PRV_TBD(skb);
-
-	spin_lock_irqsave(&scq->lock, flags);
-	scq->next->word_1 = cpu_to_le32(tbd->word_1 |
-					SAR_TBD_TSIF | SAR_TBD_GTSI);
-	scq->next->word_2 = cpu_to_le32(tbd->word_2);
-	scq->next->word_3 = cpu_to_le32(tbd->word_3);
-	scq->next->word_4 = cpu_to_le32(tbd->word_4);
-
-	if (scq->next == scq->last)
-		scq->next = scq->base;
-	else
-		scq->next++;
-
-	write_sram(card, scq->scd,
-		   scq->paddr +
-		   (u32)((unsigned long)scq->next - (unsigned long)scq->base));
-	spin_unlock_irqrestore(&scq->lock, flags);
-
-	scq->trans_start = jiffies;
-
-	if (test_and_clear_bit(VCF_IDLE, &vc->flags)) {
-		writel(TCMDQ_START_LACR | (vc->lacr << 16) | vc->index,
-		       SAR_REG_TCMDQ);
-	}
-
-	TXPRINTK("%d entries in SCQ used (push).\n", atomic_read(&scq->used));
-
-	XPRINTK("%s: SCQ (after push %2d) head = 0x%x, next = 0x%p.\n",
-		card->name, atomic_read(&scq->used),
-		read_sram(card, scq->scd + 1), scq->next);
-
-	return 0;
-
-out:
-	if (time_after(jiffies, scq->trans_start + HZ)) {
-		printk("%s: Error pushing TBD for %d.%d\n",
-		       card->name, vc->tx_vcc->vpi, vc->tx_vcc->vci);
-#ifdef CONFIG_ATM_IDT77252_DEBUG
-		idt77252_tx_dump(card);
-#endif
-		scq->trans_start = jiffies;
-	}
-
-	return -ENOBUFS;
-}
-
-
-static void
-drain_scq(struct idt77252_dev *card, struct vc_map *vc)
-{
-	struct scq_info *scq = vc->scq;
-	struct sk_buff *skb;
-	struct atm_vcc *vcc;
-
-	TXPRINTK("%s: SCQ (before drain %2d) next = 0x%p.\n",
-		 card->name, atomic_read(&scq->used), scq->next);
-
-	skb = skb_dequeue(&scq->transmit);
-	if (skb) {
-		TXPRINTK("%s: freeing skb at %p.\n", card->name, skb);
-
-		dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-				 skb->len, DMA_TO_DEVICE);
-
-		vcc = ATM_SKB(skb)->vcc;
-
-		if (vcc->pop)
-			vcc->pop(vcc, skb);
-		else
-			dev_kfree_skb(skb);
-
-		atomic_inc(&vcc->stats->tx);
-	}
-
-	atomic_dec(&scq->used);
-
-	spin_lock(&scq->skblock);
-	while ((skb = skb_dequeue(&scq->pending))) {
-		if (push_on_scq(card, vc, skb)) {
-			skb_queue_head(&vc->scq->pending, skb);
-			break;
-		}
-	}
-	spin_unlock(&scq->skblock);
-}
-
-static int
-queue_skb(struct idt77252_dev *card, struct vc_map *vc,
-	  struct sk_buff *skb, int oam)
-{
-	struct atm_vcc *vcc;
-	struct scqe *tbd;
-	unsigned long flags;
-	int error;
-	int aal;
-	u32 word4;
-
-	if (skb->len == 0) {
-		printk("%s: invalid skb->len (%d)\n", card->name, skb->len);
-		return -EINVAL;
-	}
-
-	TXPRINTK("%s: Sending %d bytes of data.\n",
-		 card->name, skb->len);
-
-	tbd = &IDT77252_PRV_TBD(skb);
-	vcc = ATM_SKB(skb)->vcc;
-	word4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
-			(skb->data[2] <<  8) | (skb->data[3] <<  0);
-
-	IDT77252_PRV_PADDR(skb) = dma_map_single(&card->pcidev->dev, skb->data,
-						 skb->len, DMA_TO_DEVICE);
-	if (dma_mapping_error(&card->pcidev->dev, IDT77252_PRV_PADDR(skb)))
-		return -ENOMEM;
-
-	error = -EINVAL;
-
-	if (oam) {
-		if (skb->len != 52)
-			goto errout;
-
-		tbd->word_1 = SAR_TBD_OAM | ATM_CELL_PAYLOAD | SAR_TBD_EPDU;
-		tbd->word_2 = IDT77252_PRV_PADDR(skb) + 4;
-		tbd->word_3 = 0x00000000;
-		tbd->word_4 = word4;
-
-		if (test_bit(VCF_RSV, &vc->flags))
-			vc = card->vcs[0];
-
-		goto done;
-	}
-
-	if (test_bit(VCF_RSV, &vc->flags)) {
-		printk("%s: Trying to transmit on reserved VC\n", card->name);
-		goto errout;
-	}
-
-	aal = vcc->qos.aal;
-
-	switch (aal) {
-	case ATM_AAL0:
-	case ATM_AAL34:
-		if (skb->len > 52)
-			goto errout;
-
-		if (aal == ATM_AAL0)
-			tbd->word_1 = SAR_TBD_EPDU | SAR_TBD_AAL0 |
-				      ATM_CELL_PAYLOAD;
-		else
-			tbd->word_1 = SAR_TBD_EPDU | SAR_TBD_AAL34 |
-				      ATM_CELL_PAYLOAD;
-
-		tbd->word_2 = IDT77252_PRV_PADDR(skb) + 4;
-		tbd->word_3 = 0x00000000;
-		tbd->word_4 = word4;
-		break;
-
-	case ATM_AAL5:
-		tbd->word_1 = SAR_TBD_EPDU | SAR_TBD_AAL5 | skb->len;
-		tbd->word_2 = IDT77252_PRV_PADDR(skb);
-		tbd->word_3 = skb->len;
-		tbd->word_4 = (vcc->vpi << SAR_TBD_VPI_SHIFT) |
-			      (vcc->vci << SAR_TBD_VCI_SHIFT);
-		break;
-
-	case ATM_AAL1:
-	case ATM_AAL2:
-	default:
-		printk("%s: Traffic type not supported.\n", card->name);
-		error = -EPROTONOSUPPORT;
-		goto errout;
-	}
-
-done:
-	spin_lock_irqsave(&vc->scq->skblock, flags);
-	skb_queue_tail(&vc->scq->pending, skb);
-
-	while ((skb = skb_dequeue(&vc->scq->pending))) {
-		if (push_on_scq(card, vc, skb)) {
-			skb_queue_head(&vc->scq->pending, skb);
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&vc->scq->skblock, flags);
-
-	return 0;
-
-errout:
-	dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-			 skb->len, DMA_TO_DEVICE);
-	return error;
-}
-
-static unsigned long
-get_free_scd(struct idt77252_dev *card, struct vc_map *vc)
-{
-	int i;
-
-	for (i = 0; i < card->scd_size; i++) {
-		if (!card->scd2vc[i]) {
-			card->scd2vc[i] = vc;
-			vc->scd_index = i;
-			return card->scd_base + i * SAR_SRAM_SCD_SIZE;
-		}
-	}
-	return 0;
-}
-
-static void
-fill_scd(struct idt77252_dev *card, struct scq_info *scq, int class)
-{
-	write_sram(card, scq->scd, scq->paddr);
-	write_sram(card, scq->scd + 1, 0x00000000);
-	write_sram(card, scq->scd + 2, 0xffffffff);
-	write_sram(card, scq->scd + 3, 0x00000000);
-}
-
-static void
-clear_scd(struct idt77252_dev *card, struct scq_info *scq, int class)
-{
-	return;
-}
-
-/*****************************************************************************/
-/*                                                                           */
-/* RSQ Handling                                                              */
-/*                                                                           */
-/*****************************************************************************/
-
-static int
-init_rsq(struct idt77252_dev *card)
-{
-	struct rsq_entry *rsqe;
-
-	card->rsq.base = dma_alloc_coherent(&card->pcidev->dev, RSQSIZE,
-					    &card->rsq.paddr, GFP_KERNEL);
-	if (card->rsq.base == NULL) {
-		printk("%s: can't allocate RSQ.\n", card->name);
-		return -1;
-	}
-
-	card->rsq.last = card->rsq.base + RSQ_NUM_ENTRIES - 1;
-	card->rsq.next = card->rsq.last;
-	for (rsqe = card->rsq.base; rsqe <= card->rsq.last; rsqe++)
-		rsqe->word_4 = 0;
-
-	writel((unsigned long) card->rsq.last - (unsigned long) card->rsq.base,
-	       SAR_REG_RSQH);
-	writel(card->rsq.paddr, SAR_REG_RSQB);
-
-	IPRINTK("%s: RSQ base at 0x%lx (0x%x).\n", card->name,
-		(unsigned long) card->rsq.base,
-		readl(SAR_REG_RSQB));
-	IPRINTK("%s: RSQ head = 0x%x, base = 0x%x, tail = 0x%x.\n",
-		card->name,
-		readl(SAR_REG_RSQH),
-		readl(SAR_REG_RSQB),
-		readl(SAR_REG_RSQT));
-
-	return 0;
-}
-
-static void
-deinit_rsq(struct idt77252_dev *card)
-{
-	dma_free_coherent(&card->pcidev->dev, RSQSIZE,
-			  card->rsq.base, card->rsq.paddr);
-}
-
-static void
-dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
-{
-	struct atm_vcc *vcc;
-	struct sk_buff *skb;
-	struct rx_pool *rpp;
-	struct vc_map *vc;
-	u32 header, vpi, vci;
-	u32 stat;
-	int i;
-
-	stat = le32_to_cpu(rsqe->word_4);
-
-	if (stat & SAR_RSQE_IDLE) {
-		RXPRINTK("%s: message about inactive connection.\n",
-			 card->name);
-		return;
-	}
-
-	skb = sb_pool_skb(card, le32_to_cpu(rsqe->word_2));
-	if (skb == NULL) {
-		printk("%s: NULL skb in %s, rsqe: %08x %08x %08x %08x\n",
-		       card->name, __func__,
-		       le32_to_cpu(rsqe->word_1), le32_to_cpu(rsqe->word_2),
-		       le32_to_cpu(rsqe->word_3), le32_to_cpu(rsqe->word_4));
-		return;
-	}
-
-	header = le32_to_cpu(rsqe->word_1);
-	vpi = (header >> 16) & 0x00ff;
-	vci = (header >>  0) & 0xffff;
-
-	RXPRINTK("%s: SDU for %d.%d received in buffer 0x%p (data 0x%p).\n",
-		 card->name, vpi, vci, skb, skb->data);
-
-	if ((vpi >= (1 << card->vpibits)) || (vci != (vci & card->vcimask))) {
-		printk("%s: SDU received for out-of-range vc %u.%u\n",
-		       card->name, vpi, vci);
-		recycle_rx_skb(card, skb);
-		return;
-	}
-
-	vc = card->vcs[VPCI2VC(card, vpi, vci)];
-	if (!vc || !test_bit(VCF_RX, &vc->flags)) {
-		printk("%s: SDU received on non RX vc %u.%u\n",
-		       card->name, vpi, vci);
-		recycle_rx_skb(card, skb);
-		return;
-	}
-
-	vcc = vc->rx_vcc;
-
-	dma_sync_single_for_cpu(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-				skb_end_pointer(skb) - skb->data,
-				DMA_FROM_DEVICE);
-
-	if ((vcc->qos.aal == ATM_AAL0) ||
-	    (vcc->qos.aal == ATM_AAL34)) {
-		struct sk_buff *sb;
-		unsigned char *cell;
-		u32 aal0;
-
-		cell = skb->data;
-		for (i = (stat & SAR_RSQE_CELLCNT); i; i--) {
-			if ((sb = dev_alloc_skb(64)) == NULL) {
-				printk("%s: Can't allocate buffers for aal0.\n",
-				       card->name);
-				atomic_add(i, &vcc->stats->rx_drop);
-				break;
-			}
-			if (!atm_charge(vcc, sb->truesize)) {
-				RXPRINTK("%s: atm_charge() dropped aal0 packets.\n",
-					 card->name);
-				atomic_add(i - 1, &vcc->stats->rx_drop);
-				dev_kfree_skb(sb);
-				break;
-			}
-			aal0 = (vpi << ATM_HDR_VPI_SHIFT) |
-			       (vci << ATM_HDR_VCI_SHIFT);
-			aal0 |= (stat & SAR_RSQE_EPDU) ? 0x00000002 : 0;
-			aal0 |= (stat & SAR_RSQE_CLP)  ? 0x00000001 : 0;
-
-			*((u32 *) sb->data) = aal0;
-			skb_put(sb, sizeof(u32));
-			skb_put_data(sb, cell, ATM_CELL_PAYLOAD);
-
-			ATM_SKB(sb)->vcc = vcc;
-			__net_timestamp(sb);
-			vcc->push(vcc, sb);
-			atomic_inc(&vcc->stats->rx);
-
-			cell += ATM_CELL_PAYLOAD;
-		}
-
-		recycle_rx_skb(card, skb);
-		return;
-	}
-	if (vcc->qos.aal != ATM_AAL5) {
-		printk("%s: Unexpected AAL type in dequeue_rx(): %d.\n",
-		       card->name, vcc->qos.aal);
-		recycle_rx_skb(card, skb);
-		return;
-	}
-	skb->len = (stat & SAR_RSQE_CELLCNT) * ATM_CELL_PAYLOAD;
-
-	rpp = &vc->rcv.rx_pool;
-
-	__skb_queue_tail(&rpp->queue, skb);
-	rpp->len += skb->len;
-
-	if (stat & SAR_RSQE_EPDU) {
-		unsigned int len, truesize;
-		unsigned char *l1l2;
-
-		l1l2 = (unsigned char *) ((unsigned long) skb->data + skb->len - 6);
-
-		len = (l1l2[0] << 8) | l1l2[1];
-		len = len ? len : 0x10000;
-
-		RXPRINTK("%s: PDU has %d bytes.\n", card->name, len);
-
-		if ((len + 8 > rpp->len) || (len + (47 + 8) < rpp->len)) {
-			RXPRINTK("%s: AAL5 PDU size mismatch: %d != %d. "
-			         "(CDC: %08x)\n",
-			         card->name, len, rpp->len, readl(SAR_REG_CDC));
-			recycle_rx_pool_skb(card, rpp);
-			atomic_inc(&vcc->stats->rx_err);
-			return;
-		}
-		if (stat & SAR_RSQE_CRC) {
-			RXPRINTK("%s: AAL5 CRC error.\n", card->name);
-			recycle_rx_pool_skb(card, rpp);
-			atomic_inc(&vcc->stats->rx_err);
-			return;
-		}
-		if (skb_queue_len(&rpp->queue) > 1) {
-			struct sk_buff *sb;
-
-			skb = dev_alloc_skb(rpp->len);
-			if (!skb) {
-				RXPRINTK("%s: Can't alloc RX skb.\n",
-					 card->name);
-				recycle_rx_pool_skb(card, rpp);
-				atomic_inc(&vcc->stats->rx_err);
-				return;
-			}
-			if (!atm_charge(vcc, skb->truesize)) {
-				recycle_rx_pool_skb(card, rpp);
-				dev_kfree_skb(skb);
-				return;
-			}
-			skb_queue_walk(&rpp->queue, sb)
-				skb_put_data(skb, sb->data, sb->len);
-
-			recycle_rx_pool_skb(card, rpp);
-
-			skb_trim(skb, len);
-			ATM_SKB(skb)->vcc = vcc;
-			__net_timestamp(skb);
-
-			vcc->push(vcc, skb);
-			atomic_inc(&vcc->stats->rx);
-
-			return;
-		}
-
-		flush_rx_pool(card, rpp);
-
-		if (!atm_charge(vcc, skb->truesize)) {
-			recycle_rx_skb(card, skb);
-			return;
-		}
-
-		dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-				 skb_end_pointer(skb) - skb->data,
-				 DMA_FROM_DEVICE);
-		sb_pool_remove(card, skb);
-
-		skb_trim(skb, len);
-		ATM_SKB(skb)->vcc = vcc;
-		__net_timestamp(skb);
-
-		truesize = skb->truesize;
-		vcc->push(vcc, skb);
-		atomic_inc(&vcc->stats->rx);
-
-		if (truesize > SAR_FB_SIZE_3)
-			add_rx_skb(card, 3, SAR_FB_SIZE_3, 1);
-		else if (truesize > SAR_FB_SIZE_2)
-			add_rx_skb(card, 2, SAR_FB_SIZE_2, 1);
-		else if (truesize > SAR_FB_SIZE_1)
-			add_rx_skb(card, 1, SAR_FB_SIZE_1, 1);
-		else
-			add_rx_skb(card, 0, SAR_FB_SIZE_0, 1);
-		return;
-	}
-}
-
-static void
-idt77252_rx(struct idt77252_dev *card)
-{
-	struct rsq_entry *rsqe;
-
-	if (card->rsq.next == card->rsq.last)
-		rsqe = card->rsq.base;
-	else
-		rsqe = card->rsq.next + 1;
-
-	if (!(le32_to_cpu(rsqe->word_4) & SAR_RSQE_VALID)) {
-		RXPRINTK("%s: no entry in RSQ.\n", card->name);
-		return;
-	}
-
-	do {
-		dequeue_rx(card, rsqe);
-		rsqe->word_4 = 0;
-		card->rsq.next = rsqe;
-		if (card->rsq.next == card->rsq.last)
-			rsqe = card->rsq.base;
-		else
-			rsqe = card->rsq.next + 1;
-	} while (le32_to_cpu(rsqe->word_4) & SAR_RSQE_VALID);
-
-	writel((unsigned long) card->rsq.next - (unsigned long) card->rsq.base,
-	       SAR_REG_RSQH);
-}
-
-static void
-idt77252_rx_raw(struct idt77252_dev *card)
-{
-	struct sk_buff	*queue;
-	u32		head, tail;
-	struct atm_vcc	*vcc;
-	struct vc_map	*vc;
-	struct sk_buff	*sb;
-
-	if (card->raw_cell_head == NULL) {
-		u32 handle = le32_to_cpu(*(card->raw_cell_hnd + 1));
-		card->raw_cell_head = sb_pool_skb(card, handle);
-	}
-
-	queue = card->raw_cell_head;
-	if (!queue)
-		return;
-
-	head = IDT77252_PRV_PADDR(queue) + (queue->data - queue->head - 16);
-	tail = readl(SAR_REG_RAWCT);
-
-	dma_sync_single_for_cpu(&card->pcidev->dev, IDT77252_PRV_PADDR(queue),
-				skb_end_offset(queue) - 16,
-				DMA_FROM_DEVICE);
-
-	while (head != tail) {
-		unsigned int vpi, vci;
-		u32 header;
-
-		header = le32_to_cpu(*(u32 *) &queue->data[0]);
-
-		vpi = (header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT;
-		vci = (header & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT;
-
-#ifdef CONFIG_ATM_IDT77252_DEBUG
-		if (debug & DBG_RAW_CELL) {
-			int i;
-
-			printk("%s: raw cell %x.%02x.%04x.%x.%x\n",
-			       card->name, (header >> 28) & 0x000f,
-			       (header >> 20) & 0x00ff,
-			       (header >>  4) & 0xffff,
-			       (header >>  1) & 0x0007,
-			       (header >>  0) & 0x0001);
-			for (i = 16; i < 64; i++)
-				printk(" %02x", queue->data[i]);
-			printk("\n");
-		}
-#endif
-
-		if (vpi >= (1<<card->vpibits) || vci >= (1<<card->vcibits)) {
-			RPRINTK("%s: SDU received for out-of-range vc %u.%u\n",
-				card->name, vpi, vci);
-			goto drop;
-		}
-
-		vc = card->vcs[VPCI2VC(card, vpi, vci)];
-		if (!vc || !test_bit(VCF_RX, &vc->flags)) {
-			RPRINTK("%s: SDU received on non RX vc %u.%u\n",
-				card->name, vpi, vci);
-			goto drop;
-		}
-
-		vcc = vc->rx_vcc;
-
-		if (vcc->qos.aal != ATM_AAL0) {
-			RPRINTK("%s: raw cell for non AAL0 vc %u.%u\n",
-				card->name, vpi, vci);
-			atomic_inc(&vcc->stats->rx_drop);
-			goto drop;
-		}
-	
-		if ((sb = dev_alloc_skb(64)) == NULL) {
-			printk("%s: Can't allocate buffers for AAL0.\n",
-			       card->name);
-			atomic_inc(&vcc->stats->rx_err);
-			goto drop;
-		}
-
-		if (!atm_charge(vcc, sb->truesize)) {
-			RXPRINTK("%s: atm_charge() dropped AAL0 packets.\n",
-				 card->name);
-			dev_kfree_skb(sb);
-			goto drop;
-		}
-
-		*((u32 *) sb->data) = header;
-		skb_put(sb, sizeof(u32));
-		skb_put_data(sb, &(queue->data[16]), ATM_CELL_PAYLOAD);
-
-		ATM_SKB(sb)->vcc = vcc;
-		__net_timestamp(sb);
-		vcc->push(vcc, sb);
-		atomic_inc(&vcc->stats->rx);
-
-drop:
-		skb_pull(queue, 64);
-
-		head = IDT77252_PRV_PADDR(queue)
-					+ (queue->data - queue->head - 16);
-
-		if (queue->len < 128) {
-			struct sk_buff *next;
-			u32 handle;
-
-			head = le32_to_cpu(*(u32 *) &queue->data[0]);
-			handle = le32_to_cpu(*(u32 *) &queue->data[4]);
-
-			next = sb_pool_skb(card, handle);
-			recycle_rx_skb(card, queue);
-
-			if (next) {
-				card->raw_cell_head = next;
-				queue = card->raw_cell_head;
-				dma_sync_single_for_cpu(&card->pcidev->dev,
-							IDT77252_PRV_PADDR(queue),
-							(skb_end_pointer(queue) -
-							 queue->data),
-							DMA_FROM_DEVICE);
-			} else {
-				card->raw_cell_head = NULL;
-				printk("%s: raw cell queue overrun\n",
-				       card->name);
-				break;
-			}
-		}
-	}
-}
-
-
-/*****************************************************************************/
-/*                                                                           */
-/* TSQ Handling                                                              */
-/*                                                                           */
-/*****************************************************************************/
-
-static int
-init_tsq(struct idt77252_dev *card)
-{
-	struct tsq_entry *tsqe;
-
-	card->tsq.base = dma_alloc_coherent(&card->pcidev->dev, RSQSIZE,
-					    &card->tsq.paddr, GFP_KERNEL);
-	if (card->tsq.base == NULL) {
-		printk("%s: can't allocate TSQ.\n", card->name);
-		return -1;
-	}
-
-	card->tsq.last = card->tsq.base + TSQ_NUM_ENTRIES - 1;
-	card->tsq.next = card->tsq.last;
-	for (tsqe = card->tsq.base; tsqe <= card->tsq.last; tsqe++)
-		tsqe->word_2 = cpu_to_le32(SAR_TSQE_INVALID);
-
-	writel(card->tsq.paddr, SAR_REG_TSQB);
-	writel((unsigned long) card->tsq.next - (unsigned long) card->tsq.base,
-	       SAR_REG_TSQH);
-
-	return 0;
-}
-
-static void
-deinit_tsq(struct idt77252_dev *card)
-{
-	dma_free_coherent(&card->pcidev->dev, TSQSIZE,
-			  card->tsq.base, card->tsq.paddr);
-}
-
-static void
-idt77252_tx(struct idt77252_dev *card)
-{
-	struct tsq_entry *tsqe;
-	unsigned int vpi, vci;
-	struct vc_map *vc;
-	u32 conn, stat;
-
-	if (card->tsq.next == card->tsq.last)
-		tsqe = card->tsq.base;
-	else
-		tsqe = card->tsq.next + 1;
-
-	TXPRINTK("idt77252_tx: tsq  %p: base %p, next %p, last %p\n", tsqe,
-		 card->tsq.base, card->tsq.next, card->tsq.last);
-	TXPRINTK("idt77252_tx: tsqb %08x, tsqt %08x, tsqh %08x, \n",
-		 readl(SAR_REG_TSQB),
-		 readl(SAR_REG_TSQT),
-		 readl(SAR_REG_TSQH));
-
-	stat = le32_to_cpu(tsqe->word_2);
-
-	if (stat & SAR_TSQE_INVALID)
-		return;
-
-	do {
-		TXPRINTK("tsqe: 0x%p [0x%08x 0x%08x]\n", tsqe,
-			 le32_to_cpu(tsqe->word_1),
-			 le32_to_cpu(tsqe->word_2));
-
-		switch (stat & SAR_TSQE_TYPE) {
-		case SAR_TSQE_TYPE_TIMER:
-			TXPRINTK("%s: Timer RollOver detected.\n", card->name);
-			break;
-
-		case SAR_TSQE_TYPE_IDLE:
-
-			conn = le32_to_cpu(tsqe->word_1);
-
-			if (SAR_TSQE_TAG(stat) == 0x10) {
-#ifdef	NOTDEF
-				printk("%s: Connection %d halted.\n",
-				       card->name,
-				       le32_to_cpu(tsqe->word_1) & 0x1fff);
-#endif
-				break;
-			}
-
-			vc = card->vcs[conn & 0x1fff];
-			if (!vc) {
-				printk("%s: could not find VC from conn %d\n",
-				       card->name, conn & 0x1fff);
-				break;
-			}
-
-			printk("%s: Connection %d IDLE.\n",
-			       card->name, vc->index);
-
-			set_bit(VCF_IDLE, &vc->flags);
-			break;
-
-		case SAR_TSQE_TYPE_TSR:
-
-			conn = le32_to_cpu(tsqe->word_1);
-
-			vc = card->vcs[conn & 0x1fff];
-			if (!vc) {
-				printk("%s: no VC at index %d\n",
-				       card->name,
-				       le32_to_cpu(tsqe->word_1) & 0x1fff);
-				break;
-			}
-
-			drain_scq(card, vc);
-			break;
-
-		case SAR_TSQE_TYPE_TBD_COMP:
-
-			conn = le32_to_cpu(tsqe->word_1);
-
-			vpi = (conn >> SAR_TBD_VPI_SHIFT) & 0x00ff;
-			vci = (conn >> SAR_TBD_VCI_SHIFT) & 0xffff;
-
-			if (vpi >= (1 << card->vpibits) ||
-			    vci >= (1 << card->vcibits)) {
-				printk("%s: TBD complete: "
-				       "out of range VPI.VCI %u.%u\n",
-				       card->name, vpi, vci);
-				break;
-			}
-
-			vc = card->vcs[VPCI2VC(card, vpi, vci)];
-			if (!vc) {
-				printk("%s: TBD complete: "
-				       "no VC at VPI.VCI %u.%u\n",
-				       card->name, vpi, vci);
-				break;
-			}
-
-			drain_scq(card, vc);
-			break;
-		}
-
-		tsqe->word_2 = cpu_to_le32(SAR_TSQE_INVALID);
-
-		card->tsq.next = tsqe;
-		if (card->tsq.next == card->tsq.last)
-			tsqe = card->tsq.base;
-		else
-			tsqe = card->tsq.next + 1;
-
-		TXPRINTK("tsqe: %p: base %p, next %p, last %p\n", tsqe,
-			 card->tsq.base, card->tsq.next, card->tsq.last);
-
-		stat = le32_to_cpu(tsqe->word_2);
-
-	} while (!(stat & SAR_TSQE_INVALID));
-
-	writel((unsigned long)card->tsq.next - (unsigned long)card->tsq.base,
-	       SAR_REG_TSQH);
-
-	XPRINTK("idt77252_tx-after writel%d: TSQ head = 0x%x, tail = 0x%x, next = 0x%p.\n",
-		card->index, readl(SAR_REG_TSQH),
-		readl(SAR_REG_TSQT), card->tsq.next);
-}
-
-
-static void
-tst_timer(struct timer_list *t)
-{
-	struct idt77252_dev *card = timer_container_of(card, t, tst_timer);
-	unsigned long base, idle, jump;
-	unsigned long flags;
-	u32 pc;
-	int e;
-
-	spin_lock_irqsave(&card->tst_lock, flags);
-
-	base = card->tst[card->tst_index];
-	idle = card->tst[card->tst_index ^ 1];
-
-	if (test_bit(TST_SWITCH_WAIT, &card->tst_state)) {
-		jump = base + card->tst_size - 2;
-
-		pc = readl(SAR_REG_NOW) >> 2;
-		if ((pc ^ idle) & ~(card->tst_size - 1)) {
-			mod_timer(&card->tst_timer, jiffies + 1);
-			goto out;
-		}
-
-		clear_bit(TST_SWITCH_WAIT, &card->tst_state);
-
-		card->tst_index ^= 1;
-		write_sram(card, jump, TSTE_OPC_JMP | (base << 2));
-
-		base = card->tst[card->tst_index];
-		idle = card->tst[card->tst_index ^ 1];
-
-		for (e = 0; e < card->tst_size - 2; e++) {
-			if (card->soft_tst[e].tste & TSTE_PUSH_IDLE) {
-				write_sram(card, idle + e,
-					   card->soft_tst[e].tste & TSTE_MASK);
-				card->soft_tst[e].tste &= ~(TSTE_PUSH_IDLE);
-			}
-		}
-	}
-
-	if (test_and_clear_bit(TST_SWITCH_PENDING, &card->tst_state)) {
-
-		for (e = 0; e < card->tst_size - 2; e++) {
-			if (card->soft_tst[e].tste & TSTE_PUSH_ACTIVE) {
-				write_sram(card, idle + e,
-					   card->soft_tst[e].tste & TSTE_MASK);
-				card->soft_tst[e].tste &= ~(TSTE_PUSH_ACTIVE);
-				card->soft_tst[e].tste |= TSTE_PUSH_IDLE;
-			}
-		}
-
-		jump = base + card->tst_size - 2;
-
-		write_sram(card, jump, TSTE_OPC_NULL);
-		set_bit(TST_SWITCH_WAIT, &card->tst_state);
-
-		mod_timer(&card->tst_timer, jiffies + 1);
-	}
-
-out:
-	spin_unlock_irqrestore(&card->tst_lock, flags);
-}
-
-static int
-__fill_tst(struct idt77252_dev *card, struct vc_map *vc,
-	   int n, unsigned int opc)
-{
-	unsigned long cl, avail;
-	unsigned long idle;
-	int e, r;
-	u32 data;
-
-	avail = card->tst_size - 2;
-	for (e = 0; e < avail; e++) {
-		if (card->soft_tst[e].vc == NULL)
-			break;
-	}
-	if (e >= avail) {
-		printk("%s: No free TST entries found\n", card->name);
-		return -1;
-	}
-
-	NPRINTK("%s: conn %d: first TST entry at %d.\n",
-		card->name, vc ? vc->index : -1, e);
-
-	r = n;
-	cl = avail;
-	data = opc & TSTE_OPC_MASK;
-	if (vc && (opc != TSTE_OPC_NULL))
-		data = opc | vc->index;
-
-	idle = card->tst[card->tst_index ^ 1];
-
-	/*
-	 * Fill Soft TST.
-	 */
-	while (r > 0) {
-		if ((cl >= avail) && (card->soft_tst[e].vc == NULL)) {
-			if (vc)
-				card->soft_tst[e].vc = vc;
-			else
-				card->soft_tst[e].vc = (void *)-1;
-
-			card->soft_tst[e].tste = data;
-			if (timer_pending(&card->tst_timer))
-				card->soft_tst[e].tste |= TSTE_PUSH_ACTIVE;
-			else {
-				write_sram(card, idle + e, data);
-				card->soft_tst[e].tste |= TSTE_PUSH_IDLE;
-			}
-
-			cl -= card->tst_size;
-			r--;
-		}
-
-		if (++e == avail)
-			e = 0;
-		cl += n;
-	}
-
-	return 0;
-}
-
-static int
-fill_tst(struct idt77252_dev *card, struct vc_map *vc, int n, unsigned int opc)
-{
-	unsigned long flags;
-	int res;
-
-	spin_lock_irqsave(&card->tst_lock, flags);
-
-	res = __fill_tst(card, vc, n, opc);
-
-	set_bit(TST_SWITCH_PENDING, &card->tst_state);
-	if (!timer_pending(&card->tst_timer))
-		mod_timer(&card->tst_timer, jiffies + 1);
-
-	spin_unlock_irqrestore(&card->tst_lock, flags);
-	return res;
-}
-
-static int
-__clear_tst(struct idt77252_dev *card, struct vc_map *vc)
-{
-	unsigned long idle;
-	int e;
-
-	idle = card->tst[card->tst_index ^ 1];
-
-	for (e = 0; e < card->tst_size - 2; e++) {
-		if (card->soft_tst[e].vc == vc) {
-			card->soft_tst[e].vc = NULL;
-
-			card->soft_tst[e].tste = TSTE_OPC_VAR;
-			if (timer_pending(&card->tst_timer))
-				card->soft_tst[e].tste |= TSTE_PUSH_ACTIVE;
-			else {
-				write_sram(card, idle + e, TSTE_OPC_VAR);
-				card->soft_tst[e].tste |= TSTE_PUSH_IDLE;
-			}
-		}
-	}
-
-	return 0;
-}
-
-static int
-clear_tst(struct idt77252_dev *card, struct vc_map *vc)
-{
-	unsigned long flags;
-	int res;
-
-	spin_lock_irqsave(&card->tst_lock, flags);
-
-	res = __clear_tst(card, vc);
-
-	set_bit(TST_SWITCH_PENDING, &card->tst_state);
-	if (!timer_pending(&card->tst_timer))
-		mod_timer(&card->tst_timer, jiffies + 1);
-
-	spin_unlock_irqrestore(&card->tst_lock, flags);
-	return res;
-}
-
-static int
-change_tst(struct idt77252_dev *card, struct vc_map *vc,
-	   int n, unsigned int opc)
-{
-	unsigned long flags;
-	int res;
-
-	spin_lock_irqsave(&card->tst_lock, flags);
-
-	__clear_tst(card, vc);
-	res = __fill_tst(card, vc, n, opc);
-
-	set_bit(TST_SWITCH_PENDING, &card->tst_state);
-	if (!timer_pending(&card->tst_timer))
-		mod_timer(&card->tst_timer, jiffies + 1);
-
-	spin_unlock_irqrestore(&card->tst_lock, flags);
-	return res;
-}
-
-
-static int
-set_tct(struct idt77252_dev *card, struct vc_map *vc)
-{
-	unsigned long tct;
-
-	tct = (unsigned long) (card->tct_base + vc->index * SAR_SRAM_TCT_SIZE);
-
-	switch (vc->class) {
-	case SCHED_CBR:
-		OPRINTK("%s: writing TCT at 0x%lx, SCD 0x%lx.\n",
-		        card->name, tct, vc->scq->scd);
-
-		write_sram(card, tct + 0, TCT_CBR | vc->scq->scd);
-		write_sram(card, tct + 1, 0);
-		write_sram(card, tct + 2, 0);
-		write_sram(card, tct + 3, 0);
-		write_sram(card, tct + 4, 0);
-		write_sram(card, tct + 5, 0);
-		write_sram(card, tct + 6, 0);
-		write_sram(card, tct + 7, 0);
-		break;
-
-	case SCHED_UBR:
-		OPRINTK("%s: writing TCT at 0x%lx, SCD 0x%lx.\n",
-		        card->name, tct, vc->scq->scd);
-
-		write_sram(card, tct + 0, TCT_UBR | vc->scq->scd);
-		write_sram(card, tct + 1, 0);
-		write_sram(card, tct + 2, TCT_TSIF);
-		write_sram(card, tct + 3, TCT_HALT | TCT_IDLE);
-		write_sram(card, tct + 4, 0);
-		write_sram(card, tct + 5, vc->init_er);
-		write_sram(card, tct + 6, 0);
-		write_sram(card, tct + 7, TCT_FLAG_UBR);
-		break;
-
-	case SCHED_VBR:
-	case SCHED_ABR:
-	default:
-		return -ENOSYS;
-	}
-
-	return 0;
-}
-
-/*****************************************************************************/
-/*                                                                           */
-/* FBQ Handling                                                              */
-/*                                                                           */
-/*****************************************************************************/
-
-static __inline__ int
-idt77252_fbq_full(struct idt77252_dev *card, int queue)
-{
-	return (readl(SAR_REG_STAT) >> (16 + (queue << 2))) == 0x0f;
-}
-
-static int
-push_rx_skb(struct idt77252_dev *card, struct sk_buff *skb, int queue)
-{
-	unsigned long flags;
-	u32 handle;
-	u32 addr;
-
-	skb->data = skb->head;
-	skb_reset_tail_pointer(skb);
-	skb->len = 0;
-
-	skb_reserve(skb, 16);
-
-	switch (queue) {
-	case 0:
-		skb_put(skb, SAR_FB_SIZE_0);
-		break;
-	case 1:
-		skb_put(skb, SAR_FB_SIZE_1);
-		break;
-	case 2:
-		skb_put(skb, SAR_FB_SIZE_2);
-		break;
-	case 3:
-		skb_put(skb, SAR_FB_SIZE_3);
-		break;
-	default:
-		return -1;
-	}
-
-	if (idt77252_fbq_full(card, queue))
-		return -1;
-
-	memset(&skb->data[(skb->len & ~(0x3f)) - 64], 0, 2 * sizeof(u32));
-
-	handle = IDT77252_PRV_POOL(skb);
-	addr = IDT77252_PRV_PADDR(skb);
-
-	spin_lock_irqsave(&card->cmd_lock, flags);
-	writel(handle, card->fbq[queue]);
-	writel(addr, card->fbq[queue]);
-	spin_unlock_irqrestore(&card->cmd_lock, flags);
-
-	return 0;
-}
-
-static void
-add_rx_skb(struct idt77252_dev *card, int queue,
-	   unsigned int size, unsigned int count)
-{
-	struct sk_buff *skb;
-	dma_addr_t paddr;
-
-	while (count--) {
-		skb = dev_alloc_skb(size);
-		if (!skb)
-			return;
-
-		if (sb_pool_add(card, skb, queue)) {
-			printk("%s: SB POOL full\n", __func__);
-			goto outfree;
-		}
-
-		paddr = dma_map_single(&card->pcidev->dev, skb->data,
-				       skb_end_pointer(skb) - skb->data,
-				       DMA_FROM_DEVICE);
-		if (dma_mapping_error(&card->pcidev->dev, paddr))
-			goto outpoolrm;
-		IDT77252_PRV_PADDR(skb) = paddr;
-
-		if (push_rx_skb(card, skb, queue)) {
-			printk("%s: FB QUEUE full\n", __func__);
-			goto outunmap;
-		}
-	}
-
-	return;
-
-outunmap:
-	dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-			 skb_end_pointer(skb) - skb->data, DMA_FROM_DEVICE);
-
-outpoolrm:
-	sb_pool_remove(card, skb);
-
-outfree:
-	dev_kfree_skb(skb);
-}
-
-
-static void
-recycle_rx_skb(struct idt77252_dev *card, struct sk_buff *skb)
-{
-	u32 handle = IDT77252_PRV_POOL(skb);
-	int err;
-
-	dma_sync_single_for_device(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-				   skb_end_pointer(skb) - skb->data,
-				   DMA_FROM_DEVICE);
-
-	err = push_rx_skb(card, skb, POOL_QUEUE(handle));
-	if (err) {
-		dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-				 skb_end_pointer(skb) - skb->data,
-				 DMA_FROM_DEVICE);
-		sb_pool_remove(card, skb);
-		dev_kfree_skb(skb);
-	}
-}
-
-static void
-flush_rx_pool(struct idt77252_dev *card, struct rx_pool *rpp)
-{
-	skb_queue_head_init(&rpp->queue);
-	rpp->len = 0;
-}
-
-static void
-recycle_rx_pool_skb(struct idt77252_dev *card, struct rx_pool *rpp)
-{
-	struct sk_buff *skb, *tmp;
-
-	skb_queue_walk_safe(&rpp->queue, skb, tmp)
-		recycle_rx_skb(card, skb);
-
-	flush_rx_pool(card, rpp);
-}
-
-/*****************************************************************************/
-/*                                                                           */
-/* ATM Interface                                                             */
-/*                                                                           */
-/*****************************************************************************/
-
-static void
-idt77252_phy_put(struct atm_dev *dev, unsigned char value, unsigned long addr)
-{
-	write_utility(dev->dev_data, 0x100 + (addr & 0x1ff), value);
-}
-
-static unsigned char
-idt77252_phy_get(struct atm_dev *dev, unsigned long addr)
-{
-	return read_utility(dev->dev_data, 0x100 + (addr & 0x1ff));
-}
-
-static inline int
-idt77252_send_skb(struct atm_vcc *vcc, struct sk_buff *skb, int oam)
-{
-	struct atm_dev *dev = vcc->dev;
-	struct idt77252_dev *card = dev->dev_data;
-	struct vc_map *vc = vcc->dev_data;
-	int err;
-
-	if (vc == NULL) {
-		printk("%s: NULL connection in send().\n", card->name);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb(skb);
-		return -EINVAL;
-	}
-	if (!test_bit(VCF_TX, &vc->flags)) {
-		printk("%s: Trying to transmit on a non-tx VC.\n", card->name);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb(skb);
-		return -EINVAL;
-	}
-
-	switch (vcc->qos.aal) {
-	case ATM_AAL0:
-	case ATM_AAL1:
-	case ATM_AAL5:
-		break;
-	default:
-		printk("%s: Unsupported AAL: %d\n", card->name, vcc->qos.aal);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb(skb);
-		return -EINVAL;
-	}
-
-	if (skb_shinfo(skb)->nr_frags != 0) {
-		printk("%s: No scatter-gather yet.\n", card->name);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb(skb);
-		return -EINVAL;
-	}
-	ATM_SKB(skb)->vcc = vcc;
-
-	err = queue_skb(card, vc, skb, oam);
-	if (err) {
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb(skb);
-		return err;
-	}
-
-	return 0;
-}
-
-static int idt77252_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	return idt77252_send_skb(vcc, skb, 0);
-}
-
-static int
-idt77252_send_oam(struct atm_vcc *vcc, void *cell, int flags)
-{
-	struct atm_dev *dev = vcc->dev;
-	struct idt77252_dev *card = dev->dev_data;
-	struct sk_buff *skb;
-
-	skb = dev_alloc_skb(64);
-	if (!skb) {
-		printk("%s: Out of memory in send_oam().\n", card->name);
-		atomic_inc(&vcc->stats->tx_err);
-		return -ENOMEM;
-	}
-	refcount_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
-
-	skb_put_data(skb, cell, 52);
-
-	return idt77252_send_skb(vcc, skb, 1);
-}
-
-static __inline__ unsigned int
-idt77252_fls(unsigned int x)
-{
-	int r = 1;
-
-	if (x == 0)
-		return 0;
-	if (x & 0xffff0000) {
-		x >>= 16;
-		r += 16;
-	}
-	if (x & 0xff00) {
-		x >>= 8;
-		r += 8;
-	}
-	if (x & 0xf0) {
-		x >>= 4;
-		r += 4;
-	}
-	if (x & 0xc) {
-		x >>= 2;
-		r += 2;
-	}
-	if (x & 0x2)
-		r += 1;
-	return r;
-}
-
-static u16
-idt77252_int_to_atmfp(unsigned int rate)
-{
-	u16 m, e;
-
-	if (rate == 0)
-		return 0;
-	e = idt77252_fls(rate) - 1;
-	if (e < 9)
-		m = (rate - (1 << e)) << (9 - e);
-	else if (e == 9)
-		m = (rate - (1 << e));
-	else /* e > 9 */
-		m = (rate - (1 << e)) >> (e - 9);
-	return 0x4000 | (e << 9) | m;
-}
-
-static u8
-idt77252_rate_logindex(struct idt77252_dev *card, int pcr)
-{
-	u16 afp;
-
-	afp = idt77252_int_to_atmfp(pcr < 0 ? -pcr : pcr);
-	if (pcr < 0)
-		return rate_to_log[(afp >> 5) & 0x1ff];
-	return rate_to_log[((afp >> 5) + 1) & 0x1ff];
-}
-
-static void
-idt77252_est_timer(struct timer_list *t)
-{
-	struct rate_estimator *est = timer_container_of(est, t, timer);
-	struct vc_map *vc = est->vc;
-	struct idt77252_dev *card = vc->card;
-	unsigned long flags;
-	u32 rate, cps;
-	u64 ncells;
-	u8 lacr;
-
-	spin_lock_irqsave(&vc->lock, flags);
-	if (!vc->estimator)
-		goto out;
-	ncells = est->cells;
-
-	rate = ((u32)(ncells - est->last_cells)) << (7 - est->interval);
-	est->last_cells = ncells;
-	est->avcps += ((long)rate - (long)est->avcps) >> est->ewma_log;
-	est->cps = (est->avcps + 0x1f) >> 5;
-
-	cps = est->cps;
-	if (cps < (est->maxcps >> 4))
-		cps = est->maxcps >> 4;
-
-	lacr = idt77252_rate_logindex(card, cps);
-	if (lacr > vc->max_er)
-		lacr = vc->max_er;
-
-	if (lacr != vc->lacr) {
-		vc->lacr = lacr;
-		writel(TCMDQ_LACR|(vc->lacr << 16)|vc->index, SAR_REG_TCMDQ);
-	}
-
-	est->timer.expires = jiffies + ((HZ / 4) << est->interval);
-	add_timer(&est->timer);
-
-out:
-	spin_unlock_irqrestore(&vc->lock, flags);
-}
-
-static struct rate_estimator *
-idt77252_init_est(struct vc_map *vc, int pcr)
-{
-	struct rate_estimator *est;
-
-	est = kzalloc_obj(struct rate_estimator);
-	if (!est)
-		return NULL;
-	est->maxcps = pcr < 0 ? -pcr : pcr;
-	est->cps = est->maxcps;
-	est->avcps = est->cps << 5;
-	est->vc = vc;
-
-	est->interval = 2;		/* XXX: make this configurable */
-	est->ewma_log = 2;		/* XXX: make this configurable */
-	timer_setup(&est->timer, idt77252_est_timer, 0);
-	mod_timer(&est->timer, jiffies + ((HZ / 4) << est->interval));
-
-	return est;
-}
-
-static int
-idt77252_init_cbr(struct idt77252_dev *card, struct vc_map *vc,
-		  struct atm_vcc *vcc, struct atm_qos *qos)
-{
-	int tst_free, tst_used, tst_entries;
-	unsigned long tmpl, modl;
-	int tcr, tcra;
-
-	if ((qos->txtp.max_pcr == 0) &&
-	    (qos->txtp.pcr == 0) && (qos->txtp.min_pcr == 0)) {
-		printk("%s: trying to open a CBR VC with cell rate = 0\n",
-		       card->name);
-		return -EINVAL;
-	}
-
-	tst_used = 0;
-	tst_free = card->tst_free;
-	if (test_bit(VCF_TX, &vc->flags))
-		tst_used = vc->ntste;
-	tst_free += tst_used;
-
-	tcr = atm_pcr_goal(&qos->txtp);
-	tcra = tcr >= 0 ? tcr : -tcr;
-
-	TXPRINTK("%s: CBR target cell rate = %d\n", card->name, tcra);
-
-	tmpl = (unsigned long) tcra * ((unsigned long) card->tst_size - 2);
-	modl = tmpl % (unsigned long)card->utopia_pcr;
-
-	tst_entries = (int) (tmpl / card->utopia_pcr);
-	if (tcr > 0) {
-		if (modl > 0)
-			tst_entries++;
-	} else if (tcr == 0) {
-		tst_entries = tst_free - SAR_TST_RESERVED;
-		if (tst_entries <= 0) {
-			printk("%s: no CBR bandwidth free.\n", card->name);
-			return -ENOSR;
-		}
-	}
-
-	if (tst_entries == 0) {
-		printk("%s: selected CBR bandwidth < granularity.\n",
-		       card->name);
-		return -EINVAL;
-	}
-
-	if (tst_entries > (tst_free - SAR_TST_RESERVED)) {
-		printk("%s: not enough CBR bandwidth free.\n", card->name);
-		return -ENOSR;
-	}
-
-	vc->ntste = tst_entries;
-
-	card->tst_free = tst_free - tst_entries;
-	if (test_bit(VCF_TX, &vc->flags)) {
-		if (tst_used == tst_entries)
-			return 0;
-
-		OPRINTK("%s: modify %d -> %d entries in TST.\n",
-			card->name, tst_used, tst_entries);
-		change_tst(card, vc, tst_entries, TSTE_OPC_CBR);
-		return 0;
-	}
-
-	OPRINTK("%s: setting %d entries in TST.\n", card->name, tst_entries);
-	fill_tst(card, vc, tst_entries, TSTE_OPC_CBR);
-	return 0;
-}
-
-static int
-idt77252_init_ubr(struct idt77252_dev *card, struct vc_map *vc,
-		  struct atm_vcc *vcc, struct atm_qos *qos)
-{
-	struct rate_estimator *est = NULL;
-	unsigned long flags;
-	int tcr;
-
-	spin_lock_irqsave(&vc->lock, flags);
-	if (vc->estimator) {
-		est = vc->estimator;
-		vc->estimator = NULL;
-	}
-	spin_unlock_irqrestore(&vc->lock, flags);
-	if (est) {
-		timer_shutdown_sync(&est->timer);
-		kfree(est);
-	}
-
-	tcr = atm_pcr_goal(&qos->txtp);
-	if (tcr == 0)
-		tcr = card->link_pcr;
-
-	vc->estimator = idt77252_init_est(vc, tcr);
-
-	vc->class = SCHED_UBR;
-	vc->init_er = idt77252_rate_logindex(card, tcr);
-	vc->lacr = vc->init_er;
-	if (tcr < 0)
-		vc->max_er = vc->init_er;
-	else
-		vc->max_er = 0xff;
-
-	return 0;
-}
-
-static int
-idt77252_init_tx(struct idt77252_dev *card, struct vc_map *vc,
-		 struct atm_vcc *vcc, struct atm_qos *qos)
-{
-	int error;
-
-	if (test_bit(VCF_TX, &vc->flags))
-		return -EBUSY;
-
-	switch (qos->txtp.traffic_class) {
-		case ATM_CBR:
-			vc->class = SCHED_CBR;
-			break;
-
-		case ATM_UBR:
-			vc->class = SCHED_UBR;
-			break;
-
-		case ATM_VBR:
-		case ATM_ABR:
-		default:
-			return -EPROTONOSUPPORT;
-	}
-
-	vc->scq = alloc_scq(card, vc->class);
-	if (!vc->scq) {
-		printk("%s: can't get SCQ.\n", card->name);
-		return -ENOMEM;
-	}
-
-	vc->scq->scd = get_free_scd(card, vc);
-	if (vc->scq->scd == 0) {
-		printk("%s: no SCD available.\n", card->name);
-		free_scq(card, vc->scq);
-		return -ENOMEM;
-	}
-
-	fill_scd(card, vc->scq, vc->class);
-
-	if (set_tct(card, vc)) {
-		printk("%s: class %d not supported.\n",
-		       card->name, qos->txtp.traffic_class);
-
-		card->scd2vc[vc->scd_index] = NULL;
-		free_scq(card, vc->scq);
-		return -EPROTONOSUPPORT;
-	}
-
-	switch (vc->class) {
-		case SCHED_CBR:
-			error = idt77252_init_cbr(card, vc, vcc, qos);
-			if (error) {
-				card->scd2vc[vc->scd_index] = NULL;
-				free_scq(card, vc->scq);
-				return error;
-			}
-
-			clear_bit(VCF_IDLE, &vc->flags);
-			writel(TCMDQ_START | vc->index, SAR_REG_TCMDQ);
-			break;
-
-		case SCHED_UBR:
-			error = idt77252_init_ubr(card, vc, vcc, qos);
-			if (error) {
-				card->scd2vc[vc->scd_index] = NULL;
-				free_scq(card, vc->scq);
-				return error;
-			}
-
-			set_bit(VCF_IDLE, &vc->flags);
-			break;
-	}
-
-	vc->tx_vcc = vcc;
-	set_bit(VCF_TX, &vc->flags);
-	return 0;
-}
-
-static int
-idt77252_init_rx(struct idt77252_dev *card, struct vc_map *vc,
-		 struct atm_vcc *vcc, struct atm_qos *qos)
-{
-	unsigned long flags;
-	unsigned long addr;
-	u32 rcte = 0;
-
-	if (test_bit(VCF_RX, &vc->flags))
-		return -EBUSY;
-
-	vc->rx_vcc = vcc;
-	set_bit(VCF_RX, &vc->flags);
-
-	if ((vcc->vci == 3) || (vcc->vci == 4))
-		return 0;
-
-	flush_rx_pool(card, &vc->rcv.rx_pool);
-
-	rcte |= SAR_RCTE_CONNECTOPEN;
-	rcte |= SAR_RCTE_RAWCELLINTEN;
-
-	switch (qos->aal) {
-		case ATM_AAL0:
-			rcte |= SAR_RCTE_RCQ;
-			break;
-		case ATM_AAL1:
-			rcte |= SAR_RCTE_OAM; /* Let SAR drop Video */
-			break;
-		case ATM_AAL34:
-			rcte |= SAR_RCTE_AAL34;
-			break;
-		case ATM_AAL5:
-			rcte |= SAR_RCTE_AAL5;
-			break;
-		default:
-			rcte |= SAR_RCTE_RCQ;
-			break;
-	}
-
-	if (qos->aal != ATM_AAL5)
-		rcte |= SAR_RCTE_FBP_1;
-	else if (qos->rxtp.max_sdu > SAR_FB_SIZE_2)
-		rcte |= SAR_RCTE_FBP_3;
-	else if (qos->rxtp.max_sdu > SAR_FB_SIZE_1)
-		rcte |= SAR_RCTE_FBP_2;
-	else if (qos->rxtp.max_sdu > SAR_FB_SIZE_0)
-		rcte |= SAR_RCTE_FBP_1;
-	else
-		rcte |= SAR_RCTE_FBP_01;
-
-	addr = card->rct_base + (vc->index << 2);
-
-	OPRINTK("%s: writing RCT at 0x%lx\n", card->name, addr);
-	write_sram(card, addr, rcte);
-
-	spin_lock_irqsave(&card->cmd_lock, flags);
-	writel(SAR_CMD_OPEN_CONNECTION | (addr << 2), SAR_REG_CMD);
-	waitfor_idle(card);
-	spin_unlock_irqrestore(&card->cmd_lock, flags);
-
-	return 0;
-}
-
-static int
-idt77252_open(struct atm_vcc *vcc)
-{
-	struct atm_dev *dev = vcc->dev;
-	struct idt77252_dev *card = dev->dev_data;
-	struct vc_map *vc;
-	unsigned int index;
-	unsigned int inuse;
-	int error;
-	int vci = vcc->vci;
-	short vpi = vcc->vpi;
-
-	if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC)
-		return 0;
-
-	if (vpi >= (1 << card->vpibits)) {
-		printk("%s: unsupported VPI: %d\n", card->name, vpi);
-		return -EINVAL;
-	}
-
-	if (vci >= (1 << card->vcibits)) {
-		printk("%s: unsupported VCI: %d\n", card->name, vci);
-		return -EINVAL;
-	}
-
-	set_bit(ATM_VF_ADDR, &vcc->flags);
-
-	mutex_lock(&card->mutex);
-
-	OPRINTK("%s: opening vpi.vci: %d.%d\n", card->name, vpi, vci);
-
-	switch (vcc->qos.aal) {
-	case ATM_AAL0:
-	case ATM_AAL1:
-	case ATM_AAL5:
-		break;
-	default:
-		printk("%s: Unsupported AAL: %d\n", card->name, vcc->qos.aal);
-		mutex_unlock(&card->mutex);
-		return -EPROTONOSUPPORT;
-	}
-
-	index = VPCI2VC(card, vpi, vci);
-	if (!card->vcs[index]) {
-		card->vcs[index] = kzalloc_obj(struct vc_map);
-		if (!card->vcs[index]) {
-			printk("%s: can't alloc vc in open()\n", card->name);
-			mutex_unlock(&card->mutex);
-			return -ENOMEM;
-		}
-		card->vcs[index]->card = card;
-		card->vcs[index]->index = index;
-
-		spin_lock_init(&card->vcs[index]->lock);
-	}
-	vc = card->vcs[index];
-
-	vcc->dev_data = vc;
-
-	IPRINTK("%s: idt77252_open: vc = %d (%d.%d) %s/%s (max RX SDU: %u)\n",
-	        card->name, vc->index, vcc->vpi, vcc->vci,
-	        vcc->qos.rxtp.traffic_class != ATM_NONE ? "rx" : "--",
-	        vcc->qos.txtp.traffic_class != ATM_NONE ? "tx" : "--",
-	        vcc->qos.rxtp.max_sdu);
-
-	inuse = 0;
-	if (vcc->qos.txtp.traffic_class != ATM_NONE &&
-	    test_bit(VCF_TX, &vc->flags))
-		inuse = 1;
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE &&
-	    test_bit(VCF_RX, &vc->flags))
-		inuse += 2;
-
-	if (inuse) {
-		printk("%s: %s vci already in use.\n", card->name,
-		       inuse == 1 ? "tx" : inuse == 2 ? "rx" : "tx and rx");
-		mutex_unlock(&card->mutex);
-		return -EADDRINUSE;
-	}
-
-	if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-		error = idt77252_init_tx(card, vc, vcc, &vcc->qos);
-		if (error) {
-			mutex_unlock(&card->mutex);
-			return error;
-		}
-	}
-
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
-		error = idt77252_init_rx(card, vc, vcc, &vcc->qos);
-		if (error) {
-			mutex_unlock(&card->mutex);
-			return error;
-		}
-	}
-
-	set_bit(ATM_VF_READY, &vcc->flags);
-
-	mutex_unlock(&card->mutex);
-	return 0;
-}
-
-static void
-idt77252_close(struct atm_vcc *vcc)
-{
-	struct atm_dev *dev = vcc->dev;
-	struct idt77252_dev *card = dev->dev_data;
-	struct vc_map *vc = vcc->dev_data;
-	unsigned long flags;
-	unsigned long addr;
-	unsigned long timeout;
-
-	mutex_lock(&card->mutex);
-
-	IPRINTK("%s: idt77252_close: vc = %d (%d.%d)\n",
-		card->name, vc->index, vcc->vpi, vcc->vci);
-
-	clear_bit(ATM_VF_READY, &vcc->flags);
-
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
-
-		spin_lock_irqsave(&vc->lock, flags);
-		clear_bit(VCF_RX, &vc->flags);
-		vc->rx_vcc = NULL;
-		spin_unlock_irqrestore(&vc->lock, flags);
-
-		if ((vcc->vci == 3) || (vcc->vci == 4))
-			goto done;
-
-		addr = card->rct_base + vc->index * SAR_SRAM_RCT_SIZE;
-
-		spin_lock_irqsave(&card->cmd_lock, flags);
-		writel(SAR_CMD_CLOSE_CONNECTION | (addr << 2), SAR_REG_CMD);
-		waitfor_idle(card);
-		spin_unlock_irqrestore(&card->cmd_lock, flags);
-
-		if (skb_queue_len(&vc->rcv.rx_pool.queue) != 0) {
-			DPRINTK("%s: closing a VC with pending rx buffers.\n",
-				card->name);
-
-			recycle_rx_pool_skb(card, &vc->rcv.rx_pool);
-		}
-	}
-
-done:
-	if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-
-		spin_lock_irqsave(&vc->lock, flags);
-		clear_bit(VCF_TX, &vc->flags);
-		clear_bit(VCF_IDLE, &vc->flags);
-		clear_bit(VCF_RSV, &vc->flags);
-		vc->tx_vcc = NULL;
-
-		if (vc->estimator) {
-			timer_shutdown(&vc->estimator->timer);
-			kfree(vc->estimator);
-			vc->estimator = NULL;
-		}
-		spin_unlock_irqrestore(&vc->lock, flags);
-
-		timeout = 5 * 1000;
-		while (atomic_read(&vc->scq->used) > 0) {
-			timeout = msleep_interruptible(timeout);
-			if (!timeout) {
-				pr_warn("%s: SCQ drain timeout: %u used\n",
-					card->name, atomic_read(&vc->scq->used));
-				break;
-			}
-		}
-
-		writel(TCMDQ_HALT | vc->index, SAR_REG_TCMDQ);
-		clear_scd(card, vc->scq, vc->class);
-
-		if (vc->class == SCHED_CBR) {
-			clear_tst(card, vc);
-			card->tst_free += vc->ntste;
-			vc->ntste = 0;
-		}
-
-		card->scd2vc[vc->scd_index] = NULL;
-		free_scq(card, vc->scq);
-	}
-
-	mutex_unlock(&card->mutex);
-}
-
-static int
-idt77252_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags)
-{
-	struct atm_dev *dev = vcc->dev;
-	struct idt77252_dev *card = dev->dev_data;
-	struct vc_map *vc = vcc->dev_data;
-	int error = 0;
-
-	mutex_lock(&card->mutex);
-
-	if (qos->txtp.traffic_class != ATM_NONE) {
-	    	if (!test_bit(VCF_TX, &vc->flags)) {
-			error = idt77252_init_tx(card, vc, vcc, qos);
-			if (error)
-				goto out;
-		} else {
-			switch (qos->txtp.traffic_class) {
-			case ATM_CBR:
-				error = idt77252_init_cbr(card, vc, vcc, qos);
-				if (error)
-					goto out;
-				break;
-
-			case ATM_UBR:
-				error = idt77252_init_ubr(card, vc, vcc, qos);
-				if (error)
-					goto out;
-
-				if (!test_bit(VCF_IDLE, &vc->flags)) {
-					writel(TCMDQ_LACR | (vc->lacr << 16) |
-					       vc->index, SAR_REG_TCMDQ);
-				}
-				break;
-
-			case ATM_VBR:
-			case ATM_ABR:
-				error = -EOPNOTSUPP;
-				goto out;
-			}
-		}
-	}
-
-	if ((qos->rxtp.traffic_class != ATM_NONE) &&
-	    !test_bit(VCF_RX, &vc->flags)) {
-		error = idt77252_init_rx(card, vc, vcc, qos);
-		if (error)
-			goto out;
-	}
-
-	memcpy(&vcc->qos, qos, sizeof(struct atm_qos));
-
-	set_bit(ATM_VF_HASQOS, &vcc->flags);
-
-out:
-	mutex_unlock(&card->mutex);
-	return error;
-}
-
-static int
-idt77252_proc_read(struct atm_dev *dev, loff_t * pos, char *page)
-{
-	struct idt77252_dev *card = dev->dev_data;
-	int i, left;
-
-	left = (int) *pos;
-	if (!left--)
-		return sprintf(page, "IDT77252 Interrupts:\n");
-	if (!left--)
-		return sprintf(page, "TSIF:  %lu\n", card->irqstat[15]);
-	if (!left--)
-		return sprintf(page, "TXICP: %lu\n", card->irqstat[14]);
-	if (!left--)
-		return sprintf(page, "TSQF:  %lu\n", card->irqstat[12]);
-	if (!left--)
-		return sprintf(page, "TMROF: %lu\n", card->irqstat[11]);
-	if (!left--)
-		return sprintf(page, "PHYI:  %lu\n", card->irqstat[10]);
-	if (!left--)
-		return sprintf(page, "FBQ3A: %lu\n", card->irqstat[8]);
-	if (!left--)
-		return sprintf(page, "FBQ2A: %lu\n", card->irqstat[7]);
-	if (!left--)
-		return sprintf(page, "RSQF:  %lu\n", card->irqstat[6]);
-	if (!left--)
-		return sprintf(page, "EPDU:  %lu\n", card->irqstat[5]);
-	if (!left--)
-		return sprintf(page, "RAWCF: %lu\n", card->irqstat[4]);
-	if (!left--)
-		return sprintf(page, "FBQ1A: %lu\n", card->irqstat[3]);
-	if (!left--)
-		return sprintf(page, "FBQ0A: %lu\n", card->irqstat[2]);
-	if (!left--)
-		return sprintf(page, "RSQAF: %lu\n", card->irqstat[1]);
-	if (!left--)
-		return sprintf(page, "IDT77252 Transmit Connection Table:\n");
-
-	for (i = 0; i < card->tct_size; i++) {
-		unsigned long tct;
-		struct atm_vcc *vcc;
-		struct vc_map *vc;
-		char *p;
-
-		vc = card->vcs[i];
-		if (!vc)
-			continue;
-
-		vcc = NULL;
-		if (vc->tx_vcc)
-			vcc = vc->tx_vcc;
-		if (!vcc)
-			continue;
-		if (left--)
-			continue;
-
-		p = page;
-		p += sprintf(p, "  %4u: %u.%u: ", i, vcc->vpi, vcc->vci);
-		tct = (unsigned long) (card->tct_base + i * SAR_SRAM_TCT_SIZE);
-
-		for (i = 0; i < 8; i++)
-			p += sprintf(p, " %08x", read_sram(card, tct + i));
-		p += sprintf(p, "\n");
-		return p - page;
-	}
-	return 0;
-}
-
-/*****************************************************************************/
-/*                                                                           */
-/* Interrupt handler                                                         */
-/*                                                                           */
-/*****************************************************************************/
-
-static void
-idt77252_collect_stat(struct idt77252_dev *card)
-{
-	(void) readl(SAR_REG_CDC);
-	(void) readl(SAR_REG_VPEC);
-	(void) readl(SAR_REG_ICC);
-
-}
-
-static irqreturn_t
-idt77252_interrupt(int irq, void *dev_id)
-{
-	struct idt77252_dev *card = dev_id;
-	u32 stat;
-
-	stat = readl(SAR_REG_STAT) & 0xffff;
-	if (!stat)	/* no interrupt for us */
-		return IRQ_NONE;
-
-	if (test_and_set_bit(IDT77252_BIT_INTERRUPT, &card->flags)) {
-		printk("%s: Re-entering irq_handler()\n", card->name);
-		goto out;
-	}
-
-	writel(stat, SAR_REG_STAT);	/* reset interrupt */
-
-	if (stat & SAR_STAT_TSIF) {	/* entry written to TSQ  */
-		INTPRINTK("%s: TSIF\n", card->name);
-		card->irqstat[15]++;
-		idt77252_tx(card);
-	}
-	if (stat & SAR_STAT_TXICP) {	/* Incomplete CS-PDU has  */
-		INTPRINTK("%s: TXICP\n", card->name);
-		card->irqstat[14]++;
-#ifdef CONFIG_ATM_IDT77252_DEBUG
-		idt77252_tx_dump(card);
-#endif
-	}
-	if (stat & SAR_STAT_TSQF) {	/* TSQ 7/8 full           */
-		INTPRINTK("%s: TSQF\n", card->name);
-		card->irqstat[12]++;
-		idt77252_tx(card);
-	}
-	if (stat & SAR_STAT_TMROF) {	/* Timer overflow         */
-		INTPRINTK("%s: TMROF\n", card->name);
-		card->irqstat[11]++;
-		idt77252_collect_stat(card);
-	}
-
-	if (stat & SAR_STAT_EPDU) {	/* Got complete CS-PDU    */
-		INTPRINTK("%s: EPDU\n", card->name);
-		card->irqstat[5]++;
-		idt77252_rx(card);
-	}
-	if (stat & SAR_STAT_RSQAF) {	/* RSQ is 7/8 full        */
-		INTPRINTK("%s: RSQAF\n", card->name);
-		card->irqstat[1]++;
-		idt77252_rx(card);
-	}
-	if (stat & SAR_STAT_RSQF) {	/* RSQ is full            */
-		INTPRINTK("%s: RSQF\n", card->name);
-		card->irqstat[6]++;
-		idt77252_rx(card);
-	}
-	if (stat & SAR_STAT_RAWCF) {	/* Raw cell received      */
-		INTPRINTK("%s: RAWCF\n", card->name);
-		card->irqstat[4]++;
-		idt77252_rx_raw(card);
-	}
-
-	if (stat & SAR_STAT_PHYI) {	/* PHY device interrupt   */
-		INTPRINTK("%s: PHYI", card->name);
-		card->irqstat[10]++;
-		if (card->atmdev->phy && card->atmdev->phy->interrupt)
-			card->atmdev->phy->interrupt(card->atmdev);
-	}
-
-	if (stat & (SAR_STAT_FBQ0A | SAR_STAT_FBQ1A |
-		    SAR_STAT_FBQ2A | SAR_STAT_FBQ3A)) {
-
-		writel(readl(SAR_REG_CFG) & ~(SAR_CFG_FBIE), SAR_REG_CFG);
-
-		INTPRINTK("%s: FBQA: %04x\n", card->name, stat);
-
-		if (stat & SAR_STAT_FBQ0A)
-			card->irqstat[2]++;
-		if (stat & SAR_STAT_FBQ1A)
-			card->irqstat[3]++;
-		if (stat & SAR_STAT_FBQ2A)
-			card->irqstat[7]++;
-		if (stat & SAR_STAT_FBQ3A)
-			card->irqstat[8]++;
-
-		schedule_work(&card->tqueue);
-	}
-
-out:
-	clear_bit(IDT77252_BIT_INTERRUPT, &card->flags);
-	return IRQ_HANDLED;
-}
-
-static void
-idt77252_softint(struct work_struct *work)
-{
-	struct idt77252_dev *card =
-		container_of(work, struct idt77252_dev, tqueue);
-	u32 stat;
-	int done;
-
-	for (done = 1; ; done = 1) {
-		stat = readl(SAR_REG_STAT) >> 16;
-
-		if ((stat & 0x0f) < SAR_FBQ0_HIGH) {
-			add_rx_skb(card, 0, SAR_FB_SIZE_0, 32);
-			done = 0;
-		}
-
-		stat >>= 4;
-		if ((stat & 0x0f) < SAR_FBQ1_HIGH) {
-			add_rx_skb(card, 1, SAR_FB_SIZE_1, 32);
-			done = 0;
-		}
-
-		stat >>= 4;
-		if ((stat & 0x0f) < SAR_FBQ2_HIGH) {
-			add_rx_skb(card, 2, SAR_FB_SIZE_2, 32);
-			done = 0;
-		}
-
-		stat >>= 4;
-		if ((stat & 0x0f) < SAR_FBQ3_HIGH) {
-			add_rx_skb(card, 3, SAR_FB_SIZE_3, 32);
-			done = 0;
-		}
-
-		if (done)
-			break;
-	}
-
-	writel(readl(SAR_REG_CFG) | SAR_CFG_FBIE, SAR_REG_CFG);
-}
-
-
-static int
-open_card_oam(struct idt77252_dev *card)
-{
-	unsigned long flags;
-	unsigned long addr;
-	struct vc_map *vc;
-	int vpi, vci;
-	int index;
-	u32 rcte;
-
-	for (vpi = 0; vpi < (1 << card->vpibits); vpi++) {
-		for (vci = 3; vci < 5; vci++) {
-			index = VPCI2VC(card, vpi, vci);
-
-			vc = kzalloc_obj(struct vc_map);
-			if (!vc) {
-				printk("%s: can't alloc vc\n", card->name);
-				return -ENOMEM;
-			}
-			vc->index = index;
-			card->vcs[index] = vc;
-
-			flush_rx_pool(card, &vc->rcv.rx_pool);
-
-			rcte = SAR_RCTE_CONNECTOPEN |
-			       SAR_RCTE_RAWCELLINTEN |
-			       SAR_RCTE_RCQ |
-			       SAR_RCTE_FBP_1;
-
-			addr = card->rct_base + (vc->index << 2);
-			write_sram(card, addr, rcte);
-
-			spin_lock_irqsave(&card->cmd_lock, flags);
-			writel(SAR_CMD_OPEN_CONNECTION | (addr << 2),
-			       SAR_REG_CMD);
-			waitfor_idle(card);
-			spin_unlock_irqrestore(&card->cmd_lock, flags);
-		}
-	}
-
-	return 0;
-}
-
-static void
-close_card_oam(struct idt77252_dev *card)
-{
-	unsigned long flags;
-	unsigned long addr;
-	struct vc_map *vc;
-	int vpi, vci;
-	int index;
-
-	for (vpi = 0; vpi < (1 << card->vpibits); vpi++) {
-		for (vci = 3; vci < 5; vci++) {
-			index = VPCI2VC(card, vpi, vci);
-			vc = card->vcs[index];
-
-			addr = card->rct_base + vc->index * SAR_SRAM_RCT_SIZE;
-
-			spin_lock_irqsave(&card->cmd_lock, flags);
-			writel(SAR_CMD_CLOSE_CONNECTION | (addr << 2),
-			       SAR_REG_CMD);
-			waitfor_idle(card);
-			spin_unlock_irqrestore(&card->cmd_lock, flags);
-
-			if (skb_queue_len(&vc->rcv.rx_pool.queue) != 0) {
-				DPRINTK("%s: closing a VC "
-					"with pending rx buffers.\n",
-					card->name);
-
-				recycle_rx_pool_skb(card, &vc->rcv.rx_pool);
-			}
-			kfree(vc);
-		}
-	}
-}
-
-static int
-open_card_ubr0(struct idt77252_dev *card)
-{
-	struct vc_map *vc;
-
-	vc = kzalloc_obj(struct vc_map);
-	if (!vc) {
-		printk("%s: can't alloc vc\n", card->name);
-		return -ENOMEM;
-	}
-	card->vcs[0] = vc;
-	vc->class = SCHED_UBR0;
-
-	vc->scq = alloc_scq(card, vc->class);
-	if (!vc->scq) {
-		printk("%s: can't get SCQ.\n", card->name);
-		kfree(card->vcs[0]);
-		card->vcs[0] = NULL;
-		return -ENOMEM;
-	}
-
-	card->scd2vc[0] = vc;
-	vc->scd_index = 0;
-	vc->scq->scd = card->scd_base;
-
-	fill_scd(card, vc->scq, vc->class);
-
-	write_sram(card, card->tct_base + 0, TCT_UBR | card->scd_base);
-	write_sram(card, card->tct_base + 1, 0);
-	write_sram(card, card->tct_base + 2, 0);
-	write_sram(card, card->tct_base + 3, 0);
-	write_sram(card, card->tct_base + 4, 0);
-	write_sram(card, card->tct_base + 5, 0);
-	write_sram(card, card->tct_base + 6, 0);
-	write_sram(card, card->tct_base + 7, TCT_FLAG_UBR);
-
-	clear_bit(VCF_IDLE, &vc->flags);
-	writel(TCMDQ_START | 0, SAR_REG_TCMDQ);
-	return 0;
-}
-
-static void
-close_card_ubr0(struct idt77252_dev *card)
-{
-	struct vc_map *vc = card->vcs[0];
-
-	free_scq(card, vc->scq);
-	kfree(vc);
-}
-
-static int
-idt77252_dev_open(struct idt77252_dev *card)
-{
-	u32 conf;
-
-	if (!test_bit(IDT77252_BIT_INIT, &card->flags)) {
-		printk("%s: SAR not yet initialized.\n", card->name);
-		return -1;
-	}
-
-	conf = SAR_CFG_RXPTH|	/* enable receive path                  */
-	    SAR_RX_DELAY |	/* interrupt on complete PDU		*/
-	    SAR_CFG_RAWIE |	/* interrupt enable on raw cells        */
-	    SAR_CFG_RQFIE |	/* interrupt on RSQ almost full         */
-	    SAR_CFG_TMOIE |	/* interrupt on timer overflow          */
-	    SAR_CFG_FBIE |	/* interrupt on low free buffers        */
-	    SAR_CFG_TXEN |	/* transmit operation enable            */
-	    SAR_CFG_TXINT |	/* interrupt on transmit status         */
-	    SAR_CFG_TXUIE |	/* interrupt on transmit underrun       */
-	    SAR_CFG_TXSFI |	/* interrupt on TSQ almost full         */
-	    SAR_CFG_PHYIE	/* enable PHY interrupts		*/
-	    ;
-
-#ifdef CONFIG_ATM_IDT77252_RCV_ALL
-	/* Test RAW cell receive. */
-	conf |= SAR_CFG_VPECA;
-#endif
-
-	writel(readl(SAR_REG_CFG) | conf, SAR_REG_CFG);
-
-	if (open_card_oam(card)) {
-		printk("%s: Error initializing OAM.\n", card->name);
-		return -1;
-	}
-
-	if (open_card_ubr0(card)) {
-		printk("%s: Error initializing UBR0.\n", card->name);
-		return -1;
-	}
-
-	IPRINTK("%s: opened IDT77252 ABR SAR.\n", card->name);
-	return 0;
-}
-
-static void idt77252_dev_close(struct atm_dev *dev)
-{
-	struct idt77252_dev *card = dev->dev_data;
-	u32 conf;
-
-	close_card_ubr0(card);
-	close_card_oam(card);
-
-	conf = SAR_CFG_RXPTH |	/* enable receive path           */
-	    SAR_RX_DELAY |	/* interrupt on complete PDU     */
-	    SAR_CFG_RAWIE |	/* interrupt enable on raw cells */
-	    SAR_CFG_RQFIE |	/* interrupt on RSQ almost full  */
-	    SAR_CFG_TMOIE |	/* interrupt on timer overflow   */
-	    SAR_CFG_FBIE |	/* interrupt on low free buffers */
-	    SAR_CFG_TXEN |	/* transmit operation enable     */
-	    SAR_CFG_TXINT |	/* interrupt on transmit status  */
-	    SAR_CFG_TXUIE |	/* interrupt on xmit underrun    */
-	    SAR_CFG_TXSFI	/* interrupt on TSQ almost full  */
-	    ;
-
-	writel(readl(SAR_REG_CFG) & ~(conf), SAR_REG_CFG);
-
-	DIPRINTK("%s: closed IDT77252 ABR SAR.\n", card->name);
-}
-
-
-/*****************************************************************************/
-/*                                                                           */
-/* Initialisation and Deinitialization of IDT77252                           */
-/*                                                                           */
-/*****************************************************************************/
-
-
-static void
-deinit_card(struct idt77252_dev *card)
-{
-	struct sk_buff *skb;
-	int i, j;
-
-	if (!test_bit(IDT77252_BIT_INIT, &card->flags)) {
-		printk("%s: SAR not yet initialized.\n", card->name);
-		return;
-	}
-	DIPRINTK("idt77252: deinitialize card %u\n", card->index);
-
-	writel(0, SAR_REG_CFG);
-
-	if (card->atmdev)
-		atm_dev_deregister(card->atmdev);
-
-	for (i = 0; i < 4; i++) {
-		for (j = 0; j < FBQ_SIZE; j++) {
-			skb = card->sbpool[i].skb[j];
-			if (skb) {
-				dma_unmap_single(&card->pcidev->dev,
-						 IDT77252_PRV_PADDR(skb),
-						 (skb_end_pointer(skb) -
-						  skb->data),
-						 DMA_FROM_DEVICE);
-				card->sbpool[i].skb[j] = NULL;
-				dev_kfree_skb(skb);
-			}
-		}
-	}
-
-	vfree(card->soft_tst);
-
-	vfree(card->scd2vc);
-
-	vfree(card->vcs);
-
-	if (card->raw_cell_hnd) {
-		dma_free_coherent(&card->pcidev->dev, 2 * sizeof(u32),
-				  card->raw_cell_hnd, card->raw_cell_paddr);
-	}
-
-	if (card->rsq.base) {
-		DIPRINTK("%s: Release RSQ ...\n", card->name);
-		deinit_rsq(card);
-	}
-
-	if (card->tsq.base) {
-		DIPRINTK("%s: Release TSQ ...\n", card->name);
-		deinit_tsq(card);
-	}
-
-	DIPRINTK("idt77252: Release IRQ.\n");
-	free_irq(card->pcidev->irq, card);
-
-	for (i = 0; i < 4; i++) {
-		if (card->fbq[i])
-			iounmap(card->fbq[i]);
-	}
-
-	if (card->membase)
-		iounmap(card->membase);
-
-	clear_bit(IDT77252_BIT_INIT, &card->flags);
-	DIPRINTK("%s: Card deinitialized.\n", card->name);
-}
-
-
-static void init_sram(struct idt77252_dev *card)
-{
-	int i;
-
-	for (i = 0; i < card->sramsize; i += 4)
-		write_sram(card, (i >> 2), 0);
-
-	/* set SRAM layout for THIS card */
-	if (card->sramsize == (512 * 1024)) {
-		card->tct_base = SAR_SRAM_TCT_128_BASE;
-		card->tct_size = (SAR_SRAM_TCT_128_TOP - card->tct_base + 1)
-		    / SAR_SRAM_TCT_SIZE;
-		card->rct_base = SAR_SRAM_RCT_128_BASE;
-		card->rct_size = (SAR_SRAM_RCT_128_TOP - card->rct_base + 1)
-		    / SAR_SRAM_RCT_SIZE;
-		card->rt_base = SAR_SRAM_RT_128_BASE;
-		card->scd_base = SAR_SRAM_SCD_128_BASE;
-		card->scd_size = (SAR_SRAM_SCD_128_TOP - card->scd_base + 1)
-		    / SAR_SRAM_SCD_SIZE;
-		card->tst[0] = SAR_SRAM_TST1_128_BASE;
-		card->tst[1] = SAR_SRAM_TST2_128_BASE;
-		card->tst_size = SAR_SRAM_TST1_128_TOP - card->tst[0] + 1;
-		card->abrst_base = SAR_SRAM_ABRSTD_128_BASE;
-		card->abrst_size = SAR_ABRSTD_SIZE_8K;
-		card->fifo_base = SAR_SRAM_FIFO_128_BASE;
-		card->fifo_size = SAR_RXFD_SIZE_32K;
-	} else {
-		card->tct_base = SAR_SRAM_TCT_32_BASE;
-		card->tct_size = (SAR_SRAM_TCT_32_TOP - card->tct_base + 1)
-		    / SAR_SRAM_TCT_SIZE;
-		card->rct_base = SAR_SRAM_RCT_32_BASE;
-		card->rct_size = (SAR_SRAM_RCT_32_TOP - card->rct_base + 1)
-		    / SAR_SRAM_RCT_SIZE;
-		card->rt_base = SAR_SRAM_RT_32_BASE;
-		card->scd_base = SAR_SRAM_SCD_32_BASE;
-		card->scd_size = (SAR_SRAM_SCD_32_TOP - card->scd_base + 1)
-		    / SAR_SRAM_SCD_SIZE;
-		card->tst[0] = SAR_SRAM_TST1_32_BASE;
-		card->tst[1] = SAR_SRAM_TST2_32_BASE;
-		card->tst_size = (SAR_SRAM_TST1_32_TOP - card->tst[0] + 1);
-		card->abrst_base = SAR_SRAM_ABRSTD_32_BASE;
-		card->abrst_size = SAR_ABRSTD_SIZE_1K;
-		card->fifo_base = SAR_SRAM_FIFO_32_BASE;
-		card->fifo_size = SAR_RXFD_SIZE_4K;
-	}
-
-	/* Initialize TCT */
-	for (i = 0; i < card->tct_size; i++) {
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 0, 0);
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 1, 0);
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 2, 0);
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 3, 0);
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 4, 0);
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 5, 0);
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 6, 0);
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 7, 0);
-	}
-
-	/* Initialize RCT */
-	for (i = 0; i < card->rct_size; i++) {
-		write_sram(card, card->rct_base + i * SAR_SRAM_RCT_SIZE,
-				    (u32) SAR_RCTE_RAWCELLINTEN);
-		write_sram(card, card->rct_base + i * SAR_SRAM_RCT_SIZE + 1,
-				    (u32) 0);
-		write_sram(card, card->rct_base + i * SAR_SRAM_RCT_SIZE + 2,
-				    (u32) 0);
-		write_sram(card, card->rct_base + i * SAR_SRAM_RCT_SIZE + 3,
-				    (u32) 0xffffffff);
-	}
-
-	writel((SAR_FBQ0_LOW << 28) | (SAR_FB_SIZE_0 / 48), SAR_REG_FBQS0);
-	writel((SAR_FBQ1_LOW << 28) | (SAR_FB_SIZE_1 / 48), SAR_REG_FBQS1);
-	writel((SAR_FBQ2_LOW << 28) | (SAR_FB_SIZE_2 / 48), SAR_REG_FBQS2);
-	writel((SAR_FBQ3_LOW << 28) | (SAR_FB_SIZE_3 / 48), SAR_REG_FBQS3);
-
-	/* Initialize rate table  */
-	for (i = 0; i < 256; i++) {
-		write_sram(card, card->rt_base + i, log_to_rate[i]);
-	}
-
-	for (i = 0; i < 128; i++) {
-		unsigned int tmp;
-
-		tmp  = rate_to_log[(i << 2) + 0] << 0;
-		tmp |= rate_to_log[(i << 2) + 1] << 8;
-		tmp |= rate_to_log[(i << 2) + 2] << 16;
-		tmp |= rate_to_log[(i << 2) + 3] << 24;
-		write_sram(card, card->rt_base + 256 + i, tmp);
-	}
-
-#if 0 /* Fill RDF and AIR tables. */
-	for (i = 0; i < 128; i++) {
-		unsigned int tmp;
-
-		tmp = RDF[0][(i << 1) + 0] << 16;
-		tmp |= RDF[0][(i << 1) + 1] << 0;
-		write_sram(card, card->rt_base + 512 + i, tmp);
-	}
-
-	for (i = 0; i < 128; i++) {
-		unsigned int tmp;
-
-		tmp = AIR[0][(i << 1) + 0] << 16;
-		tmp |= AIR[0][(i << 1) + 1] << 0;
-		write_sram(card, card->rt_base + 640 + i, tmp);
-	}
-#endif
-
-	IPRINTK("%s: initialize rate table ...\n", card->name);
-	writel(card->rt_base << 2, SAR_REG_RTBL);
-
-	/* Initialize TSTs */
-	IPRINTK("%s: initialize TST ...\n", card->name);
-	card->tst_free = card->tst_size - 2;	/* last two are jumps */
-
-	for (i = card->tst[0]; i < card->tst[0] + card->tst_size - 2; i++)
-		write_sram(card, i, TSTE_OPC_VAR);
-	write_sram(card, i++, TSTE_OPC_JMP | (card->tst[0] << 2));
-	idt77252_sram_write_errors = 1;
-	write_sram(card, i++, TSTE_OPC_JMP | (card->tst[1] << 2));
-	idt77252_sram_write_errors = 0;
-	for (i = card->tst[1]; i < card->tst[1] + card->tst_size - 2; i++)
-		write_sram(card, i, TSTE_OPC_VAR);
-	write_sram(card, i++, TSTE_OPC_JMP | (card->tst[1] << 2));
-	idt77252_sram_write_errors = 1;
-	write_sram(card, i++, TSTE_OPC_JMP | (card->tst[0] << 2));
-	idt77252_sram_write_errors = 0;
-
-	card->tst_index = 0;
-	writel(card->tst[0] << 2, SAR_REG_TSTB);
-
-	/* Initialize ABRSTD and Receive FIFO */
-	IPRINTK("%s: initialize ABRSTD ...\n", card->name);
-	writel(card->abrst_size | (card->abrst_base << 2),
-	       SAR_REG_ABRSTD);
-
-	IPRINTK("%s: initialize receive fifo ...\n", card->name);
-	writel(card->fifo_size | (card->fifo_base << 2),
-	       SAR_REG_RXFD);
-
-	IPRINTK("%s: SRAM initialization complete.\n", card->name);
-}
-
-static int init_card(struct atm_dev *dev)
-{
-	struct idt77252_dev *card = dev->dev_data;
-	struct pci_dev *pcidev = card->pcidev;
-	unsigned long tmpl, modl;
-	unsigned int linkrate, rsvdcr;
-	unsigned int tst_entries;
-	struct net_device *tmp;
-	char tname[10];
-
-	u32 size;
-	u_char pci_byte;
-	u32 conf;
-	int i, k;
-
-	if (test_bit(IDT77252_BIT_INIT, &card->flags)) {
-		printk("Error: SAR already initialized.\n");
-		return -1;
-	}
-
-/*****************************************************************/
-/*   P C I   C O N F I G U R A T I O N                           */
-/*****************************************************************/
-
-	/* Set PCI Retry-Timeout and TRDY timeout */
-	IPRINTK("%s: Checking PCI retries.\n", card->name);
-	if (pci_read_config_byte(pcidev, 0x40, &pci_byte) != 0) {
-		printk("%s: can't read PCI retry timeout.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-	if (pci_byte != 0) {
-		IPRINTK("%s: PCI retry timeout: %d, set to 0.\n",
-			card->name, pci_byte);
-		if (pci_write_config_byte(pcidev, 0x40, 0) != 0) {
-			printk("%s: can't set PCI retry timeout.\n",
-			       card->name);
-			deinit_card(card);
-			return -1;
-		}
-	}
-	IPRINTK("%s: Checking PCI TRDY.\n", card->name);
-	if (pci_read_config_byte(pcidev, 0x41, &pci_byte) != 0) {
-		printk("%s: can't read PCI TRDY timeout.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-	if (pci_byte != 0) {
-		IPRINTK("%s: PCI TRDY timeout: %d, set to 0.\n",
-		        card->name, pci_byte);
-		if (pci_write_config_byte(pcidev, 0x41, 0) != 0) {
-			printk("%s: can't set PCI TRDY timeout.\n", card->name);
-			deinit_card(card);
-			return -1;
-		}
-	}
-	/* Reset Timer register */
-	if (readl(SAR_REG_STAT) & SAR_STAT_TMROF) {
-		printk("%s: resetting timer overflow.\n", card->name);
-		writel(SAR_STAT_TMROF, SAR_REG_STAT);
-	}
-	IPRINTK("%s: Request IRQ ... ", card->name);
-	if (request_irq(pcidev->irq, idt77252_interrupt, IRQF_SHARED,
-			card->name, card) != 0) {
-		printk("%s: can't allocate IRQ.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-	IPRINTK("got %d.\n", pcidev->irq);
-
-/*****************************************************************/
-/*   C H E C K   A N D   I N I T   S R A M                       */
-/*****************************************************************/
-
-	IPRINTK("%s: Initializing SRAM\n", card->name);
-
-	/* preset size of connecton table, so that init_sram() knows about it */
-	conf =	SAR_CFG_TX_FIFO_SIZE_9 |	/* Use maximum fifo size */
-		SAR_CFG_RXSTQ_SIZE_8k |		/* Receive Status Queue is 8k */
-		SAR_CFG_IDLE_CLP |		/* Set CLP on idle cells */
-#ifndef ATM_IDT77252_SEND_IDLE
-		SAR_CFG_NO_IDLE |		/* Do not send idle cells */
-#endif
-		0;
-
-	if (card->sramsize == (512 * 1024))
-		conf |= SAR_CFG_CNTBL_1k;
-	else
-		conf |= SAR_CFG_CNTBL_512;
-
-	switch (vpibits) {
-	case 0:
-		conf |= SAR_CFG_VPVCS_0;
-		break;
-	default:
-	case 1:
-		conf |= SAR_CFG_VPVCS_1;
-		break;
-	case 2:
-		conf |= SAR_CFG_VPVCS_2;
-		break;
-	case 8:
-		conf |= SAR_CFG_VPVCS_8;
-		break;
-	}
-
-	writel(readl(SAR_REG_CFG) | conf, SAR_REG_CFG);
-
-	init_sram(card);
-
-/********************************************************************/
-/*  A L L O C   R A M   A N D   S E T   V A R I O U S   T H I N G S */
-/********************************************************************/
-	/* Initialize TSQ */
-	if (0 != init_tsq(card)) {
-		deinit_card(card);
-		return -1;
-	}
-	/* Initialize RSQ */
-	if (0 != init_rsq(card)) {
-		deinit_card(card);
-		return -1;
-	}
-
-	card->vpibits = vpibits;
-	if (card->sramsize == (512 * 1024)) {
-		card->vcibits = 10 - card->vpibits;
-	} else {
-		card->vcibits = 9 - card->vpibits;
-	}
-
-	card->vcimask = 0;
-	for (k = 0, i = 1; k < card->vcibits; k++) {
-		card->vcimask |= i;
-		i <<= 1;
-	}
-
-	IPRINTK("%s: Setting VPI/VCI mask to zero.\n", card->name);
-	writel(0, SAR_REG_VPM);
-
-	/* Little Endian Order   */
-	writel(0, SAR_REG_GP);
-
-	/* Initialize RAW Cell Handle Register  */
-	card->raw_cell_hnd = dma_alloc_coherent(&card->pcidev->dev,
-						2 * sizeof(u32),
-						&card->raw_cell_paddr,
-						GFP_KERNEL);
-	if (!card->raw_cell_hnd) {
-		printk("%s: memory allocation failure.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-	writel(card->raw_cell_paddr, SAR_REG_RAWHND);
-	IPRINTK("%s: raw cell handle is at 0x%p.\n", card->name,
-		card->raw_cell_hnd);
-
-	size = sizeof(struct vc_map *) * card->tct_size;
-	IPRINTK("%s: allocate %d byte for VC map.\n", card->name, size);
-	card->vcs = vzalloc(size);
-	if (!card->vcs) {
-		printk("%s: memory allocation failure.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-
-	size = sizeof(struct vc_map *) * card->scd_size;
-	IPRINTK("%s: allocate %d byte for SCD to VC mapping.\n",
-	        card->name, size);
-	card->scd2vc = vzalloc(size);
-	if (!card->scd2vc) {
-		printk("%s: memory allocation failure.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-
-	size = sizeof(struct tst_info) * (card->tst_size - 2);
-	IPRINTK("%s: allocate %d byte for TST to VC mapping.\n",
-		card->name, size);
-	card->soft_tst = vmalloc(size);
-	if (!card->soft_tst) {
-		printk("%s: memory allocation failure.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-	for (i = 0; i < card->tst_size - 2; i++) {
-		card->soft_tst[i].tste = TSTE_OPC_VAR;
-		card->soft_tst[i].vc = NULL;
-	}
-
-	if (dev->phy == NULL) {
-		printk("%s: No LT device defined.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-	if (dev->phy->ioctl == NULL) {
-		printk("%s: LT had no IOCTL function defined.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-
-#ifdef	CONFIG_ATM_IDT77252_USE_SUNI
-	/*
-	 * this is a jhs hack to get around special functionality in the
-	 * phy driver for the atecom hardware; the functionality doesn't
-	 * exist in the linux atm suni driver
-	 *
-	 * it isn't the right way to do things, but as the guy from NIST
-	 * said, talking about their measurement of the fine structure
-	 * constant, "it's good enough for government work."
-	 */
-	linkrate = 149760000;
-#endif
-
-	card->link_pcr = (linkrate / 8 / 53);
-	printk("%s: Linkrate on ATM line : %u bit/s, %u cell/s.\n",
-	       card->name, linkrate, card->link_pcr);
-
-#ifdef ATM_IDT77252_SEND_IDLE
-	card->utopia_pcr = card->link_pcr;
-#else
-	card->utopia_pcr = (160000000 / 8 / 54);
-#endif
-
-	rsvdcr = 0;
-	if (card->utopia_pcr > card->link_pcr)
-		rsvdcr = card->utopia_pcr - card->link_pcr;
-
-	tmpl = (unsigned long) rsvdcr * ((unsigned long) card->tst_size - 2);
-	modl = tmpl % (unsigned long)card->utopia_pcr;
-	tst_entries = (int) (tmpl / (unsigned long)card->utopia_pcr);
-	if (modl)
-		tst_entries++;
-	card->tst_free -= tst_entries;
-	fill_tst(card, NULL, tst_entries, TSTE_OPC_NULL);
-
-#ifdef HAVE_EEPROM
-	idt77252_eeprom_init(card);
-	printk("%s: EEPROM: %02x:", card->name,
-		idt77252_eeprom_read_status(card));
-
-	for (i = 0; i < 0x80; i++) {
-		printk(" %02x", 
-		idt77252_eeprom_read_byte(card, i)
-		);
-	}
-	printk("\n");
-#endif /* HAVE_EEPROM */
-
-	/*
-	 * XXX: <hack>
-	 */
-	sprintf(tname, "eth%d", card->index);
-	tmp = dev_get_by_name(&init_net, tname);	/* jhs: was "tmp = dev_get(tname);" */
-	if (tmp) {
-		memcpy(card->atmdev->esi, tmp->dev_addr, 6);
-		dev_put(tmp);
-		printk("%s: ESI %pM\n", card->name, card->atmdev->esi);
-	}
-	/*
-	 * XXX: </hack>
-	 */
-
-	/* Set Maximum Deficit Count for now. */
-	writel(0xffff, SAR_REG_MDFCT);
-
-	set_bit(IDT77252_BIT_INIT, &card->flags);
-
-	XPRINTK("%s: IDT77252 ABR SAR initialization complete.\n", card->name);
-	return 0;
-}
-
-
-/*****************************************************************************/
-/*                                                                           */
-/* Probing of IDT77252 ABR SAR                                               */
-/*                                                                           */
-/*****************************************************************************/
-
-
-static int idt77252_preset(struct idt77252_dev *card)
-{
-	u16 pci_command;
-
-/*****************************************************************/
-/*   P C I   C O N F I G U R A T I O N                           */
-/*****************************************************************/
-
-	XPRINTK("%s: Enable PCI master and memory access for SAR.\n",
-		card->name);
-	if (pci_read_config_word(card->pcidev, PCI_COMMAND, &pci_command)) {
-		printk("%s: can't read PCI_COMMAND.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-	if (!(pci_command & PCI_COMMAND_IO)) {
-		printk("%s: PCI_COMMAND: %04x (?)\n",
-		       card->name, pci_command);
-		deinit_card(card);
-		return (-1);
-	}
-	pci_command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-	if (pci_write_config_word(card->pcidev, PCI_COMMAND, pci_command)) {
-		printk("%s: can't write PCI_COMMAND.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-/*****************************************************************/
-/*   G E N E R I C   R E S E T                                   */
-/*****************************************************************/
-
-	/* Software reset */
-	writel(SAR_CFG_SWRST, SAR_REG_CFG);
-	mdelay(1);
-	writel(0, SAR_REG_CFG);
-
-	IPRINTK("%s: Software resetted.\n", card->name);
-	return 0;
-}
-
-
-static unsigned long probe_sram(struct idt77252_dev *card)
-{
-	u32 data, addr;
-
-	writel(0, SAR_REG_DR0);
-	writel(SAR_CMD_WRITE_SRAM | (0 << 2), SAR_REG_CMD);
-
-	for (addr = 0x4000; addr < 0x80000; addr += 0x4000) {
-		writel(ATM_POISON, SAR_REG_DR0);
-		writel(SAR_CMD_WRITE_SRAM | (addr << 2), SAR_REG_CMD);
-
-		writel(SAR_CMD_READ_SRAM | (0 << 2), SAR_REG_CMD);
-		data = readl(SAR_REG_DR0);
-
-		if (data != 0)
-			break;
-	}
-
-	return addr * sizeof(u32);
-}
-
-static int idt77252_init_one(struct pci_dev *pcidev,
-			     const struct pci_device_id *id)
-{
-	static struct idt77252_dev **last = &idt77252_chain;
-	static int index = 0;
-
-	unsigned long membase, srambase;
-	struct idt77252_dev *card;
-	struct atm_dev *dev;
-	int i, err;
-
-
-	if ((err = pci_enable_device(pcidev))) {
-		printk("idt77252: can't enable PCI device at %s\n", pci_name(pcidev));
-		return err;
-	}
-
-	if ((err = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32)))) {
-		printk("idt77252: can't enable DMA for PCI device at %s\n", pci_name(pcidev));
-		goto err_out_disable_pdev;
-	}
-
-	card = kzalloc_obj(struct idt77252_dev);
-	if (!card) {
-		printk("idt77252-%d: can't allocate private data\n", index);
-		err = -ENOMEM;
-		goto err_out_disable_pdev;
-	}
-	card->revision = pcidev->revision;
-	card->index = index;
-	card->pcidev = pcidev;
-	sprintf(card->name, "idt77252-%d", card->index);
-
-	INIT_WORK(&card->tqueue, idt77252_softint);
-
-	membase = pci_resource_start(pcidev, 1);
-	srambase = pci_resource_start(pcidev, 2);
-
-	mutex_init(&card->mutex);
-	spin_lock_init(&card->cmd_lock);
-	spin_lock_init(&card->tst_lock);
-
-	timer_setup(&card->tst_timer, tst_timer, 0);
-
-	/* Do the I/O remapping... */
-	card->membase = ioremap(membase, 1024);
-	if (!card->membase) {
-		printk("%s: can't ioremap() membase\n", card->name);
-		err = -EIO;
-		goto err_out_free_card;
-	}
-
-	if (idt77252_preset(card)) {
-		printk("%s: preset failed\n", card->name);
-		err = -EIO;
-		goto err_out_iounmap;
-	}
-
-	dev = atm_dev_register("idt77252", &pcidev->dev, &idt77252_ops, -1,
-			       NULL);
-	if (!dev) {
-		printk("%s: can't register atm device\n", card->name);
-		err = -EIO;
-		goto err_out_iounmap;
-	}
-	dev->dev_data = card;
-	card->atmdev = dev;
-
-#ifdef	CONFIG_ATM_IDT77252_USE_SUNI
-	suni_init(dev);
-	if (!dev->phy) {
-		printk("%s: can't init SUNI\n", card->name);
-		err = -EIO;
-		goto err_out_deinit_card;
-	}
-#endif	/* CONFIG_ATM_IDT77252_USE_SUNI */
-
-	card->sramsize = probe_sram(card);
-
-	for (i = 0; i < 4; i++) {
-		card->fbq[i] = ioremap(srambase | 0x200000 | (i << 18), 4);
-		if (!card->fbq[i]) {
-			printk("%s: can't ioremap() FBQ%d\n", card->name, i);
-			err = -EIO;
-			goto err_out_deinit_card;
-		}
-	}
-
-	printk("%s: ABR SAR (Rev %c): MEM %08lx SRAM %08lx [%u KB]\n",
-	       card->name, ((card->revision > 1) && (card->revision < 25)) ?
-	       'A' + card->revision - 1 : '?', membase, srambase,
-	       card->sramsize / 1024);
-
-	if (init_card(dev)) {
-		printk("%s: init_card failed\n", card->name);
-		err = -EIO;
-		goto err_out_deinit_card;
-	}
-
-	dev->ci_range.vpi_bits = card->vpibits;
-	dev->ci_range.vci_bits = card->vcibits;
-	dev->link_rate = card->link_pcr;
-
-	if (dev->phy->start)
-		dev->phy->start(dev);
-
-	if (idt77252_dev_open(card)) {
-		printk("%s: dev_open failed\n", card->name);
-		err = -EIO;
-		goto err_out_stop;
-	}
-
-	*last = card;
-	last = &card->next;
-	index++;
-
-	return 0;
-
-err_out_stop:
-	if (dev->phy->stop)
-		dev->phy->stop(dev);
-
-err_out_deinit_card:
-	deinit_card(card);
-
-err_out_iounmap:
-	iounmap(card->membase);
-
-err_out_free_card:
-	kfree(card);
-
-err_out_disable_pdev:
-	pci_disable_device(pcidev);
-	return err;
-}
-
-static const struct pci_device_id idt77252_pci_tbl[] =
-{
-	{ PCI_VDEVICE(IDT, PCI_DEVICE_ID_IDT_IDT77252), 0 },
-	{ 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, idt77252_pci_tbl);
-
-static struct pci_driver idt77252_driver = {
-	.name		= "idt77252",
-	.id_table	= idt77252_pci_tbl,
-	.probe		= idt77252_init_one,
-};
-
-static int __init idt77252_init(void)
-{
-	struct sk_buff *skb;
-
-	printk("%s: at %p\n", __func__, idt77252_init);
-	BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct idt77252_skb_prv) + sizeof(struct atm_skb_data));
-	return pci_register_driver(&idt77252_driver);
-}
-
-static void __exit idt77252_exit(void)
-{
-	struct idt77252_dev *card;
-	struct atm_dev *dev;
-
-	pci_unregister_driver(&idt77252_driver);
-
-	while (idt77252_chain) {
-		card = idt77252_chain;
-		dev = card->atmdev;
-		idt77252_chain = card->next;
-		timer_shutdown_sync(&card->tst_timer);
-
-		if (dev->phy->stop)
-			dev->phy->stop(dev);
-		deinit_card(card);
-		pci_disable_device(card->pcidev);
-		kfree(card);
-	}
-
-	DIPRINTK("idt77252: finished cleanup-module().\n");
-}
-
-module_init(idt77252_init);
-module_exit(idt77252_exit);
-
-MODULE_LICENSE("GPL");
-
-module_param(vpibits, uint, 0);
-MODULE_PARM_DESC(vpibits, "number of VPI bits supported (0, 1, or 2)");
-#ifdef CONFIG_ATM_IDT77252_DEBUG
-module_param(debug, ulong, 0644);
-MODULE_PARM_DESC(debug,   "debug bitmap, see drivers/atm/idt77252.h");
-#endif
-
-MODULE_AUTHOR("Eddie C. Dost <ecd@atecom.com>");
-MODULE_DESCRIPTION("IDT77252 ABR SAR Driver");
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
deleted file mode 100644
index 0d38e93772c2..000000000000
--- a/drivers/atm/iphase.c
+++ /dev/null
@@ -1,3283 +0,0 @@
-/******************************************************************************
-         iphase.c: Device driver for Interphase ATM PCI adapter cards 
-                    Author: Peter Wang  <pwang@iphase.com>            
-		   Some fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-                   Interphase Corporation  <www.iphase.com>           
-                               Version: 1.0                           
-*******************************************************************************
-      
-      This software may be used and distributed according to the terms
-      of the GNU General Public License (GPL), incorporated herein by reference.
-      Drivers based on this skeleton fall under the GPL and must retain
-      the authorship (implicit copyright) notice.
-
-      This program is distributed in the hope that it will be useful, but
-      WITHOUT ANY WARRANTY; without even the implied warranty of
-      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-      General Public License for more details.
-      
-      Modified from an incomplete driver for Interphase 5575 1KVC 1M card which 
-      was originally written by Monalisa Agrawal at UNH. Now this driver 
-      supports a variety of varients of Interphase ATM PCI (i)Chip adapter 
-      card family (See www.iphase.com/products/ClassSheet.cfm?ClassID=ATM) 
-      in terms of PHY type, the size of control memory and the size of 
-      packet memory. The following are the change log and history:
-     
-          Bugfix the Mona's UBR driver.
-          Modify the basic memory allocation and dma logic.
-          Port the driver to the latest kernel from 2.0.46.
-          Complete the ABR logic of the driver, and added the ABR work-
-              around for the hardware anormalies.
-          Add the CBR support.
-	  Add the flow control logic to the driver to allow rate-limit VC.
-          Add 4K VC support to the board with 512K control memory.
-          Add the support of all the variants of the Interphase ATM PCI 
-          (i)Chip adapter cards including x575 (155M OC3 and UTP155), x525
-          (25M UTP25) and x531 (DS3 and E3).
-          Add SMP support.
-
-      Support and updates available at: ftp://ftp.iphase.com/pub/atm
-
-*******************************************************************************/
-
-#include <linux/module.h>  
-#include <linux/kernel.h>  
-#include <linux/mm.h>  
-#include <linux/pci.h>  
-#include <linux/errno.h>  
-#include <linux/atm.h>  
-#include <linux/atmdev.h>  
-#include <linux/ctype.h>
-#include <linux/sonet.h>  
-#include <linux/skbuff.h>  
-#include <linux/time.h>  
-#include <linux/delay.h>  
-#include <linux/uio.h>  
-#include <linux/init.h>  
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/slab.h>
-#include <asm/io.h>  
-#include <linux/atomic.h>
-#include <linux/uaccess.h>  
-#include <asm/string.h>  
-#include <asm/byteorder.h>  
-#include <linux/vmalloc.h>
-#include <linux/jiffies.h>
-#include <linux/nospec.h>
-#include "iphase.h"		  
-#include "suni.h"		  
-#define swap_byte_order(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8))
-
-#define PRIV(dev) ((struct suni_priv *) dev->phy_data)
-
-static unsigned char ia_phy_get(struct atm_dev *dev, unsigned long addr);
-static void desc_dbg(IADEV *iadev);
-
-static IADEV *ia_dev[8];
-static struct atm_dev *_ia_dev[8];
-static int iadev_count;
-static void ia_led_timer(struct timer_list *unused);
-static DEFINE_TIMER(ia_timer, ia_led_timer);
-static int IA_TX_BUF = DFL_TX_BUFFERS, IA_TX_BUF_SZ = DFL_TX_BUF_SZ;
-static int IA_RX_BUF = DFL_RX_BUFFERS, IA_RX_BUF_SZ = DFL_RX_BUF_SZ;
-static uint IADebugFlag = /* IF_IADBG_ERR | IF_IADBG_CBR| IF_IADBG_INIT_ADAPTER
-            |IF_IADBG_ABR | IF_IADBG_EVENT*/ 0; 
-
-module_param(IA_TX_BUF, int, 0);
-module_param(IA_TX_BUF_SZ, int, 0);
-module_param(IA_RX_BUF, int, 0);
-module_param(IA_RX_BUF_SZ, int, 0);
-module_param(IADebugFlag, uint, 0644);
-
-MODULE_DESCRIPTION("Driver for Interphase ATM PCI NICs");
-MODULE_LICENSE("GPL");
-
-/**************************** IA_LIB **********************************/
-
-static void ia_init_rtn_q (IARTN_Q *que) 
-{ 
-   que->next = NULL; 
-   que->tail = NULL; 
-}
-
-static void ia_enque_head_rtn_q (IARTN_Q *que, IARTN_Q * data) 
-{
-   data->next = NULL;
-   if (que->next == NULL) 
-      que->next = que->tail = data;
-   else {
-      data->next = que->next;
-      que->next = data;
-   } 
-   return;
-}
-
-static int ia_enque_rtn_q (IARTN_Q *que, struct desc_tbl_t data) {
-   IARTN_Q *entry = kmalloc_obj(*entry, GFP_ATOMIC);
-   if (!entry)
-      return -ENOMEM;
-   entry->data = data;
-   entry->next = NULL;
-   if (que->next == NULL) 
-      que->next = que->tail = entry;
-   else {
-      que->tail->next = entry;
-      que->tail = que->tail->next;
-   }      
-   return 1;
-}
-
-static IARTN_Q * ia_deque_rtn_q (IARTN_Q *que) {
-   IARTN_Q *tmpdata;
-   if (que->next == NULL)
-      return NULL;
-   tmpdata = que->next;
-   if ( que->next == que->tail)  
-      que->next = que->tail = NULL;
-   else 
-      que->next = que->next->next;
-   return tmpdata;
-}
-
-static void ia_hack_tcq(IADEV *dev) {
-
-  u_short 		desc1;
-  u_short		tcq_wr;
-  struct ia_vcc         *iavcc_r = NULL; 
-
-  tcq_wr = readl(dev->seg_reg+TCQ_WR_PTR) & 0xffff;
-  while (dev->host_tcq_wr != tcq_wr) {
-     desc1 = *(u_short *)(dev->seg_ram + dev->host_tcq_wr);
-     if (!desc1) ;
-     else if (!dev->desc_tbl[desc1 -1].timestamp) {
-        IF_ABR(printk(" Desc %d is reset at %ld\n", desc1 -1, jiffies);)
-        *(u_short *) (dev->seg_ram + dev->host_tcq_wr) = 0;
-     }                                 
-     else if (dev->desc_tbl[desc1 -1].timestamp) {
-        if (!(iavcc_r = dev->desc_tbl[desc1 -1].iavcc)) { 
-           printk("IA: Fatal err in get_desc\n");
-           continue;
-        }
-        iavcc_r->vc_desc_cnt--;
-        dev->desc_tbl[desc1 -1].timestamp = 0;
-        IF_EVENT(printk("ia_hack: return_q skb = 0x%p desc = %d\n",
-                                   dev->desc_tbl[desc1 -1].txskb, desc1);)
-        if (iavcc_r->pcr < dev->rate_limit) {
-           IA_SKB_STATE (dev->desc_tbl[desc1-1].txskb) |= IA_TX_DONE;
-           if (ia_enque_rtn_q(&dev->tx_return_q, dev->desc_tbl[desc1 -1]) < 0)
-              printk("ia_hack_tcq: No memory available\n");
-        } 
-        dev->desc_tbl[desc1 -1].iavcc = NULL;
-        dev->desc_tbl[desc1 -1].txskb = NULL;
-     }
-     dev->host_tcq_wr += 2;
-     if (dev->host_tcq_wr > dev->ffL.tcq_ed) 
-        dev->host_tcq_wr = dev->ffL.tcq_st;
-  }
-} /* ia_hack_tcq */
-
-static u16 get_desc (IADEV *dev, struct ia_vcc *iavcc) {
-  u_short 		desc_num, i;
-  struct ia_vcc         *iavcc_r = NULL; 
-  unsigned long delta;
-  static unsigned long timer = 0;
-  int ltimeout;
-
-  ia_hack_tcq (dev);
-  if((time_after(jiffies,timer+50)) || ((dev->ffL.tcq_rd==dev->host_tcq_wr))) {
-     timer = jiffies; 
-     i=0;
-     while (i < dev->num_tx_desc) {
-        if (!dev->desc_tbl[i].timestamp) {
-           i++;
-           continue;
-        }
-        ltimeout = dev->desc_tbl[i].iavcc->ltimeout; 
-        delta = jiffies - dev->desc_tbl[i].timestamp;
-        if (delta >= ltimeout) {
-           IF_ABR(printk("RECOVER run!! desc_tbl %d = %d  delta = %ld, time = %ld\n", i,dev->desc_tbl[i].timestamp, delta, jiffies);)
-           if (dev->ffL.tcq_rd == dev->ffL.tcq_st) 
-              dev->ffL.tcq_rd =  dev->ffL.tcq_ed;
-           else 
-              dev->ffL.tcq_rd -= 2;
-           *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd) = i+1;
-           if (!dev->desc_tbl[i].txskb || !(iavcc_r = dev->desc_tbl[i].iavcc))
-              printk("Fatal err, desc table vcc or skb is NULL\n");
-           else 
-              iavcc_r->vc_desc_cnt--;
-           dev->desc_tbl[i].timestamp = 0;
-           dev->desc_tbl[i].iavcc = NULL;
-           dev->desc_tbl[i].txskb = NULL;
-        }
-        i++;
-     } /* while */
-  }
-  if (dev->ffL.tcq_rd == dev->host_tcq_wr) 
-     return 0xFFFF;
-    
-  /* Get the next available descriptor number from TCQ */
-  desc_num = *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd);
-
-  while (!desc_num || (dev->desc_tbl[desc_num -1]).timestamp) {
-     dev->ffL.tcq_rd += 2;
-     if (dev->ffL.tcq_rd > dev->ffL.tcq_ed) 
-	dev->ffL.tcq_rd = dev->ffL.tcq_st;
-     if (dev->ffL.tcq_rd == dev->host_tcq_wr) 
-        return 0xFFFF; 
-     desc_num = *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd);
-  }
-
-  /* get system time */
-  dev->desc_tbl[desc_num -1].timestamp = jiffies;
-  return desc_num;
-}
-
-static void clear_lockup (struct atm_vcc *vcc, IADEV *dev) {
-  u_char          	foundLockUp;
-  vcstatus_t		*vcstatus;
-  u_short               *shd_tbl;
-  u_short               tempCellSlot, tempFract;
-  struct main_vc *abr_vc = (struct main_vc *)dev->MAIN_VC_TABLE_ADDR;
-  struct ext_vc *eabr_vc = (struct ext_vc *)dev->EXT_VC_TABLE_ADDR;
-  u_int  i;
-
-  if (vcc->qos.txtp.traffic_class == ATM_ABR) {
-     vcstatus = (vcstatus_t *) &(dev->testTable[vcc->vci]->vc_status);
-     vcstatus->cnt++;
-     foundLockUp = 0;
-     if( vcstatus->cnt == 0x05 ) {
-        abr_vc += vcc->vci;
-	eabr_vc += vcc->vci;
-	if( eabr_vc->last_desc ) {
-	   if( (abr_vc->status & 0x07) == ABR_STATE /* 0x2 */ ) {
-              /* Wait for 10 Micro sec */
-              udelay(10);
-	      if ((eabr_vc->last_desc)&&((abr_vc->status & 0x07)==ABR_STATE))
-		 foundLockUp = 1;
-           }
-	   else {
-	      tempCellSlot = abr_vc->last_cell_slot;
-              tempFract    = abr_vc->fraction;
-              if((tempCellSlot == dev->testTable[vcc->vci]->lastTime)
-                         && (tempFract == dev->testTable[vcc->vci]->fract))
-	         foundLockUp = 1; 		    
-              dev->testTable[vcc->vci]->lastTime = tempCellSlot;   
-              dev->testTable[vcc->vci]->fract = tempFract; 
-	   } 	    
-        } /* last descriptor */	 	   
-        vcstatus->cnt = 0;     	
-     } /* vcstatus->cnt */
-	
-     if (foundLockUp) {
-        IF_ABR(printk("LOCK UP found\n");) 
-	writew(0xFFFD, dev->seg_reg+MODE_REG_0);
-        /* Wait for 10 Micro sec */
-        udelay(10); 
-        abr_vc->status &= 0xFFF8;
-        abr_vc->status |= 0x0001;  /* state is idle */
-	shd_tbl = (u_short *)dev->ABR_SCHED_TABLE_ADDR;                
-	for( i = 0; ((i < dev->num_vc) && (shd_tbl[i])); i++ );
-	if (i < dev->num_vc)
-           shd_tbl[i] = vcc->vci;
-        else
-           IF_ERR(printk("ABR Seg. may not continue on VC %x\n",vcc->vci);)
-        writew(T_ONLINE, dev->seg_reg+MODE_REG_0);
-        writew(~(TRANSMIT_DONE|TCQ_NOT_EMPTY), dev->seg_reg+SEG_MASK_REG);
-        writew(TRANSMIT_DONE, dev->seg_reg+SEG_INTR_STATUS_REG);       
-	vcstatus->cnt = 0;
-     } /* foundLockUp */
-
-  } /* if an ABR VC */
-
-
-}
- 
-/*
-** Conversion of 24-bit cellrate (cells/sec) to 16-bit floating point format.
-**
-**  +----+----+------------------+-------------------------------+
-**  |  R | NZ |  5-bit exponent  |        9-bit mantissa         |
-**  +----+----+------------------+-------------------------------+
-** 
-**    R = reserved (written as 0)
-**    NZ = 0 if 0 cells/sec; 1 otherwise
-**
-**    if NZ = 1, rate = 1.mmmmmmmmm x 2^(eeeee) cells/sec
-*/
-static u16
-cellrate_to_float(u32 cr)
-{
-
-#define	NZ 		0x4000
-#define	M_BITS		9		/* Number of bits in mantissa */
-#define	E_BITS		5		/* Number of bits in exponent */
-#define	M_MASK		0x1ff		
-#define	E_MASK		0x1f
-  u16   flot;
-  u32	tmp = cr & 0x00ffffff;
-  int 	i   = 0;
-  if (cr == 0)
-     return 0;
-  while (tmp != 1) {
-     tmp >>= 1;
-     i++;
-  }
-  if (i == M_BITS)
-     flot = NZ | (i << M_BITS) | (cr & M_MASK);
-  else if (i < M_BITS)
-     flot = NZ | (i << M_BITS) | ((cr << (M_BITS - i)) & M_MASK);
-  else
-     flot = NZ | (i << M_BITS) | ((cr >> (i - M_BITS)) & M_MASK);
-  return flot;
-}
-
-#if 0
-/*
-** Conversion of 16-bit floating point format to 24-bit cellrate (cells/sec).
-*/
-static u32
-float_to_cellrate(u16 rate)
-{
-  u32   exp, mantissa, cps;
-  if ((rate & NZ) == 0)
-     return 0;
-  exp = (rate >> M_BITS) & E_MASK;
-  mantissa = rate & M_MASK;
-  if (exp == 0)
-     return 1;
-  cps = (1 << M_BITS) | mantissa;
-  if (exp == M_BITS)
-     cps = cps;
-  else if (exp > M_BITS)
-     cps <<= (exp - M_BITS);
-  else
-     cps >>= (M_BITS - exp);
-  return cps;
-}
-#endif 
-
-static void init_abr_vc (IADEV *dev, srv_cls_param_t *srv_p) {
-  srv_p->class_type = ATM_ABR;
-  srv_p->pcr        = dev->LineRate;
-  srv_p->mcr        = 0;
-  srv_p->icr        = 0x055cb7;
-  srv_p->tbe        = 0xffffff;
-  srv_p->frtt       = 0x3a;
-  srv_p->rif        = 0xf;
-  srv_p->rdf        = 0xb;
-  srv_p->nrm        = 0x4;
-  srv_p->trm        = 0x7;
-  srv_p->cdf        = 0x3;
-  srv_p->adtf       = 50;
-}
-
-static int
-ia_open_abr_vc(IADEV *dev, srv_cls_param_t *srv_p, 
-                                                struct atm_vcc *vcc, u8 flag)
-{
-  f_vc_abr_entry  *f_abr_vc;
-  r_vc_abr_entry  *r_abr_vc;
-  u32		icr;
-  u8		trm, nrm, crm;
-  u16		adtf, air, *ptr16;	
-  f_abr_vc =(f_vc_abr_entry *)dev->MAIN_VC_TABLE_ADDR;
-  f_abr_vc += vcc->vci;       
-  switch (flag) {
-     case 1: /* FFRED initialization */
-#if 0  /* sanity check */
-       if (srv_p->pcr == 0)
-          return INVALID_PCR;
-       if (srv_p->pcr > dev->LineRate)
-          srv_p->pcr = dev->LineRate;
-       if ((srv_p->mcr + dev->sum_mcr) > dev->LineRate)
-	  return MCR_UNAVAILABLE;
-       if (srv_p->mcr > srv_p->pcr)
-	  return INVALID_MCR;
-       if (!(srv_p->icr))
-	  srv_p->icr = srv_p->pcr;
-       if ((srv_p->icr < srv_p->mcr) || (srv_p->icr > srv_p->pcr))
-	  return INVALID_ICR;
-       if ((srv_p->tbe < MIN_TBE) || (srv_p->tbe > MAX_TBE))
-	  return INVALID_TBE;
-       if ((srv_p->frtt < MIN_FRTT) || (srv_p->frtt > MAX_FRTT))
-	  return INVALID_FRTT;
-       if (srv_p->nrm > MAX_NRM)
-	  return INVALID_NRM;
-       if (srv_p->trm > MAX_TRM)
-	  return INVALID_TRM;
-       if (srv_p->adtf > MAX_ADTF)
-          return INVALID_ADTF;
-       else if (srv_p->adtf == 0)
-	  srv_p->adtf = 1;
-       if (srv_p->cdf > MAX_CDF)
-	  return INVALID_CDF;
-       if (srv_p->rif > MAX_RIF)
-	  return INVALID_RIF;
-       if (srv_p->rdf > MAX_RDF)
-	  return INVALID_RDF;
-#endif
-       memset ((caddr_t)f_abr_vc, 0, sizeof(*f_abr_vc));
-       f_abr_vc->f_vc_type = ABR;
-       nrm = 2 << srv_p->nrm;     /* (2 ** (srv_p->nrm +1)) */
-			          /* i.e 2**n = 2 << (n-1) */
-       f_abr_vc->f_nrm = nrm << 8 | nrm;
-       trm = 100000/(2 << (16 - srv_p->trm));
-       if ( trm == 0) trm = 1;
-       f_abr_vc->f_nrmexp =(((srv_p->nrm +1) & 0x0f) << 12)|(MRM << 8) | trm;
-       crm = srv_p->tbe / nrm;
-       if (crm == 0) crm = 1;
-       f_abr_vc->f_crm = crm & 0xff;
-       f_abr_vc->f_pcr = cellrate_to_float(srv_p->pcr);
-       icr = min( srv_p->icr, (srv_p->tbe > srv_p->frtt) ?
-				((srv_p->tbe/srv_p->frtt)*1000000) :
-				(1000000/(srv_p->frtt/srv_p->tbe)));
-       f_abr_vc->f_icr = cellrate_to_float(icr);
-       adtf = (10000 * srv_p->adtf)/8192;
-       if (adtf == 0) adtf = 1; 
-       f_abr_vc->f_cdf = ((7 - srv_p->cdf) << 12 | adtf) & 0xfff;
-       f_abr_vc->f_mcr = cellrate_to_float(srv_p->mcr);
-       f_abr_vc->f_acr = f_abr_vc->f_icr;
-       f_abr_vc->f_status = 0x0042;
-       break;
-    case 0: /* RFRED initialization */	
-       ptr16 = (u_short *)(dev->reass_ram + REASS_TABLE*dev->memSize); 
-       *(ptr16 + vcc->vci) = NO_AAL5_PKT | REASS_ABR;
-       r_abr_vc = (r_vc_abr_entry*)(dev->reass_ram+ABR_VC_TABLE*dev->memSize);
-       r_abr_vc += vcc->vci;
-       r_abr_vc->r_status_rdf = (15 - srv_p->rdf) & 0x000f;
-       air = srv_p->pcr << (15 - srv_p->rif);
-       if (air == 0) air = 1;
-       r_abr_vc->r_air = cellrate_to_float(air);
-       dev->testTable[vcc->vci]->vc_status = VC_ACTIVE | VC_ABR;
-       dev->sum_mcr	   += srv_p->mcr;
-       dev->n_abr++;
-       break;
-    default:
-       break;
-  }
-  return	0;
-}
-static int ia_cbr_setup (IADEV *dev, struct atm_vcc *vcc) {
-   u32 rateLow=0, rateHigh, rate;
-   int entries;
-   struct ia_vcc *ia_vcc;
-
-   int   idealSlot =0, testSlot, toBeAssigned, inc;
-   u32   spacing;
-   u16  *SchedTbl, *TstSchedTbl;
-   u16  cbrVC, vcIndex;
-   u32   fracSlot    = 0;
-   u32   sp_mod      = 0;
-   u32   sp_mod2     = 0;
-
-   /* IpAdjustTrafficParams */
-   if (vcc->qos.txtp.max_pcr <= 0) {
-      IF_ERR(printk("PCR for CBR not defined\n");)
-      return -1;
-   }
-   rate = vcc->qos.txtp.max_pcr;
-   entries = rate / dev->Granularity;
-   IF_CBR(printk("CBR: CBR entries=0x%x for rate=0x%x & Gran=0x%x\n",
-                                entries, rate, dev->Granularity);)
-   if (entries < 1)
-      IF_CBR(printk("CBR: Bandwidth smaller than granularity of CBR table\n");) 
-   rateLow  =  entries * dev->Granularity;
-   rateHigh = (entries + 1) * dev->Granularity;
-   if (3*(rate - rateLow) > (rateHigh - rate))
-      entries++;
-   if (entries > dev->CbrRemEntries) {
-      IF_CBR(printk("CBR: Not enough bandwidth to support this PCR.\n");)
-      IF_CBR(printk("Entries = 0x%x, CbrRemEntries = 0x%x.\n",
-                                       entries, dev->CbrRemEntries);)
-      return -EBUSY;
-   }   
-
-   ia_vcc = INPH_IA_VCC(vcc);
-   ia_vcc->NumCbrEntry = entries; 
-   dev->sum_mcr += entries * dev->Granularity; 
-   /* IaFFrednInsertCbrSched */
-   // Starting at an arbitrary location, place the entries into the table
-   // as smoothly as possible
-   cbrVC   = 0;
-   spacing = dev->CbrTotEntries / entries;
-   sp_mod  = dev->CbrTotEntries % entries; // get modulo
-   toBeAssigned = entries;
-   fracSlot = 0;
-   vcIndex  = vcc->vci;
-   IF_CBR(printk("Vci=0x%x,Spacing=0x%x,Sp_mod=0x%x\n",vcIndex,spacing,sp_mod);)
-   while (toBeAssigned)
-   {
-      // If this is the first time, start the table loading for this connection
-      // as close to entryPoint as possible.
-      if (toBeAssigned == entries)
-      {
-         idealSlot = dev->CbrEntryPt;
-         dev->CbrEntryPt += 2;    // Adding 2 helps to prevent clumping
-         if (dev->CbrEntryPt >= dev->CbrTotEntries) 
-            dev->CbrEntryPt -= dev->CbrTotEntries;// Wrap if necessary
-      } else {
-         idealSlot += (u32)(spacing + fracSlot); // Point to the next location
-         // in the table that would be  smoothest
-         fracSlot = ((sp_mod + sp_mod2) / entries);  // get new integer part
-         sp_mod2  = ((sp_mod + sp_mod2) % entries);  // calc new fractional part
-      }
-      if (idealSlot >= (int)dev->CbrTotEntries) 
-         idealSlot -= dev->CbrTotEntries;  
-      // Continuously check around this ideal value until a null
-      // location is encountered.
-      SchedTbl = (u16*)(dev->seg_ram+CBR_SCHED_TABLE*dev->memSize); 
-      inc = 0;
-      testSlot = idealSlot;
-      TstSchedTbl = (u16*)(SchedTbl+testSlot);  //set index and read in value
-      IF_CBR(printk("CBR Testslot 0x%x AT Location 0x%p, NumToAssign=%d\n",
-                                testSlot, TstSchedTbl,toBeAssigned);)
-      memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(cbrVC));
-      while (cbrVC)  // If another VC at this location, we have to keep looking
-      {
-          inc++;
-          testSlot = idealSlot - inc;
-          if (testSlot < 0) { // Wrap if necessary
-             testSlot += dev->CbrTotEntries;
-             IF_CBR(printk("Testslot Wrap. STable Start=0x%p,Testslot=%d\n",
-                                                       SchedTbl,testSlot);)
-          }
-          TstSchedTbl = (u16 *)(SchedTbl + testSlot);  // set table index
-          memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(cbrVC)); 
-          if (!cbrVC)
-             break;
-          testSlot = idealSlot + inc;
-          if (testSlot >= (int)dev->CbrTotEntries) { // Wrap if necessary
-             testSlot -= dev->CbrTotEntries;
-             IF_CBR(printk("TotCbrEntries=%d",dev->CbrTotEntries);)
-             IF_CBR(printk(" Testslot=0x%x ToBeAssgned=%d\n", 
-                                            testSlot, toBeAssigned);)
-          } 
-          // set table index and read in value
-          TstSchedTbl = (u16*)(SchedTbl + testSlot);
-          IF_CBR(printk("Reading CBR Tbl from 0x%p, CbrVal=0x%x Iteration %d\n",
-                          TstSchedTbl,cbrVC,inc);)
-          memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(cbrVC));
-       } /* while */
-       // Move this VCI number into this location of the CBR Sched table.
-       memcpy((caddr_t)TstSchedTbl, (caddr_t)&vcIndex, sizeof(*TstSchedTbl));
-       dev->CbrRemEntries--;
-       toBeAssigned--;
-   } /* while */ 
-
-   /* IaFFrednCbrEnable */
-   dev->NumEnabledCBR++;
-   if (dev->NumEnabledCBR == 1) {
-       writew((CBR_EN | UBR_EN | ABR_EN | (0x23 << 2)), dev->seg_reg+STPARMS);
-       IF_CBR(printk("CBR is enabled\n");)
-   }
-   return 0;
-}
-static void ia_cbrVc_close (struct atm_vcc *vcc) {
-   IADEV *iadev;
-   u16 *SchedTbl, NullVci = 0;
-   u32 i, NumFound;
-
-   iadev = INPH_IA_DEV(vcc->dev);
-   iadev->NumEnabledCBR--;
-   SchedTbl = (u16*)(iadev->seg_ram+CBR_SCHED_TABLE*iadev->memSize);
-   if (iadev->NumEnabledCBR == 0) {
-      writew((UBR_EN | ABR_EN | (0x23 << 2)), iadev->seg_reg+STPARMS);
-      IF_CBR (printk("CBR support disabled\n");)
-   }
-   NumFound = 0;
-   for (i=0; i < iadev->CbrTotEntries; i++)
-   {
-      if (*SchedTbl == vcc->vci) {
-         iadev->CbrRemEntries++;
-         *SchedTbl = NullVci;
-         IF_CBR(NumFound++;)
-      }
-      SchedTbl++;   
-   } 
-   IF_CBR(printk("Exit ia_cbrVc_close, NumRemoved=%d\n",NumFound);)
-}
-
-static int ia_avail_descs(IADEV *iadev) {
-   int tmp = 0;
-   ia_hack_tcq(iadev);
-   if (iadev->host_tcq_wr >= iadev->ffL.tcq_rd)
-      tmp = (iadev->host_tcq_wr - iadev->ffL.tcq_rd) / 2;
-   else
-      tmp = (iadev->ffL.tcq_ed - iadev->ffL.tcq_rd + 2 + iadev->host_tcq_wr -
-                   iadev->ffL.tcq_st) / 2;
-   return tmp;
-}    
-
-static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb);
-
-static int ia_que_tx (IADEV *iadev) { 
-   struct sk_buff *skb;
-   int num_desc;
-   struct atm_vcc *vcc;
-   num_desc = ia_avail_descs(iadev);
-
-   while (num_desc && (skb = skb_dequeue(&iadev->tx_backlog))) {
-      if (!(vcc = ATM_SKB(skb)->vcc)) {
-         dev_kfree_skb_any(skb);
-         printk("ia_que_tx: Null vcc\n");
-         break;
-      }
-      if (!test_bit(ATM_VF_READY,&vcc->flags)) {
-         dev_kfree_skb_any(skb);
-         printk("Free the SKB on closed vci %d \n", vcc->vci);
-         break;
-      }
-      if (ia_pkt_tx (vcc, skb)) {
-         skb_queue_head(&iadev->tx_backlog, skb);
-      }
-      num_desc--;
-   }
-   return 0;
-}
-
-static void ia_tx_poll (IADEV *iadev) {
-   struct atm_vcc *vcc = NULL;
-   struct sk_buff *skb = NULL, *skb1 = NULL;
-   struct ia_vcc *iavcc;
-   IARTN_Q *  rtne;
-
-   ia_hack_tcq(iadev);
-   while ( (rtne = ia_deque_rtn_q(&iadev->tx_return_q))) {
-       skb = rtne->data.txskb;
-       if (!skb) {
-           printk("ia_tx_poll: skb is null\n");
-           goto out;
-       }
-       vcc = ATM_SKB(skb)->vcc;
-       if (!vcc) {
-           printk("ia_tx_poll: vcc is null\n");
-           dev_kfree_skb_any(skb);
-	   goto out;
-       }
-
-       iavcc = INPH_IA_VCC(vcc);
-       if (!iavcc) {
-           printk("ia_tx_poll: iavcc is null\n");
-           dev_kfree_skb_any(skb);
-	   goto out;
-       }
-
-       skb1 = skb_dequeue(&iavcc->txing_skb);
-       while (skb1 && (skb1 != skb)) {
-          if (!(IA_SKB_STATE(skb1) & IA_TX_DONE)) {
-             printk("IA_tx_intr: Vci %d lost pkt!!!\n", vcc->vci);
-          }
-          IF_ERR(printk("Release the SKB not match\n");)
-          if ((vcc->pop) && (skb1->len != 0))
-          {
-             vcc->pop(vcc, skb1);
-             IF_EVENT(printk("Transmit Done - skb 0x%lx return\n",
-                                                          (long)skb1);)
-          }
-          else 
-             dev_kfree_skb_any(skb1);
-          skb1 = skb_dequeue(&iavcc->txing_skb);
-       }                                                        
-       if (!skb1) {
-          IF_EVENT(printk("IA: Vci %d - skb not found requeued\n",vcc->vci);)
-          ia_enque_head_rtn_q (&iadev->tx_return_q, rtne);
-          break;
-       }
-       if ((vcc->pop) && (skb->len != 0))
-       {
-          vcc->pop(vcc, skb);
-          IF_EVENT(printk("Tx Done - skb 0x%lx return\n",(long)skb);)
-       }
-       else 
-          dev_kfree_skb_any(skb);
-       kfree(rtne);
-    }
-    ia_que_tx(iadev);
-out:
-    return;
-}
-#if 0
-static void ia_eeprom_put (IADEV *iadev, u32 addr, u_short val)
-{
-        u32	t;
-	int	i;
-	/*
-	 * Issue a command to enable writes to the NOVRAM
-	 */
-	NVRAM_CMD (EXTEND + EWEN);
-	NVRAM_CLR_CE;
-	/*
-	 * issue the write command
-	 */
-	NVRAM_CMD(IAWRITE + addr);
-	/* 
-	 * Send the data, starting with D15, then D14, and so on for 16 bits
-	 */
-	for (i=15; i>=0; i--) {
-		NVRAM_CLKOUT (val & 0x8000);
-		val <<= 1;
-	}
-	NVRAM_CLR_CE;
-	CFG_OR(NVCE);
-	t = readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); 
-	while (!(t & NVDO))
-		t = readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); 
-
-	NVRAM_CLR_CE;
-	/*
-	 * disable writes again
-	 */
-	NVRAM_CMD(EXTEND + EWDS)
-	NVRAM_CLR_CE;
-	CFG_AND(~NVDI);
-}
-#endif
-
-static u16 ia_eeprom_get (IADEV *iadev, u32 addr)
-{
-	u_short	val;
-        u32	t;
-	int	i;
-	/*
-	 * Read the first bit that was clocked with the falling edge of
-	 * the last command data clock
-	 */
-	NVRAM_CMD(IAREAD + addr);
-	/*
-	 * Now read the rest of the bits, the next bit read is D14, then D13,
-	 * and so on.
-	 */
-	val = 0;
-	for (i=15; i>=0; i--) {
-		NVRAM_CLKIN(t);
-		val |= (t << i);
-	}
-	NVRAM_CLR_CE;
-	CFG_AND(~NVDI);
-	return val;
-}
-
-static void ia_hw_type(IADEV *iadev) {
-   u_short memType = ia_eeprom_get(iadev, 25);   
-   iadev->memType = memType;
-   if ((memType & MEM_SIZE_MASK) == MEM_SIZE_1M) {
-      iadev->num_tx_desc = IA_TX_BUF;
-      iadev->tx_buf_sz = IA_TX_BUF_SZ;
-      iadev->num_rx_desc = IA_RX_BUF;
-      iadev->rx_buf_sz = IA_RX_BUF_SZ; 
-   } else if ((memType & MEM_SIZE_MASK) == MEM_SIZE_512K) {
-      if (IA_TX_BUF == DFL_TX_BUFFERS)
-        iadev->num_tx_desc = IA_TX_BUF / 2;
-      else 
-        iadev->num_tx_desc = IA_TX_BUF;
-      iadev->tx_buf_sz = IA_TX_BUF_SZ;
-      if (IA_RX_BUF == DFL_RX_BUFFERS)
-        iadev->num_rx_desc = IA_RX_BUF / 2;
-      else
-        iadev->num_rx_desc = IA_RX_BUF;
-      iadev->rx_buf_sz = IA_RX_BUF_SZ;
-   }
-   else {
-      if (IA_TX_BUF == DFL_TX_BUFFERS) 
-        iadev->num_tx_desc = IA_TX_BUF / 8;
-      else
-        iadev->num_tx_desc = IA_TX_BUF;
-      iadev->tx_buf_sz = IA_TX_BUF_SZ;
-      if (IA_RX_BUF == DFL_RX_BUFFERS)
-        iadev->num_rx_desc = IA_RX_BUF / 8;
-      else
-        iadev->num_rx_desc = IA_RX_BUF;
-      iadev->rx_buf_sz = IA_RX_BUF_SZ; 
-   } 
-   iadev->rx_pkt_ram = TX_PACKET_RAM + (iadev->num_tx_desc * iadev->tx_buf_sz); 
-   IF_INIT(printk("BUF: tx=%d,sz=%d rx=%d sz= %d rx_pkt_ram=%d\n",
-         iadev->num_tx_desc, iadev->tx_buf_sz, iadev->num_rx_desc,
-         iadev->rx_buf_sz, iadev->rx_pkt_ram);)
-
-#if 0
-   if ((memType & FE_MASK) == FE_SINGLE_MODE) {
-      iadev->phy_type = PHY_OC3C_S;
-   else if ((memType & FE_MASK) == FE_UTP_OPTION)
-      iadev->phy_type = PHY_UTP155;
-   else
-     iadev->phy_type = PHY_OC3C_M;
-#endif
-   
-   iadev->phy_type = memType & FE_MASK;
-   IF_INIT(printk("memType = 0x%x iadev->phy_type = 0x%x\n", 
-                                         memType,iadev->phy_type);)
-   if (iadev->phy_type == FE_25MBIT_PHY) 
-      iadev->LineRate = (u32)(((25600000/8)*26)/(27*53));
-   else if (iadev->phy_type == FE_DS3_PHY)
-      iadev->LineRate = (u32)(((44736000/8)*26)/(27*53));
-   else if (iadev->phy_type == FE_E3_PHY) 
-      iadev->LineRate = (u32)(((34368000/8)*26)/(27*53));
-   else
-       iadev->LineRate = (u32)(ATM_OC3_PCR);
-   IF_INIT(printk("iadev->LineRate = %d \n", iadev->LineRate);)
-
-}
-
-static u32 ia_phy_read32(struct iadev_priv *ia, unsigned int reg)
-{
-	return readl(ia->phy + (reg >> 2));
-}
-
-static void ia_phy_write32(struct iadev_priv *ia, unsigned int reg, u32 val)
-{
-	writel(val, ia->phy + (reg >> 2));
-}
-
-static void ia_frontend_intr(struct iadev_priv *iadev)
-{
-	u32 status;
-
-	if (iadev->phy_type & FE_25MBIT_PHY) {
-		status = ia_phy_read32(iadev, MB25_INTR_STATUS);
-		iadev->carrier_detect = (status & MB25_IS_GSB) ? 1 : 0;
-	} else if (iadev->phy_type & FE_DS3_PHY) {
-		ia_phy_read32(iadev, SUNI_DS3_FRM_INTR_STAT);
-		status = ia_phy_read32(iadev, SUNI_DS3_FRM_STAT);
-		iadev->carrier_detect = (status & SUNI_DS3_LOSV) ? 0 : 1;
-	} else if (iadev->phy_type & FE_E3_PHY) {
-		ia_phy_read32(iadev, SUNI_E3_FRM_MAINT_INTR_IND);
-		status = ia_phy_read32(iadev, SUNI_E3_FRM_FRAM_INTR_IND_STAT);
-		iadev->carrier_detect = (status & SUNI_E3_LOS) ? 0 : 1;
-	} else {
-		status = ia_phy_read32(iadev, SUNI_RSOP_STATUS);
-		iadev->carrier_detect = (status & SUNI_LOSV) ? 0 : 1;
-	}
-
-	printk(KERN_INFO "IA: SUNI carrier %s\n",
-		iadev->carrier_detect ? "detected" : "lost signal");
-}
-
-static void ia_mb25_init(struct iadev_priv *iadev)
-{
-#if 0
-   mb25->mb25_master_ctrl = MB25_MC_DRIC | MB25_MC_DREC | MB25_MC_ENABLED;
-#endif
-	ia_phy_write32(iadev, MB25_MASTER_CTRL, MB25_MC_DRIC | MB25_MC_DREC);
-	ia_phy_write32(iadev, MB25_DIAG_CONTROL, 0);
-
-	iadev->carrier_detect =
-		(ia_phy_read32(iadev, MB25_INTR_STATUS) & MB25_IS_GSB) ? 1 : 0;
-}
-
-struct ia_reg {
-	u16 reg;
-	u16 val;
-};
-
-static void ia_phy_write(struct iadev_priv *iadev,
-			 const struct ia_reg *regs, int len)
-{
-	while (len--) {
-		ia_phy_write32(iadev, regs->reg, regs->val);
-		regs++;
-	}
-}
-
-static void ia_suni_pm7345_init_ds3(struct iadev_priv *iadev)
-{
-	static const struct ia_reg suni_ds3_init[] = {
-		{ SUNI_DS3_FRM_INTR_ENBL,	0x17 },
-		{ SUNI_DS3_FRM_CFG,		0x01 },
-		{ SUNI_DS3_TRAN_CFG,		0x01 },
-		{ SUNI_CONFIG,			0 },
-		{ SUNI_SPLR_CFG,		0 },
-		{ SUNI_SPLT_CFG,		0 }
-	};
-	u32 status;
-
-	status = ia_phy_read32(iadev, SUNI_DS3_FRM_STAT);
-	iadev->carrier_detect = (status & SUNI_DS3_LOSV) ? 0 : 1;
-
-	ia_phy_write(iadev, suni_ds3_init, ARRAY_SIZE(suni_ds3_init));
-}
-
-static void ia_suni_pm7345_init_e3(struct iadev_priv *iadev)
-{
-	static const struct ia_reg suni_e3_init[] = {
-		{ SUNI_E3_FRM_FRAM_OPTIONS,		0x04 },
-		{ SUNI_E3_FRM_MAINT_OPTIONS,		0x20 },
-		{ SUNI_E3_FRM_FRAM_INTR_ENBL,		0x1d },
-		{ SUNI_E3_FRM_MAINT_INTR_ENBL,		0x30 },
-		{ SUNI_E3_TRAN_STAT_DIAG_OPTIONS,	0 },
-		{ SUNI_E3_TRAN_FRAM_OPTIONS,		0x01 },
-		{ SUNI_CONFIG,				SUNI_PM7345_E3ENBL },
-		{ SUNI_SPLR_CFG,			0x41 },
-		{ SUNI_SPLT_CFG,			0x41 }
-	};
-	u32 status;
-
-	status = ia_phy_read32(iadev, SUNI_E3_FRM_FRAM_INTR_IND_STAT);
-	iadev->carrier_detect = (status & SUNI_E3_LOS) ? 0 : 1;
-	ia_phy_write(iadev, suni_e3_init, ARRAY_SIZE(suni_e3_init));
-}
-
-static void ia_suni_pm7345_init(struct iadev_priv *iadev)
-{
-	static const struct ia_reg suni_init[] = {
-		/* Enable RSOP loss of signal interrupt. */
-		{ SUNI_INTR_ENBL,		0x28 },
-		/* Clear error counters. */
-		{ SUNI_ID_RESET,		0 },
-		/* Clear "PMCTST" in master test register. */
-		{ SUNI_MASTER_TEST,		0 },
-
-		{ SUNI_RXCP_CTRL,		0x2c },
-		{ SUNI_RXCP_FCTRL,		0x81 },
-
-		{ SUNI_RXCP_IDLE_PAT_H1,	0 },
-		{ SUNI_RXCP_IDLE_PAT_H2,	0 },
-		{ SUNI_RXCP_IDLE_PAT_H3,	0 },
-		{ SUNI_RXCP_IDLE_PAT_H4,	0x01 },
-
-		{ SUNI_RXCP_IDLE_MASK_H1,	0xff },
-		{ SUNI_RXCP_IDLE_MASK_H2,	0xff },
-		{ SUNI_RXCP_IDLE_MASK_H3,	0xff },
-		{ SUNI_RXCP_IDLE_MASK_H4,	0xfe },
-
-		{ SUNI_RXCP_CELL_PAT_H1,	0 },
-		{ SUNI_RXCP_CELL_PAT_H2,	0 },
-		{ SUNI_RXCP_CELL_PAT_H3,	0 },
-		{ SUNI_RXCP_CELL_PAT_H4,	0x01 },
-
-		{ SUNI_RXCP_CELL_MASK_H1,	0xff },
-		{ SUNI_RXCP_CELL_MASK_H2,	0xff },
-		{ SUNI_RXCP_CELL_MASK_H3,	0xff },
-		{ SUNI_RXCP_CELL_MASK_H4,	0xff },
-
-		{ SUNI_TXCP_CTRL,		0xa4 },
-		{ SUNI_TXCP_INTR_EN_STS,	0x10 },
-		{ SUNI_TXCP_IDLE_PAT_H5,	0x55 }
-	};
-
-	if (iadev->phy_type & FE_DS3_PHY)
-		ia_suni_pm7345_init_ds3(iadev);
-	else
-		ia_suni_pm7345_init_e3(iadev);
-
-	ia_phy_write(iadev, suni_init, ARRAY_SIZE(suni_init));
-
-	ia_phy_write32(iadev, SUNI_CONFIG, ia_phy_read32(iadev, SUNI_CONFIG) &
-		~(SUNI_PM7345_LLB | SUNI_PM7345_CLB |
-		  SUNI_PM7345_DLB | SUNI_PM7345_PLB));
-#ifdef __SNMP__
-   suni_pm7345->suni_rxcp_intr_en_sts |= SUNI_OOCDE;
-#endif /* __SNMP__ */
-   return;
-}
-
-
-/***************************** IA_LIB END *****************************/
-    
-#ifdef CONFIG_ATM_IA_DEBUG
-static int tcnter = 0;
-static void xdump( u_char*  cp, int  length, char*  prefix )
-{
-    int col, count;
-    u_char prntBuf[120];
-    u_char*  pBuf = prntBuf;
-    count = 0;
-    while(count < length){
-        pBuf += sprintf( pBuf, "%s", prefix );
-        for(col = 0;count + col < length && col < 16; col++){
-            if (col != 0 && (col % 4) == 0)
-                pBuf += sprintf( pBuf, " " );
-            pBuf += sprintf( pBuf, "%02X ", cp[count + col] );
-        }
-        while(col++ < 16){      /* pad end of buffer with blanks */
-            if ((col % 4) == 0)
-                sprintf( pBuf, " " );
-            pBuf += sprintf( pBuf, "   " );
-        }
-        pBuf += sprintf( pBuf, "  " );
-        for(col = 0;count + col < length && col < 16; col++){
-		u_char c = cp[count + col];
-
-		if (isascii(c) && isprint(c))
-			pBuf += sprintf(pBuf, "%c", c);
-		else
-			pBuf += sprintf(pBuf, ".");
-                }
-        printk("%s\n", prntBuf);
-        count += col;
-        pBuf = prntBuf;
-    }
-
-}  /* close xdump(... */
-#endif /* CONFIG_ATM_IA_DEBUG */
-
-  
-static struct atm_dev *ia_boards = NULL;  
-  
-#define ACTUAL_RAM_BASE \
-	RAM_BASE*((iadev->mem)/(128 * 1024))  
-#define ACTUAL_SEG_RAM_BASE \
-	IPHASE5575_FRAG_CONTROL_RAM_BASE*((iadev->mem)/(128 * 1024))  
-#define ACTUAL_REASS_RAM_BASE \
-	IPHASE5575_REASS_CONTROL_RAM_BASE*((iadev->mem)/(128 * 1024))  
-  
-  
-/*-- some utilities and memory allocation stuff will come here -------------*/  
-  
-static void desc_dbg(IADEV *iadev) {
-
-  u_short tcq_wr_ptr, tcq_st_ptr, tcq_ed_ptr;
-  u32 i;
-  void __iomem *tmp;
-  // regval = readl((u32)ia_cmds->maddr);
-  tcq_wr_ptr =  readw(iadev->seg_reg+TCQ_WR_PTR);
-  printk("B_tcq_wr = 0x%x desc = %d last desc = %d\n",
-                     tcq_wr_ptr, readw(iadev->seg_ram+tcq_wr_ptr),
-                     readw(iadev->seg_ram+tcq_wr_ptr-2));
-  printk(" host_tcq_wr = 0x%x  host_tcq_rd = 0x%x \n",  iadev->host_tcq_wr, 
-                   iadev->ffL.tcq_rd);
-  tcq_st_ptr =  readw(iadev->seg_reg+TCQ_ST_ADR);
-  tcq_ed_ptr =  readw(iadev->seg_reg+TCQ_ED_ADR);
-  printk("tcq_st_ptr = 0x%x    tcq_ed_ptr = 0x%x \n", tcq_st_ptr, tcq_ed_ptr);
-  i = 0;
-  while (tcq_st_ptr != tcq_ed_ptr) {
-      tmp = iadev->seg_ram+tcq_st_ptr;
-      printk("TCQ slot %d desc = %d  Addr = %p\n", i++, readw(tmp), tmp);
-      tcq_st_ptr += 2;
-  }
-  for(i=0; i <iadev->num_tx_desc; i++)
-      printk("Desc_tbl[%d] = %d \n", i, iadev->desc_tbl[i].timestamp);
-} 
-  
-  
-/*----------------------------- Receiving side stuff --------------------------*/  
- 
-static void rx_excp_rcvd(struct atm_dev *dev)  
-{  
-#if 0 /* closing the receiving size will cause too many excp int */  
-  IADEV *iadev;  
-  u_short state;  
-  u_short excpq_rd_ptr;  
-  //u_short *ptr;  
-  int vci, error = 1;  
-  iadev = INPH_IA_DEV(dev);  
-  state = readl(iadev->reass_reg + STATE_REG) & 0xffff;  
-  while((state & EXCPQ_EMPTY) != EXCPQ_EMPTY)  
-  { printk("state = %x \n", state); 
-        excpq_rd_ptr = readw(iadev->reass_reg + EXCP_Q_RD_PTR) & 0xffff;  
- printk("state = %x excpq_rd_ptr = %x \n", state, excpq_rd_ptr); 
-        if (excpq_rd_ptr == *(u16*)(iadev->reass_reg + EXCP_Q_WR_PTR))
-            IF_ERR(printk("excpq_rd_ptr is wrong!!!\n");)
-        // TODO: update exception stat
-	vci = readw(iadev->reass_ram+excpq_rd_ptr);  
-	error = readw(iadev->reass_ram+excpq_rd_ptr+2) & 0x0007;  
-        // pwang_test
-	excpq_rd_ptr += 4;  
-	if (excpq_rd_ptr > (readw(iadev->reass_reg + EXCP_Q_ED_ADR)& 0xffff))  
- 	    excpq_rd_ptr = readw(iadev->reass_reg + EXCP_Q_ST_ADR)& 0xffff;
-	writew( excpq_rd_ptr, iadev->reass_reg + EXCP_Q_RD_PTR);  
-        state = readl(iadev->reass_reg + STATE_REG) & 0xffff;  
-  }  
-#endif
-}  
-  
-static void free_desc(struct atm_dev *dev, int desc)  
-{  
-	IADEV *iadev;  
-	iadev = INPH_IA_DEV(dev);  
-        writew(desc, iadev->reass_ram+iadev->rfL.fdq_wr); 
-	iadev->rfL.fdq_wr +=2;
-	if (iadev->rfL.fdq_wr > iadev->rfL.fdq_ed)
-		iadev->rfL.fdq_wr =  iadev->rfL.fdq_st;  
-	writew(iadev->rfL.fdq_wr, iadev->reass_reg+FREEQ_WR_PTR);  
-}  
-  
-  
-static int rx_pkt(struct atm_dev *dev)  
-{  
-	IADEV *iadev;  
-	struct atm_vcc *vcc;  
-	unsigned short status;  
-	struct rx_buf_desc __iomem *buf_desc_ptr;  
-	int desc;   
-	struct dle* wr_ptr;  
-	int len;  
-	struct sk_buff *skb;  
-	u_int buf_addr, dma_addr;  
-
-	iadev = INPH_IA_DEV(dev);  
-	if (iadev->rfL.pcq_rd == (readw(iadev->reass_reg+PCQ_WR_PTR)&0xffff)) 
-	{  
-   	    printk(KERN_ERR DEV_LABEL "(itf %d) Receive queue empty\n", dev->number);  
-	    return -EINVAL;  
-	}  
-	/* mask 1st 3 bits to get the actual descno. */  
-	desc = readw(iadev->reass_ram+iadev->rfL.pcq_rd) & 0x1fff;  
-        IF_RX(printk("reass_ram = %p iadev->rfL.pcq_rd = 0x%x desc = %d\n", 
-                                    iadev->reass_ram, iadev->rfL.pcq_rd, desc);
-              printk(" pcq_wr_ptr = 0x%x\n",
-                               readw(iadev->reass_reg+PCQ_WR_PTR)&0xffff);)
-	/* update the read pointer  - maybe we shud do this in the end*/  
-	if ( iadev->rfL.pcq_rd== iadev->rfL.pcq_ed) 
-		iadev->rfL.pcq_rd = iadev->rfL.pcq_st;  
-	else  
-		iadev->rfL.pcq_rd += 2;
-	writew(iadev->rfL.pcq_rd, iadev->reass_reg+PCQ_RD_PTR);  
-  
-	/* get the buffer desc entry.  
-		update stuff. - doesn't seem to be any update necessary  
-	*/  
-	buf_desc_ptr = iadev->RX_DESC_BASE_ADDR;
-	/* make the ptr point to the corresponding buffer desc entry */  
-	buf_desc_ptr += desc;	  
-        if (!desc || (desc > iadev->num_rx_desc) || 
-                      ((buf_desc_ptr->vc_index & 0xffff) >= iadev->num_vc)) {
-            free_desc(dev, desc);
-            IF_ERR(printk("IA: bad descriptor desc = %d \n", desc);)
-            return -1;
-        }
-	vcc = iadev->rx_open[buf_desc_ptr->vc_index & 0xffff];  
-	if (!vcc)  
-	{      
-                free_desc(dev, desc); 
-		printk("IA: null vcc, drop PDU\n");  
-		return -1;  
-	}  
-	  
-  
-	/* might want to check the status bits for errors */  
-	status = (u_short) (buf_desc_ptr->desc_mode);  
-	if (status & (RX_CER | RX_PTE | RX_OFL))  
-	{  
-                atomic_inc(&vcc->stats->rx_err);
-		IF_ERR(printk("IA: bad packet, dropping it");)  
-                if (status & RX_CER) { 
-                    IF_ERR(printk(" cause: packet CRC error\n");)
-                }
-                else if (status & RX_PTE) {
-                    IF_ERR(printk(" cause: packet time out\n");)
-                }
-                else {
-                    IF_ERR(printk(" cause: buffer overflow\n");)
-                }
-		goto out_free_desc;
-	}  
-  
-	/*  
-		build DLE.	  
-	*/  
-  
-	buf_addr = (buf_desc_ptr->buf_start_hi << 16) | buf_desc_ptr->buf_start_lo;  
-	dma_addr = (buf_desc_ptr->dma_start_hi << 16) | buf_desc_ptr->dma_start_lo;  
-	len = dma_addr - buf_addr;  
-        if (len > iadev->rx_buf_sz) {
-           printk("Over %d bytes sdu received, dropped!!!\n", iadev->rx_buf_sz);
-           atomic_inc(&vcc->stats->rx_err);
-	   goto out_free_desc;
-        }
-		  
-        if (!(skb = atm_alloc_charge(vcc, len, GFP_ATOMIC))) {
-           if (vcc->vci < 32)
-              printk("Drop control packets\n");
-	   goto out_free_desc;
-        }
-	skb_put(skb,len);  
-        // pwang_test
-        ATM_SKB(skb)->vcc = vcc;
-        ATM_DESC(skb) = desc;        
-	skb_queue_tail(&iadev->rx_dma_q, skb);  
-
-	/* Build the DLE structure */  
-	wr_ptr = iadev->rx_dle_q.write;  
-	wr_ptr->sys_pkt_addr = dma_map_single(&iadev->pci->dev, skb->data,
-					      len, DMA_FROM_DEVICE);
-	wr_ptr->local_pkt_addr = buf_addr;  
-	wr_ptr->bytes = len;	/* We don't know this do we ?? */  
-	wr_ptr->mode = DMA_INT_ENABLE;  
-  
-	/* shud take care of wrap around here too. */  
-        if(++wr_ptr == iadev->rx_dle_q.end)
-             wr_ptr = iadev->rx_dle_q.start;
-	iadev->rx_dle_q.write = wr_ptr;  
-	udelay(1);  
-	/* Increment transaction counter */  
-	writel(1, iadev->dma+IPHASE5575_RX_COUNTER);   
-out:	return 0;  
-out_free_desc:
-        free_desc(dev, desc);
-        goto out;
-}  
-  
-static void rx_intr(struct atm_dev *dev)  
-{  
-  IADEV *iadev;  
-  u_short status;  
-  u_short state, i;  
-  
-  iadev = INPH_IA_DEV(dev);  
-  status = readl(iadev->reass_reg+REASS_INTR_STATUS_REG) & 0xffff;  
-  IF_EVENT(printk("rx_intr: status = 0x%x\n", status);)
-  if (status & RX_PKT_RCVD)  
-  {  
-	/* do something */  
-	/* Basically recvd an interrupt for receiving a packet.  
-	A descriptor would have been written to the packet complete   
-	queue. Get all the descriptors and set up dma to move the   
-	packets till the packet complete queue is empty..  
-	*/  
-	state = readl(iadev->reass_reg + STATE_REG) & 0xffff;  
-        IF_EVENT(printk("Rx intr status: RX_PKT_RCVD %08x\n", status);) 
-	while(!(state & PCQ_EMPTY))  
-	{  
-             rx_pkt(dev);  
-	     state = readl(iadev->reass_reg + STATE_REG) & 0xffff;  
-	}  
-        iadev->rxing = 1;
-  }  
-  if (status & RX_FREEQ_EMPT)  
-  {   
-     if (iadev->rxing) {
-        iadev->rx_tmp_cnt = iadev->rx_pkt_cnt;
-        iadev->rx_tmp_jif = jiffies; 
-        iadev->rxing = 0;
-     } 
-     else if ((time_after(jiffies, iadev->rx_tmp_jif + 50)) &&
-               ((iadev->rx_pkt_cnt - iadev->rx_tmp_cnt) == 0)) {
-        for (i = 1; i <= iadev->num_rx_desc; i++)
-               free_desc(dev, i);
-printk("Test logic RUN!!!!\n");
-        writew( ~(RX_FREEQ_EMPT|RX_EXCP_RCVD),iadev->reass_reg+REASS_MASK_REG);
-        iadev->rxing = 1;
-     }
-     IF_EVENT(printk("Rx intr status: RX_FREEQ_EMPT %08x\n", status);)  
-  }  
-
-  if (status & RX_EXCP_RCVD)  
-  {  
-	/* probably need to handle the exception queue also. */  
-	IF_EVENT(printk("Rx intr status: RX_EXCP_RCVD %08x\n", status);)  
-	rx_excp_rcvd(dev);  
-  }  
-
-
-  if (status & RX_RAW_RCVD)  
-  {  
-	/* need to handle the raw incoming cells. This deepnds on   
-	whether we have programmed to receive the raw cells or not.  
-	Else ignore. */  
-	IF_EVENT(printk("Rx intr status:  RX_RAW_RCVD %08x\n", status);)  
-  }  
-}  
-  
-  
-static void rx_dle_intr(struct atm_dev *dev)  
-{  
-  IADEV *iadev;  
-  struct atm_vcc *vcc;   
-  struct sk_buff *skb;  
-  int desc;  
-  u_short state;   
-  struct dle *dle, *cur_dle;  
-  u_int dle_lp;  
-  int len;
-  iadev = INPH_IA_DEV(dev);  
- 
-  /* free all the dles done, that is just update our own dle read pointer   
-	- do we really need to do this. Think not. */  
-  /* DMA is done, just get all the recevie buffers from the rx dma queue  
-	and push them up to the higher layer protocol. Also free the desc  
-	associated with the buffer. */  
-  dle = iadev->rx_dle_q.read;  
-  dle_lp = readl(iadev->dma+IPHASE5575_RX_LIST_ADDR) & (sizeof(struct dle)*DLE_ENTRIES - 1);  
-  cur_dle = (struct dle*)(iadev->rx_dle_q.start + (dle_lp >> 4));  
-  while(dle != cur_dle)  
-  {  
-      /* free the DMAed skb */  
-      skb = skb_dequeue(&iadev->rx_dma_q);  
-      if (!skb)  
-         goto INCR_DLE;
-      desc = ATM_DESC(skb);
-      free_desc(dev, desc);  
-               
-      if (!(len = skb->len))
-      {  
-          printk("rx_dle_intr: skb len 0\n");  
-	  dev_kfree_skb_any(skb);  
-      }  
-      else  
-      {  
-          struct cpcs_trailer *trailer;
-          u_short length;
-          struct ia_vcc *ia_vcc;
-
-	  dma_unmap_single(&iadev->pci->dev, iadev->rx_dle_q.write->sys_pkt_addr,
-			   len, DMA_FROM_DEVICE);
-          /* no VCC related housekeeping done as yet. lets see */  
-          vcc = ATM_SKB(skb)->vcc;
-	  if (!vcc) {
-	      printk("IA: null vcc\n");  
-              dev_kfree_skb_any(skb);
-              goto INCR_DLE;
-          }
-          ia_vcc = INPH_IA_VCC(vcc);
-          if (ia_vcc == NULL)
-          {
-             atomic_inc(&vcc->stats->rx_err);
-             atm_return(vcc, skb->truesize);
-             dev_kfree_skb_any(skb);
-             goto INCR_DLE;
-           }
-          // get real pkt length  pwang_test
-          trailer = (struct cpcs_trailer*)((u_char *)skb->data +
-                                 skb->len - sizeof(*trailer));
-	  length = swap_byte_order(trailer->length);
-          if ((length > iadev->rx_buf_sz) || (length > 
-                              (skb->len - sizeof(struct cpcs_trailer))))
-          {
-             atomic_inc(&vcc->stats->rx_err);
-             IF_ERR(printk("rx_dle_intr: Bad  AAL5 trailer %d (skb len %d)", 
-                                                            length, skb->len);)
-             atm_return(vcc, skb->truesize);
-             dev_kfree_skb_any(skb);
-             goto INCR_DLE;
-          }
-          skb_trim(skb, length);
-          
-	  /* Display the packet */  
-	  IF_RXPKT(printk("\nDmad Recvd data: len = %d \n", skb->len);  
-          xdump(skb->data, skb->len, "RX: ");
-          printk("\n");)
-
-	  IF_RX(printk("rx_dle_intr: skb push");)  
-	  vcc->push(vcc,skb);  
-	  atomic_inc(&vcc->stats->rx);
-          iadev->rx_pkt_cnt++;
-      }  
-INCR_DLE:
-      if (++dle == iadev->rx_dle_q.end)  
-    	  dle = iadev->rx_dle_q.start;  
-  }  
-  iadev->rx_dle_q.read = dle;  
-  
-  /* if the interrupts are masked because there were no free desc available,  
-		unmask them now. */ 
-  if (!iadev->rxing) {
-     state = readl(iadev->reass_reg + STATE_REG) & 0xffff;
-     if (!(state & FREEQ_EMPTY)) {
-        state = readl(iadev->reass_reg + REASS_MASK_REG) & 0xffff;
-        writel(state & ~(RX_FREEQ_EMPT |/* RX_EXCP_RCVD |*/ RX_PKT_RCVD),
-                                      iadev->reass_reg+REASS_MASK_REG);
-        iadev->rxing++; 
-     }
-  }
-}  
-  
-  
-static int open_rx(struct atm_vcc *vcc)  
-{  
-	IADEV *iadev;  
-	u_short __iomem *vc_table;  
-	u_short __iomem *reass_ptr;  
-	IF_EVENT(printk("iadev: open_rx %d.%d\n", vcc->vpi, vcc->vci);)
-
-	if (vcc->qos.rxtp.traffic_class == ATM_NONE) return 0;    
-	iadev = INPH_IA_DEV(vcc->dev);  
-        if (vcc->qos.rxtp.traffic_class == ATM_ABR) {  
-           if (iadev->phy_type & FE_25MBIT_PHY) {
-               printk("IA:  ABR not support\n");
-               return -EINVAL; 
-           }
-        }
-	/* Make only this VCI in the vc table valid and let all   
-		others be invalid entries */  
-	vc_table = iadev->reass_ram+RX_VC_TABLE*iadev->memSize;
-	vc_table += vcc->vci;
-	/* mask the last 6 bits and OR it with 3 for 1K VCs */  
-
-        *vc_table = vcc->vci << 6;
-	/* Also keep a list of open rx vcs so that we can attach them with  
-		incoming PDUs later. */  
-	if ((vcc->qos.rxtp.traffic_class == ATM_ABR) || 
-                                (vcc->qos.txtp.traffic_class == ATM_ABR))  
-	{  
-                srv_cls_param_t srv_p;
-                init_abr_vc(iadev, &srv_p);
-                ia_open_abr_vc(iadev, &srv_p, vcc, 0);
-	} 
-       	else {  /* for UBR  later may need to add CBR logic */
-        	reass_ptr = iadev->reass_ram+REASS_TABLE*iadev->memSize;
-           	reass_ptr += vcc->vci;
-           	*reass_ptr = NO_AAL5_PKT;
-       	}
-	
-	if (iadev->rx_open[vcc->vci])  
-		printk(KERN_CRIT DEV_LABEL "(itf %d): VCI %d already open\n",  
-			vcc->dev->number, vcc->vci);  
-	iadev->rx_open[vcc->vci] = vcc;  
-	return 0;  
-}  
-  
-static int rx_init(struct atm_dev *dev)  
-{  
-	IADEV *iadev;  
-	struct rx_buf_desc __iomem *buf_desc_ptr;  
-	unsigned long rx_pkt_start = 0;  
-	void *dle_addr;  
-	struct abr_vc_table  *abr_vc_table; 
-	u16 *vc_table;  
-	u16 *reass_table;  
-	int i,j, vcsize_sel;  
-	u_short freeq_st_adr;  
-	u_short *freeq_start;  
-  
-	iadev = INPH_IA_DEV(dev);  
-  //    spin_lock_init(&iadev->rx_lock); 
-  
-	/* Allocate 4k bytes - more aligned than needed (4k boundary) */
-	dle_addr = dma_alloc_coherent(&iadev->pci->dev, DLE_TOTAL_SIZE,
-				      &iadev->rx_dle_dma, GFP_KERNEL);
-	if (!dle_addr)  {  
-		printk(KERN_ERR DEV_LABEL "can't allocate DLEs\n");
-		goto err_out;
-	}
-	iadev->rx_dle_q.start = (struct dle *)dle_addr;
-	iadev->rx_dle_q.read = iadev->rx_dle_q.start;  
-	iadev->rx_dle_q.write = iadev->rx_dle_q.start;  
-	iadev->rx_dle_q.end = (struct dle*)((unsigned long)dle_addr+sizeof(struct dle)*DLE_ENTRIES);
-	/* the end of the dle q points to the entry after the last  
-	DLE that can be used. */  
-  
-	/* write the upper 20 bits of the start address to rx list address register */  
-	/* We know this is 32bit bus addressed so the following is safe */
-	writel(iadev->rx_dle_dma & 0xfffff000,
-	       iadev->dma + IPHASE5575_RX_LIST_ADDR);  
-	IF_INIT(printk("Tx Dle list addr: 0x%p value: 0x%0x\n",
-                      iadev->dma+IPHASE5575_TX_LIST_ADDR,
-                      readl(iadev->dma + IPHASE5575_TX_LIST_ADDR));
-	printk("Rx Dle list addr: 0x%p value: 0x%0x\n",
-                      iadev->dma+IPHASE5575_RX_LIST_ADDR,
-                      readl(iadev->dma + IPHASE5575_RX_LIST_ADDR));)
-  
-	writew(0xffff, iadev->reass_reg+REASS_MASK_REG);  
-	writew(0, iadev->reass_reg+MODE_REG);  
-	writew(RESET_REASS, iadev->reass_reg+REASS_COMMAND_REG);  
-  
-	/* Receive side control memory map  
-	   -------------------------------  
-  
-		Buffer descr	0x0000 (736 - 23K)  
-		VP Table	0x5c00 (256 - 512)  
-		Except q	0x5e00 (128 - 512)  
-		Free buffer q	0x6000 (1K - 2K)  
-		Packet comp q	0x6800 (1K - 2K)  
-		Reass Table	0x7000 (1K - 2K)  
-		VC Table	0x7800 (1K - 2K)  
-		ABR VC Table	0x8000 (1K - 32K)  
-	*/  
-	  
-	/* Base address for Buffer Descriptor Table */  
-	writew(RX_DESC_BASE >> 16, iadev->reass_reg+REASS_DESC_BASE);  
-	/* Set the buffer size register */  
-	writew(iadev->rx_buf_sz, iadev->reass_reg+BUF_SIZE);  
-  
-	/* Initialize each entry in the Buffer Descriptor Table */  
-        iadev->RX_DESC_BASE_ADDR = iadev->reass_ram+RX_DESC_BASE*iadev->memSize;
-	buf_desc_ptr = iadev->RX_DESC_BASE_ADDR;
-	memset_io(buf_desc_ptr, 0, sizeof(*buf_desc_ptr));
-	buf_desc_ptr++;  
-	rx_pkt_start = iadev->rx_pkt_ram;  
-	for(i=1; i<=iadev->num_rx_desc; i++)  
-	{  
-		memset_io(buf_desc_ptr, 0, sizeof(*buf_desc_ptr));  
-		buf_desc_ptr->buf_start_hi = rx_pkt_start >> 16;  
-		buf_desc_ptr->buf_start_lo = rx_pkt_start & 0x0000ffff;  
-		buf_desc_ptr++;		  
-		rx_pkt_start += iadev->rx_buf_sz;  
-	}  
-	IF_INIT(printk("Rx Buffer desc ptr: 0x%p\n", buf_desc_ptr);)
-        i = FREE_BUF_DESC_Q*iadev->memSize; 
-	writew(i >> 16,  iadev->reass_reg+REASS_QUEUE_BASE); 
-        writew(i, iadev->reass_reg+FREEQ_ST_ADR);
-        writew(i+iadev->num_rx_desc*sizeof(u_short), 
-                                         iadev->reass_reg+FREEQ_ED_ADR);
-        writew(i, iadev->reass_reg+FREEQ_RD_PTR);
-        writew(i+iadev->num_rx_desc*sizeof(u_short), 
-                                        iadev->reass_reg+FREEQ_WR_PTR);    
-	/* Fill the FREEQ with all the free descriptors. */  
-	freeq_st_adr = readw(iadev->reass_reg+FREEQ_ST_ADR);  
-	freeq_start = (u_short *)(iadev->reass_ram+freeq_st_adr);  
-	for(i=1; i<=iadev->num_rx_desc; i++)  
-	{  
-		*freeq_start = (u_short)i;  
-		freeq_start++;  
-	}  
-	IF_INIT(printk("freeq_start: 0x%p\n", freeq_start);)
-        /* Packet Complete Queue */
-        i = (PKT_COMP_Q * iadev->memSize) & 0xffff;
-        writew(i, iadev->reass_reg+PCQ_ST_ADR);
-        writew(i+iadev->num_vc*sizeof(u_short), iadev->reass_reg+PCQ_ED_ADR);
-        writew(i, iadev->reass_reg+PCQ_RD_PTR);
-        writew(i, iadev->reass_reg+PCQ_WR_PTR);
-
-        /* Exception Queue */
-        i = (EXCEPTION_Q * iadev->memSize) & 0xffff;
-        writew(i, iadev->reass_reg+EXCP_Q_ST_ADR);
-        writew(i + NUM_RX_EXCP * sizeof(RX_ERROR_Q), 
-                                             iadev->reass_reg+EXCP_Q_ED_ADR);
-        writew(i, iadev->reass_reg+EXCP_Q_RD_PTR);
-        writew(i, iadev->reass_reg+EXCP_Q_WR_PTR); 
- 
-    	/* Load local copy of FREEQ and PCQ ptrs */
-        iadev->rfL.fdq_st = readw(iadev->reass_reg+FREEQ_ST_ADR) & 0xffff;
-       	iadev->rfL.fdq_ed = readw(iadev->reass_reg+FREEQ_ED_ADR) & 0xffff ;
-	iadev->rfL.fdq_rd = readw(iadev->reass_reg+FREEQ_RD_PTR) & 0xffff;
-	iadev->rfL.fdq_wr = readw(iadev->reass_reg+FREEQ_WR_PTR) & 0xffff;
-        iadev->rfL.pcq_st = readw(iadev->reass_reg+PCQ_ST_ADR) & 0xffff;
-	iadev->rfL.pcq_ed = readw(iadev->reass_reg+PCQ_ED_ADR) & 0xffff;
-	iadev->rfL.pcq_rd = readw(iadev->reass_reg+PCQ_RD_PTR) & 0xffff;
-	iadev->rfL.pcq_wr = readw(iadev->reass_reg+PCQ_WR_PTR) & 0xffff;
-	
-        IF_INIT(printk("INIT:pcq_st:0x%x pcq_ed:0x%x pcq_rd:0x%x pcq_wr:0x%x", 
-              iadev->rfL.pcq_st, iadev->rfL.pcq_ed, iadev->rfL.pcq_rd, 
-              iadev->rfL.pcq_wr);)		  
-	/* just for check - no VP TBL */  
-	/* VP Table */  
-	/* writew(0x0b80, iadev->reass_reg+VP_LKUP_BASE); */  
-	/* initialize VP Table for invalid VPIs  
-		- I guess we can write all 1s or 0x000f in the entire memory  
-		  space or something similar.  
-	*/  
-  
-	/* This seems to work and looks right to me too !!! */  
-        i =  REASS_TABLE * iadev->memSize;
-	writew((i >> 3), iadev->reass_reg+REASS_TABLE_BASE);   
- 	/* initialize Reassembly table to I don't know what ???? */  
-	reass_table = (u16 *)(iadev->reass_ram+i);  
-        j = REASS_TABLE_SZ * iadev->memSize;
-	for(i=0; i < j; i++)  
-		*reass_table++ = NO_AAL5_PKT;  
-       i = 8*1024;
-       vcsize_sel =  0;
-       while (i != iadev->num_vc) {
-          i /= 2;
-          vcsize_sel++;
-       }
-       i = RX_VC_TABLE * iadev->memSize;
-       writew(((i>>3) & 0xfff8) | vcsize_sel, iadev->reass_reg+VC_LKUP_BASE);
-       vc_table = (u16 *)(iadev->reass_ram+RX_VC_TABLE*iadev->memSize);  
-        j = RX_VC_TABLE_SZ * iadev->memSize;
-	for(i = 0; i < j; i++)  
-	{  
-		/* shift the reassembly pointer by 3 + lower 3 bits of   
-		vc_lkup_base register (=3 for 1K VCs) and the last byte   
-		is those low 3 bits.   
-		Shall program this later.  
-		*/  
-		*vc_table = (i << 6) | 15;	/* for invalid VCI */  
-		vc_table++;  
-	}  
-        /* ABR VC table */
-        i =  ABR_VC_TABLE * iadev->memSize;
-        writew(i >> 3, iadev->reass_reg+ABR_LKUP_BASE);
-                   
-        i = ABR_VC_TABLE * iadev->memSize;
-	abr_vc_table = (struct abr_vc_table *)(iadev->reass_ram+i);  
-        j = REASS_TABLE_SZ * iadev->memSize;
-        memset ((char*)abr_vc_table, 0, j * sizeof(*abr_vc_table));
-    	for(i = 0; i < j; i++) {   		
-		abr_vc_table->rdf = 0x0003;
-             	abr_vc_table->air = 0x5eb1;
-	       	abr_vc_table++;   	
-        }  
-
-	/* Initialize other registers */  
-  
-	/* VP Filter Register set for VC Reassembly only */  
-	writew(0xff00, iadev->reass_reg+VP_FILTER);  
-        writew(0, iadev->reass_reg+XTRA_RM_OFFSET);
-	writew(0x1,  iadev->reass_reg+PROTOCOL_ID);
-
-	/* Packet Timeout Count  related Registers : 
-	   Set packet timeout to occur in about 3 seconds
-	   Set Packet Aging Interval count register to overflow in about 4 us
- 	*/  
-        writew(0xF6F8, iadev->reass_reg+PKT_TM_CNT );
-
-        i = (j >> 6) & 0xFF;
-        j += 2 * (j - 1);
-        i |= ((j << 2) & 0xFF00);
-        writew(i, iadev->reass_reg+TMOUT_RANGE);
-
-        /* initiate the desc_tble */
-        for(i=0; i<iadev->num_tx_desc;i++)
-            iadev->desc_tbl[i].timestamp = 0;
-
-	/* to clear the interrupt status register - read it */  
-	readw(iadev->reass_reg+REASS_INTR_STATUS_REG);   
-  
-	/* Mask Register - clear it */  
-	writew(~(RX_FREEQ_EMPT|RX_PKT_RCVD), iadev->reass_reg+REASS_MASK_REG);  
-  
-	skb_queue_head_init(&iadev->rx_dma_q);  
-	iadev->rx_free_desc_qhead = NULL;   
-
-	iadev->rx_open = kcalloc(iadev->num_vc, sizeof(void *), GFP_KERNEL);
-	if (!iadev->rx_open) {
-		printk(KERN_ERR DEV_LABEL "itf %d couldn't get free page\n",
-		dev->number);  
-		goto err_free_dle;
-	}  
-
-        iadev->rxing = 1;
-        iadev->rx_pkt_cnt = 0;
-	/* Mode Register */  
-	writew(R_ONLINE, iadev->reass_reg+MODE_REG);  
-	return 0;  
-
-err_free_dle:
-	dma_free_coherent(&iadev->pci->dev, DLE_TOTAL_SIZE, iadev->rx_dle_q.start,
-			  iadev->rx_dle_dma);
-err_out:
-	return -ENOMEM;
-}  
-  
-
-/*  
-	The memory map suggested in appendix A and the coding for it.   
-	Keeping it around just in case we change our mind later.  
-  
-		Buffer descr	0x0000 (128 - 4K)  
-		UBR sched	0x1000 (1K - 4K)  
-		UBR Wait q	0x2000 (1K - 4K)  
-		Commn queues	0x3000 Packet Ready, Trasmit comp(0x3100)  
-					(128 - 256) each  
-		extended VC	0x4000 (1K - 8K)  
-		ABR sched	0x6000	and ABR wait queue (1K - 2K) each  
-		CBR sched	0x7000 (as needed)  
-		VC table	0x8000 (1K - 32K)  
-*/  
-  
-static void tx_intr(struct atm_dev *dev)  
-{  
-	IADEV *iadev;  
-	unsigned short status;  
-        unsigned long flags;
-
-	iadev = INPH_IA_DEV(dev);  
-  
-	status = readl(iadev->seg_reg+SEG_INTR_STATUS_REG);  
-        if (status & TRANSMIT_DONE){
-
-           IF_EVENT(printk("Transmit Done Intr logic run\n");)
-           spin_lock_irqsave(&iadev->tx_lock, flags);
-           ia_tx_poll(iadev);
-           spin_unlock_irqrestore(&iadev->tx_lock, flags);
-           writew(TRANSMIT_DONE, iadev->seg_reg+SEG_INTR_STATUS_REG);
-           if (iadev->close_pending)  
-               wake_up(&iadev->close_wait);
-        }     	  
-	if (status & TCQ_NOT_EMPTY)  
-	{  
-	    IF_EVENT(printk("TCQ_NOT_EMPTY int received\n");)  
-	}  
-}  
-  
-static void tx_dle_intr(struct atm_dev *dev)
-{
-        IADEV *iadev;
-        struct dle *dle, *cur_dle; 
-        struct sk_buff *skb;
-        struct atm_vcc *vcc;
-        struct ia_vcc  *iavcc;
-        u_int dle_lp;
-        unsigned long flags;
-
-        iadev = INPH_IA_DEV(dev);
-        spin_lock_irqsave(&iadev->tx_lock, flags);   
-        dle = iadev->tx_dle_q.read;
-        dle_lp = readl(iadev->dma+IPHASE5575_TX_LIST_ADDR) & 
-                                        (sizeof(struct dle)*DLE_ENTRIES - 1);
-        cur_dle = (struct dle*)(iadev->tx_dle_q.start + (dle_lp >> 4));
-        while (dle != cur_dle)
-        {
-            /* free the DMAed skb */ 
-            skb = skb_dequeue(&iadev->tx_dma_q); 
-            if (!skb) break;
-
-	    /* Revenge of the 2 dle (skb + trailer) used in ia_pkt_tx() */
-	    if (!((dle - iadev->tx_dle_q.start)%(2*sizeof(struct dle)))) {
-		dma_unmap_single(&iadev->pci->dev, dle->sys_pkt_addr, skb->len,
-				 DMA_TO_DEVICE);
-	    }
-            vcc = ATM_SKB(skb)->vcc;
-            if (!vcc) {
-                  printk("tx_dle_intr: vcc is null\n");
-		  spin_unlock_irqrestore(&iadev->tx_lock, flags);
-                  dev_kfree_skb_any(skb);
-
-                  return;
-            }
-            iavcc = INPH_IA_VCC(vcc);
-            if (!iavcc) {
-                  printk("tx_dle_intr: iavcc is null\n");
-		  spin_unlock_irqrestore(&iadev->tx_lock, flags);
-                  dev_kfree_skb_any(skb);
-                  return;
-            }
-            if (vcc->qos.txtp.pcr >= iadev->rate_limit) {
-               if ((vcc->pop) && (skb->len != 0))
-               {     
-                 vcc->pop(vcc, skb);
-               } 
-               else {
-                 dev_kfree_skb_any(skb);
-               }
-            }
-            else { /* Hold the rate-limited skb for flow control */
-               IA_SKB_STATE(skb) |= IA_DLED;
-               skb_queue_tail(&iavcc->txing_skb, skb);
-            }
-            IF_EVENT(printk("tx_dle_intr: enque skb = 0x%p \n", skb);)
-            if (++dle == iadev->tx_dle_q.end)
-                 dle = iadev->tx_dle_q.start;
-        }
-        iadev->tx_dle_q.read = dle;
-        spin_unlock_irqrestore(&iadev->tx_lock, flags);
-}
-  
-static int open_tx(struct atm_vcc *vcc)  
-{  
-	struct ia_vcc *ia_vcc;  
-	IADEV *iadev;  
-	struct main_vc *vc;  
-	struct ext_vc *evc;  
-        int ret;
-	IF_EVENT(printk("iadev: open_tx entered vcc->vci = %d\n", vcc->vci);)  
-	if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0;  
-	iadev = INPH_IA_DEV(vcc->dev);  
-        
-        if (iadev->phy_type & FE_25MBIT_PHY) {
-           if (vcc->qos.txtp.traffic_class == ATM_ABR) {
-               printk("IA:  ABR not support\n");
-               return -EINVAL; 
-           }
-	  if (vcc->qos.txtp.traffic_class == ATM_CBR) {
-               printk("IA:  CBR not support\n");
-               return -EINVAL; 
-          }
-        }
-        ia_vcc =  INPH_IA_VCC(vcc);
-        memset((caddr_t)ia_vcc, 0, sizeof(*ia_vcc));
-        if (vcc->qos.txtp.max_sdu > 
-                         (iadev->tx_buf_sz - sizeof(struct cpcs_trailer))){
-           printk("IA:  SDU size over (%d) the configured SDU size %d\n",
-		  vcc->qos.txtp.max_sdu,iadev->tx_buf_sz);
-	   vcc->dev_data = NULL;
-           kfree(ia_vcc);
-           return -EINVAL; 
-        }
-	ia_vcc->vc_desc_cnt = 0;
-        ia_vcc->txing = 1;
-
-        /* find pcr */
-        if (vcc->qos.txtp.max_pcr == ATM_MAX_PCR) 
-           vcc->qos.txtp.pcr = iadev->LineRate;
-        else if ((vcc->qos.txtp.max_pcr == 0)&&( vcc->qos.txtp.pcr <= 0))
-           vcc->qos.txtp.pcr = iadev->LineRate;
-        else if ((vcc->qos.txtp.max_pcr > vcc->qos.txtp.pcr) && (vcc->qos.txtp.max_pcr> 0)) 
-           vcc->qos.txtp.pcr = vcc->qos.txtp.max_pcr;
-        if (vcc->qos.txtp.pcr > iadev->LineRate)
-             vcc->qos.txtp.pcr = iadev->LineRate;
-        ia_vcc->pcr = vcc->qos.txtp.pcr;
-
-        if (ia_vcc->pcr > (iadev->LineRate / 6) ) ia_vcc->ltimeout = HZ / 10;
-        else if (ia_vcc->pcr > (iadev->LineRate / 130)) ia_vcc->ltimeout = HZ;
-        else if (ia_vcc->pcr <= 170) ia_vcc->ltimeout = 16 * HZ;
-        else ia_vcc->ltimeout = 2700 * HZ  / ia_vcc->pcr;
-        if (ia_vcc->pcr < iadev->rate_limit)
-           skb_queue_head_init (&ia_vcc->txing_skb);
-        if (ia_vcc->pcr < iadev->rate_limit) {
-	   struct sock *sk = sk_atm(vcc);
-
-	   if (vcc->qos.txtp.max_sdu != 0) {
-               if (ia_vcc->pcr > 60000)
-                  sk->sk_sndbuf = vcc->qos.txtp.max_sdu * 5;
-               else if (ia_vcc->pcr > 2000)
-                  sk->sk_sndbuf = vcc->qos.txtp.max_sdu * 4;
-               else
-                 sk->sk_sndbuf = vcc->qos.txtp.max_sdu * 3;
-           }
-           else
-             sk->sk_sndbuf = 24576;
-        }
-           
-	vc = (struct main_vc *)iadev->MAIN_VC_TABLE_ADDR;  
-	evc = (struct ext_vc *)iadev->EXT_VC_TABLE_ADDR;  
-	vc += vcc->vci;  
-	evc += vcc->vci;  
-	memset((caddr_t)vc, 0, sizeof(*vc));  
-	memset((caddr_t)evc, 0, sizeof(*evc));  
-	  
-	/* store the most significant 4 bits of vci as the last 4 bits   
-		of first part of atm header.  
-	   store the last 12 bits of vci as first 12 bits of the second  
-		part of the atm header.  
-	*/  
-	evc->atm_hdr1 = (vcc->vci >> 12) & 0x000f;  
-	evc->atm_hdr2 = (vcc->vci & 0x0fff) << 4;  
- 
-	/* check the following for different traffic classes */  
-	if (vcc->qos.txtp.traffic_class == ATM_UBR)  
-	{  
-		vc->type = UBR;  
-                vc->status = CRC_APPEND;
-		vc->acr = cellrate_to_float(iadev->LineRate);  
-                if (vcc->qos.txtp.pcr > 0) 
-                   vc->acr = cellrate_to_float(vcc->qos.txtp.pcr);  
-                IF_UBR(printk("UBR: txtp.pcr = 0x%x f_rate = 0x%x\n", 
-                                             vcc->qos.txtp.max_pcr,vc->acr);)
-	}  
-	else if (vcc->qos.txtp.traffic_class == ATM_ABR)  
-	{       srv_cls_param_t srv_p;
-		IF_ABR(printk("Tx ABR VCC\n");)  
-                init_abr_vc(iadev, &srv_p);
-                if (vcc->qos.txtp.pcr > 0) 
-                   srv_p.pcr = vcc->qos.txtp.pcr;
-                if (vcc->qos.txtp.min_pcr > 0) {
-                   int tmpsum = iadev->sum_mcr+iadev->sum_cbr+vcc->qos.txtp.min_pcr;
-                   if (tmpsum > iadev->LineRate)
-                       return -EBUSY;
-                   srv_p.mcr = vcc->qos.txtp.min_pcr;
-                   iadev->sum_mcr += vcc->qos.txtp.min_pcr;
-                } 
-                else srv_p.mcr = 0;
-                if (vcc->qos.txtp.icr)
-                   srv_p.icr = vcc->qos.txtp.icr;
-                if (vcc->qos.txtp.tbe)
-                   srv_p.tbe = vcc->qos.txtp.tbe;
-                if (vcc->qos.txtp.frtt)
-                   srv_p.frtt = vcc->qos.txtp.frtt;
-                if (vcc->qos.txtp.rif)
-                   srv_p.rif = vcc->qos.txtp.rif;
-                if (vcc->qos.txtp.rdf)
-                   srv_p.rdf = vcc->qos.txtp.rdf;
-                if (vcc->qos.txtp.nrm_pres)
-                   srv_p.nrm = vcc->qos.txtp.nrm;
-                if (vcc->qos.txtp.trm_pres)
-                   srv_p.trm = vcc->qos.txtp.trm;
-                if (vcc->qos.txtp.adtf_pres)
-                   srv_p.adtf = vcc->qos.txtp.adtf;
-                if (vcc->qos.txtp.cdf_pres)
-                   srv_p.cdf = vcc->qos.txtp.cdf;    
-                if (srv_p.icr > srv_p.pcr)
-                   srv_p.icr = srv_p.pcr;    
-                IF_ABR(printk("ABR:vcc->qos.txtp.max_pcr = %d  mcr = %d\n", 
-                                                      srv_p.pcr, srv_p.mcr);)
-		ia_open_abr_vc(iadev, &srv_p, vcc, 1);
-	} else if (vcc->qos.txtp.traffic_class == ATM_CBR) {
-                if (iadev->phy_type & FE_25MBIT_PHY) {
-                    printk("IA:  CBR not support\n");
-                    return -EINVAL; 
-                }
-                if (vcc->qos.txtp.max_pcr > iadev->LineRate) {
-                   IF_CBR(printk("PCR is not available\n");)
-                   return -1;
-                }
-                vc->type = CBR;
-                vc->status = CRC_APPEND;
-                if ((ret = ia_cbr_setup (iadev, vcc)) < 0) {     
-                    return ret;
-                }
-	} else {
-		printk("iadev:  Non UBR, ABR and CBR traffic not supported\n");
-	}
-        
-        iadev->testTable[vcc->vci]->vc_status |= VC_ACTIVE;
-	IF_EVENT(printk("ia open_tx returning \n");)  
-	return 0;  
-}  
-  
-  
-static int tx_init(struct atm_dev *dev)  
-{  
-	IADEV *iadev;  
-	struct tx_buf_desc *buf_desc_ptr;
-	unsigned int tx_pkt_start;  
-	void *dle_addr;  
-	int i;  
-	u_short tcq_st_adr;  
-	u_short *tcq_start;  
-	u_short prq_st_adr;  
-	u_short *prq_start;  
-	struct main_vc *vc;  
-	struct ext_vc *evc;   
-        u_short tmp16;
-        u32 vcsize_sel;
- 
-	iadev = INPH_IA_DEV(dev);  
-        spin_lock_init(&iadev->tx_lock);
- 
-	IF_INIT(printk("Tx MASK REG: 0x%0x\n", 
-                                readw(iadev->seg_reg+SEG_MASK_REG));)  
-
-	/* Allocate 4k (boundary aligned) bytes */
-	dle_addr = dma_alloc_coherent(&iadev->pci->dev, DLE_TOTAL_SIZE,
-				      &iadev->tx_dle_dma, GFP_KERNEL);
-	if (!dle_addr)  {
-		printk(KERN_ERR DEV_LABEL "can't allocate DLEs\n");
-		goto err_out;
-	}
-	iadev->tx_dle_q.start = (struct dle*)dle_addr;  
-	iadev->tx_dle_q.read = iadev->tx_dle_q.start;  
-	iadev->tx_dle_q.write = iadev->tx_dle_q.start;  
-	iadev->tx_dle_q.end = (struct dle*)((unsigned long)dle_addr+sizeof(struct dle)*DLE_ENTRIES);
-
-	/* write the upper 20 bits of the start address to tx list address register */  
-	writel(iadev->tx_dle_dma & 0xfffff000,
-	       iadev->dma + IPHASE5575_TX_LIST_ADDR);  
-	writew(0xffff, iadev->seg_reg+SEG_MASK_REG);  
-	writew(0, iadev->seg_reg+MODE_REG_0);  
-	writew(RESET_SEG, iadev->seg_reg+SEG_COMMAND_REG);  
-        iadev->MAIN_VC_TABLE_ADDR = iadev->seg_ram+MAIN_VC_TABLE*iadev->memSize;
-        iadev->EXT_VC_TABLE_ADDR = iadev->seg_ram+EXT_VC_TABLE*iadev->memSize;
-        iadev->ABR_SCHED_TABLE_ADDR=iadev->seg_ram+ABR_SCHED_TABLE*iadev->memSize;
-  
-	/*  
-	   Transmit side control memory map  
-	   --------------------------------    
-	 Buffer descr 	0x0000 (128 - 4K)  
-	 Commn queues	0x1000	Transmit comp, Packet ready(0x1400)   
-					(512 - 1K) each  
-					TCQ - 4K, PRQ - 5K  
-	 CBR Table 	0x1800 (as needed) - 6K  
-	 UBR Table	0x3000 (1K - 4K) - 12K  
-	 UBR Wait queue	0x4000 (1K - 4K) - 16K  
-	 ABR sched	0x5000	and ABR wait queue (1K - 2K) each  
-				ABR Tbl - 20K, ABR Wq - 22K   
-	 extended VC	0x6000 (1K - 8K) - 24K  
-	 VC Table	0x8000 (1K - 32K) - 32K  
-	  
-	Between 0x2000 (8K) and 0x3000 (12K) there is 4K space left for VBR Tbl  
-	and Wait q, which can be allotted later.  
-	*/  
-     
-	/* Buffer Descriptor Table Base address */  
-	writew(TX_DESC_BASE, iadev->seg_reg+SEG_DESC_BASE);  
-  
-	/* initialize each entry in the buffer descriptor table */  
-	buf_desc_ptr =(struct tx_buf_desc *)(iadev->seg_ram+TX_DESC_BASE);  
-	memset((caddr_t)buf_desc_ptr, 0, sizeof(*buf_desc_ptr));  
-	buf_desc_ptr++;  
-	tx_pkt_start = TX_PACKET_RAM;  
-	for(i=1; i<=iadev->num_tx_desc; i++)  
-	{  
-		memset((caddr_t)buf_desc_ptr, 0, sizeof(*buf_desc_ptr));  
-		buf_desc_ptr->desc_mode = AAL5;  
-		buf_desc_ptr->buf_start_hi = tx_pkt_start >> 16;  
-		buf_desc_ptr->buf_start_lo = tx_pkt_start & 0x0000ffff;  
-		buf_desc_ptr++;		  
-		tx_pkt_start += iadev->tx_buf_sz;  
-	}  
-	iadev->tx_buf = kmalloc_objs(*iadev->tx_buf, iadev->num_tx_desc);
-        if (!iadev->tx_buf) {
-            printk(KERN_ERR DEV_LABEL " couldn't get mem\n");
-	    goto err_free_dle;
-        }
-       	for (i= 0; i< iadev->num_tx_desc; i++)
-       	{
-	    struct cpcs_trailer *cpcs;
- 
-       	    cpcs = kmalloc_obj(*cpcs, GFP_KERNEL | GFP_DMA);
-            if(!cpcs) {                
-		printk(KERN_ERR DEV_LABEL " couldn't get freepage\n"); 
-		goto err_free_tx_bufs;
-            }
-	    iadev->tx_buf[i].cpcs = cpcs;
-	    iadev->tx_buf[i].dma_addr = dma_map_single(&iadev->pci->dev,
-						       cpcs,
-						       sizeof(*cpcs),
-						       DMA_TO_DEVICE);
-        }
-	iadev->desc_tbl = kmalloc_objs(*iadev->desc_tbl, iadev->num_tx_desc);
-	if (!iadev->desc_tbl) {
-		printk(KERN_ERR DEV_LABEL " couldn't get mem\n");
-		goto err_free_all_tx_bufs;
-	}
-  
-	/* Communication Queues base address */  
-        i = TX_COMP_Q * iadev->memSize;
-	writew(i >> 16, iadev->seg_reg+SEG_QUEUE_BASE);  
-  
-	/* Transmit Complete Queue */  
-	writew(i, iadev->seg_reg+TCQ_ST_ADR);  
-	writew(i, iadev->seg_reg+TCQ_RD_PTR);  
-	writew(i+iadev->num_tx_desc*sizeof(u_short),iadev->seg_reg+TCQ_WR_PTR); 
-	iadev->host_tcq_wr = i + iadev->num_tx_desc*sizeof(u_short);
-        writew(i+2 * iadev->num_tx_desc * sizeof(u_short), 
-                                              iadev->seg_reg+TCQ_ED_ADR); 
-	/* Fill the TCQ with all the free descriptors. */  
-	tcq_st_adr = readw(iadev->seg_reg+TCQ_ST_ADR);  
-	tcq_start = (u_short *)(iadev->seg_ram+tcq_st_adr);  
-	for(i=1; i<=iadev->num_tx_desc; i++)  
-	{  
-		*tcq_start = (u_short)i;  
-		tcq_start++;  
-	}  
-  
-	/* Packet Ready Queue */  
-        i = PKT_RDY_Q * iadev->memSize; 
-	writew(i, iadev->seg_reg+PRQ_ST_ADR);  
-	writew(i+2 * iadev->num_tx_desc * sizeof(u_short), 
-                                              iadev->seg_reg+PRQ_ED_ADR);
-	writew(i, iadev->seg_reg+PRQ_RD_PTR);  
-	writew(i, iadev->seg_reg+PRQ_WR_PTR);  
-	 
-        /* Load local copy of PRQ and TCQ ptrs */
-        iadev->ffL.prq_st = readw(iadev->seg_reg+PRQ_ST_ADR) & 0xffff;
-	iadev->ffL.prq_ed = readw(iadev->seg_reg+PRQ_ED_ADR) & 0xffff;
- 	iadev->ffL.prq_wr = readw(iadev->seg_reg+PRQ_WR_PTR) & 0xffff;
-
-	iadev->ffL.tcq_st = readw(iadev->seg_reg+TCQ_ST_ADR) & 0xffff;
-	iadev->ffL.tcq_ed = readw(iadev->seg_reg+TCQ_ED_ADR) & 0xffff;
-	iadev->ffL.tcq_rd = readw(iadev->seg_reg+TCQ_RD_PTR) & 0xffff;
-
-	/* Just for safety initializing the queue to have desc 1 always */  
-	/* Fill the PRQ with all the free descriptors. */  
-	prq_st_adr = readw(iadev->seg_reg+PRQ_ST_ADR);  
-	prq_start = (u_short *)(iadev->seg_ram+prq_st_adr);  
-	for(i=1; i<=iadev->num_tx_desc; i++)  
-	{  
-		*prq_start = (u_short)0;	/* desc 1 in all entries */  
-		prq_start++;  
-	}  
-	/* CBR Table */  
-        IF_INIT(printk("Start CBR Init\n");)
-#if 1  /* for 1K VC board, CBR_PTR_BASE is 0 */
-        writew(0,iadev->seg_reg+CBR_PTR_BASE);
-#else /* Charlie's logic is wrong ? */
-        tmp16 = (iadev->seg_ram+CBR_SCHED_TABLE*iadev->memSize)>>17;
-        IF_INIT(printk("cbr_ptr_base = 0x%x ", tmp16);)
-        writew(tmp16,iadev->seg_reg+CBR_PTR_BASE);
-#endif
-
-        IF_INIT(printk("value in register = 0x%x\n",
-                                   readw(iadev->seg_reg+CBR_PTR_BASE));)
-        tmp16 = (CBR_SCHED_TABLE*iadev->memSize) >> 1;
-        writew(tmp16, iadev->seg_reg+CBR_TAB_BEG);
-        IF_INIT(printk("cbr_tab_beg = 0x%x in reg = 0x%x \n", tmp16,
-                                        readw(iadev->seg_reg+CBR_TAB_BEG));)
-        writew(tmp16, iadev->seg_reg+CBR_TAB_END+1); // CBR_PTR;
-        tmp16 = (CBR_SCHED_TABLE*iadev->memSize + iadev->num_vc*6 - 2) >> 1;
-        writew(tmp16, iadev->seg_reg+CBR_TAB_END);
-        IF_INIT(printk("iadev->seg_reg = 0x%p CBR_PTR_BASE = 0x%x\n",
-               iadev->seg_reg, readw(iadev->seg_reg+CBR_PTR_BASE));)
-        IF_INIT(printk("CBR_TAB_BEG = 0x%x, CBR_TAB_END = 0x%x, CBR_PTR = 0x%x\n",
-          readw(iadev->seg_reg+CBR_TAB_BEG), readw(iadev->seg_reg+CBR_TAB_END),
-          readw(iadev->seg_reg+CBR_TAB_END+1));)
-
-        /* Initialize the CBR Schedualing Table */
-        memset_io(iadev->seg_ram+CBR_SCHED_TABLE*iadev->memSize, 
-                                                          0, iadev->num_vc*6); 
-        iadev->CbrRemEntries = iadev->CbrTotEntries = iadev->num_vc*3;
-        iadev->CbrEntryPt = 0;
-        iadev->Granularity = MAX_ATM_155 / iadev->CbrTotEntries;
-        iadev->NumEnabledCBR = 0;
-
-	/* UBR scheduling Table and wait queue */  
-	/* initialize all bytes of UBR scheduler table and wait queue to 0   
-		- SCHEDSZ is 1K (# of entries).  
-		- UBR Table size is 4K  
-		- UBR wait queue is 4K  
-	   since the table and wait queues are contiguous, all the bytes   
-	   can be initialized by one memeset.
-	*/  
-        
-        vcsize_sel = 0;
-        i = 8*1024;
-        while (i != iadev->num_vc) {
-          i /= 2;
-          vcsize_sel++;
-        }
- 
-        i = MAIN_VC_TABLE * iadev->memSize;
-        writew(vcsize_sel | ((i >> 8) & 0xfff8),iadev->seg_reg+VCT_BASE);
-        i =  EXT_VC_TABLE * iadev->memSize;
-        writew((i >> 8) & 0xfffe, iadev->seg_reg+VCTE_BASE);
-        i = UBR_SCHED_TABLE * iadev->memSize;
-        writew((i & 0xffff) >> 11,  iadev->seg_reg+UBR_SBPTR_BASE);
-        i = UBR_WAIT_Q * iadev->memSize; 
-        writew((i >> 7) & 0xffff,  iadev->seg_reg+UBRWQ_BASE);
- 	memset((caddr_t)(iadev->seg_ram+UBR_SCHED_TABLE*iadev->memSize),
-                                                       0, iadev->num_vc*8);
-	/* ABR scheduling Table(0x5000-0x57ff) and wait queue(0x5800-0x5fff)*/  
-	/* initialize all bytes of ABR scheduler table and wait queue to 0   
-		- SCHEDSZ is 1K (# of entries).  
-		- ABR Table size is 2K  
-		- ABR wait queue is 2K  
-	   since the table and wait queues are contiguous, all the bytes   
-	   can be initialized by one memeset.
-	*/  
-        i = ABR_SCHED_TABLE * iadev->memSize;
-        writew((i >> 11) & 0xffff, iadev->seg_reg+ABR_SBPTR_BASE);
-        i = ABR_WAIT_Q * iadev->memSize;
-        writew((i >> 7) & 0xffff, iadev->seg_reg+ABRWQ_BASE);
- 
-        i = ABR_SCHED_TABLE*iadev->memSize;
-	memset((caddr_t)(iadev->seg_ram+i),  0, iadev->num_vc*4);
-	vc = (struct main_vc *)iadev->MAIN_VC_TABLE_ADDR;  
-	evc = (struct ext_vc *)iadev->EXT_VC_TABLE_ADDR;  
-	iadev->testTable = kmalloc_objs(*iadev->testTable, iadev->num_vc);
-        if (!iadev->testTable) {
-           printk("Get freepage  failed\n");
-	   goto err_free_desc_tbl;
-        }
-	for(i=0; i<iadev->num_vc; i++)  
-	{  
-		memset((caddr_t)vc, 0, sizeof(*vc));  
-		memset((caddr_t)evc, 0, sizeof(*evc));  
-                iadev->testTable[i] = kmalloc_obj(struct testTable_t);
-		if (!iadev->testTable[i])
-			goto err_free_test_tables;
-              	iadev->testTable[i]->lastTime = 0;
- 		iadev->testTable[i]->fract = 0;
-                iadev->testTable[i]->vc_status = VC_UBR;
-		vc++;  
-		evc++;  
-	}  
-  
-	/* Other Initialization */  
-	  
-	/* Max Rate Register */  
-        if (iadev->phy_type & FE_25MBIT_PHY) {
-	   writew(RATE25, iadev->seg_reg+MAXRATE);  
-	   writew((UBR_EN | (0x23 << 2)), iadev->seg_reg+STPARMS);  
-        }
-        else {
-	   writew(cellrate_to_float(iadev->LineRate),iadev->seg_reg+MAXRATE);
-	   writew((UBR_EN | ABR_EN | (0x23 << 2)), iadev->seg_reg+STPARMS);  
-        }
-	/* Set Idle Header Reigisters to be sure */  
-	writew(0, iadev->seg_reg+IDLEHEADHI);  
-	writew(0, iadev->seg_reg+IDLEHEADLO);  
-  
-	/* Program ABR UBR Priority Register  as  PRI_ABR_UBR_EQUAL */
-        writew(0xaa00, iadev->seg_reg+ABRUBR_ARB); 
-
-        iadev->close_pending = 0;
-        init_waitqueue_head(&iadev->close_wait);
-        init_waitqueue_head(&iadev->timeout_wait);
-	skb_queue_head_init(&iadev->tx_dma_q);  
-	ia_init_rtn_q(&iadev->tx_return_q);  
-
-	/* RM Cell Protocol ID and Message Type */  
-	writew(RM_TYPE_4_0, iadev->seg_reg+RM_TYPE);  
-        skb_queue_head_init (&iadev->tx_backlog);
-  
-	/* Mode Register 1 */  
-	writew(MODE_REG_1_VAL, iadev->seg_reg+MODE_REG_1);  
-  
-	/* Mode Register 0 */  
-	writew(T_ONLINE, iadev->seg_reg+MODE_REG_0);  
-  
-	/* Interrupt Status Register - read to clear */  
-	readw(iadev->seg_reg+SEG_INTR_STATUS_REG);  
-  
-	/* Interrupt Mask Reg- don't mask TCQ_NOT_EMPTY interrupt generation */  
-        writew(~(TRANSMIT_DONE | TCQ_NOT_EMPTY), iadev->seg_reg+SEG_MASK_REG);
-        writew(TRANSMIT_DONE, iadev->seg_reg+SEG_INTR_STATUS_REG);  
-        iadev->tx_pkt_cnt = 0;
-        iadev->rate_limit = iadev->LineRate / 3;
-  
-	return 0;
-
-err_free_test_tables:
-	while (--i >= 0)
-		kfree(iadev->testTable[i]);
-	kfree(iadev->testTable);
-err_free_desc_tbl:
-	kfree(iadev->desc_tbl);
-err_free_all_tx_bufs:
-	i = iadev->num_tx_desc;
-err_free_tx_bufs:
-	while (--i >= 0) {
-		struct cpcs_trailer_desc *desc = iadev->tx_buf + i;
-
-		dma_unmap_single(&iadev->pci->dev, desc->dma_addr,
-				 sizeof(*desc->cpcs), DMA_TO_DEVICE);
-		kfree(desc->cpcs);
-	}
-	kfree(iadev->tx_buf);
-err_free_dle:
-	dma_free_coherent(&iadev->pci->dev, DLE_TOTAL_SIZE, iadev->tx_dle_q.start,
-			  iadev->tx_dle_dma);
-err_out:
-	return -ENOMEM;
-}   
-   
-static irqreturn_t ia_int(int irq, void *dev_id)  
-{  
-   struct atm_dev *dev;  
-   IADEV *iadev;  
-   unsigned int status;  
-   int handled = 0;
-
-   dev = dev_id;  
-   iadev = INPH_IA_DEV(dev);  
-   while( (status = readl(iadev->reg+IPHASE5575_BUS_STATUS_REG) & 0x7f))  
-   { 
-	handled = 1;
-        IF_EVENT(printk("ia_int: status = 0x%x\n", status);) 
-	if (status & STAT_REASSINT)  
-	{  
-	   /* do something */  
-	   IF_EVENT(printk("REASSINT Bus status reg: %08x\n", status);) 
-	   rx_intr(dev);  
-	}  
-	if (status & STAT_DLERINT)  
-	{  
-	   /* Clear this bit by writing a 1 to it. */  
-	   writel(STAT_DLERINT, iadev->reg + IPHASE5575_BUS_STATUS_REG);
-	   rx_dle_intr(dev);  
-	}  
-	if (status & STAT_SEGINT)  
-	{  
-	   /* do something */ 
-           IF_EVENT(printk("IA: tx_intr \n");) 
-	   tx_intr(dev);  
-	}  
-	if (status & STAT_DLETINT)  
-	{  
-	   writel(STAT_DLETINT, iadev->reg + IPHASE5575_BUS_STATUS_REG);
-	   tx_dle_intr(dev);  
-	}  
-	if (status & (STAT_FEINT | STAT_ERRINT | STAT_MARKINT))  
-	{  
-           if (status & STAT_FEINT) 
-               ia_frontend_intr(iadev);
-	}  
-   }
-   return IRQ_RETVAL(handled);
-}  
-	  
-	  
-	  
-/*----------------------------- entries --------------------------------*/  
-static int get_esi(struct atm_dev *dev)  
-{  
-	IADEV *iadev;  
-	int i;  
-	u32 mac1;  
-	u16 mac2;  
-	  
-	iadev = INPH_IA_DEV(dev);  
-	mac1 = cpu_to_be32(le32_to_cpu(readl(  
-				iadev->reg+IPHASE5575_MAC1)));  
-	mac2 = cpu_to_be16(le16_to_cpu(readl(iadev->reg+IPHASE5575_MAC2)));  
-	IF_INIT(printk("ESI: 0x%08x%04x\n", mac1, mac2);)  
-	for (i=0; i<MAC1_LEN; i++)  
-		dev->esi[i] = mac1 >>(8*(MAC1_LEN-1-i));  
-	  
-	for (i=0; i<MAC2_LEN; i++)  
-		dev->esi[i+MAC1_LEN] = mac2 >>(8*(MAC2_LEN - 1 -i));  
-	return 0;  
-}  
-	  
-static int reset_sar(struct atm_dev *dev)  
-{  
-	IADEV *iadev;  
-	int i, error;
-	unsigned int pci[64];  
-	  
-	iadev = INPH_IA_DEV(dev);  
-	for (i = 0; i < 64; i++) {
-		error = pci_read_config_dword(iadev->pci, i * 4, &pci[i]);
-		if (error != PCIBIOS_SUCCESSFUL)
-			return error;
-	}
-	writel(0, iadev->reg+IPHASE5575_EXT_RESET);  
-	for (i = 0; i < 64; i++) {
-		error = pci_write_config_dword(iadev->pci, i * 4, pci[i]);
-		if (error != PCIBIOS_SUCCESSFUL)
-			return error;
-	}
-	udelay(5);  
-	return 0;  
-}  
-	  
-	  
-static int ia_init(struct atm_dev *dev)
-{  
-	IADEV *iadev;  
-	unsigned long real_base;
-	void __iomem *base;
-	unsigned short command;  
-	int error, i; 
-	  
-	/* The device has been identified and registered. Now we read   
-	   necessary configuration info like memory base address,   
-	   interrupt number etc */  
-	  
-	IF_INIT(printk(">ia_init\n");)  
-	dev->ci_range.vpi_bits = 0;  
-	dev->ci_range.vci_bits = NR_VCI_LD;  
-
-	iadev = INPH_IA_DEV(dev);  
-	real_base = pci_resource_start (iadev->pci, 0);
-	iadev->irq = iadev->pci->irq;
-		  
-	error = pci_read_config_word(iadev->pci, PCI_COMMAND, &command);
-	if (error) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): init error 0x%x\n",  
-				dev->number,error);  
-		return -EINVAL;  
-	}  
-	IF_INIT(printk(DEV_LABEL "(itf %d): rev.%d,realbase=0x%lx,irq=%d\n",  
-			dev->number, iadev->pci->revision, real_base, iadev->irq);)
-	  
-	/* find mapping size of board */  
-	  
-	iadev->pci_map_size = pci_resource_len(iadev->pci, 0);
-
-        if (iadev->pci_map_size == 0x100000){
-          iadev->num_vc = 4096;
-	  dev->ci_range.vci_bits = NR_VCI_4K_LD;  
-          iadev->memSize = 4;
-        }
-        else if (iadev->pci_map_size == 0x40000) {
-          iadev->num_vc = 1024;
-          iadev->memSize = 1;
-        }
-        else {
-           printk("Unknown pci_map_size = 0x%x\n", iadev->pci_map_size);
-           return -EINVAL;
-        }
-	IF_INIT(printk (DEV_LABEL "map size: %i\n", iadev->pci_map_size);)  
-	  
-	/* enable bus mastering */
-	pci_set_master(iadev->pci);
-
-	/*  
-	 * Delay at least 1us before doing any mem accesses (how 'bout 10?)  
-	 */  
-	udelay(10);  
-	  
-	/* mapping the physical address to a virtual address in address space */  
-	base = ioremap(real_base,iadev->pci_map_size);  /* ioremap is not resolved ??? */  
-	  
-	if (!base)  
-	{  
-		printk(DEV_LABEL " (itf %d): can't set up page mapping\n",  
-			    dev->number);  
-		return -ENOMEM;
-	}  
-	IF_INIT(printk(DEV_LABEL " (itf %d): rev.%d,base=%p,irq=%d\n",  
-			dev->number, iadev->pci->revision, base, iadev->irq);)
-	  
-	/* filling the iphase dev structure */  
-	iadev->mem = iadev->pci_map_size /2;  
-	iadev->real_base = real_base;  
-	iadev->base = base;  
-		  
-	/* Bus Interface Control Registers */  
-	iadev->reg = base + REG_BASE;
-	/* Segmentation Control Registers */  
-	iadev->seg_reg = base + SEG_BASE;
-	/* Reassembly Control Registers */  
-	iadev->reass_reg = base + REASS_BASE;  
-	/* Front end/ DMA control registers */  
-	iadev->phy = base + PHY_BASE;  
-	iadev->dma = base + PHY_BASE;  
-	/* RAM - Segmentation RAm and Reassembly RAM */  
-	iadev->ram = base + ACTUAL_RAM_BASE;  
-	iadev->seg_ram = base + ACTUAL_SEG_RAM_BASE;  
-	iadev->reass_ram = base + ACTUAL_REASS_RAM_BASE;  
-  
-	/* lets print out the above */  
-	IF_INIT(printk("Base addrs: %p %p %p \n %p %p %p %p\n", 
-          iadev->reg,iadev->seg_reg,iadev->reass_reg, 
-          iadev->phy, iadev->ram, iadev->seg_ram, 
-          iadev->reass_ram);) 
-	  
-	/* lets try reading the MAC address */  
-	error = get_esi(dev);  
-	if (error) {
-	  iounmap(iadev->base);
-	  return error;  
-	}
-        printk("IA: ");
-	for (i=0; i < ESI_LEN; i++)  
-                printk("%s%02X",i ? "-" : "",dev->esi[i]);  
-        printk("\n");  
-  
-        /* reset SAR */  
-        if (reset_sar(dev)) {
-	   iounmap(iadev->base);
-           printk("IA: reset SAR fail, please try again\n");
-           return 1;
-        }
-	return 0;  
-}  
-
-static void ia_update_stats(IADEV *iadev) {
-    if (!iadev->carrier_detect)
-        return;
-    iadev->rx_cell_cnt += readw(iadev->reass_reg+CELL_CTR0)&0xffff;
-    iadev->rx_cell_cnt += (readw(iadev->reass_reg+CELL_CTR1) & 0xffff) << 16;
-    iadev->drop_rxpkt +=  readw(iadev->reass_reg + DRP_PKT_CNTR ) & 0xffff;
-    iadev->drop_rxcell += readw(iadev->reass_reg + ERR_CNTR) & 0xffff;
-    iadev->tx_cell_cnt += readw(iadev->seg_reg + CELL_CTR_LO_AUTO)&0xffff;
-    iadev->tx_cell_cnt += (readw(iadev->seg_reg+CELL_CTR_HIGH_AUTO)&0xffff)<<16;
-    return;
-}
-  
-static void ia_led_timer(struct timer_list *unused) {
- 	unsigned long flags;
-  	static u_char blinking[8] = {0, 0, 0, 0, 0, 0, 0, 0};
-        u_char i;
-        static u32 ctrl_reg; 
-        for (i = 0; i < iadev_count; i++) {
-           if (ia_dev[i]) {
-	      ctrl_reg = readl(ia_dev[i]->reg+IPHASE5575_BUS_CONTROL_REG);
-	      if (blinking[i] == 0) {
-		 blinking[i]++;
-                 ctrl_reg &= (~CTRL_LED);
-                 writel(ctrl_reg, ia_dev[i]->reg+IPHASE5575_BUS_CONTROL_REG);
-                 ia_update_stats(ia_dev[i]);
-              }
-              else {
-		 blinking[i] = 0;
-		 ctrl_reg |= CTRL_LED;
-                 writel(ctrl_reg, ia_dev[i]->reg+IPHASE5575_BUS_CONTROL_REG);
-                 spin_lock_irqsave(&ia_dev[i]->tx_lock, flags);
-                 if (ia_dev[i]->close_pending)  
-                    wake_up(&ia_dev[i]->close_wait);
-                 ia_tx_poll(ia_dev[i]);
-                 spin_unlock_irqrestore(&ia_dev[i]->tx_lock, flags);
-              }
-           }
-        }
-	mod_timer(&ia_timer, jiffies + HZ / 4);
- 	return;
-}
-
-static void ia_phy_put(struct atm_dev *dev, unsigned char value,   
-	unsigned long addr)  
-{  
-	writel(value, INPH_IA_DEV(dev)->phy+addr);  
-}  
-  
-static unsigned char ia_phy_get(struct atm_dev *dev, unsigned long addr)  
-{  
-	return readl(INPH_IA_DEV(dev)->phy+addr);  
-}  
-
-static void ia_free_tx(IADEV *iadev)
-{
-	int i;
-
-	kfree(iadev->desc_tbl);
-	for (i = 0; i < iadev->num_vc; i++)
-		kfree(iadev->testTable[i]);
-	kfree(iadev->testTable);
-	for (i = 0; i < iadev->num_tx_desc; i++) {
-		struct cpcs_trailer_desc *desc = iadev->tx_buf + i;
-
-		dma_unmap_single(&iadev->pci->dev, desc->dma_addr,
-				 sizeof(*desc->cpcs), DMA_TO_DEVICE);
-		kfree(desc->cpcs);
-	}
-	kfree(iadev->tx_buf);
-	dma_free_coherent(&iadev->pci->dev, DLE_TOTAL_SIZE, iadev->tx_dle_q.start,
-			  iadev->tx_dle_dma);
-}
-
-static void ia_free_rx(IADEV *iadev)
-{
-	kfree(iadev->rx_open);
-	dma_free_coherent(&iadev->pci->dev, DLE_TOTAL_SIZE, iadev->rx_dle_q.start,
-			  iadev->rx_dle_dma);
-}
-
-static int ia_start(struct atm_dev *dev)
-{  
-	IADEV *iadev;  
-	int error;  
-	unsigned char phy;  
-	u32 ctrl_reg;  
-	IF_EVENT(printk(">ia_start\n");)  
-	iadev = INPH_IA_DEV(dev);  
-        if (request_irq(iadev->irq, &ia_int, IRQF_SHARED, DEV_LABEL, dev)) {
-                printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",  
-                    dev->number, iadev->irq);  
-		error = -EAGAIN;
-		goto err_out;
-        }  
-        /* @@@ should release IRQ on error */  
-	/* enabling memory + master */  
-        if ((error = pci_write_config_word(iadev->pci,   
-				PCI_COMMAND,   
-				PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER )))   
-	{  
-                printk(KERN_ERR DEV_LABEL "(itf %d): can't enable memory+"  
-                    "master (0x%x)\n",dev->number, error);  
-		error = -EIO;  
-		goto err_free_irq;
-        }  
-	udelay(10);  
-  
-	/* Maybe we should reset the front end, initialize Bus Interface Control   
-		Registers and see. */  
-  
-	IF_INIT(printk("Bus ctrl reg: %08x\n", 
-                            readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG));)  
-	ctrl_reg = readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG);  
-	ctrl_reg = (ctrl_reg & (CTRL_LED | CTRL_FE_RST))  
-			| CTRL_B8  
-			| CTRL_B16  
-			| CTRL_B32  
-			| CTRL_B48  
-			| CTRL_B64  
-			| CTRL_B128  
-			| CTRL_ERRMASK  
-			| CTRL_DLETMASK		/* shud be removed l8r */  
-			| CTRL_DLERMASK  
-			| CTRL_SEGMASK  
-			| CTRL_REASSMASK 	  
-			| CTRL_FEMASK  
-			| CTRL_CSPREEMPT;  
-  
-       writel(ctrl_reg, iadev->reg+IPHASE5575_BUS_CONTROL_REG);   
-  
-	IF_INIT(printk("Bus ctrl reg after initializing: %08x\n", 
-                           readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG));  
-	   printk("Bus status reg after init: %08x\n", 
-                            readl(iadev->reg+IPHASE5575_BUS_STATUS_REG));)  
-    
-        ia_hw_type(iadev); 
-	error = tx_init(dev);  
-	if (error)
-		goto err_free_irq;
-	error = rx_init(dev);  
-	if (error)
-		goto err_free_tx;
-  
-	ctrl_reg = readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG);  
-       	writel(ctrl_reg | CTRL_FE_RST, iadev->reg+IPHASE5575_BUS_CONTROL_REG);   
-	IF_INIT(printk("Bus ctrl reg after initializing: %08x\n", 
-                               readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG));)  
-        phy = 0; /* resolve compiler complaint */
-        IF_INIT ( 
-	if ((phy=ia_phy_get(dev,0)) == 0x30)  
-		printk("IA: pm5346,rev.%d\n",phy&0x0f);  
-	else  
-		printk("IA: utopia,rev.%0x\n",phy);) 
-
-	if (iadev->phy_type &  FE_25MBIT_PHY)
-           ia_mb25_init(iadev);
-	else if (iadev->phy_type & (FE_DS3_PHY | FE_E3_PHY))
-           ia_suni_pm7345_init(iadev);
-	else {
-		error = suni_init(dev);
-		if (error)
-			goto err_free_rx;
-		if (dev->phy->start) {
-			error = dev->phy->start(dev);
-			if (error)
-				goto err_free_rx;
-		}
-		/* Get iadev->carrier_detect status */
-		ia_frontend_intr(iadev);
-	}
-	return 0;
-
-err_free_rx:
-	ia_free_rx(iadev);
-err_free_tx:
-	ia_free_tx(iadev);
-err_free_irq:
-	free_irq(iadev->irq, dev);  
-err_out:
-	return error;
-}  
-  
-static void ia_close(struct atm_vcc *vcc)  
-{
-	DEFINE_WAIT(wait);
-        u16 *vc_table;
-        IADEV *iadev;
-        struct ia_vcc *ia_vcc;
-        struct sk_buff *skb = NULL;
-        struct sk_buff_head tmp_tx_backlog, tmp_vcc_backlog;
-        unsigned long closetime, flags;
-
-        iadev = INPH_IA_DEV(vcc->dev);
-        ia_vcc = INPH_IA_VCC(vcc);
-	if (!ia_vcc) return;  
-
-        IF_EVENT(printk("ia_close: ia_vcc->vc_desc_cnt = %d  vci = %d\n", 
-                                              ia_vcc->vc_desc_cnt,vcc->vci);)
-	clear_bit(ATM_VF_READY,&vcc->flags);
-        skb_queue_head_init (&tmp_tx_backlog);
-        skb_queue_head_init (&tmp_vcc_backlog); 
-        if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-           iadev->close_pending++;
-	   prepare_to_wait(&iadev->timeout_wait, &wait, TASK_UNINTERRUPTIBLE);
-	   schedule_timeout(msecs_to_jiffies(500));
-	   finish_wait(&iadev->timeout_wait, &wait);
-           spin_lock_irqsave(&iadev->tx_lock, flags); 
-           while((skb = skb_dequeue(&iadev->tx_backlog))) {
-              if (ATM_SKB(skb)->vcc == vcc){ 
-                 if (vcc->pop) vcc->pop(vcc, skb);
-                 else dev_kfree_skb_any(skb);
-              }
-              else 
-                 skb_queue_tail(&tmp_tx_backlog, skb);
-           } 
-           while((skb = skb_dequeue(&tmp_tx_backlog))) 
-             skb_queue_tail(&iadev->tx_backlog, skb);
-           IF_EVENT(printk("IA TX Done decs_cnt = %d\n", ia_vcc->vc_desc_cnt);) 
-           closetime = 300000 / ia_vcc->pcr;
-           if (closetime == 0)
-              closetime = 1;
-           spin_unlock_irqrestore(&iadev->tx_lock, flags);
-           wait_event_timeout(iadev->close_wait, (ia_vcc->vc_desc_cnt <= 0), closetime);
-           spin_lock_irqsave(&iadev->tx_lock, flags);
-           iadev->close_pending--;
-           iadev->testTable[vcc->vci]->lastTime = 0;
-           iadev->testTable[vcc->vci]->fract = 0; 
-           iadev->testTable[vcc->vci]->vc_status = VC_UBR; 
-           if (vcc->qos.txtp.traffic_class == ATM_ABR) {
-              if (vcc->qos.txtp.min_pcr > 0)
-                 iadev->sum_mcr -= vcc->qos.txtp.min_pcr;
-           }
-           if (vcc->qos.txtp.traffic_class == ATM_CBR) {
-              ia_vcc = INPH_IA_VCC(vcc); 
-              iadev->sum_mcr -= ia_vcc->NumCbrEntry*iadev->Granularity;
-              ia_cbrVc_close (vcc);
-           }
-           spin_unlock_irqrestore(&iadev->tx_lock, flags);
-        }
-        
-        if (vcc->qos.rxtp.traffic_class != ATM_NONE) {   
-           // reset reass table
-           vc_table = (u16 *)(iadev->reass_ram+REASS_TABLE*iadev->memSize);
-           vc_table += vcc->vci; 
-           *vc_table = NO_AAL5_PKT;
-           // reset vc table
-           vc_table = (u16 *)(iadev->reass_ram+RX_VC_TABLE*iadev->memSize);
-           vc_table += vcc->vci;
-           *vc_table = (vcc->vci << 6) | 15;
-           if (vcc->qos.rxtp.traffic_class == ATM_ABR) {
-              struct abr_vc_table __iomem *abr_vc_table = 
-                                (iadev->reass_ram+ABR_VC_TABLE*iadev->memSize);
-              abr_vc_table +=  vcc->vci;
-              abr_vc_table->rdf = 0x0003;
-              abr_vc_table->air = 0x5eb1;
-           }                                 
-           // Drain the packets
-           rx_dle_intr(vcc->dev); 
-           iadev->rx_open[vcc->vci] = NULL;
-        }
-	kfree(INPH_IA_VCC(vcc));  
-        ia_vcc = NULL;
-        vcc->dev_data = NULL;
-        clear_bit(ATM_VF_ADDR,&vcc->flags);
-        return;        
-}  
-  
-static int ia_open(struct atm_vcc *vcc)
-{  
-	struct ia_vcc *ia_vcc;  
-	int error;  
-	if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))  
-	{  
-		IF_EVENT(printk("ia: not partially allocated resources\n");)  
-		vcc->dev_data = NULL;
-	}  
-	if (vcc->vci != ATM_VPI_UNSPEC && vcc->vpi != ATM_VCI_UNSPEC)  
-	{  
-		IF_EVENT(printk("iphase open: unspec part\n");)  
-		set_bit(ATM_VF_ADDR,&vcc->flags);
-	}  
-	if (vcc->qos.aal != ATM_AAL5)  
-		return -EINVAL;  
-	IF_EVENT(printk(DEV_LABEL "(itf %d): open %d.%d\n", 
-                                 vcc->dev->number, vcc->vpi, vcc->vci);)  
-  
-	/* Device dependent initialization */  
-	ia_vcc = kmalloc_obj(*ia_vcc);  
-	if (!ia_vcc) return -ENOMEM;  
-	vcc->dev_data = ia_vcc;
-  
-	if ((error = open_rx(vcc)))  
-	{  
-		IF_EVENT(printk("iadev: error in open_rx, closing\n");)  
-		ia_close(vcc);  
-		return error;  
-	}  
-  
-	if ((error = open_tx(vcc)))  
-	{  
-		IF_EVENT(printk("iadev: error in open_tx, closing\n");)  
-		ia_close(vcc);  
-		return error;  
-	}  
-  
-	set_bit(ATM_VF_READY,&vcc->flags);
-
-#if 0
-        {
-           static u8 first = 1; 
-           if (first) {
-              ia_timer.expires = jiffies + 3*HZ;
-              add_timer(&ia_timer);
-              first = 0;
-           }           
-        }
-#endif
-	IF_EVENT(printk("ia open returning\n");)  
-	return 0;  
-}  
-  
-static int ia_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags)  
-{  
-	IF_EVENT(printk(">ia_change_qos\n");)  
-	return 0;  
-}  
-  
-static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)  
-{  
-   IA_CMDBUF ia_cmds;
-   IADEV *iadev;
-   int i, board;
-   u16 __user *tmps;
-   IF_EVENT(printk(">ia_ioctl\n");)  
-   if (cmd != IA_CMD) {
-      if (!dev->phy->ioctl) return -EINVAL;
-      return dev->phy->ioctl(dev,cmd,arg);
-   }
-   if (copy_from_user(&ia_cmds, arg, sizeof ia_cmds)) return -EFAULT; 
-   board = ia_cmds.status;
-
-	if ((board < 0) || (board > iadev_count))
-		board = 0;
-	board = array_index_nospec(board, iadev_count + 1);
-
-   iadev = ia_dev[board];
-   switch (ia_cmds.cmd) {
-   case MEMDUMP:
-   {
-	switch (ia_cmds.sub_cmd) {
-          case MEMDUMP_SEGREG:
-	     if (!capable(CAP_NET_ADMIN)) return -EPERM;
-             tmps = (u16 __user *)ia_cmds.buf;
-             for(i=0; i<0x80; i+=2, tmps++)
-                if(put_user((u16)(readl(iadev->seg_reg+i) & 0xffff), tmps)) return -EFAULT;
-             ia_cmds.status = 0;
-             ia_cmds.len = 0x80;
-             break;
-          case MEMDUMP_REASSREG:
-	     if (!capable(CAP_NET_ADMIN)) return -EPERM;
-             tmps = (u16 __user *)ia_cmds.buf;
-             for(i=0; i<0x80; i+=2, tmps++)
-                if(put_user((u16)(readl(iadev->reass_reg+i) & 0xffff), tmps)) return -EFAULT;
-             ia_cmds.status = 0;
-             ia_cmds.len = 0x80;
-             break;
-          case MEMDUMP_FFL:
-          {  
-             ia_regs_t       *regs_local;
-             ffredn_t        *ffL;
-             rfredn_t        *rfL;
-                     
-	     if (!capable(CAP_NET_ADMIN)) return -EPERM;
-	     regs_local = kmalloc_obj(*regs_local);
-	     if (!regs_local) return -ENOMEM;
-	     ffL = &regs_local->ffredn;
-	     rfL = &regs_local->rfredn;
-             /* Copy real rfred registers into the local copy */
- 	     for (i=0; i<(sizeof (rfredn_t))/4; i++)
-                ((u_int *)rfL)[i] = readl(iadev->reass_reg + i) & 0xffff;
-             	/* Copy real ffred registers into the local copy */
-	     for (i=0; i<(sizeof (ffredn_t))/4; i++)
-                ((u_int *)ffL)[i] = readl(iadev->seg_reg + i) & 0xffff;
-
-             if (copy_to_user(ia_cmds.buf, regs_local,sizeof(ia_regs_t))) {
-                kfree(regs_local);
-                return -EFAULT;
-             }
-             kfree(regs_local);
-             printk("Board %d registers dumped\n", board);
-             ia_cmds.status = 0;                  
-	 }	
-    	     break;        
-         case READ_REG:
-         {  
-	     if (!capable(CAP_NET_ADMIN)) return -EPERM;
-             desc_dbg(iadev); 
-             ia_cmds.status = 0; 
-         }
-             break;
-         case 0x6:
-         {  
-             ia_cmds.status = 0; 
-             printk("skb = 0x%p\n", skb_peek(&iadev->tx_backlog));
-             printk("rtn_q: 0x%p\n",ia_deque_rtn_q(&iadev->tx_return_q));
-         }
-             break;
-         case 0x8:
-         {
-             struct k_sonet_stats *stats;
-             stats = &PRIV(_ia_dev[board])->sonet_stats;
-             printk("section_bip: %d\n", atomic_read(&stats->section_bip));
-             printk("line_bip   : %d\n", atomic_read(&stats->line_bip));
-             printk("path_bip   : %d\n", atomic_read(&stats->path_bip));
-             printk("line_febe  : %d\n", atomic_read(&stats->line_febe));
-             printk("path_febe  : %d\n", atomic_read(&stats->path_febe));
-             printk("corr_hcs   : %d\n", atomic_read(&stats->corr_hcs));
-             printk("uncorr_hcs : %d\n", atomic_read(&stats->uncorr_hcs));
-             printk("tx_cells   : %d\n", atomic_read(&stats->tx_cells));
-             printk("rx_cells   : %d\n", atomic_read(&stats->rx_cells));
-         }
-            ia_cmds.status = 0;
-            break;
-         case 0x9:
-	    if (!capable(CAP_NET_ADMIN)) return -EPERM;
-            for (i = 1; i <= iadev->num_rx_desc; i++)
-               free_desc(_ia_dev[board], i);
-            writew( ~(RX_FREEQ_EMPT | RX_EXCP_RCVD), 
-                                            iadev->reass_reg+REASS_MASK_REG);
-            iadev->rxing = 1;
-            
-            ia_cmds.status = 0;
-            break;
-
-         case 0xb:
-	    if (!capable(CAP_NET_ADMIN)) return -EPERM;
-            ia_frontend_intr(iadev);
-            break;
-         case 0xa:
-	    if (!capable(CAP_NET_ADMIN)) return -EPERM;
-         {  
-             ia_cmds.status = 0; 
-             IADebugFlag = ia_cmds.maddr;
-             printk("New debug option loaded\n");
-         }
-             break;
-         default:
-             ia_cmds.status = 0;
-             break;
-      }	
-   }
-      break;
-   default:
-      break;
-
-   }	
-   return 0;  
-}  
-  
-static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) {
-        IADEV *iadev;
-        struct dle *wr_ptr;
-        struct tx_buf_desc __iomem *buf_desc_ptr;
-        int desc;
-        int comp_code;
-        int total_len;
-        struct cpcs_trailer *trailer;
-        struct ia_vcc *iavcc;
-
-        iadev = INPH_IA_DEV(vcc->dev);  
-        iavcc = INPH_IA_VCC(vcc);
-        if (!iavcc->txing) {
-           printk("discard packet on closed VC\n");
-           if (vcc->pop)
-		vcc->pop(vcc, skb);
-           else
-		dev_kfree_skb_any(skb);
-	   return 0;
-        }
-
-        if (skb->len > iadev->tx_buf_sz - 8) {
-           printk("Transmit size over tx buffer size\n");
-           if (vcc->pop)
-                 vcc->pop(vcc, skb);
-           else
-                 dev_kfree_skb_any(skb);
-          return 0;
-        }
-        if ((unsigned long)skb->data & 3) {
-           printk("Misaligned SKB\n");
-           if (vcc->pop)
-                 vcc->pop(vcc, skb);
-           else
-                 dev_kfree_skb_any(skb);
-           return 0;
-        }       
-	/* Get a descriptor number from our free descriptor queue  
-	   We get the descr number from the TCQ now, since I am using  
-	   the TCQ as a free buffer queue. Initially TCQ will be   
-	   initialized with all the descriptors and is hence, full.  
-	*/
-	desc = get_desc (iadev, iavcc);
-	if (desc == 0xffff) 
-	    return 1;
-	comp_code = desc >> 13;  
-	desc &= 0x1fff;  
-  
-	if ((desc == 0) || (desc > iadev->num_tx_desc))  
-	{  
-		IF_ERR(printk(DEV_LABEL "invalid desc for send: %d\n", desc);) 
-                atomic_inc(&vcc->stats->tx);
-		if (vcc->pop)   
-		    vcc->pop(vcc, skb);   
-		else  
-		    dev_kfree_skb_any(skb);
-		return 0;   /* return SUCCESS */
-	}  
-  
-	if (comp_code)  
-	{  
-	    IF_ERR(printk(DEV_LABEL "send desc:%d completion code %d error\n", 
-                                                            desc, comp_code);)  
-	}  
-       
-        /* remember the desc and vcc mapping */
-        iavcc->vc_desc_cnt++;
-        iadev->desc_tbl[desc-1].iavcc = iavcc;
-        iadev->desc_tbl[desc-1].txskb = skb;
-        IA_SKB_STATE(skb) = 0;
-
-        iadev->ffL.tcq_rd += 2;
-        if (iadev->ffL.tcq_rd > iadev->ffL.tcq_ed)
-	  	iadev->ffL.tcq_rd  = iadev->ffL.tcq_st;
-	writew(iadev->ffL.tcq_rd, iadev->seg_reg+TCQ_RD_PTR);
-  
-	/* Put the descriptor number in the packet ready queue  
-		and put the updated write pointer in the DLE field   
-	*/   
-	*(u16*)(iadev->seg_ram+iadev->ffL.prq_wr) = desc; 
-
- 	iadev->ffL.prq_wr += 2;
-        if (iadev->ffL.prq_wr > iadev->ffL.prq_ed)
-                iadev->ffL.prq_wr = iadev->ffL.prq_st;
-	  
-	/* Figure out the exact length of the packet and padding required to 
-           make it  aligned on a 48 byte boundary.  */
-	total_len = skb->len + sizeof(struct cpcs_trailer);  
-	total_len = ((total_len + 47) / 48) * 48;
-	IF_TX(printk("ia packet len:%d padding:%d\n", total_len, total_len - skb->len);)  
- 
-	/* Put the packet in a tx buffer */   
-	trailer = iadev->tx_buf[desc-1].cpcs;
-        IF_TX(printk("Sent: skb = 0x%p skb->data: 0x%p len: %d, desc: %d\n",
-                  skb, skb->data, skb->len, desc);)
-	trailer->control = 0; 
-        /*big endian*/ 
-	trailer->length = ((skb->len & 0xff) << 8) | ((skb->len & 0xff00) >> 8);
-	trailer->crc32 = 0;	/* not needed - dummy bytes */  
-
-	/* Display the packet */  
-	IF_TXPKT(printk("Sent data: len = %d MsgNum = %d\n", 
-                                                        skb->len, tcnter++);  
-        xdump(skb->data, skb->len, "TX: ");
-        printk("\n");)
-
-	/* Build the buffer descriptor */  
-	buf_desc_ptr = iadev->seg_ram+TX_DESC_BASE;
-	buf_desc_ptr += desc;	/* points to the corresponding entry */  
-	buf_desc_ptr->desc_mode = AAL5 | EOM_EN | APP_CRC32 | CMPL_INT;   
-	/* Huh ? p.115 of users guide describes this as a read-only register */
-        writew(TRANSMIT_DONE, iadev->seg_reg+SEG_INTR_STATUS_REG);
-	buf_desc_ptr->vc_index = vcc->vci;
-	buf_desc_ptr->bytes = total_len;  
-
-        if (vcc->qos.txtp.traffic_class == ATM_ABR)  
-	   clear_lockup (vcc, iadev);
-
-	/* Build the DLE structure */  
-	wr_ptr = iadev->tx_dle_q.write;  
-	memset((caddr_t)wr_ptr, 0, sizeof(*wr_ptr));  
-	wr_ptr->sys_pkt_addr = dma_map_single(&iadev->pci->dev, skb->data,
-					      skb->len, DMA_TO_DEVICE);
-	wr_ptr->local_pkt_addr = (buf_desc_ptr->buf_start_hi << 16) | 
-                                                  buf_desc_ptr->buf_start_lo;  
-	/* wr_ptr->bytes = swap_byte_order(total_len); didn't seem to affect?? */
-	wr_ptr->bytes = skb->len;  
-
-        /* hw bug - DLEs of 0x2d, 0x2e, 0x2f cause DMA lockup */
-        if ((wr_ptr->bytes >> 2) == 0xb)
-           wr_ptr->bytes = 0x30;
-
-	wr_ptr->mode = TX_DLE_PSI; 
-	wr_ptr->prq_wr_ptr_data = 0;
-  
-	/* end is not to be used for the DLE q */  
-	if (++wr_ptr == iadev->tx_dle_q.end)  
-		wr_ptr = iadev->tx_dle_q.start;  
-        
-        /* Build trailer dle */
-        wr_ptr->sys_pkt_addr = iadev->tx_buf[desc-1].dma_addr;
-        wr_ptr->local_pkt_addr = ((buf_desc_ptr->buf_start_hi << 16) | 
-          buf_desc_ptr->buf_start_lo) + total_len - sizeof(struct cpcs_trailer);
-
-        wr_ptr->bytes = sizeof(struct cpcs_trailer);
-        wr_ptr->mode = DMA_INT_ENABLE; 
-        wr_ptr->prq_wr_ptr_data = iadev->ffL.prq_wr;
-        
-        /* end is not to be used for the DLE q */
-        if (++wr_ptr == iadev->tx_dle_q.end)  
-                wr_ptr = iadev->tx_dle_q.start;
-
-	iadev->tx_dle_q.write = wr_ptr;  
-        ATM_DESC(skb) = vcc->vci;
-        skb_queue_tail(&iadev->tx_dma_q, skb);
-
-        atomic_inc(&vcc->stats->tx);
-        iadev->tx_pkt_cnt++;
-	/* Increment transaction counter */  
-	writel(2, iadev->dma+IPHASE5575_TX_COUNTER);  
-        
-#if 0        
-        /* add flow control logic */ 
-        if (atomic_read(&vcc->stats->tx) % 20 == 0) {
-          if (iavcc->vc_desc_cnt > 10) {
-             vcc->tx_quota =  vcc->tx_quota * 3 / 4;
-            printk("Tx1:  vcc->tx_quota = %d \n", (u32)vcc->tx_quota );
-              iavcc->flow_inc = -1;
-              iavcc->saved_tx_quota = vcc->tx_quota;
-           } else if ((iavcc->flow_inc < 0) && (iavcc->vc_desc_cnt < 3)) {
-             // vcc->tx_quota = 3 * iavcc->saved_tx_quota / 4;
-             printk("Tx2:  vcc->tx_quota = %d \n", (u32)vcc->tx_quota ); 
-              iavcc->flow_inc = 0;
-           }
-        }
-#endif
-	IF_TX(printk("ia send done\n");)  
-	return 0;  
-}  
-
-static int ia_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-        IADEV *iadev; 
-        unsigned long flags;
-
-        iadev = INPH_IA_DEV(vcc->dev);
-        if ((!skb)||(skb->len>(iadev->tx_buf_sz-sizeof(struct cpcs_trailer))))
-        {
-            if (!skb)
-                printk(KERN_CRIT "null skb in ia_send\n");
-            else dev_kfree_skb_any(skb);
-            return -EINVAL;
-        }                         
-        spin_lock_irqsave(&iadev->tx_lock, flags); 
-        if (!test_bit(ATM_VF_READY,&vcc->flags)){ 
-            dev_kfree_skb_any(skb);
-            spin_unlock_irqrestore(&iadev->tx_lock, flags);
-            return -EINVAL; 
-        }
-        ATM_SKB(skb)->vcc = vcc;
- 
-        if (skb_peek(&iadev->tx_backlog)) {
-           skb_queue_tail(&iadev->tx_backlog, skb);
-        }
-        else {
-           if (ia_pkt_tx (vcc, skb)) {
-              skb_queue_tail(&iadev->tx_backlog, skb);
-           }
-        }
-        spin_unlock_irqrestore(&iadev->tx_lock, flags);
-        return 0;
-
-}
-
-static int ia_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
-{ 
-  int   left = *pos, n;   
-  char  *tmpPtr;
-  IADEV *iadev = INPH_IA_DEV(dev);
-  if(!left--) {
-     if (iadev->phy_type == FE_25MBIT_PHY) {
-       n = sprintf(page, "  Board Type         :  Iphase5525-1KVC-128K\n");
-       return n;
-     }
-     if (iadev->phy_type == FE_DS3_PHY)
-        n = sprintf(page, "  Board Type         :  Iphase-ATM-DS3");
-     else if (iadev->phy_type == FE_E3_PHY)
-        n = sprintf(page, "  Board Type         :  Iphase-ATM-E3");
-     else if (iadev->phy_type == FE_UTP_OPTION)
-         n = sprintf(page, "  Board Type         :  Iphase-ATM-UTP155"); 
-     else
-        n = sprintf(page, "  Board Type         :  Iphase-ATM-OC3");
-     tmpPtr = page + n;
-     if (iadev->pci_map_size == 0x40000)
-        n += sprintf(tmpPtr, "-1KVC-");
-     else
-        n += sprintf(tmpPtr, "-4KVC-");  
-     tmpPtr = page + n; 
-     if ((iadev->memType & MEM_SIZE_MASK) == MEM_SIZE_1M)
-        n += sprintf(tmpPtr, "1M  \n");
-     else if ((iadev->memType & MEM_SIZE_MASK) == MEM_SIZE_512K)
-        n += sprintf(tmpPtr, "512K\n");
-     else
-       n += sprintf(tmpPtr, "128K\n");
-     return n;
-  }
-  if (!left) {
-     return  sprintf(page, "  Number of Tx Buffer:  %u\n"
-                           "  Size of Tx Buffer  :  %u\n"
-                           "  Number of Rx Buffer:  %u\n"
-                           "  Size of Rx Buffer  :  %u\n"
-                           "  Packets Received   :  %u\n"
-                           "  Packets Transmitted:  %u\n"
-                           "  Cells Received     :  %u\n"
-                           "  Cells Transmitted  :  %u\n"
-                           "  Board Dropped Cells:  %u\n"
-                           "  Board Dropped Pkts :  %u\n",
-                           iadev->num_tx_desc,  iadev->tx_buf_sz,
-                           iadev->num_rx_desc,  iadev->rx_buf_sz,
-                           iadev->rx_pkt_cnt,   iadev->tx_pkt_cnt,
-                           iadev->rx_cell_cnt, iadev->tx_cell_cnt,
-                           iadev->drop_rxcell, iadev->drop_rxpkt);                        
-  }
-  return 0;
-}
-  
-static const struct atmdev_ops ops = {  
-	.open		= ia_open,  
-	.close		= ia_close,  
-	.ioctl		= ia_ioctl,  
-	.send		= ia_send,  
-	.phy_put	= ia_phy_put,  
-	.phy_get	= ia_phy_get,  
-	.change_qos	= ia_change_qos,  
-	.proc_read	= ia_proc_read,
-	.owner		= THIS_MODULE,
-};  
-	  
-static int ia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
-{  
-	struct atm_dev *dev;  
-	IADEV *iadev;  
-	int ret;
-
-	iadev = kzalloc_obj(*iadev);
-	if (!iadev) {
-		ret = -ENOMEM;
-		goto err_out;
-	}
-
-	iadev->pci = pdev;
-
-	IF_INIT(printk("ia detected at bus:%d dev: %d function:%d\n",
-		pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));)
-	if (pci_enable_device(pdev)) {
-		ret = -ENODEV;
-		goto err_out_free_iadev;
-	}
-	dev = atm_dev_register(DEV_LABEL, &pdev->dev, &ops, -1, NULL);
-	if (!dev) {
-		ret = -ENOMEM;
-		goto err_out_disable_dev;
-	}
-	dev->dev_data = iadev;
-	IF_INIT(printk(DEV_LABEL "registered at (itf :%d)\n", dev->number);)
-	IF_INIT(printk("dev_id = 0x%p iadev->LineRate = %d \n", dev,
-		iadev->LineRate);)
-
-	pci_set_drvdata(pdev, dev);
-
-	ia_dev[iadev_count] = iadev;
-	_ia_dev[iadev_count] = dev;
-	iadev_count++;
-	if (ia_init(dev) || ia_start(dev)) {  
-		IF_INIT(printk("IA register failed!\n");)
-		iadev_count--;
-		ia_dev[iadev_count] = NULL;
-		_ia_dev[iadev_count] = NULL;
-		ret = -EINVAL;
-		goto err_out_deregister_dev;
-	}
-	IF_EVENT(printk("iadev_count = %d\n", iadev_count);)
-
-	iadev->next_board = ia_boards;  
-	ia_boards = dev;  
-
-	return 0;
-
-err_out_deregister_dev:
-	atm_dev_deregister(dev);  
-err_out_disable_dev:
-	pci_disable_device(pdev);
-err_out_free_iadev:
-	kfree(iadev);
-err_out:
-	return ret;
-}
-
-static void ia_remove_one(struct pci_dev *pdev)
-{
-	struct atm_dev *dev = pci_get_drvdata(pdev);
-	IADEV *iadev = INPH_IA_DEV(dev);
-
-	/* Disable phy interrupts */
-	ia_phy_put(dev, ia_phy_get(dev, SUNI_RSOP_CIE) & ~(SUNI_RSOP_CIE_LOSE),
-				   SUNI_RSOP_CIE);
-	udelay(1);
-
-	if (dev->phy && dev->phy->stop)
-		dev->phy->stop(dev);
-
-	/* De-register device */  
-      	free_irq(iadev->irq, dev);
-	iadev_count--;
-	ia_dev[iadev_count] = NULL;
-	_ia_dev[iadev_count] = NULL;
-	IF_EVENT(printk("deregistering iav at (itf:%d)\n", dev->number);)
-	atm_dev_deregister(dev);
-
-      	iounmap(iadev->base);  
-	pci_disable_device(pdev);
-
-	ia_free_rx(iadev);
-	ia_free_tx(iadev);
-
-      	kfree(iadev);
-}
-
-static const struct pci_device_id ia_pci_tbl[] = {
-	{ PCI_VENDOR_ID_IPHASE, 0x0008, PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_IPHASE, 0x0009, PCI_ANY_ID, PCI_ANY_ID, },
-	{ 0,}
-};
-MODULE_DEVICE_TABLE(pci, ia_pci_tbl);
-
-static struct pci_driver ia_driver = {
-	.name =         DEV_LABEL,
-	.id_table =     ia_pci_tbl,
-	.probe =        ia_init_one,
-	.remove =       ia_remove_one,
-};
-
-static int __init ia_module_init(void)
-{
-	int ret;
-
-	ret = pci_register_driver(&ia_driver);
-	if (ret >= 0) {
-		ia_timer.expires = jiffies + 3*HZ;
-		add_timer(&ia_timer); 
-	} else
-		printk(KERN_ERR DEV_LABEL ": no adapter found\n");  
-	return ret;
-}
-
-static void __exit ia_module_exit(void)
-{
-	pci_unregister_driver(&ia_driver);
-
-	timer_delete_sync(&ia_timer);
-}
-
-module_init(ia_module_init);
-module_exit(ia_module_exit);
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
deleted file mode 100644
index d6af999a9ebb..000000000000
--- a/drivers/atm/lanai.c
+++ /dev/null
@@ -1,2603 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* lanai.c -- Copyright 1999-2003 by Mitchell Blank Jr <mitch@sfgoth.com>
- *
- * This driver supports ATM cards based on the Efficient "Lanai"
- * chipset such as the Speedstream 3010 and the ENI-25p.  The
- * Speedstream 3060 is currently not supported since we don't
- * have the code to drive the on-board Alcatel DSL chipset (yet).
- *
- * Thanks to Efficient for supporting this project with hardware,
- * documentation, and by answering my questions.
- *
- * Things not working yet:
- *
- * o  We don't support the Speedstream 3060 yet - this card has
- *    an on-board DSL modem chip by Alcatel and the driver will
- *    need some extra code added to handle it
- *
- * o  Note that due to limitations of the Lanai only one VCC can be
- *    in CBR at once
- *
- * o We don't currently parse the EEPROM at all.  The code is all
- *   there as per the spec, but it doesn't actually work.  I think
- *   there may be some issues with the docs.  Anyway, do NOT
- *   enable it yet - bugs in that code may actually damage your
- *   hardware!  Because of this you should hardware an ESI before
- *   trying to use this in a LANE or MPOA environment.
- *
- * o  AAL0 is stubbed in but the actual rx/tx path isn't written yet:
- *	vcc_tx_aal0() needs to send or queue a SKB
- *	vcc_tx_unqueue_aal0() needs to attempt to send queued SKBs
- *	vcc_rx_aal0() needs to handle AAL0 interrupts
- *    This isn't too much work - I just wanted to get other things
- *    done first.
- *
- * o  lanai_change_qos() isn't written yet
- *
- * o  There aren't any ioctl's yet -- I'd like to eventually support
- *    setting loopback and LED modes that way.
- *
- * o  If the segmentation engine or DMA gets shut down we should restart
- *    card as per section 17.0i.  (see lanai_reset)
- *
- * o setsockopt(SO_CIRANGE) isn't done (although despite what the
- *   API says it isn't exactly commonly implemented)
- */
-
-/* Version history:
- *   v.1.00 -- 26-JUL-2003 -- PCI/DMA updates
- *   v.0.02 -- 11-JAN-2000 -- Endian fixes
- *   v.0.01 -- 30-NOV-1999 -- Initial release
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/atmdev.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-#include <linux/spinlock.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-/* -------------------- TUNABLE PARAMATERS: */
-
-/*
- * Maximum number of VCIs per card.  Setting it lower could theoretically
- * save some memory, but since we allocate our vcc list with get_free_pages,
- * it's not really likely for most architectures
- */
-#define NUM_VCI			(1024)
-
-/*
- * Enable extra debugging
- */
-#define DEBUG
-/*
- * Debug _all_ register operations with card, except the memory test.
- * Also disables the timed poll to prevent extra chattiness.  This
- * isn't for normal use
- */
-#undef DEBUG_RW
-
-/*
- * The programming guide specifies a full test of the on-board SRAM
- * at initialization time.  Undefine to remove this
- */
-#define FULL_MEMORY_TEST
-
-/*
- * This is the number of (4 byte) service entries that we will
- * try to allocate at startup.  Note that we will end up with
- * one PAGE_SIZE's worth regardless of what this is set to
- */
-#define SERVICE_ENTRIES		(1024)
-/* TODO: make above a module load-time option */
-
-/*
- * We normally read the onboard EEPROM in order to discover our MAC
- * address.  Undefine to _not_ do this
- */
-/* #define READ_EEPROM */ /* ***DONT ENABLE YET*** */
-/* TODO: make above a module load-time option (also) */
-
-/*
- * Depth of TX fifo (in 128 byte units; range 2-31)
- * Smaller numbers are better for network latency
- * Larger numbers are better for PCI latency
- * I'm really sure where the best tradeoff is, but the BSD driver uses
- * 7 and it seems to work ok.
- */
-#define TX_FIFO_DEPTH		(7)
-/* TODO: make above a module load-time option */
-
-/*
- * How often (in jiffies) we will try to unstick stuck connections -
- * shouldn't need to happen much
- */
-#define LANAI_POLL_PERIOD	(10*HZ)
-/* TODO: make above a module load-time option */
-
-/*
- * When allocating an AAL5 receiving buffer, try to make it at least
- * large enough to hold this many max_sdu sized PDUs
- */
-#define AAL5_RX_MULTIPLIER	(3)
-/* TODO: make above a module load-time option */
-
-/*
- * Same for transmitting buffer
- */
-#define AAL5_TX_MULTIPLIER	(3)
-/* TODO: make above a module load-time option */
-
-/*
- * When allocating an AAL0 transmiting buffer, how many cells should fit.
- * Remember we'll end up with a PAGE_SIZE of them anyway, so this isn't
- * really critical
- */
-#define AAL0_TX_MULTIPLIER	(40)
-/* TODO: make above a module load-time option */
-
-/*
- * How large should we make the AAL0 receiving buffer.  Remember that this
- * is shared between all AAL0 VC's
- */
-#define AAL0_RX_BUFFER_SIZE	(PAGE_SIZE)
-/* TODO: make above a module load-time option */
-
-/*
- * Should we use Lanai's "powerdown" feature when no vcc's are bound?
- */
-/* #define USE_POWERDOWN */
-/* TODO: make above a module load-time option (also) */
-
-/* -------------------- DEBUGGING AIDS: */
-
-#define DEV_LABEL "lanai"
-
-#ifdef DEBUG
-
-#define DPRINTK(format, args...) \
-	printk(KERN_DEBUG DEV_LABEL ": " format, ##args)
-#define APRINTK(truth, format, args...) \
-	do { \
-		if (unlikely(!(truth))) \
-			printk(KERN_ERR DEV_LABEL ": " format, ##args); \
-	} while (0)
-
-#else /* !DEBUG */
-
-#define DPRINTK(format, args...)
-#define APRINTK(truth, format, args...)
-
-#endif /* DEBUG */
-
-#ifdef DEBUG_RW
-#define RWDEBUG(format, args...) \
-	printk(KERN_DEBUG DEV_LABEL ": " format, ##args)
-#else /* !DEBUG_RW */
-#define RWDEBUG(format, args...)
-#endif
-
-/* -------------------- DATA DEFINITIONS: */
-
-#define LANAI_MAPPING_SIZE	(0x40000)
-#define LANAI_EEPROM_SIZE	(128)
-
-typedef int vci_t;
-typedef void __iomem *bus_addr_t;
-
-/* DMA buffer in host memory for TX, RX, or service list. */
-struct lanai_buffer {
-	u32 *start;	/* From get_free_pages */
-	u32 *end;	/* One past last byte */
-	u32 *ptr;	/* Pointer to current host location */
-	dma_addr_t dmaaddr;
-};
-
-struct lanai_vcc_stats {
-	unsigned rx_nomem;
-	union {
-		struct {
-			unsigned rx_badlen;
-			unsigned service_trash;
-			unsigned service_stream;
-			unsigned service_rxcrc;
-		} aal5;
-		struct {
-		} aal0;
-	} x;
-};
-
-struct lanai_dev;			/* Forward declaration */
-
-/*
- * This is the card-specific per-vcc data.  Note that unlike some other
- * drivers there is NOT a 1-to-1 correspondance between these and
- * atm_vcc's - each one of these represents an actual 2-way vcc, but
- * an atm_vcc can be 1-way and share with a 1-way vcc in the other
- * direction.  To make it weirder, there can even be 0-way vccs
- * bound to us, waiting to do a change_qos
- */
-struct lanai_vcc {
-	bus_addr_t vbase;		/* Base of VCC's registers */
-	struct lanai_vcc_stats stats;
-	int nref;			/* # of atm_vcc's who reference us */
-	vci_t vci;
-	struct {
-		struct lanai_buffer buf;
-		struct atm_vcc *atmvcc;	/* atm_vcc who is receiver */
-	} rx;
-	struct {
-		struct lanai_buffer buf;
-		struct atm_vcc *atmvcc;	/* atm_vcc who is transmitter */
-		int endptr;		/* last endptr from service entry */
-		struct sk_buff_head backlog;
-		void (*unqueue)(struct lanai_dev *, struct lanai_vcc *, int);
-	} tx;
-};
-
-enum lanai_type {
-	lanai2	= PCI_DEVICE_ID_EF_ATM_LANAI2,
-	lanaihb	= PCI_DEVICE_ID_EF_ATM_LANAIHB
-};
-
-struct lanai_dev_stats {
-	unsigned ovfl_trash;	/* # of cells dropped - buffer overflow */
-	unsigned vci_trash;	/* # of cells dropped - closed vci */
-	unsigned hec_err;	/* # of cells dropped - bad HEC */
-	unsigned atm_ovfl;	/* # of cells dropped - rx fifo overflow */
-	unsigned pcierr_parity_detect;
-	unsigned pcierr_serr_set;
-	unsigned pcierr_master_abort;
-	unsigned pcierr_m_target_abort;
-	unsigned pcierr_s_target_abort;
-	unsigned pcierr_master_parity;
-	unsigned service_notx;
-	unsigned service_norx;
-	unsigned service_rxnotaal5;
-	unsigned dma_reenable;
-	unsigned card_reset;
-};
-
-struct lanai_dev {
-	bus_addr_t base;
-	struct lanai_dev_stats stats;
-	struct lanai_buffer service;
-	struct lanai_vcc **vccs;
-#ifdef USE_POWERDOWN
-	int nbound;			/* number of bound vccs */
-#endif
-	enum lanai_type type;
-	vci_t num_vci;			/* Currently just NUM_VCI */
-	u8 eeprom[LANAI_EEPROM_SIZE];
-	u32 serialno, magicno;
-	struct pci_dev *pci;
-	DECLARE_BITMAP(backlog_vccs, NUM_VCI);   /* VCCs with tx backlog */
-	DECLARE_BITMAP(transmit_ready, NUM_VCI); /* VCCs with transmit space */
-	struct timer_list timer;
-	int naal0;
-	struct lanai_buffer aal0buf;	/* AAL0 RX buffers */
-	u32 conf1, conf2;		/* CONFIG[12] registers */
-	u32 status;			/* STATUS register */
-	spinlock_t endtxlock;
-	spinlock_t servicelock;
-	struct atm_vcc *cbrvcc;
-	int number;
-	int board_rev;
-/* TODO - look at race conditions with maintence of conf1/conf2 */
-/* TODO - transmit locking: should we use _irq not _irqsave? */
-/* TODO - organize above in some rational fashion (see <asm/cache.h>) */
-};
-
-/*
- * Each device has two bitmaps for each VCC (baclog_vccs and transmit_ready)
- * This function iterates one of these, calling a given function for each
- * vci with their bit set
- */
-static void vci_bitfield_iterate(struct lanai_dev *lanai,
-	const unsigned long *lp,
-	void (*func)(struct lanai_dev *,vci_t vci))
-{
-	vci_t vci;
-
-	for_each_set_bit(vci, lp, NUM_VCI)
-		func(lanai, vci);
-}
-
-/* -------------------- BUFFER  UTILITIES: */
-
-/*
- * Lanai needs DMA buffers aligned to 256 bytes of at least 1024 bytes -
- * usually any page allocation will do.  Just to be safe in case
- * PAGE_SIZE is insanely tiny, though...
- */
-#define LANAI_PAGE_SIZE   ((PAGE_SIZE >= 1024) ? PAGE_SIZE : 1024)
-
-/*
- * Allocate a buffer in host RAM for service list, RX, or TX
- * Returns buf->start==NULL if no memory
- * Note that the size will be rounded up 2^n bytes, and
- * if we can't allocate that we'll settle for something smaller
- * until minbytes
- */
-static void lanai_buf_allocate(struct lanai_buffer *buf,
-	size_t bytes, size_t minbytes, struct pci_dev *pci)
-{
-	int size;
-
-	if (bytes > (128 * 1024))	/* max lanai buffer size */
-		bytes = 128 * 1024;
-	for (size = LANAI_PAGE_SIZE; size < bytes; size *= 2)
-		;
-	if (minbytes < LANAI_PAGE_SIZE)
-		minbytes = LANAI_PAGE_SIZE;
-	do {
-		/*
-		 * Technically we could use non-consistent mappings for
-		 * everything, but the way the lanai uses DMA memory would
-		 * make that a terrific pain.  This is much simpler.
-		 */
-		buf->start = dma_alloc_coherent(&pci->dev,
-						size, &buf->dmaaddr, GFP_KERNEL);
-		if (buf->start != NULL) {	/* Success */
-			/* Lanai requires 256-byte alignment of DMA bufs */
-			APRINTK((buf->dmaaddr & ~0xFFFFFF00) == 0,
-			    "bad dmaaddr: 0x%lx\n",
-			    (unsigned long) buf->dmaaddr);
-			buf->ptr = buf->start;
-			buf->end = (u32 *)
-			    (&((unsigned char *) buf->start)[size]);
-			memset(buf->start, 0, size);
-			break;
-		}
-		size /= 2;
-	} while (size >= minbytes);
-}
-
-/* size of buffer in bytes */
-static inline size_t lanai_buf_size(const struct lanai_buffer *buf)
-{
-	return ((unsigned long) buf->end) - ((unsigned long) buf->start);
-}
-
-static void lanai_buf_deallocate(struct lanai_buffer *buf,
-	struct pci_dev *pci)
-{
-	if (buf->start != NULL) {
-		dma_free_coherent(&pci->dev, lanai_buf_size(buf),
-				  buf->start, buf->dmaaddr);
-		buf->start = buf->end = buf->ptr = NULL;
-	}
-}
-
-/* size of buffer as "card order" (0=1k .. 7=128k) */
-static int lanai_buf_size_cardorder(const struct lanai_buffer *buf)
-{
-	int order = get_order(lanai_buf_size(buf)) + (PAGE_SHIFT - 10);
-
-	/* This can only happen if PAGE_SIZE is gigantic, but just in case */
-	if (order > 7)
-		order = 7;
-	return order;
-}
-
-/* -------------------- PORT I/O UTILITIES: */
-
-/* Registers (and their bit-fields) */
-enum lanai_register {
-	Reset_Reg		= 0x00,	/* Reset; read for chip type; bits: */
-#define   RESET_GET_BOARD_REV(x)    (((x)>> 0)&0x03)	/* Board revision */
-#define   RESET_GET_BOARD_ID(x)	    (((x)>> 2)&0x03)	/* Board ID */
-#define     BOARD_ID_LANAI256		(0)	/* 25.6M adapter card */
-	Endian_Reg		= 0x04,	/* Endian setting */
-	IntStatus_Reg		= 0x08,	/* Interrupt status */
-	IntStatusMasked_Reg	= 0x0C,	/* Interrupt status (masked) */
-	IntAck_Reg		= 0x10,	/* Interrupt acknowledge */
-	IntAckMasked_Reg	= 0x14,	/* Interrupt acknowledge (masked) */
-	IntStatusSet_Reg	= 0x18,	/* Get status + enable/disable */
-	IntStatusSetMasked_Reg	= 0x1C,	/* Get status + en/di (masked) */
-	IntControlEna_Reg	= 0x20,	/* Interrupt control enable */
-	IntControlDis_Reg	= 0x24,	/* Interrupt control disable */
-	Status_Reg		= 0x28,	/* Status */
-#define   STATUS_PROMDATA	 (0x00000001)	/* PROM_DATA pin */
-#define   STATUS_WAITING	 (0x00000002)	/* Interrupt being delayed */
-#define	  STATUS_SOOL		 (0x00000004)	/* SOOL alarm */
-#define   STATUS_LOCD		 (0x00000008)	/* LOCD alarm */
-#define	  STATUS_LED		 (0x00000010)	/* LED (HAPPI) output */
-#define   STATUS_GPIN		 (0x00000020)	/* GPIN pin */
-#define   STATUS_BUTTBUSY	 (0x00000040)	/* Butt register is pending */
-	Config1_Reg		= 0x2C,	/* Config word 1; bits: */
-#define   CONFIG1_PROMDATA	 (0x00000001)	/* PROM_DATA pin */
-#define   CONFIG1_PROMCLK	 (0x00000002)	/* PROM_CLK pin */
-#define   CONFIG1_SET_READMODE(x) ((x)*0x004)	/* PCI BM reads; values: */
-#define     READMODE_PLAIN	    (0)		/*   Plain memory read */
-#define     READMODE_LINE	    (2)		/*   Memory read line */
-#define     READMODE_MULTIPLE	    (3)		/*   Memory read multiple */
-#define   CONFIG1_DMA_ENABLE	 (0x00000010)	/* Turn on DMA */
-#define   CONFIG1_POWERDOWN	 (0x00000020)	/* Turn off clocks */
-#define   CONFIG1_SET_LOOPMODE(x) ((x)*0x080)	/* Clock&loop mode; values: */
-#define     LOOPMODE_NORMAL	    (0)		/*   Normal - no loop */
-#define     LOOPMODE_TIME	    (1)
-#define     LOOPMODE_DIAG	    (2)
-#define     LOOPMODE_LINE	    (3)
-#define   CONFIG1_MASK_LOOPMODE  (0x00000180)
-#define   CONFIG1_SET_LEDMODE(x) ((x)*0x0200)	/* Mode of LED; values: */
-#define     LEDMODE_NOT_SOOL	    (0)		/*   !SOOL */
-#define	    LEDMODE_OFF		    (1)		/*   0     */
-#define	    LEDMODE_ON		    (2)		/*   1     */
-#define	    LEDMODE_NOT_LOCD	    (3)		/*   !LOCD */
-#define	    LEDMORE_GPIN	    (4)		/*   GPIN  */
-#define     LEDMODE_NOT_GPIN	    (7)		/*   !GPIN */
-#define   CONFIG1_MASK_LEDMODE	 (0x00000E00)
-#define   CONFIG1_GPOUT1	 (0x00001000)	/* Toggle for reset */
-#define   CONFIG1_GPOUT2	 (0x00002000)	/* Loopback PHY */
-#define   CONFIG1_GPOUT3	 (0x00004000)	/* Loopback lanai */
-	Config2_Reg		= 0x30,	/* Config word 2; bits: */
-#define   CONFIG2_HOWMANY	 (0x00000001)	/* >512 VCIs? */
-#define   CONFIG2_PTI7_MODE	 (0x00000002)	/* Make PTI=7 RM, not OAM */
-#define   CONFIG2_VPI_CHK_DIS	 (0x00000004)	/* Ignore RX VPI value */
-#define   CONFIG2_HEC_DROP	 (0x00000008)	/* Drop cells w/ HEC errors */
-#define   CONFIG2_VCI0_NORMAL	 (0x00000010)	/* Treat VCI=0 normally */
-#define   CONFIG2_CBR_ENABLE	 (0x00000020)	/* Deal with CBR traffic */
-#define   CONFIG2_TRASH_ALL	 (0x00000040)	/* Trashing incoming cells */
-#define   CONFIG2_TX_DISABLE	 (0x00000080)	/* Trashing outgoing cells */
-#define   CONFIG2_SET_TRASH	 (0x00000100)	/* Turn trashing on */
-	Statistics_Reg		= 0x34,	/* Statistics; bits: */
-#define   STATS_GET_FIFO_OVFL(x)    (((x)>> 0)&0xFF)	/* FIFO overflowed */
-#define   STATS_GET_HEC_ERR(x)      (((x)>> 8)&0xFF)	/* HEC was bad */
-#define   STATS_GET_BAD_VCI(x)      (((x)>>16)&0xFF)	/* VCI not open */
-#define   STATS_GET_BUF_OVFL(x)     (((x)>>24)&0xFF)	/* VCC buffer full */
-	ServiceStuff_Reg	= 0x38,	/* Service stuff; bits: */
-#define   SSTUFF_SET_SIZE(x) ((x)*0x20000000)	/* size of service buffer */
-#define   SSTUFF_SET_ADDR(x)	    ((x)>>8)	/* set address of buffer */
-	ServWrite_Reg		= 0x3C,	/* ServWrite Pointer */
-	ServRead_Reg		= 0x40,	/* ServRead Pointer */
-	TxDepth_Reg		= 0x44,	/* FIFO Transmit Depth */
-	Butt_Reg		= 0x48,	/* Butt register */
-	CBR_ICG_Reg		= 0x50,
-	CBR_PTR_Reg		= 0x54,
-	PingCount_Reg		= 0x58,	/* Ping count */
-	DMA_Addr_Reg		= 0x5C	/* DMA address */
-};
-
-static inline bus_addr_t reg_addr(const struct lanai_dev *lanai,
-	enum lanai_register reg)
-{
-	return lanai->base + reg;
-}
-
-static inline u32 reg_read(const struct lanai_dev *lanai,
-	enum lanai_register reg)
-{
-	u32 t;
-	t = readl(reg_addr(lanai, reg));
-	RWDEBUG("R [0x%08X] 0x%02X = 0x%08X\n", (unsigned int) lanai->base,
-	    (int) reg, t);
-	return t;
-}
-
-static inline void reg_write(const struct lanai_dev *lanai, u32 val,
-	enum lanai_register reg)
-{
-	RWDEBUG("W [0x%08X] 0x%02X < 0x%08X\n", (unsigned int) lanai->base,
-	    (int) reg, val);
-	writel(val, reg_addr(lanai, reg));
-}
-
-static inline void conf1_write(const struct lanai_dev *lanai)
-{
-	reg_write(lanai, lanai->conf1, Config1_Reg);
-}
-
-static inline void conf2_write(const struct lanai_dev *lanai)
-{
-	reg_write(lanai, lanai->conf2, Config2_Reg);
-}
-
-/* Same as conf2_write(), but defers I/O if we're powered down */
-static inline void conf2_write_if_powerup(const struct lanai_dev *lanai)
-{
-#ifdef USE_POWERDOWN
-	if (unlikely((lanai->conf1 & CONFIG1_POWERDOWN) != 0))
-		return;
-#endif /* USE_POWERDOWN */
-	conf2_write(lanai);
-}
-
-static inline void reset_board(const struct lanai_dev *lanai)
-{
-	DPRINTK("about to reset board\n");
-	reg_write(lanai, 0, Reset_Reg);
-	/*
-	 * If we don't delay a little while here then we can end up
-	 * leaving the card in a VERY weird state and lock up the
-	 * PCI bus.  This isn't documented anywhere but I've convinced
-	 * myself after a lot of painful experimentation
-	 */
-	udelay(5);
-}
-
-/* -------------------- CARD SRAM UTILITIES: */
-
-/* The SRAM is mapped into normal PCI memory space - the only catch is
- * that it is only 16-bits wide but must be accessed as 32-bit.  The
- * 16 high bits will be zero.  We don't hide this, since they get
- * programmed mostly like discrete registers anyway
- */
-#define SRAM_START (0x20000)
-#define SRAM_BYTES (0x20000)	/* Again, half don't really exist */
-
-static inline bus_addr_t sram_addr(const struct lanai_dev *lanai, int offset)
-{
-	return lanai->base + SRAM_START + offset;
-}
-
-static inline u32 sram_read(const struct lanai_dev *lanai, int offset)
-{
-	return readl(sram_addr(lanai, offset));
-}
-
-static inline void sram_write(const struct lanai_dev *lanai,
-	u32 val, int offset)
-{
-	writel(val, sram_addr(lanai, offset));
-}
-
-static int sram_test_word(const struct lanai_dev *lanai, int offset,
-			  u32 pattern)
-{
-	u32 readback;
-	sram_write(lanai, pattern, offset);
-	readback = sram_read(lanai, offset);
-	if (likely(readback == pattern))
-		return 0;
-	printk(KERN_ERR DEV_LABEL
-	    "(itf %d): SRAM word at %d bad: wrote 0x%X, read 0x%X\n",
-	    lanai->number, offset,
-	    (unsigned int) pattern, (unsigned int) readback);
-	return -EIO;
-}
-
-static int sram_test_pass(const struct lanai_dev *lanai, u32 pattern)
-{
-	int offset, result = 0;
-	for (offset = 0; offset < SRAM_BYTES && result == 0; offset += 4)
-		result = sram_test_word(lanai, offset, pattern);
-	return result;
-}
-
-static int sram_test_and_clear(const struct lanai_dev *lanai)
-{
-#ifdef FULL_MEMORY_TEST
-	int result;
-	DPRINTK("testing SRAM\n");
-	if ((result = sram_test_pass(lanai, 0x5555)) != 0)
-		return result;
-	if ((result = sram_test_pass(lanai, 0xAAAA)) != 0)
-		return result;
-#endif
-	DPRINTK("clearing SRAM\n");
-	return sram_test_pass(lanai, 0x0000);
-}
-
-/* -------------------- CARD-BASED VCC TABLE UTILITIES: */
-
-/* vcc table */
-enum lanai_vcc_offset {
-	vcc_rxaddr1		= 0x00,	/* Location1, plus bits: */
-#define   RXADDR1_SET_SIZE(x) ((x)*0x0000100)	/* size of RX buffer */
-#define   RXADDR1_SET_RMMODE(x) ((x)*0x00800)	/* RM cell action; values: */
-#define     RMMODE_TRASH	  (0)		/*   discard */
-#define     RMMODE_PRESERVE	  (1)		/*   input as AAL0 */
-#define     RMMODE_PIPE		  (2)		/*   pipe to coscheduler */
-#define     RMMODE_PIPEALL	  (3)		/*   pipe non-RM too */
-#define   RXADDR1_OAM_PRESERVE	 (0x00002000)	/* Input OAM cells as AAL0 */
-#define   RXADDR1_SET_MODE(x) ((x)*0x0004000)	/* Reassembly mode */
-#define     RXMODE_TRASH	  (0)		/*   discard */
-#define     RXMODE_AAL0		  (1)		/*   non-AAL5 mode */
-#define     RXMODE_AAL5		  (2)		/*   AAL5, intr. each PDU */
-#define     RXMODE_AAL5_STREAM	  (3)		/*   AAL5 w/o per-PDU intr */
-	vcc_rxaddr2		= 0x04,	/* Location2 */
-	vcc_rxcrc1		= 0x08,	/* RX CRC claculation space */
-	vcc_rxcrc2		= 0x0C,
-	vcc_rxwriteptr		= 0x10, /* RX writeptr, plus bits: */
-#define   RXWRITEPTR_LASTEFCI	 (0x00002000)	/* Last PDU had EFCI bit */
-#define   RXWRITEPTR_DROPPING	 (0x00004000)	/* Had error, dropping */
-#define   RXWRITEPTR_TRASHING	 (0x00008000)	/* Trashing */
-	vcc_rxbufstart		= 0x14,	/* RX bufstart, plus bits: */
-#define   RXBUFSTART_CLP	 (0x00004000)
-#define   RXBUFSTART_CI		 (0x00008000)
-	vcc_rxreadptr		= 0x18,	/* RX readptr */
-	vcc_txicg		= 0x1C, /* TX ICG */
-	vcc_txaddr1		= 0x20,	/* Location1, plus bits: */
-#define   TXADDR1_SET_SIZE(x) ((x)*0x0000100)	/* size of TX buffer */
-#define   TXADDR1_ABR		 (0x00008000)	/* use ABR (doesn't work) */
-	vcc_txaddr2		= 0x24,	/* Location2 */
-	vcc_txcrc1		= 0x28,	/* TX CRC claculation space */
-	vcc_txcrc2		= 0x2C,
-	vcc_txreadptr		= 0x30, /* TX Readptr, plus bits: */
-#define   TXREADPTR_GET_PTR(x) ((x)&0x01FFF)
-#define   TXREADPTR_MASK_DELTA	(0x0000E000)	/* ? */
-	vcc_txendptr		= 0x34, /* TX Endptr, plus bits: */
-#define   TXENDPTR_CLP		(0x00002000)
-#define   TXENDPTR_MASK_PDUMODE	(0x0000C000)	/* PDU mode; values: */
-#define     PDUMODE_AAL0	 (0*0x04000)
-#define     PDUMODE_AAL5	 (2*0x04000)
-#define     PDUMODE_AAL5STREAM	 (3*0x04000)
-	vcc_txwriteptr		= 0x38,	/* TX Writeptr */
-#define   TXWRITEPTR_GET_PTR(x) ((x)&0x1FFF)
-	vcc_txcbr_next		= 0x3C	/* # of next CBR VCI in ring */
-#define   TXCBR_NEXT_BOZO	(0x00008000)	/* "bozo bit" */
-};
-
-#define CARDVCC_SIZE	(0x40)
-
-static inline bus_addr_t cardvcc_addr(const struct lanai_dev *lanai,
-	vci_t vci)
-{
-	return sram_addr(lanai, vci * CARDVCC_SIZE);
-}
-
-static inline u32 cardvcc_read(const struct lanai_vcc *lvcc,
-	enum lanai_vcc_offset offset)
-{
-	u32 val;
-	APRINTK(lvcc->vbase != NULL, "cardvcc_read: unbound vcc!\n");
-	val= readl(lvcc->vbase + offset);
-	RWDEBUG("VR vci=%04d 0x%02X = 0x%08X\n",
-	    lvcc->vci, (int) offset, val);
-	return val;
-}
-
-static inline void cardvcc_write(const struct lanai_vcc *lvcc,
-	u32 val, enum lanai_vcc_offset offset)
-{
-	APRINTK(lvcc->vbase != NULL, "cardvcc_write: unbound vcc!\n");
-	APRINTK((val & ~0xFFFF) == 0,
-	    "cardvcc_write: bad val 0x%X (vci=%d, addr=0x%02X)\n",
-	    (unsigned int) val, lvcc->vci, (unsigned int) offset);
-	RWDEBUG("VW vci=%04d 0x%02X > 0x%08X\n",
-	    lvcc->vci, (unsigned int) offset, (unsigned int) val);
-	writel(val, lvcc->vbase + offset);
-}
-
-/* -------------------- COMPUTE SIZE OF AN AAL5 PDU: */
-
-/* How many bytes will an AAL5 PDU take to transmit - remember that:
- *   o  we need to add 8 bytes for length, CPI, UU, and CRC
- *   o  we need to round up to 48 bytes for cells
- */
-static inline int aal5_size(int size)
-{
-	int cells = (size + 8 + 47) / 48;
-	return cells * 48;
-}
-
-/* -------------------- FREE AN ATM SKB: */
-
-static inline void lanai_free_skb(struct atm_vcc *atmvcc, struct sk_buff *skb)
-{
-	if (atmvcc->pop != NULL)
-		atmvcc->pop(atmvcc, skb);
-	else
-		dev_kfree_skb_any(skb);
-}
-
-/* -------------------- TURN VCCS ON AND OFF: */
-
-static void host_vcc_start_rx(const struct lanai_vcc *lvcc)
-{
-	u32 addr1;
-	if (lvcc->rx.atmvcc->qos.aal == ATM_AAL5) {
-		dma_addr_t dmaaddr = lvcc->rx.buf.dmaaddr;
-		cardvcc_write(lvcc, 0xFFFF, vcc_rxcrc1);
-		cardvcc_write(lvcc, 0xFFFF, vcc_rxcrc2);
-		cardvcc_write(lvcc, 0, vcc_rxwriteptr);
-		cardvcc_write(lvcc, 0, vcc_rxbufstart);
-		cardvcc_write(lvcc, 0, vcc_rxreadptr);
-		cardvcc_write(lvcc, (dmaaddr >> 16) & 0xFFFF, vcc_rxaddr2);
-		addr1 = ((dmaaddr >> 8) & 0xFF) |
-		    RXADDR1_SET_SIZE(lanai_buf_size_cardorder(&lvcc->rx.buf))|
-		    RXADDR1_SET_RMMODE(RMMODE_TRASH) |	/* ??? */
-		 /* RXADDR1_OAM_PRESERVE |	--- no OAM support yet */
-		    RXADDR1_SET_MODE(RXMODE_AAL5);
-	} else
-		addr1 = RXADDR1_SET_RMMODE(RMMODE_PRESERVE) | /* ??? */
-		    RXADDR1_OAM_PRESERVE |		      /* ??? */
-		    RXADDR1_SET_MODE(RXMODE_AAL0);
-	/* This one must be last! */
-	cardvcc_write(lvcc, addr1, vcc_rxaddr1);
-}
-
-static void host_vcc_start_tx(const struct lanai_vcc *lvcc)
-{
-	dma_addr_t dmaaddr = lvcc->tx.buf.dmaaddr;
-	cardvcc_write(lvcc, 0, vcc_txicg);
-	cardvcc_write(lvcc, 0xFFFF, vcc_txcrc1);
-	cardvcc_write(lvcc, 0xFFFF, vcc_txcrc2);
-	cardvcc_write(lvcc, 0, vcc_txreadptr);
-	cardvcc_write(lvcc, 0, vcc_txendptr);
-	cardvcc_write(lvcc, 0, vcc_txwriteptr);
-	cardvcc_write(lvcc,
-		(lvcc->tx.atmvcc->qos.txtp.traffic_class == ATM_CBR) ?
-		TXCBR_NEXT_BOZO | lvcc->vci : 0, vcc_txcbr_next);
-	cardvcc_write(lvcc, (dmaaddr >> 16) & 0xFFFF, vcc_txaddr2);
-	cardvcc_write(lvcc,
-	    ((dmaaddr >> 8) & 0xFF) |
-	    TXADDR1_SET_SIZE(lanai_buf_size_cardorder(&lvcc->tx.buf)),
-	    vcc_txaddr1);
-}
-
-/* Shutdown receiving on card */
-static void lanai_shutdown_rx_vci(const struct lanai_vcc *lvcc)
-{
-	if (lvcc->vbase == NULL)	/* We were never bound to a VCI */
-		return;
-	/* 15.1.1 - set to trashing, wait one cell time (15us) */
-	cardvcc_write(lvcc,
-	    RXADDR1_SET_RMMODE(RMMODE_TRASH) |
-	    RXADDR1_SET_MODE(RXMODE_TRASH), vcc_rxaddr1);
-	udelay(15);
-	/* 15.1.2 - clear rest of entries */
-	cardvcc_write(lvcc, 0, vcc_rxaddr2);
-	cardvcc_write(lvcc, 0, vcc_rxcrc1);
-	cardvcc_write(lvcc, 0, vcc_rxcrc2);
-	cardvcc_write(lvcc, 0, vcc_rxwriteptr);
-	cardvcc_write(lvcc, 0, vcc_rxbufstart);
-	cardvcc_write(lvcc, 0, vcc_rxreadptr);
-}
-
-/* Shutdown transmitting on card.
- * Unfortunately the lanai needs us to wait until all the data
- * drains out of the buffer before we can dealloc it, so this
- * can take a while -- up to 370ms for a full 128KB buffer
- * assuming everone else is quiet.  In theory the time is
- * boundless if there's a CBR VCC holding things up.
- */
-static void lanai_shutdown_tx_vci(struct lanai_dev *lanai,
-	struct lanai_vcc *lvcc)
-{
-	struct sk_buff *skb;
-	unsigned long flags, timeout;
-	int read, write, lastread = -1;
-
-	if (lvcc->vbase == NULL)	/* We were never bound to a VCI */
-		return;
-	/* 15.2.1 - wait for queue to drain */
-	while ((skb = skb_dequeue(&lvcc->tx.backlog)) != NULL)
-		lanai_free_skb(lvcc->tx.atmvcc, skb);
-	read_lock_irqsave(&vcc_sklist_lock, flags);
-	__clear_bit(lvcc->vci, lanai->backlog_vccs);
-	read_unlock_irqrestore(&vcc_sklist_lock, flags);
-	/*
-	 * We need to wait for the VCC to drain but don't wait forever.  We
-	 * give each 1K of buffer size 1/128th of a second to clear out.
-	 * TODO: maybe disable CBR if we're about to timeout?
-	 */
-	timeout = jiffies +
-	    (((lanai_buf_size(&lvcc->tx.buf) / 1024) * HZ) >> 7);
-	write = TXWRITEPTR_GET_PTR(cardvcc_read(lvcc, vcc_txwriteptr));
-	for (;;) {
-		read = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));
-		if (read == write &&	   /* Is TX buffer empty? */
-		    (lvcc->tx.atmvcc->qos.txtp.traffic_class != ATM_CBR ||
-		    (cardvcc_read(lvcc, vcc_txcbr_next) &
-		    TXCBR_NEXT_BOZO) == 0))
-			break;
-		if (read != lastread) {	   /* Has there been any progress? */
-			lastread = read;
-			timeout += HZ / 10;
-		}
-		if (unlikely(time_after(jiffies, timeout))) {
-			printk(KERN_ERR DEV_LABEL "(itf %d): Timed out on "
-			    "backlog closing vci %d\n",
-			    lvcc->tx.atmvcc->dev->number, lvcc->vci);
-			DPRINTK("read, write = %d, %d\n", read, write);
-			break;
-		}
-		msleep(40);
-	}
-	/* 15.2.2 - clear out all tx registers */
-	cardvcc_write(lvcc, 0, vcc_txreadptr);
-	cardvcc_write(lvcc, 0, vcc_txwriteptr);
-	cardvcc_write(lvcc, 0, vcc_txendptr);
-	cardvcc_write(lvcc, 0, vcc_txcrc1);
-	cardvcc_write(lvcc, 0, vcc_txcrc2);
-	cardvcc_write(lvcc, 0, vcc_txaddr2);
-	cardvcc_write(lvcc, 0, vcc_txaddr1);
-}
-
-/* -------------------- MANAGING AAL0 RX BUFFER: */
-
-static inline int aal0_buffer_allocate(struct lanai_dev *lanai)
-{
-	DPRINTK("aal0_buffer_allocate: allocating AAL0 RX buffer\n");
-	lanai_buf_allocate(&lanai->aal0buf, AAL0_RX_BUFFER_SIZE, 80,
-			   lanai->pci);
-	return (lanai->aal0buf.start == NULL) ? -ENOMEM : 0;
-}
-
-static inline void aal0_buffer_free(struct lanai_dev *lanai)
-{
-	DPRINTK("aal0_buffer_allocate: freeing AAL0 RX buffer\n");
-	lanai_buf_deallocate(&lanai->aal0buf, lanai->pci);
-}
-
-/* -------------------- EEPROM UTILITIES: */
-
-/* Offsets of data in the EEPROM */
-#define EEPROM_COPYRIGHT	(0)
-#define EEPROM_COPYRIGHT_LEN	(44)
-#define EEPROM_CHECKSUM		(62)
-#define EEPROM_CHECKSUM_REV	(63)
-#define EEPROM_MAC		(64)
-#define EEPROM_MAC_REV		(70)
-#define EEPROM_SERIAL		(112)
-#define EEPROM_SERIAL_REV	(116)
-#define EEPROM_MAGIC		(120)
-#define EEPROM_MAGIC_REV	(124)
-
-#define EEPROM_MAGIC_VALUE	(0x5AB478D2)
-
-#ifndef READ_EEPROM
-
-/* Stub functions to use if EEPROM reading is disabled */
-static int eeprom_read(struct lanai_dev *lanai)
-{
-	printk(KERN_INFO DEV_LABEL "(itf %d): *NOT* reading EEPROM\n",
-	    lanai->number);
-	memset(&lanai->eeprom[EEPROM_MAC], 0, 6);
-	return 0;
-}
-
-static int eeprom_validate(struct lanai_dev *lanai)
-{
-	lanai->serialno = 0;
-	lanai->magicno = EEPROM_MAGIC_VALUE;
-	return 0;
-}
-
-#else /* READ_EEPROM */
-
-static int eeprom_read(struct lanai_dev *lanai)
-{
-	int i, address;
-	u8 data;
-	u32 tmp;
-#define set_config1(x)   do { lanai->conf1 = x; conf1_write(lanai); \
-			    } while (0)
-#define clock_h()	 set_config1(lanai->conf1 | CONFIG1_PROMCLK)
-#define clock_l()	 set_config1(lanai->conf1 &~ CONFIG1_PROMCLK)
-#define data_h()	 set_config1(lanai->conf1 | CONFIG1_PROMDATA)
-#define data_l()	 set_config1(lanai->conf1 &~ CONFIG1_PROMDATA)
-#define pre_read()	 do { data_h(); clock_h(); udelay(5); } while (0)
-#define read_pin()	 (reg_read(lanai, Status_Reg) & STATUS_PROMDATA)
-#define send_stop()	 do { data_l(); udelay(5); clock_h(); udelay(5); \
-			      data_h(); udelay(5); } while (0)
-	/* start with both clock and data high */
-	data_h(); clock_h(); udelay(5);
-	for (address = 0; address < LANAI_EEPROM_SIZE; address++) {
-		data = (address << 1) | 1;	/* Command=read + address */
-		/* send start bit */
-		data_l(); udelay(5);
-		clock_l(); udelay(5);
-		for (i = 128; i != 0; i >>= 1) {   /* write command out */
-			tmp = (lanai->conf1 & ~CONFIG1_PROMDATA) |
-			    ((data & i) ? CONFIG1_PROMDATA : 0);
-			if (lanai->conf1 != tmp) {
-				set_config1(tmp);
-				udelay(5);	/* Let new data settle */
-			}
-			clock_h(); udelay(5); clock_l(); udelay(5);
-		}
-		/* look for ack */
-		data_h(); clock_h(); udelay(5);
-		if (read_pin() != 0)
-			goto error;	/* No ack seen */
-		clock_l(); udelay(5);
-		/* read back result */
-		for (data = 0, i = 7; i >= 0; i--) {
-			data_h(); clock_h(); udelay(5);
-			data = (data << 1) | !!read_pin();
-			clock_l(); udelay(5);
-		}
-		/* look again for ack */
-		data_h(); clock_h(); udelay(5);
-		if (read_pin() == 0)
-			goto error;	/* Spurious ack */
-		clock_l(); udelay(5);
-		send_stop();
-		lanai->eeprom[address] = data;
-		DPRINTK("EEPROM 0x%04X %02X\n",
-		    (unsigned int) address, (unsigned int) data);
-	}
-	return 0;
-    error:
-	clock_l(); udelay(5);		/* finish read */
-	send_stop();
-	printk(KERN_ERR DEV_LABEL "(itf %d): error reading EEPROM byte %d\n",
-	    lanai->number, address);
-	return -EIO;
-#undef set_config1
-#undef clock_h
-#undef clock_l
-#undef data_h
-#undef data_l
-#undef pre_read
-#undef read_pin
-#undef send_stop
-}
-
-/* read a big-endian 4-byte value out of eeprom */
-static inline u32 eeprom_be4(const struct lanai_dev *lanai, int address)
-{
-	return be32_to_cpup((const u32 *) &lanai->eeprom[address]);
-}
-
-/* Checksum/validate EEPROM contents */
-static int eeprom_validate(struct lanai_dev *lanai)
-{
-	int i, s;
-	u32 v;
-	const u8 *e = lanai->eeprom;
-#ifdef DEBUG
-	/* First, see if we can get an ASCIIZ string out of the copyright */
-	for (i = EEPROM_COPYRIGHT;
-	    i < (EEPROM_COPYRIGHT + EEPROM_COPYRIGHT_LEN); i++)
-		if (e[i] < 0x20 || e[i] > 0x7E)
-			break;
-	if ( i != EEPROM_COPYRIGHT &&
-	    i != EEPROM_COPYRIGHT + EEPROM_COPYRIGHT_LEN && e[i] == '\0')
-		DPRINTK("eeprom: copyright = \"%s\"\n",
-		    (char *) &e[EEPROM_COPYRIGHT]);
-	else
-		DPRINTK("eeprom: copyright not found\n");
-#endif
-	/* Validate checksum */
-	for (i = s = 0; i < EEPROM_CHECKSUM; i++)
-		s += e[i];
-	s &= 0xFF;
-	if (s != e[EEPROM_CHECKSUM]) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM checksum bad "
-		    "(wanted 0x%02X, got 0x%02X)\n", lanai->number,
-		    (unsigned int) s, (unsigned int) e[EEPROM_CHECKSUM]);
-		return -EIO;
-	}
-	s ^= 0xFF;
-	if (s != e[EEPROM_CHECKSUM_REV]) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM inverse checksum "
-		    "bad (wanted 0x%02X, got 0x%02X)\n", lanai->number,
-		    (unsigned int) s, (unsigned int) e[EEPROM_CHECKSUM_REV]);
-		return -EIO;
-	}
-	/* Verify MAC address */
-	for (i = 0; i < 6; i++)
-		if ((e[EEPROM_MAC + i] ^ e[EEPROM_MAC_REV + i]) != 0xFF) {
-			printk(KERN_ERR DEV_LABEL
-			    "(itf %d) : EEPROM MAC addresses don't match "
-			    "(0x%02X, inverse 0x%02X)\n", lanai->number,
-			    (unsigned int) e[EEPROM_MAC + i],
-			    (unsigned int) e[EEPROM_MAC_REV + i]);
-			return -EIO;
-		}
-	DPRINTK("eeprom: MAC address = %pM\n", &e[EEPROM_MAC]);
-	/* Verify serial number */
-	lanai->serialno = eeprom_be4(lanai, EEPROM_SERIAL);
-	v = eeprom_be4(lanai, EEPROM_SERIAL_REV);
-	if ((lanai->serialno ^ v) != 0xFFFFFFFF) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM serial numbers "
-		    "don't match (0x%08X, inverse 0x%08X)\n", lanai->number,
-		    (unsigned int) lanai->serialno, (unsigned int) v);
-		return -EIO;
-	}
-	DPRINTK("eeprom: Serial number = %d\n", (unsigned int) lanai->serialno);
-	/* Verify magic number */
-	lanai->magicno = eeprom_be4(lanai, EEPROM_MAGIC);
-	v = eeprom_be4(lanai, EEPROM_MAGIC_REV);
-	if ((lanai->magicno ^ v) != 0xFFFFFFFF) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM magic numbers "
-		    "don't match (0x%08X, inverse 0x%08X)\n", lanai->number,
-		    lanai->magicno, v);
-		return -EIO;
-	}
-	DPRINTK("eeprom: Magic number = 0x%08X\n", lanai->magicno);
-	if (lanai->magicno != EEPROM_MAGIC_VALUE)
-		printk(KERN_WARNING DEV_LABEL "(itf %d): warning - EEPROM "
-		    "magic not what expected (got 0x%08X, not 0x%08X)\n",
-		    lanai->number, (unsigned int) lanai->magicno,
-		    (unsigned int) EEPROM_MAGIC_VALUE);
-	return 0;
-}
-
-#endif /* READ_EEPROM */
-
-static inline const u8 *eeprom_mac(const struct lanai_dev *lanai)
-{
-	return &lanai->eeprom[EEPROM_MAC];
-}
-
-/* -------------------- INTERRUPT HANDLING UTILITIES: */
-
-/* Interrupt types */
-#define INT_STATS	(0x00000002)	/* Statistics counter overflow */
-#define INT_SOOL	(0x00000004)	/* SOOL changed state */
-#define INT_LOCD	(0x00000008)	/* LOCD changed state */
-#define INT_LED		(0x00000010)	/* LED (HAPPI) changed state */
-#define INT_GPIN	(0x00000020)	/* GPIN changed state */
-#define INT_PING	(0x00000040)	/* PING_COUNT fulfilled */
-#define INT_WAKE	(0x00000080)	/* Lanai wants bus */
-#define INT_CBR0	(0x00000100)	/* CBR sched hit VCI 0 */
-#define INT_LOCK	(0x00000200)	/* Service list overflow */
-#define INT_MISMATCH	(0x00000400)	/* TX magic list mismatch */
-#define INT_AAL0_STR	(0x00000800)	/* Non-AAL5 buffer half filled */
-#define INT_AAL0	(0x00001000)	/* Non-AAL5 data available */
-#define INT_SERVICE	(0x00002000)	/* Service list entries available */
-#define INT_TABORTSENT	(0x00004000)	/* Target abort sent by lanai */
-#define INT_TABORTBM	(0x00008000)	/* Abort rcv'd as bus master */
-#define INT_TIMEOUTBM	(0x00010000)	/* No response to bus master */
-#define INT_PCIPARITY	(0x00020000)	/* Parity error on PCI */
-
-/* Sets of the above */
-#define INT_ALL		(0x0003FFFE)	/* All interrupts */
-#define INT_STATUS	(0x0000003C)	/* Some status pin changed */
-#define INT_DMASHUT	(0x00038000)	/* DMA engine got shut down */
-#define INT_SEGSHUT	(0x00000700)	/* Segmentation got shut down */
-
-static inline u32 intr_pending(const struct lanai_dev *lanai)
-{
-	return reg_read(lanai, IntStatusMasked_Reg);
-}
-
-static inline void intr_enable(const struct lanai_dev *lanai, u32 i)
-{
-	reg_write(lanai, i, IntControlEna_Reg);
-}
-
-static inline void intr_disable(const struct lanai_dev *lanai, u32 i)
-{
-	reg_write(lanai, i, IntControlDis_Reg);
-}
-
-/* -------------------- CARD/PCI STATUS: */
-
-static void status_message(int itf, const char *name, int status)
-{
-	static const char *onoff[2] = { "off to on", "on to off" };
-	printk(KERN_INFO DEV_LABEL "(itf %d): %s changed from %s\n",
-	    itf, name, onoff[!status]);
-}
-
-static void lanai_check_status(struct lanai_dev *lanai)
-{
-	u32 new = reg_read(lanai, Status_Reg);
-	u32 changes = new ^ lanai->status;
-	lanai->status = new;
-#define e(flag, name) \
-		if (changes & flag) \
-			status_message(lanai->number, name, new & flag)
-	e(STATUS_SOOL, "SOOL");
-	e(STATUS_LOCD, "LOCD");
-	e(STATUS_LED, "LED");
-	e(STATUS_GPIN, "GPIN");
-#undef e
-}
-
-static void pcistatus_got(int itf, const char *name)
-{
-	printk(KERN_INFO DEV_LABEL "(itf %d): PCI got %s error\n", itf, name);
-}
-
-static void pcistatus_check(struct lanai_dev *lanai, int clearonly)
-{
-	u16 s;
-	int result;
-	result = pci_read_config_word(lanai->pci, PCI_STATUS, &s);
-	if (result != PCIBIOS_SUCCESSFUL) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't read PCI_STATUS: "
-		    "%d\n", lanai->number, result);
-		return;
-	}
-	s &= PCI_STATUS_DETECTED_PARITY | PCI_STATUS_SIG_SYSTEM_ERROR |
-	    PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT |
-	    PCI_STATUS_SIG_TARGET_ABORT | PCI_STATUS_PARITY;
-	if (s == 0)
-		return;
-	result = pci_write_config_word(lanai->pci, PCI_STATUS, s);
-	if (result != PCIBIOS_SUCCESSFUL)
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't write PCI_STATUS: "
-		    "%d\n", lanai->number, result);
-	if (clearonly)
-		return;
-#define e(flag, name, stat) \
-		if (s & flag) { \
-			pcistatus_got(lanai->number, name); \
-			++lanai->stats.pcierr_##stat; \
-		}
-	e(PCI_STATUS_DETECTED_PARITY, "parity", parity_detect);
-	e(PCI_STATUS_SIG_SYSTEM_ERROR, "signalled system", serr_set);
-	e(PCI_STATUS_REC_MASTER_ABORT, "master", master_abort);
-	e(PCI_STATUS_REC_TARGET_ABORT, "master target", m_target_abort);
-	e(PCI_STATUS_SIG_TARGET_ABORT, "slave", s_target_abort);
-	e(PCI_STATUS_PARITY, "master parity", master_parity);
-#undef e
-}
-
-/* -------------------- VCC TX BUFFER UTILITIES: */
-
-/* space left in tx buffer in bytes */
-static inline int vcc_tx_space(const struct lanai_vcc *lvcc, int endptr)
-{
-	int r;
-	r = endptr * 16;
-	r -= ((unsigned long) lvcc->tx.buf.ptr) -
-	    ((unsigned long) lvcc->tx.buf.start);
-	r -= 16;	/* Leave "bubble" - if start==end it looks empty */
-	if (r < 0)
-		r += lanai_buf_size(&lvcc->tx.buf);
-	return r;
-}
-
-/* test if VCC is currently backlogged */
-static inline int vcc_is_backlogged(const struct lanai_vcc *lvcc)
-{
-	return !skb_queue_empty(&lvcc->tx.backlog);
-}
-
-/* Bit fields in the segmentation buffer descriptor */
-#define DESCRIPTOR_MAGIC	(0xD0000000)
-#define DESCRIPTOR_AAL5		(0x00008000)
-#define DESCRIPTOR_AAL5_STREAM	(0x00004000)
-#define DESCRIPTOR_CLP		(0x00002000)
-
-/* Add 32-bit descriptor with its padding */
-static inline void vcc_tx_add_aal5_descriptor(struct lanai_vcc *lvcc,
-	u32 flags, int len)
-{
-	int pos;
-	APRINTK((((unsigned long) lvcc->tx.buf.ptr) & 15) == 0,
-	    "vcc_tx_add_aal5_descriptor: bad ptr=%p\n", lvcc->tx.buf.ptr);
-	lvcc->tx.buf.ptr += 4;	/* Hope the values REALLY don't matter */
-	pos = ((unsigned char *) lvcc->tx.buf.ptr) -
-	    (unsigned char *) lvcc->tx.buf.start;
-	APRINTK((pos & ~0x0001FFF0) == 0,
-	    "vcc_tx_add_aal5_descriptor: bad pos (%d) before, vci=%d, "
-	    "start,ptr,end=%p,%p,%p\n", pos, lvcc->vci,
-	    lvcc->tx.buf.start, lvcc->tx.buf.ptr, lvcc->tx.buf.end);
-	pos = (pos + len) & (lanai_buf_size(&lvcc->tx.buf) - 1);
-	APRINTK((pos & ~0x0001FFF0) == 0,
-	    "vcc_tx_add_aal5_descriptor: bad pos (%d) after, vci=%d, "
-	    "start,ptr,end=%p,%p,%p\n", pos, lvcc->vci,
-	    lvcc->tx.buf.start, lvcc->tx.buf.ptr, lvcc->tx.buf.end);
-	lvcc->tx.buf.ptr[-1] =
-	    cpu_to_le32(DESCRIPTOR_MAGIC | DESCRIPTOR_AAL5 |
-	    ((lvcc->tx.atmvcc->atm_options & ATM_ATMOPT_CLP) ?
-	    DESCRIPTOR_CLP : 0) | flags | pos >> 4);
-	if (lvcc->tx.buf.ptr >= lvcc->tx.buf.end)
-		lvcc->tx.buf.ptr = lvcc->tx.buf.start;
-}
-
-/* Add 32-bit AAL5 trailer and leave room for its CRC */
-static inline void vcc_tx_add_aal5_trailer(struct lanai_vcc *lvcc,
-	int len, int cpi, int uu)
-{
-	APRINTK((((unsigned long) lvcc->tx.buf.ptr) & 15) == 8,
-	    "vcc_tx_add_aal5_trailer: bad ptr=%p\n", lvcc->tx.buf.ptr);
-	lvcc->tx.buf.ptr += 2;
-	lvcc->tx.buf.ptr[-2] = cpu_to_be32((uu << 24) | (cpi << 16) | len);
-	if (lvcc->tx.buf.ptr >= lvcc->tx.buf.end)
-		lvcc->tx.buf.ptr = lvcc->tx.buf.start;
-}
-
-static inline void vcc_tx_memcpy(struct lanai_vcc *lvcc,
-	const unsigned char *src, int n)
-{
-	unsigned char *e;
-	int m;
-	e = ((unsigned char *) lvcc->tx.buf.ptr) + n;
-	m = e - (unsigned char *) lvcc->tx.buf.end;
-	if (m < 0)
-		m = 0;
-	memcpy(lvcc->tx.buf.ptr, src, n - m);
-	if (m != 0) {
-		memcpy(lvcc->tx.buf.start, src + n - m, m);
-		e = ((unsigned char *) lvcc->tx.buf.start) + m;
-	}
-	lvcc->tx.buf.ptr = (u32 *) e;
-}
-
-static inline void vcc_tx_memzero(struct lanai_vcc *lvcc, int n)
-{
-	unsigned char *e;
-	int m;
-	if (n == 0)
-		return;
-	e = ((unsigned char *) lvcc->tx.buf.ptr) + n;
-	m = e - (unsigned char *) lvcc->tx.buf.end;
-	if (m < 0)
-		m = 0;
-	memset(lvcc->tx.buf.ptr, 0, n - m);
-	if (m != 0) {
-		memset(lvcc->tx.buf.start, 0, m);
-		e = ((unsigned char *) lvcc->tx.buf.start) + m;
-	}
-	lvcc->tx.buf.ptr = (u32 *) e;
-}
-
-/* Update "butt" register to specify new WritePtr */
-static inline void lanai_endtx(struct lanai_dev *lanai,
-	const struct lanai_vcc *lvcc)
-{
-	int i, ptr = ((unsigned char *) lvcc->tx.buf.ptr) -
-	    (unsigned char *) lvcc->tx.buf.start;
-	APRINTK((ptr & ~0x0001FFF0) == 0,
-	    "lanai_endtx: bad ptr (%d), vci=%d, start,ptr,end=%p,%p,%p\n",
-	    ptr, lvcc->vci, lvcc->tx.buf.start, lvcc->tx.buf.ptr,
-	    lvcc->tx.buf.end);
-
-	/*
-	 * Since the "butt register" is a shared resounce on the card we
-	 * serialize all accesses to it through this spinlock.  This is
-	 * mostly just paranoia since the register is rarely "busy" anyway
-	 * but is needed for correctness.
-	 */
-	spin_lock(&lanai->endtxlock);
-	/*
-	 * We need to check if the "butt busy" bit is set before
-	 * updating the butt register.  In theory this should
-	 * never happen because the ATM card is plenty fast at
-	 * updating the register.  Still, we should make sure
-	 */
-	for (i = 0; reg_read(lanai, Status_Reg) & STATUS_BUTTBUSY; i++) {
-		if (unlikely(i > 50)) {
-			printk(KERN_ERR DEV_LABEL "(itf %d): butt register "
-			    "always busy!\n", lanai->number);
-			break;
-		}
-		udelay(5);
-	}
-	/*
-	 * Before we tall the card to start work we need to be sure 100% of
-	 * the info in the service buffer has been written before we tell
-	 * the card about it
-	 */
-	wmb();
-	reg_write(lanai, (ptr << 12) | lvcc->vci, Butt_Reg);
-	spin_unlock(&lanai->endtxlock);
-}
-
-/*
- * Add one AAL5 PDU to lvcc's transmit buffer.  Caller garauntees there's
- * space available.  "pdusize" is the number of bytes the PDU will take
- */
-static void lanai_send_one_aal5(struct lanai_dev *lanai,
-	struct lanai_vcc *lvcc, struct sk_buff *skb, int pdusize)
-{
-	int pad;
-	APRINTK(pdusize == aal5_size(skb->len),
-	    "lanai_send_one_aal5: wrong size packet (%d != %d)\n",
-	    pdusize, aal5_size(skb->len));
-	vcc_tx_add_aal5_descriptor(lvcc, 0, pdusize);
-	pad = pdusize - skb->len - 8;
-	APRINTK(pad >= 0, "pad is negative (%d)\n", pad);
-	APRINTK(pad < 48, "pad is too big (%d)\n", pad);
-	vcc_tx_memcpy(lvcc, skb->data, skb->len);
-	vcc_tx_memzero(lvcc, pad);
-	vcc_tx_add_aal5_trailer(lvcc, skb->len, 0, 0);
-	lanai_endtx(lanai, lvcc);
-	lanai_free_skb(lvcc->tx.atmvcc, skb);
-	atomic_inc(&lvcc->tx.atmvcc->stats->tx);
-}
-
-/* Try to fill the buffer - don't call unless there is backlog */
-static void vcc_tx_unqueue_aal5(struct lanai_dev *lanai,
-	struct lanai_vcc *lvcc, int endptr)
-{
-	int n;
-	struct sk_buff *skb;
-	int space = vcc_tx_space(lvcc, endptr);
-	APRINTK(vcc_is_backlogged(lvcc),
-	    "vcc_tx_unqueue() called with empty backlog (vci=%d)\n",
-	    lvcc->vci);
-	while (space >= 64) {
-		skb = skb_dequeue(&lvcc->tx.backlog);
-		if (skb == NULL)
-			goto no_backlog;
-		n = aal5_size(skb->len);
-		if (n + 16 > space) {
-			/* No room for this packet - put it back on queue */
-			skb_queue_head(&lvcc->tx.backlog, skb);
-			return;
-		}
-		lanai_send_one_aal5(lanai, lvcc, skb, n);
-		space -= n + 16;
-	}
-	if (!vcc_is_backlogged(lvcc)) {
-	    no_backlog:
-		__clear_bit(lvcc->vci, lanai->backlog_vccs);
-	}
-}
-
-/* Given an skb that we want to transmit either send it now or queue */
-static void vcc_tx_aal5(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
-	struct sk_buff *skb)
-{
-	int space, n;
-	if (vcc_is_backlogged(lvcc))		/* Already backlogged */
-		goto queue_it;
-	space = vcc_tx_space(lvcc,
-		    TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr)));
-	n = aal5_size(skb->len);
-	APRINTK(n + 16 >= 64, "vcc_tx_aal5: n too small (%d)\n", n);
-	if (space < n + 16) {			/* No space for this PDU */
-		__set_bit(lvcc->vci, lanai->backlog_vccs);
-	    queue_it:
-		skb_queue_tail(&lvcc->tx.backlog, skb);
-		return;
-	}
-	lanai_send_one_aal5(lanai, lvcc, skb, n);
-}
-
-static void vcc_tx_unqueue_aal0(struct lanai_dev *lanai,
-	struct lanai_vcc *lvcc, int endptr)
-{
-	printk(KERN_INFO DEV_LABEL
-	    ": vcc_tx_unqueue_aal0: not implemented\n");
-}
-
-static void vcc_tx_aal0(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
-	struct sk_buff *skb)
-{
-	printk(KERN_INFO DEV_LABEL ": vcc_tx_aal0: not implemented\n");
-	/* Remember to increment lvcc->tx.atmvcc->stats->tx */
-	lanai_free_skb(lvcc->tx.atmvcc, skb);
-}
-
-/* -------------------- VCC RX BUFFER UTILITIES: */
-
-/* unlike the _tx_ cousins, this doesn't update ptr */
-static inline void vcc_rx_memcpy(unsigned char *dest,
-	const struct lanai_vcc *lvcc, int n)
-{
-	int m = ((const unsigned char *) lvcc->rx.buf.ptr) + n -
-	    ((const unsigned char *) (lvcc->rx.buf.end));
-	if (m < 0)
-		m = 0;
-	memcpy(dest, lvcc->rx.buf.ptr, n - m);
-	memcpy(dest + n - m, lvcc->rx.buf.start, m);
-	/* Make sure that these copies don't get reordered */
-	barrier();
-}
-
-/* Receive AAL5 data on a VCC with a particular endptr */
-static void vcc_rx_aal5(struct lanai_vcc *lvcc, int endptr)
-{
-	int size;
-	struct sk_buff *skb;
-	const u32 *x;
-	u32 *end = &lvcc->rx.buf.start[endptr * 4];
-	int n = ((unsigned long) end) - ((unsigned long) lvcc->rx.buf.ptr);
-	if (n < 0)
-		n += lanai_buf_size(&lvcc->rx.buf);
-	APRINTK(n >= 0 && n < lanai_buf_size(&lvcc->rx.buf) && !(n & 15),
-	    "vcc_rx_aal5: n out of range (%d/%zu)\n",
-	    n, lanai_buf_size(&lvcc->rx.buf));
-	/* Recover the second-to-last word to get true pdu length */
-	if ((x = &end[-2]) < lvcc->rx.buf.start)
-		x = &lvcc->rx.buf.end[-2];
-	/*
-	 * Before we actually read from the buffer, make sure the memory
-	 * changes have arrived
-	 */
-	rmb();
-	size = be32_to_cpup(x) & 0xffff;
-	if (unlikely(n != aal5_size(size))) {
-		/* Make sure size matches padding */
-		printk(KERN_INFO DEV_LABEL "(itf %d): Got bad AAL5 length "
-		    "on vci=%d - size=%d n=%d\n",
-		    lvcc->rx.atmvcc->dev->number, lvcc->vci, size, n);
-		lvcc->stats.x.aal5.rx_badlen++;
-		goto out;
-	}
-	skb = atm_alloc_charge(lvcc->rx.atmvcc, size, GFP_ATOMIC);
-	if (unlikely(skb == NULL)) {
-		lvcc->stats.rx_nomem++;
-		goto out;
-	}
-	skb_put(skb, size);
-	vcc_rx_memcpy(skb->data, lvcc, size);
-	ATM_SKB(skb)->vcc = lvcc->rx.atmvcc;
-	__net_timestamp(skb);
-	lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb);
-	atomic_inc(&lvcc->rx.atmvcc->stats->rx);
-    out:
-	lvcc->rx.buf.ptr = end;
-	cardvcc_write(lvcc, endptr, vcc_rxreadptr);
-}
-
-static void vcc_rx_aal0(struct lanai_dev *lanai)
-{
-	printk(KERN_INFO DEV_LABEL ": vcc_rx_aal0: not implemented\n");
-	/* Remember to get read_lock(&vcc_sklist_lock) while looking up VC */
-	/* Remember to increment lvcc->rx.atmvcc->stats->rx */
-}
-
-/* -------------------- MANAGING HOST-BASED VCC TABLE: */
-
-/* Decide whether to use vmalloc or get_zeroed_page for VCC table */
-#if (NUM_VCI * BITS_PER_LONG) <= PAGE_SIZE
-#define VCCTABLE_GETFREEPAGE
-#else
-#include <linux/vmalloc.h>
-#endif
-
-static int vcc_table_allocate(struct lanai_dev *lanai)
-{
-#ifdef VCCTABLE_GETFREEPAGE
-	APRINTK((lanai->num_vci) * sizeof(struct lanai_vcc *) <= PAGE_SIZE,
-	    "vcc table > PAGE_SIZE!");
-	lanai->vccs = (struct lanai_vcc **) get_zeroed_page(GFP_KERNEL);
-	return (lanai->vccs == NULL) ? -ENOMEM : 0;
-#else
-	int bytes = (lanai->num_vci) * sizeof(struct lanai_vcc *);
-	lanai->vccs = vzalloc(bytes);
-	if (unlikely(lanai->vccs == NULL))
-		return -ENOMEM;
-	return 0;
-#endif
-}
-
-static inline void vcc_table_deallocate(const struct lanai_dev *lanai)
-{
-#ifdef VCCTABLE_GETFREEPAGE
-	free_page((unsigned long) lanai->vccs);
-#else
-	vfree(lanai->vccs);
-#endif
-}
-
-/* Allocate a fresh lanai_vcc, with the appropriate things cleared */
-static inline struct lanai_vcc *new_lanai_vcc(void)
-{
-	struct lanai_vcc *lvcc;
-	lvcc = kzalloc_obj(*lvcc);
-	if (likely(lvcc != NULL)) {
-		skb_queue_head_init(&lvcc->tx.backlog);
-#ifdef DEBUG
-		lvcc->vci = -1;
-#endif
-	}
-	return lvcc;
-}
-
-static int lanai_get_sized_buffer(struct lanai_dev *lanai,
-	struct lanai_buffer *buf, int max_sdu, int multiplier,
-	const char *name)
-{
-	int size;
-	if (unlikely(max_sdu < 1))
-		max_sdu = 1;
-	max_sdu = aal5_size(max_sdu);
-	size = (max_sdu + 16) * multiplier + 16;
-	lanai_buf_allocate(buf, size, max_sdu + 32, lanai->pci);
-	if (unlikely(buf->start == NULL))
-		return -ENOMEM;
-	if (unlikely(lanai_buf_size(buf) < size))
-		printk(KERN_WARNING DEV_LABEL "(itf %d): wanted %d bytes "
-		    "for %s buffer, got only %zu\n", lanai->number, size,
-		    name, lanai_buf_size(buf));
-	DPRINTK("Allocated %zu byte %s buffer\n", lanai_buf_size(buf), name);
-	return 0;
-}
-
-/* Setup a RX buffer for a currently unbound AAL5 vci */
-static inline int lanai_setup_rx_vci_aal5(struct lanai_dev *lanai,
-	struct lanai_vcc *lvcc, const struct atm_qos *qos)
-{
-	return lanai_get_sized_buffer(lanai, &lvcc->rx.buf,
-	    qos->rxtp.max_sdu, AAL5_RX_MULTIPLIER, "RX");
-}
-
-/* Setup a TX buffer for a currently unbound AAL5 vci */
-static int lanai_setup_tx_vci(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
-	const struct atm_qos *qos)
-{
-	int max_sdu, multiplier;
-	if (qos->aal == ATM_AAL0) {
-		lvcc->tx.unqueue = vcc_tx_unqueue_aal0;
-		max_sdu = ATM_CELL_SIZE - 1;
-		multiplier = AAL0_TX_MULTIPLIER;
-	} else {
-		lvcc->tx.unqueue = vcc_tx_unqueue_aal5;
-		max_sdu = qos->txtp.max_sdu;
-		multiplier = AAL5_TX_MULTIPLIER;
-	}
-	return lanai_get_sized_buffer(lanai, &lvcc->tx.buf, max_sdu,
-	    multiplier, "TX");
-}
-
-static inline void host_vcc_bind(struct lanai_dev *lanai,
-	struct lanai_vcc *lvcc, vci_t vci)
-{
-	if (lvcc->vbase != NULL)
-		return;    /* We already were bound in the other direction */
-	DPRINTK("Binding vci %d\n", vci);
-#ifdef USE_POWERDOWN
-	if (lanai->nbound++ == 0) {
-		DPRINTK("Coming out of powerdown\n");
-		lanai->conf1 &= ~CONFIG1_POWERDOWN;
-		conf1_write(lanai);
-		conf2_write(lanai);
-	}
-#endif
-	lvcc->vbase = cardvcc_addr(lanai, vci);
-	lanai->vccs[lvcc->vci = vci] = lvcc;
-}
-
-static inline void host_vcc_unbind(struct lanai_dev *lanai,
-	struct lanai_vcc *lvcc)
-{
-	if (lvcc->vbase == NULL)
-		return;	/* This vcc was never bound */
-	DPRINTK("Unbinding vci %d\n", lvcc->vci);
-	lvcc->vbase = NULL;
-	lanai->vccs[lvcc->vci] = NULL;
-#ifdef USE_POWERDOWN
-	if (--lanai->nbound == 0) {
-		DPRINTK("Going into powerdown\n");
-		lanai->conf1 |= CONFIG1_POWERDOWN;
-		conf1_write(lanai);
-	}
-#endif
-}
-
-/* -------------------- RESET CARD: */
-
-static void lanai_reset(struct lanai_dev *lanai)
-{
-	printk(KERN_CRIT DEV_LABEL "(itf %d): *NOT* resetting - not "
-	    "implemented\n", lanai->number);
-	/* TODO */
-	/* The following is just a hack until we write the real
-	 * resetter - at least ack whatever interrupt sent us
-	 * here
-	 */
-	reg_write(lanai, INT_ALL, IntAck_Reg);
-	lanai->stats.card_reset++;
-}
-
-/* -------------------- SERVICE LIST UTILITIES: */
-
-/*
- * Allocate service buffer and tell card about it
- */
-static int service_buffer_allocate(struct lanai_dev *lanai)
-{
-	lanai_buf_allocate(&lanai->service, SERVICE_ENTRIES * 4, 8,
-	    lanai->pci);
-	if (unlikely(lanai->service.start == NULL))
-		return -ENOMEM;
-	DPRINTK("allocated service buffer at %p, size %zu(%d)\n",
-	    lanai->service.start,
-	    lanai_buf_size(&lanai->service),
-	    lanai_buf_size_cardorder(&lanai->service));
-	/* Clear ServWrite register to be safe */
-	reg_write(lanai, 0, ServWrite_Reg);
-	/* ServiceStuff register contains size and address of buffer */
-	reg_write(lanai,
-	    SSTUFF_SET_SIZE(lanai_buf_size_cardorder(&lanai->service)) |
-	    SSTUFF_SET_ADDR(lanai->service.dmaaddr),
-	    ServiceStuff_Reg);
-	return 0;
-}
-
-static inline void service_buffer_deallocate(struct lanai_dev *lanai)
-{
-	lanai_buf_deallocate(&lanai->service, lanai->pci);
-}
-
-/* Bitfields in service list */
-#define SERVICE_TX	(0x80000000)	/* Was from transmission */
-#define SERVICE_TRASH	(0x40000000)	/* RXed PDU was trashed */
-#define SERVICE_CRCERR	(0x20000000)	/* RXed PDU had CRC error */
-#define SERVICE_CI	(0x10000000)	/* RXed PDU had CI set */
-#define SERVICE_CLP	(0x08000000)	/* RXed PDU had CLP set */
-#define SERVICE_STREAM	(0x04000000)	/* RX Stream mode */
-#define SERVICE_GET_VCI(x) (((x)>>16)&0x3FF)
-#define SERVICE_GET_END(x) ((x)&0x1FFF)
-
-/* Handle one thing from the service list - returns true if it marked a
- * VCC ready for xmit
- */
-static int handle_service(struct lanai_dev *lanai, u32 s)
-{
-	vci_t vci = SERVICE_GET_VCI(s);
-	struct lanai_vcc *lvcc;
-	read_lock(&vcc_sklist_lock);
-	lvcc = lanai->vccs[vci];
-	if (unlikely(lvcc == NULL)) {
-		read_unlock(&vcc_sklist_lock);
-		DPRINTK("(itf %d) got service entry 0x%X for nonexistent "
-		    "vcc %d\n", lanai->number, (unsigned int) s, vci);
-		if (s & SERVICE_TX)
-			lanai->stats.service_notx++;
-		else
-			lanai->stats.service_norx++;
-		return 0;
-	}
-	if (s & SERVICE_TX) {			/* segmentation interrupt */
-		if (unlikely(lvcc->tx.atmvcc == NULL)) {
-			read_unlock(&vcc_sklist_lock);
-			DPRINTK("(itf %d) got service entry 0x%X for non-TX "
-			    "vcc %d\n", lanai->number, (unsigned int) s, vci);
-			lanai->stats.service_notx++;
-			return 0;
-		}
-		__set_bit(vci, lanai->transmit_ready);
-		lvcc->tx.endptr = SERVICE_GET_END(s);
-		read_unlock(&vcc_sklist_lock);
-		return 1;
-	}
-	if (unlikely(lvcc->rx.atmvcc == NULL)) {
-		read_unlock(&vcc_sklist_lock);
-		DPRINTK("(itf %d) got service entry 0x%X for non-RX "
-		    "vcc %d\n", lanai->number, (unsigned int) s, vci);
-		lanai->stats.service_norx++;
-		return 0;
-	}
-	if (unlikely(lvcc->rx.atmvcc->qos.aal != ATM_AAL5)) {
-		read_unlock(&vcc_sklist_lock);
-		DPRINTK("(itf %d) got RX service entry 0x%X for non-AAL5 "
-		    "vcc %d\n", lanai->number, (unsigned int) s, vci);
-		lanai->stats.service_rxnotaal5++;
-		atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
-		return 0;
-	}
-	if (likely(!(s & (SERVICE_TRASH | SERVICE_STREAM | SERVICE_CRCERR)))) {
-		vcc_rx_aal5(lvcc, SERVICE_GET_END(s));
-		read_unlock(&vcc_sklist_lock);
-		return 0;
-	}
-	if (s & SERVICE_TRASH) {
-		int bytes;
-		read_unlock(&vcc_sklist_lock);
-		DPRINTK("got trashed rx pdu on vci %d\n", vci);
-		atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
-		lvcc->stats.x.aal5.service_trash++;
-		bytes = (SERVICE_GET_END(s) * 16) -
-		    (((unsigned long) lvcc->rx.buf.ptr) -
-		    ((unsigned long) lvcc->rx.buf.start)) + 47;
-		if (bytes < 0)
-			bytes += lanai_buf_size(&lvcc->rx.buf);
-		lanai->stats.ovfl_trash += (bytes / 48);
-		return 0;
-	}
-	if (s & SERVICE_STREAM) {
-		read_unlock(&vcc_sklist_lock);
-		atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
-		lvcc->stats.x.aal5.service_stream++;
-		printk(KERN_ERR DEV_LABEL "(itf %d): Got AAL5 stream "
-		    "PDU on VCI %d!\n", lanai->number, vci);
-		lanai_reset(lanai);
-		return 0;
-	}
-	DPRINTK("got rx crc error on vci %d\n", vci);
-	atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
-	lvcc->stats.x.aal5.service_rxcrc++;
-	lvcc->rx.buf.ptr = &lvcc->rx.buf.start[SERVICE_GET_END(s) * 4];
-	cardvcc_write(lvcc, SERVICE_GET_END(s), vcc_rxreadptr);
-	read_unlock(&vcc_sklist_lock);
-	return 0;
-}
-
-/* Try transmitting on all VCIs that we marked ready to serve */
-static void iter_transmit(struct lanai_dev *lanai, vci_t vci)
-{
-	struct lanai_vcc *lvcc = lanai->vccs[vci];
-	if (vcc_is_backlogged(lvcc))
-		lvcc->tx.unqueue(lanai, lvcc, lvcc->tx.endptr);
-}
-
-/* Run service queue -- called from interrupt context or with
- * interrupts otherwise disabled and with the lanai->servicelock
- * lock held
- */
-static void run_service(struct lanai_dev *lanai)
-{
-	int ntx = 0;
-	u32 wreg = reg_read(lanai, ServWrite_Reg);
-	const u32 *end = lanai->service.start + wreg;
-	while (lanai->service.ptr != end) {
-		ntx += handle_service(lanai,
-		    le32_to_cpup(lanai->service.ptr++));
-		if (lanai->service.ptr >= lanai->service.end)
-			lanai->service.ptr = lanai->service.start;
-	}
-	reg_write(lanai, wreg, ServRead_Reg);
-	if (ntx != 0) {
-		read_lock(&vcc_sklist_lock);
-		vci_bitfield_iterate(lanai, lanai->transmit_ready,
-		    iter_transmit);
-		bitmap_zero(lanai->transmit_ready, NUM_VCI);
-		read_unlock(&vcc_sklist_lock);
-	}
-}
-
-/* -------------------- GATHER STATISTICS: */
-
-static void get_statistics(struct lanai_dev *lanai)
-{
-	u32 statreg = reg_read(lanai, Statistics_Reg);
-	lanai->stats.atm_ovfl += STATS_GET_FIFO_OVFL(statreg);
-	lanai->stats.hec_err += STATS_GET_HEC_ERR(statreg);
-	lanai->stats.vci_trash += STATS_GET_BAD_VCI(statreg);
-	lanai->stats.ovfl_trash += STATS_GET_BUF_OVFL(statreg);
-}
-
-/* -------------------- POLLING TIMER: */
-
-#ifndef DEBUG_RW
-/* Try to undequeue 1 backlogged vcc */
-static void iter_dequeue(struct lanai_dev *lanai, vci_t vci)
-{
-	struct lanai_vcc *lvcc = lanai->vccs[vci];
-	int endptr;
-	if (lvcc == NULL || lvcc->tx.atmvcc == NULL ||
-	    !vcc_is_backlogged(lvcc)) {
-		__clear_bit(vci, lanai->backlog_vccs);
-		return;
-	}
-	endptr = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));
-	lvcc->tx.unqueue(lanai, lvcc, endptr);
-}
-#endif /* !DEBUG_RW */
-
-static void lanai_timed_poll(struct timer_list *t)
-{
-	struct lanai_dev *lanai = timer_container_of(lanai, t, timer);
-#ifndef DEBUG_RW
-	unsigned long flags;
-#ifdef USE_POWERDOWN
-	if (lanai->conf1 & CONFIG1_POWERDOWN)
-		return;
-#endif /* USE_POWERDOWN */
-	local_irq_save(flags);
-	/* If we can grab the spinlock, check if any services need to be run */
-	if (spin_trylock(&lanai->servicelock)) {
-		run_service(lanai);
-		spin_unlock(&lanai->servicelock);
-	}
-	/* ...and see if any backlogged VCs can make progress */
-	/* unfortunately linux has no read_trylock() currently */
-	read_lock(&vcc_sklist_lock);
-	vci_bitfield_iterate(lanai, lanai->backlog_vccs, iter_dequeue);
-	read_unlock(&vcc_sklist_lock);
-	local_irq_restore(flags);
-
-	get_statistics(lanai);
-#endif /* !DEBUG_RW */
-	mod_timer(&lanai->timer, jiffies + LANAI_POLL_PERIOD);
-}
-
-static inline void lanai_timed_poll_start(struct lanai_dev *lanai)
-{
-	timer_setup(&lanai->timer, lanai_timed_poll, 0);
-	lanai->timer.expires = jiffies + LANAI_POLL_PERIOD;
-	add_timer(&lanai->timer);
-}
-
-static inline void lanai_timed_poll_stop(struct lanai_dev *lanai)
-{
-	timer_delete_sync(&lanai->timer);
-}
-
-/* -------------------- INTERRUPT SERVICE: */
-
-static inline void lanai_int_1(struct lanai_dev *lanai, u32 reason)
-{
-	u32 ack = 0;
-	if (reason & INT_SERVICE) {
-		ack = INT_SERVICE;
-		spin_lock(&lanai->servicelock);
-		run_service(lanai);
-		spin_unlock(&lanai->servicelock);
-	}
-	if (reason & (INT_AAL0_STR | INT_AAL0)) {
-		ack |= reason & (INT_AAL0_STR | INT_AAL0);
-		vcc_rx_aal0(lanai);
-	}
-	/* The rest of the interrupts are pretty rare */
-	if (ack == reason)
-		goto done;
-	if (reason & INT_STATS) {
-		reason &= ~INT_STATS;	/* No need to ack */
-		get_statistics(lanai);
-	}
-	if (reason & INT_STATUS) {
-		ack |= reason & INT_STATUS;
-		lanai_check_status(lanai);
-	}
-	if (unlikely(reason & INT_DMASHUT)) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): driver error - DMA "
-		    "shutdown, reason=0x%08X, address=0x%08X\n",
-		    lanai->number, (unsigned int) (reason & INT_DMASHUT),
-		    (unsigned int) reg_read(lanai, DMA_Addr_Reg));
-		if (reason & INT_TABORTBM) {
-			lanai_reset(lanai);
-			return;
-		}
-		ack |= (reason & INT_DMASHUT);
-		printk(KERN_ERR DEV_LABEL "(itf %d): re-enabling DMA\n",
-		    lanai->number);
-		conf1_write(lanai);
-		lanai->stats.dma_reenable++;
-		pcistatus_check(lanai, 0);
-	}
-	if (unlikely(reason & INT_TABORTSENT)) {
-		ack |= (reason & INT_TABORTSENT);
-		printk(KERN_ERR DEV_LABEL "(itf %d): sent PCI target abort\n",
-		    lanai->number);
-		pcistatus_check(lanai, 0);
-	}
-	if (unlikely(reason & INT_SEGSHUT)) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): driver error - "
-		    "segmentation shutdown, reason=0x%08X\n", lanai->number,
-		    (unsigned int) (reason & INT_SEGSHUT));
-		lanai_reset(lanai);
-		return;
-	}
-	if (unlikely(reason & (INT_PING | INT_WAKE))) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): driver error - "
-		    "unexpected interrupt 0x%08X, resetting\n",
-		    lanai->number,
-		    (unsigned int) (reason & (INT_PING | INT_WAKE)));
-		lanai_reset(lanai);
-		return;
-	}
-#ifdef DEBUG
-	if (unlikely(ack != reason)) {
-		DPRINTK("unacked ints: 0x%08X\n",
-		    (unsigned int) (reason & ~ack));
-		ack = reason;
-	}
-#endif
-   done:
-	if (ack != 0)
-		reg_write(lanai, ack, IntAck_Reg);
-}
-
-static irqreturn_t lanai_int(int irq, void *devid)
-{
-	struct lanai_dev *lanai = devid;
-	u32 reason;
-
-#ifdef USE_POWERDOWN
-	/*
-	 * If we're powered down we shouldn't be generating any interrupts -
-	 * so assume that this is a shared interrupt line and it's for someone
-	 * else
-	 */
-	if (unlikely(lanai->conf1 & CONFIG1_POWERDOWN))
-		return IRQ_NONE;
-#endif
-
-	reason = intr_pending(lanai);
-	if (reason == 0)
-		return IRQ_NONE;	/* Must be for someone else */
-
-	do {
-		if (unlikely(reason == 0xFFFFFFFF))
-			break;		/* Maybe we've been unplugged? */
-		lanai_int_1(lanai, reason);
-		reason = intr_pending(lanai);
-	} while (reason != 0);
-
-	return IRQ_HANDLED;
-}
-
-/* TODO - it would be nice if we could use the "delayed interrupt" system
- *   to some advantage
- */
-
-/* -------------------- CHECK BOARD ID/REV: */
-
-/*
- * The board id and revision are stored both in the reset register and
- * in the PCI configuration space - the documentation says to check
- * each of them.  If revp!=NULL we store the revision there
- */
-static int check_board_id_and_rev(const char *name, u32 val, int *revp)
-{
-	DPRINTK("%s says board_id=%d, board_rev=%d\n", name,
-		(int) RESET_GET_BOARD_ID(val),
-		(int) RESET_GET_BOARD_REV(val));
-	if (RESET_GET_BOARD_ID(val) != BOARD_ID_LANAI256) {
-		printk(KERN_ERR DEV_LABEL ": Found %s board-id %d -- not a "
-		    "Lanai 25.6\n", name, (int) RESET_GET_BOARD_ID(val));
-		return -ENODEV;
-	}
-	if (revp != NULL)
-		*revp = RESET_GET_BOARD_REV(val);
-	return 0;
-}
-
-/* -------------------- PCI INITIALIZATION/SHUTDOWN: */
-
-static int lanai_pci_start(struct lanai_dev *lanai)
-{
-	struct pci_dev *pci = lanai->pci;
-	int result;
-
-	if (pci_enable_device(pci) != 0) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't enable "
-		    "PCI device", lanai->number);
-		return -ENXIO;
-	}
-	pci_set_master(pci);
-	if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32)) != 0) {
-		printk(KERN_WARNING DEV_LABEL
-		    "(itf %d): No suitable DMA available.\n", lanai->number);
-		return -EBUSY;
-	}
-	result = check_board_id_and_rev("PCI", pci->subsystem_device, NULL);
-	if (result != 0)
-		return result;
-	/* Set latency timer to zero as per lanai docs */
-	result = pci_write_config_byte(pci, PCI_LATENCY_TIMER, 0);
-	if (result != PCIBIOS_SUCCESSFUL) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't write "
-		    "PCI_LATENCY_TIMER: %d\n", lanai->number, result);
-		return -EINVAL;
-	}
-	pcistatus_check(lanai, 1);
-	pcistatus_check(lanai, 0);
-	return 0;
-}
-
-/* -------------------- VPI/VCI ALLOCATION: */
-
-/*
- * We _can_ use VCI==0 for normal traffic, but only for UBR (or we'll
- * get a CBRZERO interrupt), and we can use it only if no one is receiving
- * AAL0 traffic (since they will use the same queue) - according to the
- * docs we shouldn't even use it for AAL0 traffic
- */
-static inline int vci0_is_ok(struct lanai_dev *lanai,
-	const struct atm_qos *qos)
-{
-	if (qos->txtp.traffic_class == ATM_CBR || qos->aal == ATM_AAL0)
-		return 0;
-	if (qos->rxtp.traffic_class != ATM_NONE) {
-		if (lanai->naal0 != 0)
-			return 0;
-		lanai->conf2 |= CONFIG2_VCI0_NORMAL;
-		conf2_write_if_powerup(lanai);
-	}
-	return 1;
-}
-
-/* return true if vci is currently unused, or if requested qos is
- * compatible
- */
-static int vci_is_ok(struct lanai_dev *lanai, vci_t vci,
-	const struct atm_vcc *atmvcc)
-{
-	const struct atm_qos *qos = &atmvcc->qos;
-	const struct lanai_vcc *lvcc = lanai->vccs[vci];
-	if (vci == 0 && !vci0_is_ok(lanai, qos))
-		return 0;
-	if (unlikely(lvcc != NULL)) {
-		if (qos->rxtp.traffic_class != ATM_NONE &&
-		    lvcc->rx.atmvcc != NULL && lvcc->rx.atmvcc != atmvcc)
-			return 0;
-		if (qos->txtp.traffic_class != ATM_NONE &&
-		    lvcc->tx.atmvcc != NULL && lvcc->tx.atmvcc != atmvcc)
-			return 0;
-		if (qos->txtp.traffic_class == ATM_CBR &&
-		    lanai->cbrvcc != NULL && lanai->cbrvcc != atmvcc)
-			return 0;
-	}
-	if (qos->aal == ATM_AAL0 && lanai->naal0 == 0 &&
-	    qos->rxtp.traffic_class != ATM_NONE) {
-		const struct lanai_vcc *vci0 = lanai->vccs[0];
-		if (vci0 != NULL && vci0->rx.atmvcc != NULL)
-			return 0;
-		lanai->conf2 &= ~CONFIG2_VCI0_NORMAL;
-		conf2_write_if_powerup(lanai);
-	}
-	return 1;
-}
-
-static int lanai_normalize_ci(struct lanai_dev *lanai,
-	const struct atm_vcc *atmvcc, short *vpip, vci_t *vcip)
-{
-	switch (*vpip) {
-		case ATM_VPI_ANY:
-			*vpip = 0;
-			fallthrough;
-		case 0:
-			break;
-		default:
-			return -EADDRINUSE;
-	}
-	switch (*vcip) {
-		case ATM_VCI_ANY:
-			for (*vcip = ATM_NOT_RSV_VCI; *vcip < lanai->num_vci;
-			    (*vcip)++)
-				if (vci_is_ok(lanai, *vcip, atmvcc))
-					return 0;
-			return -EADDRINUSE;
-		default:
-			if (*vcip >= lanai->num_vci || *vcip < 0 ||
-			    !vci_is_ok(lanai, *vcip, atmvcc))
-				return -EADDRINUSE;
-	}
-	return 0;
-}
-
-/* -------------------- MANAGE CBR: */
-
-/*
- * CBR ICG is stored as a fixed-point number with 4 fractional bits.
- * Note that storing a number greater than 2046.0 will result in
- * incorrect shaping
- */
-#define CBRICG_FRAC_BITS	(4)
-#define CBRICG_MAX		(2046 << CBRICG_FRAC_BITS)
-
-/*
- * ICG is related to PCR with the formula PCR = MAXPCR / (ICG + 1)
- * where MAXPCR is (according to the docs) 25600000/(54*8),
- * which is equal to (3125<<9)/27.
- *
- * Solving for ICG, we get:
- *    ICG = MAXPCR/PCR - 1
- *    ICG = (3125<<9)/(27*PCR) - 1
- *    ICG = ((3125<<9) - (27*PCR)) / (27*PCR)
- *
- * The end result is supposed to be a fixed-point number with FRAC_BITS
- * bits of a fractional part, so we keep everything in the numerator
- * shifted by that much as we compute
- *
- */
-static int pcr_to_cbricg(const struct atm_qos *qos)
-{
-	int rounddown = 0;	/* 1 = Round PCR down, i.e. round ICG _up_ */
-	int x, icg, pcr = atm_pcr_goal(&qos->txtp);
-	if (pcr == 0)		/* Use maximum bandwidth */
-		return 0;
-	if (pcr < 0) {
-		rounddown = 1;
-		pcr = -pcr;
-	}
-	x = pcr * 27;
-	icg = (3125 << (9 + CBRICG_FRAC_BITS)) - (x << CBRICG_FRAC_BITS);
-	if (rounddown)
-		icg += x - 1;
-	icg /= x;
-	if (icg > CBRICG_MAX)
-		icg = CBRICG_MAX;
-	DPRINTK("pcr_to_cbricg: pcr=%d rounddown=%c icg=%d\n",
-	    pcr, rounddown ? 'Y' : 'N', icg);
-	return icg;
-}
-
-static inline void lanai_cbr_setup(struct lanai_dev *lanai)
-{
-	reg_write(lanai, pcr_to_cbricg(&lanai->cbrvcc->qos), CBR_ICG_Reg);
-	reg_write(lanai, lanai->cbrvcc->vci, CBR_PTR_Reg);
-	lanai->conf2 |= CONFIG2_CBR_ENABLE;
-	conf2_write(lanai);
-}
-
-static inline void lanai_cbr_shutdown(struct lanai_dev *lanai)
-{
-	lanai->conf2 &= ~CONFIG2_CBR_ENABLE;
-	conf2_write(lanai);
-}
-
-/* -------------------- OPERATIONS: */
-
-/* setup a newly detected device */
-static int lanai_dev_open(struct atm_dev *atmdev)
-{
-	struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
-	unsigned long raw_base;
-	int result;
-
-	DPRINTK("In lanai_dev_open()\n");
-	/* Basic device fields */
-	lanai->number = atmdev->number;
-	lanai->num_vci = NUM_VCI;
-	bitmap_zero(lanai->backlog_vccs, NUM_VCI);
-	bitmap_zero(lanai->transmit_ready, NUM_VCI);
-	lanai->naal0 = 0;
-#ifdef USE_POWERDOWN
-	lanai->nbound = 0;
-#endif
-	lanai->cbrvcc = NULL;
-	memset(&lanai->stats, 0, sizeof lanai->stats);
-	spin_lock_init(&lanai->endtxlock);
-	spin_lock_init(&lanai->servicelock);
-	atmdev->ci_range.vpi_bits = 0;
-	atmdev->ci_range.vci_bits = 0;
-	while (1 << atmdev->ci_range.vci_bits < lanai->num_vci)
-		atmdev->ci_range.vci_bits++;
-	atmdev->link_rate = ATM_25_PCR;
-
-	/* 3.2: PCI initialization */
-	if ((result = lanai_pci_start(lanai)) != 0)
-		goto error;
-	raw_base = lanai->pci->resource[0].start;
-	lanai->base = (bus_addr_t) ioremap(raw_base, LANAI_MAPPING_SIZE);
-	if (lanai->base == NULL) {
-		printk(KERN_ERR DEV_LABEL ": couldn't remap I/O space\n");
-		result = -ENOMEM;
-		goto error_pci;
-	}
-	/* 3.3: Reset lanai and PHY */
-	reset_board(lanai);
-	lanai->conf1 = reg_read(lanai, Config1_Reg);
-	lanai->conf1 &= ~(CONFIG1_GPOUT1 | CONFIG1_POWERDOWN |
-	    CONFIG1_MASK_LEDMODE);
-	lanai->conf1 |= CONFIG1_SET_LEDMODE(LEDMODE_NOT_SOOL);
-	reg_write(lanai, lanai->conf1 | CONFIG1_GPOUT1, Config1_Reg);
-	udelay(1000);
-	conf1_write(lanai);
-
-	/*
-	 * 3.4: Turn on endian mode for big-endian hardware
-	 *   We don't actually want to do this - the actual bit fields
-	 *   in the endian register are not documented anywhere.
-	 *   Instead we do the bit-flipping ourselves on big-endian
-	 *   hardware.
-	 *
-	 * 3.5: get the board ID/rev by reading the reset register
-	 */
-	result = check_board_id_and_rev("register",
-	    reg_read(lanai, Reset_Reg), &lanai->board_rev);
-	if (result != 0)
-		goto error_unmap;
-
-	/* 3.6: read EEPROM */
-	if ((result = eeprom_read(lanai)) != 0)
-		goto error_unmap;
-	if ((result = eeprom_validate(lanai)) != 0)
-		goto error_unmap;
-
-	/* 3.7: re-reset PHY, do loopback tests, setup PHY */
-	reg_write(lanai, lanai->conf1 | CONFIG1_GPOUT1, Config1_Reg);
-	udelay(1000);
-	conf1_write(lanai);
-	/* TODO - loopback tests */
-	lanai->conf1 |= (CONFIG1_GPOUT2 | CONFIG1_GPOUT3 | CONFIG1_DMA_ENABLE);
-	conf1_write(lanai);
-
-	/* 3.8/3.9: test and initialize card SRAM */
-	if ((result = sram_test_and_clear(lanai)) != 0)
-		goto error_unmap;
-
-	/* 3.10: initialize lanai registers */
-	lanai->conf1 |= CONFIG1_DMA_ENABLE;
-	conf1_write(lanai);
-	if ((result = service_buffer_allocate(lanai)) != 0)
-		goto error_unmap;
-	if ((result = vcc_table_allocate(lanai)) != 0)
-		goto error_service;
-	lanai->conf2 = (lanai->num_vci >= 512 ? CONFIG2_HOWMANY : 0) |
-	    CONFIG2_HEC_DROP |	/* ??? */ CONFIG2_PTI7_MODE;
-	conf2_write(lanai);
-	reg_write(lanai, TX_FIFO_DEPTH, TxDepth_Reg);
-	reg_write(lanai, 0, CBR_ICG_Reg);	/* CBR defaults to no limit */
-	if ((result = request_irq(lanai->pci->irq, lanai_int, IRQF_SHARED,
-	    DEV_LABEL, lanai)) != 0) {
-		printk(KERN_ERR DEV_LABEL ": can't allocate interrupt\n");
-		goto error_vcctable;
-	}
-	mb();				/* Make sure that all that made it */
-	intr_enable(lanai, INT_ALL & ~(INT_PING | INT_WAKE));
-	/* 3.11: initialize loop mode (i.e. turn looping off) */
-	lanai->conf1 = (lanai->conf1 & ~CONFIG1_MASK_LOOPMODE) |
-	    CONFIG1_SET_LOOPMODE(LOOPMODE_NORMAL) |
-	    CONFIG1_GPOUT2 | CONFIG1_GPOUT3;
-	conf1_write(lanai);
-	lanai->status = reg_read(lanai, Status_Reg);
-	/* We're now done initializing this card */
-#ifdef USE_POWERDOWN
-	lanai->conf1 |= CONFIG1_POWERDOWN;
-	conf1_write(lanai);
-#endif
-	memcpy(atmdev->esi, eeprom_mac(lanai), ESI_LEN);
-	lanai_timed_poll_start(lanai);
-	printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d, base=%p, irq=%u "
-		"(%pMF)\n", lanai->number, (int) lanai->pci->revision,
-		lanai->base, lanai->pci->irq, atmdev->esi);
-	printk(KERN_NOTICE DEV_LABEL "(itf %d): LANAI%s, serialno=%u(0x%X), "
-	    "board_rev=%d\n", lanai->number,
-	    lanai->type==lanai2 ? "2" : "HB", (unsigned int) lanai->serialno,
-	    (unsigned int) lanai->serialno, lanai->board_rev);
-	return 0;
-
-    error_vcctable:
-	vcc_table_deallocate(lanai);
-    error_service:
-	service_buffer_deallocate(lanai);
-    error_unmap:
-	reset_board(lanai);
-#ifdef USE_POWERDOWN
-	lanai->conf1 = reg_read(lanai, Config1_Reg) | CONFIG1_POWERDOWN;
-	conf1_write(lanai);
-#endif
-	iounmap(lanai->base);
-	lanai->base = NULL;
-    error_pci:
-	pci_disable_device(lanai->pci);
-    error:
-	return result;
-}
-
-/* called when device is being shutdown, and all vcc's are gone - higher
- * levels will deallocate the atm device for us
- */
-static void lanai_dev_close(struct atm_dev *atmdev)
-{
-	struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
-	if (lanai->base==NULL)
-		return;
-	printk(KERN_INFO DEV_LABEL "(itf %d): shutting down interface\n",
-	    lanai->number);
-	lanai_timed_poll_stop(lanai);
-#ifdef USE_POWERDOWN
-	lanai->conf1 = reg_read(lanai, Config1_Reg) & ~CONFIG1_POWERDOWN;
-	conf1_write(lanai);
-#endif
-	intr_disable(lanai, INT_ALL);
-	free_irq(lanai->pci->irq, lanai);
-	reset_board(lanai);
-#ifdef USE_POWERDOWN
-	lanai->conf1 |= CONFIG1_POWERDOWN;
-	conf1_write(lanai);
-#endif
-	pci_disable_device(lanai->pci);
-	vcc_table_deallocate(lanai);
-	service_buffer_deallocate(lanai);
-	iounmap(lanai->base);
-	kfree(lanai);
-}
-
-/* close a vcc */
-static void lanai_close(struct atm_vcc *atmvcc)
-{
-	struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data;
-	struct lanai_dev *lanai = (struct lanai_dev *) atmvcc->dev->dev_data;
-	if (lvcc == NULL)
-		return;
-	clear_bit(ATM_VF_READY, &atmvcc->flags);
-	clear_bit(ATM_VF_PARTIAL, &atmvcc->flags);
-	if (lvcc->rx.atmvcc == atmvcc) {
-		lanai_shutdown_rx_vci(lvcc);
-		if (atmvcc->qos.aal == ATM_AAL0) {
-			if (--lanai->naal0 <= 0)
-				aal0_buffer_free(lanai);
-		} else
-			lanai_buf_deallocate(&lvcc->rx.buf, lanai->pci);
-		lvcc->rx.atmvcc = NULL;
-	}
-	if (lvcc->tx.atmvcc == atmvcc) {
-		if (atmvcc == lanai->cbrvcc) {
-			if (lvcc->vbase != NULL)
-				lanai_cbr_shutdown(lanai);
-			lanai->cbrvcc = NULL;
-		}
-		lanai_shutdown_tx_vci(lanai, lvcc);
-		lanai_buf_deallocate(&lvcc->tx.buf, lanai->pci);
-		lvcc->tx.atmvcc = NULL;
-	}
-	if (--lvcc->nref == 0) {
-		host_vcc_unbind(lanai, lvcc);
-		kfree(lvcc);
-	}
-	atmvcc->dev_data = NULL;
-	clear_bit(ATM_VF_ADDR, &atmvcc->flags);
-}
-
-/* open a vcc on the card to vpi/vci */
-static int lanai_open(struct atm_vcc *atmvcc)
-{
-	struct lanai_dev *lanai;
-	struct lanai_vcc *lvcc;
-	int result = 0;
-	int vci = atmvcc->vci;
-	short vpi = atmvcc->vpi;
-	/* we don't support partial open - it's not really useful anyway */
-	if ((test_bit(ATM_VF_PARTIAL, &atmvcc->flags)) ||
-	    (vpi == ATM_VPI_UNSPEC) || (vci == ATM_VCI_UNSPEC))
-		return -EINVAL;
-	lanai = (struct lanai_dev *) atmvcc->dev->dev_data;
-	result = lanai_normalize_ci(lanai, atmvcc, &vpi, &vci);
-	if (unlikely(result != 0))
-		goto out;
-	set_bit(ATM_VF_ADDR, &atmvcc->flags);
-	if (atmvcc->qos.aal != ATM_AAL0 && atmvcc->qos.aal != ATM_AAL5)
-		return -EINVAL;
-	DPRINTK(DEV_LABEL "(itf %d): open %d.%d\n", lanai->number,
-	    (int) vpi, vci);
-	lvcc = lanai->vccs[vci];
-	if (lvcc == NULL) {
-		lvcc = new_lanai_vcc();
-		if (unlikely(lvcc == NULL))
-			return -ENOMEM;
-		atmvcc->dev_data = lvcc;
-	}
-	lvcc->nref++;
-	if (atmvcc->qos.rxtp.traffic_class != ATM_NONE) {
-		APRINTK(lvcc->rx.atmvcc == NULL, "rx.atmvcc!=NULL, vci=%d\n",
-		    vci);
-		if (atmvcc->qos.aal == ATM_AAL0) {
-			if (lanai->naal0 == 0)
-				result = aal0_buffer_allocate(lanai);
-		} else
-			result = lanai_setup_rx_vci_aal5(
-			    lanai, lvcc, &atmvcc->qos);
-		if (unlikely(result != 0))
-			goto out_free;
-		lvcc->rx.atmvcc = atmvcc;
-		lvcc->stats.rx_nomem = 0;
-		lvcc->stats.x.aal5.rx_badlen = 0;
-		lvcc->stats.x.aal5.service_trash = 0;
-		lvcc->stats.x.aal5.service_stream = 0;
-		lvcc->stats.x.aal5.service_rxcrc = 0;
-		if (atmvcc->qos.aal == ATM_AAL0)
-			lanai->naal0++;
-	}
-	if (atmvcc->qos.txtp.traffic_class != ATM_NONE) {
-		APRINTK(lvcc->tx.atmvcc == NULL, "tx.atmvcc!=NULL, vci=%d\n",
-		    vci);
-		result = lanai_setup_tx_vci(lanai, lvcc, &atmvcc->qos);
-		if (unlikely(result != 0))
-			goto out_free;
-		lvcc->tx.atmvcc = atmvcc;
-		if (atmvcc->qos.txtp.traffic_class == ATM_CBR) {
-			APRINTK(lanai->cbrvcc == NULL,
-			    "cbrvcc!=NULL, vci=%d\n", vci);
-			lanai->cbrvcc = atmvcc;
-		}
-	}
-	host_vcc_bind(lanai, lvcc, vci);
-	/*
-	 * Make sure everything made it to RAM before we tell the card about
-	 * the VCC
-	 */
-	wmb();
-	if (atmvcc == lvcc->rx.atmvcc)
-		host_vcc_start_rx(lvcc);
-	if (atmvcc == lvcc->tx.atmvcc) {
-		host_vcc_start_tx(lvcc);
-		if (lanai->cbrvcc == atmvcc)
-			lanai_cbr_setup(lanai);
-	}
-	set_bit(ATM_VF_READY, &atmvcc->flags);
-	return 0;
-    out_free:
-	lanai_close(atmvcc);
-    out:
-	return result;
-}
-
-static int lanai_send(struct atm_vcc *atmvcc, struct sk_buff *skb)
-{
-	struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data;
-	struct lanai_dev *lanai = (struct lanai_dev *) atmvcc->dev->dev_data;
-	unsigned long flags;
-	if (unlikely(lvcc == NULL || lvcc->vbase == NULL ||
-	      lvcc->tx.atmvcc != atmvcc))
-		goto einval;
-#ifdef DEBUG
-	if (unlikely(skb == NULL)) {
-		DPRINTK("lanai_send: skb==NULL for vci=%d\n", atmvcc->vci);
-		goto einval;
-	}
-	if (unlikely(lanai == NULL)) {
-		DPRINTK("lanai_send: lanai==NULL for vci=%d\n", atmvcc->vci);
-		goto einval;
-	}
-#endif
-	ATM_SKB(skb)->vcc = atmvcc;
-	switch (atmvcc->qos.aal) {
-		case ATM_AAL5:
-			read_lock_irqsave(&vcc_sklist_lock, flags);
-			vcc_tx_aal5(lanai, lvcc, skb);
-			read_unlock_irqrestore(&vcc_sklist_lock, flags);
-			return 0;
-		case ATM_AAL0:
-			if (unlikely(skb->len != ATM_CELL_SIZE-1))
-				goto einval;
-  /* NOTE - this next line is technically invalid - we haven't unshared skb */
-			cpu_to_be32s((u32 *) skb->data);
-			read_lock_irqsave(&vcc_sklist_lock, flags);
-			vcc_tx_aal0(lanai, lvcc, skb);
-			read_unlock_irqrestore(&vcc_sklist_lock, flags);
-			return 0;
-	}
-	DPRINTK("lanai_send: bad aal=%d on vci=%d\n", (int) atmvcc->qos.aal,
-	    atmvcc->vci);
-    einval:
-	lanai_free_skb(atmvcc, skb);
-	return -EINVAL;
-}
-
-static int lanai_change_qos(struct atm_vcc *atmvcc,
-	/*const*/ struct atm_qos *qos, int flags)
-{
-	return -EBUSY;		/* TODO: need to write this */
-}
-
-#ifndef CONFIG_PROC_FS
-#define lanai_proc_read NULL
-#else
-static int lanai_proc_read(struct atm_dev *atmdev, loff_t *pos, char *page)
-{
-	struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
-	loff_t left = *pos;
-	struct lanai_vcc *lvcc;
-	if (left-- == 0)
-		return sprintf(page, DEV_LABEL "(itf %d): chip=LANAI%s, "
-		    "serial=%u, magic=0x%08X, num_vci=%d\n",
-		    atmdev->number, lanai->type==lanai2 ? "2" : "HB",
-		    (unsigned int) lanai->serialno,
-		    (unsigned int) lanai->magicno, lanai->num_vci);
-	if (left-- == 0)
-		return sprintf(page, "revision: board=%d, pci_if=%d\n",
-		    lanai->board_rev, (int) lanai->pci->revision);
-	if (left-- == 0)
-		return sprintf(page, "EEPROM ESI: %pM\n",
-		    &lanai->eeprom[EEPROM_MAC]);
-	if (left-- == 0)
-		return sprintf(page, "status: SOOL=%d, LOCD=%d, LED=%d, "
-		    "GPIN=%d\n", (lanai->status & STATUS_SOOL) ? 1 : 0,
-		    (lanai->status & STATUS_LOCD) ? 1 : 0,
-		    (lanai->status & STATUS_LED) ? 1 : 0,
-		    (lanai->status & STATUS_GPIN) ? 1 : 0);
-	if (left-- == 0)
-		return sprintf(page, "global buffer sizes: service=%zu, "
-		    "aal0_rx=%zu\n", lanai_buf_size(&lanai->service),
-		    lanai->naal0 ? lanai_buf_size(&lanai->aal0buf) : 0);
-	if (left-- == 0) {
-		get_statistics(lanai);
-		return sprintf(page, "cells in error: overflow=%u, "
-		    "closed_vci=%u, bad_HEC=%u, rx_fifo=%u\n",
-		    lanai->stats.ovfl_trash, lanai->stats.vci_trash,
-		    lanai->stats.hec_err, lanai->stats.atm_ovfl);
-	}
-	if (left-- == 0)
-		return sprintf(page, "PCI errors: parity_detect=%u, "
-		    "master_abort=%u, master_target_abort=%u,\n",
-		    lanai->stats.pcierr_parity_detect,
-		    lanai->stats.pcierr_serr_set,
-		    lanai->stats.pcierr_m_target_abort);
-	if (left-- == 0)
-		return sprintf(page, "            slave_target_abort=%u, "
-		    "master_parity=%u\n", lanai->stats.pcierr_s_target_abort,
-		    lanai->stats.pcierr_master_parity);
-	if (left-- == 0)
-		return sprintf(page, "                     no_tx=%u, "
-		    "no_rx=%u, bad_rx_aal=%u\n", lanai->stats.service_norx,
-		    lanai->stats.service_notx,
-		    lanai->stats.service_rxnotaal5);
-	if (left-- == 0)
-		return sprintf(page, "resets: dma=%u, card=%u\n",
-		    lanai->stats.dma_reenable, lanai->stats.card_reset);
-	/* At this point, "left" should be the VCI we're looking for */
-	read_lock(&vcc_sklist_lock);
-	for (; ; left++) {
-		if (left >= NUM_VCI) {
-			left = 0;
-			goto out;
-		}
-		if ((lvcc = lanai->vccs[left]) != NULL)
-			break;
-		(*pos)++;
-	}
-	/* Note that we re-use "left" here since we're done with it */
-	left = sprintf(page, "VCI %4d: nref=%d, rx_nomem=%u",  (vci_t) left,
-	    lvcc->nref, lvcc->stats.rx_nomem);
-	if (lvcc->rx.atmvcc != NULL) {
-		left += sprintf(&page[left], ",\n          rx_AAL=%d",
-		    lvcc->rx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0);
-		if (lvcc->rx.atmvcc->qos.aal == ATM_AAL5)
-			left += sprintf(&page[left], ", rx_buf_size=%zu, "
-			    "rx_bad_len=%u,\n          rx_service_trash=%u, "
-			    "rx_service_stream=%u, rx_bad_crc=%u",
-			    lanai_buf_size(&lvcc->rx.buf),
-			    lvcc->stats.x.aal5.rx_badlen,
-			    lvcc->stats.x.aal5.service_trash,
-			    lvcc->stats.x.aal5.service_stream,
-			    lvcc->stats.x.aal5.service_rxcrc);
-	}
-	if (lvcc->tx.atmvcc != NULL)
-		left += sprintf(&page[left], ",\n          tx_AAL=%d, "
-		    "tx_buf_size=%zu, tx_qos=%cBR, tx_backlogged=%c",
-		    lvcc->tx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0,
-		    lanai_buf_size(&lvcc->tx.buf),
-		    lvcc->tx.atmvcc == lanai->cbrvcc ? 'C' : 'U',
-		    vcc_is_backlogged(lvcc) ? 'Y' : 'N');
-	page[left++] = '\n';
-	page[left] = '\0';
-    out:
-	read_unlock(&vcc_sklist_lock);
-	return left;
-}
-#endif /* CONFIG_PROC_FS */
-
-/* -------------------- HOOKS: */
-
-static const struct atmdev_ops ops = {
-	.dev_close	= lanai_dev_close,
-	.open		= lanai_open,
-	.close		= lanai_close,
-	.send		= lanai_send,
-	.phy_put	= NULL,
-	.phy_get	= NULL,
-	.change_qos	= lanai_change_qos,
-	.proc_read	= lanai_proc_read,
-	.owner		= THIS_MODULE
-};
-
-/* initialize one probed card */
-static int lanai_init_one(struct pci_dev *pci,
-			  const struct pci_device_id *ident)
-{
-	struct lanai_dev *lanai;
-	struct atm_dev *atmdev;
-	int result;
-
-	lanai = kzalloc_obj(*lanai);
-	if (lanai == NULL) {
-		printk(KERN_ERR DEV_LABEL
-		       ": couldn't allocate dev_data structure!\n");
-		return -ENOMEM;
-	}
-
-	atmdev = atm_dev_register(DEV_LABEL, &pci->dev, &ops, -1, NULL);
-	if (atmdev == NULL) {
-		printk(KERN_ERR DEV_LABEL
-		    ": couldn't register atm device!\n");
-		kfree(lanai);
-		return -EBUSY;
-	}
-
-	atmdev->dev_data = lanai;
-	lanai->pci = pci;
-	lanai->type = (enum lanai_type) ident->device;
-
-	result = lanai_dev_open(atmdev);
-	if (result != 0) {
-		DPRINTK("lanai_start() failed, err=%d\n", -result);
-		atm_dev_deregister(atmdev);
-		kfree(lanai);
-	}
-	return result;
-}
-
-static const struct pci_device_id lanai_pci_tbl[] = {
-	{ PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_LANAI2) },
-	{ PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_LANAIHB) },
-	{ 0, }	/* terminal entry */
-};
-MODULE_DEVICE_TABLE(pci, lanai_pci_tbl);
-
-static struct pci_driver lanai_driver = {
-	.name     = DEV_LABEL,
-	.id_table = lanai_pci_tbl,
-	.probe    = lanai_init_one,
-};
-
-module_pci_driver(lanai_driver);
-
-MODULE_AUTHOR("Mitchell Blank Jr <mitch@sfgoth.com>");
-MODULE_DESCRIPTION("Efficient Networks Speedstream 3010 driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
deleted file mode 100644
index 24e51343df15..000000000000
--- a/drivers/atm/nicstar.c
+++ /dev/null
@@ -1,2759 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * nicstar.c
- *
- * Device driver supporting CBR for IDT 77201/77211 "NICStAR" based cards.
- *
- * IMPORTANT: The included file nicstarmac.c was NOT WRITTEN BY ME.
- *            It was taken from the frle-0.22 device driver.
- *            As the file doesn't have a copyright notice, in the file
- *            nicstarmac.copyright I put the copyright notice from the
- *            frle-0.22 device driver.
- *            Some code is based on the nicstar driver by M. Welsh.
- *
- * Author: Rui Prior (rprior@inescn.pt)
- * PowerPC support by Jay Talbott (jay_talbott@mcg.mot.com) April 1999
- *
- *
- * (C) INESC 1999
- */
-
-/*
- * IMPORTANT INFORMATION
- *
- * There are currently three types of spinlocks:
- *
- * 1 - Per card interrupt spinlock (to protect structures and such)
- * 2 - Per SCQ scq spinlock
- * 3 - Per card resource spinlock (to access registers, etc.)
- *
- * These must NEVER be grabbed in reverse order.
- *
- */
-
-/* Header files */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/atmdev.h>
-#include <linux/atm.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/hex.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <linux/slab.h>
-#include <linux/idr.h>
-#include <asm/io.h>
-#include <linux/uaccess.h>
-#include <linux/atomic.h>
-#include <linux/etherdevice.h>
-#include "nicstar.h"
-#ifdef CONFIG_ATM_NICSTAR_USE_SUNI
-#include "suni.h"
-#endif /* CONFIG_ATM_NICSTAR_USE_SUNI */
-#ifdef CONFIG_ATM_NICSTAR_USE_IDT77105
-#include "idt77105.h"
-#endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */
-
-/* Additional code */
-
-#include "nicstarmac.c"
-
-/* Configurable parameters */
-
-#undef PHY_LOOPBACK
-#undef TX_DEBUG
-#undef RX_DEBUG
-#undef GENERAL_DEBUG
-#undef EXTRA_DEBUG
-
-/* Do not touch these */
-
-#ifdef TX_DEBUG
-#define TXPRINTK(args...) printk(args)
-#else
-#define TXPRINTK(args...)
-#endif /* TX_DEBUG */
-
-#ifdef RX_DEBUG
-#define RXPRINTK(args...) printk(args)
-#else
-#define RXPRINTK(args...)
-#endif /* RX_DEBUG */
-
-#ifdef GENERAL_DEBUG
-#define PRINTK(args...) printk(args)
-#else
-#define PRINTK(args...) do {} while (0)
-#endif /* GENERAL_DEBUG */
-
-#ifdef EXTRA_DEBUG
-#define XPRINTK(args...) printk(args)
-#else
-#define XPRINTK(args...)
-#endif /* EXTRA_DEBUG */
-
-/* Macros */
-
-#define CMD_BUSY(card) (readl((card)->membase + STAT) & NS_STAT_CMDBZ)
-
-#define NS_DELAY mdelay(1)
-
-#define PTR_DIFF(a, b)	((u32)((unsigned long)(a) - (unsigned long)(b)))
-
-#ifndef ATM_SKB
-#define ATM_SKB(s) (&(s)->atm)
-#endif
-
-#define scq_virt_to_bus(scq, p) \
-		(scq->dma + ((unsigned long)(p) - (unsigned long)(scq)->org))
-
-/* Function declarations */
-
-static u32 ns_read_sram(ns_dev * card, u32 sram_address);
-static void ns_write_sram(ns_dev * card, u32 sram_address, u32 * value,
-			  int count);
-static int ns_init_card(int i, struct pci_dev *pcidev);
-static void ns_init_card_error(ns_dev * card, int error);
-static scq_info *get_scq(ns_dev *card, int size, u32 scd);
-static void free_scq(ns_dev *card, scq_info * scq, struct atm_vcc *vcc);
-static void push_rxbufs(ns_dev *, struct sk_buff *);
-static irqreturn_t ns_irq_handler(int irq, void *dev_id);
-static int ns_open(struct atm_vcc *vcc);
-static void ns_close(struct atm_vcc *vcc);
-static void fill_tst(ns_dev * card, int n, vc_map * vc);
-static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb);
-static int ns_send_bh(struct atm_vcc *vcc, struct sk_buff *skb);
-static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd,
-		     struct sk_buff *skb, bool may_sleep);
-static void process_tsq(ns_dev * card);
-static void drain_scq(ns_dev * card, scq_info * scq, int pos);
-static void process_rsq(ns_dev * card);
-static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe);
-static void recycle_rx_buf(ns_dev * card, struct sk_buff *skb);
-static void recycle_iovec_rx_bufs(ns_dev * card, struct iovec *iov, int count);
-static void recycle_iov_buf(ns_dev * card, struct sk_buff *iovb);
-static void dequeue_sm_buf(ns_dev * card, struct sk_buff *sb);
-static void dequeue_lg_buf(ns_dev * card, struct sk_buff *lb);
-static int ns_proc_read(struct atm_dev *dev, loff_t * pos, char *page);
-static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user * arg);
-#ifdef EXTRA_DEBUG
-static void which_list(ns_dev * card, struct sk_buff *skb);
-#endif
-static void ns_poll(struct timer_list *unused);
-static void ns_phy_put(struct atm_dev *dev, unsigned char value,
-		       unsigned long addr);
-static unsigned char ns_phy_get(struct atm_dev *dev, unsigned long addr);
-
-/* Global variables */
-
-static struct ns_dev *cards[NS_MAX_CARDS];
-static unsigned num_cards;
-static const struct atmdev_ops atm_ops = {
-	.open = ns_open,
-	.close = ns_close,
-	.ioctl = ns_ioctl,
-	.send = ns_send,
-	.send_bh = ns_send_bh,
-	.phy_put = ns_phy_put,
-	.phy_get = ns_phy_get,
-	.proc_read = ns_proc_read,
-	.owner = THIS_MODULE,
-};
-
-static struct timer_list ns_timer;
-static char *mac[NS_MAX_CARDS];
-module_param_array(mac, charp, NULL, 0);
-MODULE_DESCRIPTION("ATM NIC driver for IDT 77201/77211 \"NICStAR\" and Fore ForeRunnerLE.");
-MODULE_LICENSE("GPL");
-
-/* Functions */
-
-static int nicstar_init_one(struct pci_dev *pcidev,
-			    const struct pci_device_id *ent)
-{
-	static int index = -1;
-	unsigned int error;
-
-	index++;
-	cards[index] = NULL;
-
-	error = ns_init_card(index, pcidev);
-	if (error) {
-		cards[index--] = NULL;	/* don't increment index */
-		goto err_out;
-	}
-
-	return 0;
-err_out:
-	return -ENODEV;
-}
-
-static void nicstar_remove_one(struct pci_dev *pcidev)
-{
-	int i, j;
-	ns_dev *card = pci_get_drvdata(pcidev);
-	struct sk_buff *hb;
-	struct sk_buff *iovb;
-	struct sk_buff *lb;
-	struct sk_buff *sb;
-
-	i = card->index;
-
-	if (cards[i] == NULL)
-		return;
-
-	if (card->atmdev->phy && card->atmdev->phy->stop)
-		card->atmdev->phy->stop(card->atmdev);
-
-	/* Stop everything */
-	writel(0x00000000, card->membase + CFG);
-
-	/* De-register device */
-	atm_dev_deregister(card->atmdev);
-
-	/* Disable PCI device */
-	pci_disable_device(pcidev);
-
-	/* Free up resources */
-	j = 0;
-	PRINTK("nicstar%d: freeing %d huge buffers.\n", i, card->hbpool.count);
-	while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL) {
-		dev_kfree_skb_any(hb);
-		j++;
-	}
-	PRINTK("nicstar%d: %d huge buffers freed.\n", i, j);
-	j = 0;
-	PRINTK("nicstar%d: freeing %d iovec buffers.\n", i,
-	       card->iovpool.count);
-	while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL) {
-		dev_kfree_skb_any(iovb);
-		j++;
-	}
-	PRINTK("nicstar%d: %d iovec buffers freed.\n", i, j);
-	while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL)
-		dev_kfree_skb_any(lb);
-	while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL)
-		dev_kfree_skb_any(sb);
-	free_scq(card, card->scq0, NULL);
-	for (j = 0; j < NS_FRSCD_NUM; j++) {
-		if (card->scd2vc[j] != NULL)
-			free_scq(card, card->scd2vc[j]->scq, card->scd2vc[j]->tx_vcc);
-	}
-	idr_destroy(&card->idr);
-	dma_free_coherent(&card->pcidev->dev, NS_RSQSIZE + NS_RSQ_ALIGNMENT,
-			  card->rsq.org, card->rsq.dma);
-	dma_free_coherent(&card->pcidev->dev, NS_TSQSIZE + NS_TSQ_ALIGNMENT,
-			  card->tsq.org, card->tsq.dma);
-	free_irq(card->pcidev->irq, card);
-	iounmap(card->membase);
-	kfree(card);
-}
-
-static const struct pci_device_id nicstar_pci_tbl[] = {
-	{ PCI_VDEVICE(IDT, PCI_DEVICE_ID_IDT_IDT77201), 0 },
-	{0,}			/* terminate list */
-};
-
-MODULE_DEVICE_TABLE(pci, nicstar_pci_tbl);
-
-static struct pci_driver nicstar_driver = {
-	.name = "nicstar",
-	.id_table = nicstar_pci_tbl,
-	.probe = nicstar_init_one,
-	.remove = nicstar_remove_one,
-};
-
-static int __init nicstar_init(void)
-{
-	unsigned error = 0;	/* Initialized to remove compile warning */
-
-	XPRINTK("nicstar: nicstar_init() called.\n");
-
-	error = pci_register_driver(&nicstar_driver);
-
-	TXPRINTK("nicstar: TX debug enabled.\n");
-	RXPRINTK("nicstar: RX debug enabled.\n");
-	PRINTK("nicstar: General debug enabled.\n");
-#ifdef PHY_LOOPBACK
-	printk("nicstar: using PHY loopback.\n");
-#endif /* PHY_LOOPBACK */
-	XPRINTK("nicstar: nicstar_init() returned.\n");
-
-	if (!error) {
-		timer_setup(&ns_timer, ns_poll, 0);
-		ns_timer.expires = jiffies + NS_POLL_PERIOD;
-		add_timer(&ns_timer);
-	}
-
-	return error;
-}
-
-static void __exit nicstar_cleanup(void)
-{
-	XPRINTK("nicstar: nicstar_cleanup() called.\n");
-
-	timer_delete_sync(&ns_timer);
-
-	pci_unregister_driver(&nicstar_driver);
-
-	XPRINTK("nicstar: nicstar_cleanup() returned.\n");
-}
-
-static u32 ns_read_sram(ns_dev * card, u32 sram_address)
-{
-	unsigned long flags;
-	u32 data;
-	sram_address <<= 2;
-	sram_address &= 0x0007FFFC;	/* address must be dword aligned */
-	sram_address |= 0x50000000;	/* SRAM read command */
-	spin_lock_irqsave(&card->res_lock, flags);
-	while (CMD_BUSY(card)) ;
-	writel(sram_address, card->membase + CMD);
-	while (CMD_BUSY(card)) ;
-	data = readl(card->membase + DR0);
-	spin_unlock_irqrestore(&card->res_lock, flags);
-	return data;
-}
-
-static void ns_write_sram(ns_dev * card, u32 sram_address, u32 * value,
-			  int count)
-{
-	unsigned long flags;
-	int i, c;
-	count--;		/* count range now is 0..3 instead of 1..4 */
-	c = count;
-	c <<= 2;		/* to use increments of 4 */
-	spin_lock_irqsave(&card->res_lock, flags);
-	while (CMD_BUSY(card)) ;
-	for (i = 0; i <= c; i += 4)
-		writel(*(value++), card->membase + i);
-	/* Note: DR# registers are the first 4 dwords in nicstar's memspace,
-	   so card->membase + DR0 == card->membase */
-	sram_address <<= 2;
-	sram_address &= 0x0007FFFC;
-	sram_address |= (0x40000000 | count);
-	writel(sram_address, card->membase + CMD);
-	spin_unlock_irqrestore(&card->res_lock, flags);
-}
-
-static int ns_init_card(int i, struct pci_dev *pcidev)
-{
-	int j;
-	struct ns_dev *card = NULL;
-	unsigned char pci_latency;
-	unsigned error;
-	u32 data;
-	u32 u32d[4];
-	u32 ns_cfg_rctsize;
-	int bcount;
-	unsigned long membase;
-
-	error = 0;
-
-	if (pci_enable_device(pcidev)) {
-		printk("nicstar%d: can't enable PCI device\n", i);
-		error = 2;
-		ns_init_card_error(card, error);
-		return error;
-	}
-        if (dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32)) != 0) {
-                printk(KERN_WARNING
-		       "nicstar%d: No suitable DMA available.\n", i);
-		error = 2;
-		ns_init_card_error(card, error);
-		return error;
-        }
-
-	card = kmalloc_obj(*card);
-	if (!card) {
-		printk
-		    ("nicstar%d: can't allocate memory for device structure.\n",
-		     i);
-		error = 2;
-		ns_init_card_error(card, error);
-		return error;
-	}
-	cards[i] = card;
-	spin_lock_init(&card->int_lock);
-	spin_lock_init(&card->res_lock);
-
-	pci_set_drvdata(pcidev, card);
-
-	card->index = i;
-	card->atmdev = NULL;
-	card->pcidev = pcidev;
-	membase = pci_resource_start(pcidev, 1);
-	card->membase = ioremap(membase, NS_IOREMAP_SIZE);
-	if (!card->membase) {
-		printk("nicstar%d: can't ioremap() membase.\n", i);
-		error = 3;
-		ns_init_card_error(card, error);
-		return error;
-	}
-	PRINTK("nicstar%d: membase at 0x%p.\n", i, card->membase);
-
-	pci_set_master(pcidev);
-
-	if (pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency) != 0) {
-		printk("nicstar%d: can't read PCI latency timer.\n", i);
-		error = 6;
-		ns_init_card_error(card, error);
-		return error;
-	}
-#ifdef NS_PCI_LATENCY
-	if (pci_latency < NS_PCI_LATENCY) {
-		PRINTK("nicstar%d: setting PCI latency timer to %d.\n", i,
-		       NS_PCI_LATENCY);
-		for (j = 1; j < 4; j++) {
-			if (pci_write_config_byte
-			    (pcidev, PCI_LATENCY_TIMER, NS_PCI_LATENCY) != 0)
-				break;
-		}
-		if (j == 4) {
-			printk
-			    ("nicstar%d: can't set PCI latency timer to %d.\n",
-			     i, NS_PCI_LATENCY);
-			error = 7;
-			ns_init_card_error(card, error);
-			return error;
-		}
-	}
-#endif /* NS_PCI_LATENCY */
-
-	/* Clear timer overflow */
-	data = readl(card->membase + STAT);
-	if (data & NS_STAT_TMROF)
-		writel(NS_STAT_TMROF, card->membase + STAT);
-
-	/* Software reset */
-	writel(NS_CFG_SWRST, card->membase + CFG);
-	NS_DELAY;
-	writel(0x00000000, card->membase + CFG);
-
-	/* PHY reset */
-	writel(0x00000008, card->membase + GP);
-	NS_DELAY;
-	writel(0x00000001, card->membase + GP);
-	NS_DELAY;
-	while (CMD_BUSY(card)) ;
-	writel(NS_CMD_WRITE_UTILITY | 0x00000100, card->membase + CMD);	/* Sync UTOPIA with SAR clock */
-	NS_DELAY;
-
-	/* Detect PHY type */
-	while (CMD_BUSY(card)) ;
-	writel(NS_CMD_READ_UTILITY | 0x00000200, card->membase + CMD);
-	while (CMD_BUSY(card)) ;
-	data = readl(card->membase + DR0);
-	switch (data) {
-	case 0x00000009:
-		printk("nicstar%d: PHY seems to be 25 Mbps.\n", i);
-		card->max_pcr = ATM_25_PCR;
-		while (CMD_BUSY(card)) ;
-		writel(0x00000008, card->membase + DR0);
-		writel(NS_CMD_WRITE_UTILITY | 0x00000200, card->membase + CMD);
-		/* Clear an eventual pending interrupt */
-		writel(NS_STAT_SFBQF, card->membase + STAT);
-#ifdef PHY_LOOPBACK
-		while (CMD_BUSY(card)) ;
-		writel(0x00000022, card->membase + DR0);
-		writel(NS_CMD_WRITE_UTILITY | 0x00000202, card->membase + CMD);
-#endif /* PHY_LOOPBACK */
-		break;
-	case 0x00000030:
-	case 0x00000031:
-		printk("nicstar%d: PHY seems to be 155 Mbps.\n", i);
-		card->max_pcr = ATM_OC3_PCR;
-#ifdef PHY_LOOPBACK
-		while (CMD_BUSY(card)) ;
-		writel(0x00000002, card->membase + DR0);
-		writel(NS_CMD_WRITE_UTILITY | 0x00000205, card->membase + CMD);
-#endif /* PHY_LOOPBACK */
-		break;
-	default:
-		printk("nicstar%d: unknown PHY type (0x%08X).\n", i, data);
-		error = 8;
-		ns_init_card_error(card, error);
-		return error;
-	}
-	writel(0x00000000, card->membase + GP);
-
-	/* Determine SRAM size */
-	data = 0x76543210;
-	ns_write_sram(card, 0x1C003, &data, 1);
-	data = 0x89ABCDEF;
-	ns_write_sram(card, 0x14003, &data, 1);
-	if (ns_read_sram(card, 0x14003) == 0x89ABCDEF &&
-	    ns_read_sram(card, 0x1C003) == 0x76543210)
-		card->sram_size = 128;
-	else
-		card->sram_size = 32;
-	PRINTK("nicstar%d: %dK x 32bit SRAM size.\n", i, card->sram_size);
-
-	card->rct_size = NS_MAX_RCTSIZE;
-
-#if (NS_MAX_RCTSIZE == 4096)
-	if (card->sram_size == 128)
-		printk
-		    ("nicstar%d: limiting maximum VCI. See NS_MAX_RCTSIZE in nicstar.h\n",
-		     i);
-#elif (NS_MAX_RCTSIZE == 16384)
-	if (card->sram_size == 32) {
-		printk
-		    ("nicstar%d: wasting memory. See NS_MAX_RCTSIZE in nicstar.h\n",
-		     i);
-		card->rct_size = 4096;
-	}
-#else
-#error NS_MAX_RCTSIZE must be either 4096 or 16384 in nicstar.c
-#endif
-
-	card->vpibits = NS_VPIBITS;
-	if (card->rct_size == 4096)
-		card->vcibits = 12 - NS_VPIBITS;
-	else			/* card->rct_size == 16384 */
-		card->vcibits = 14 - NS_VPIBITS;
-
-	/* Initialize the nicstar eeprom/eprom stuff, for the MAC addr */
-	if (mac[i] == NULL)
-		nicstar_init_eprom(card->membase);
-
-	/* Set the VPI/VCI MSb mask to zero so we can receive OAM cells */
-	writel(0x00000000, card->membase + VPM);
-
-	card->intcnt = 0;
-	if (request_irq
-	    (pcidev->irq, &ns_irq_handler, IRQF_SHARED, "nicstar", card) != 0) {
-		pr_err("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq);
-		error = 9;
-		ns_init_card_error(card, error);
-		return error;
-	}
-
-	/* Initialize TSQ */
-	card->tsq.org = dma_alloc_coherent(&card->pcidev->dev,
-					   NS_TSQSIZE + NS_TSQ_ALIGNMENT,
-					   &card->tsq.dma, GFP_KERNEL);
-	if (card->tsq.org == NULL) {
-		printk("nicstar%d: can't allocate TSQ.\n", i);
-		error = 10;
-		ns_init_card_error(card, error);
-		return error;
-	}
-	card->tsq.base = PTR_ALIGN(card->tsq.org, NS_TSQ_ALIGNMENT);
-	card->tsq.next = card->tsq.base;
-	card->tsq.last = card->tsq.base + (NS_TSQ_NUM_ENTRIES - 1);
-	for (j = 0; j < NS_TSQ_NUM_ENTRIES; j++)
-		ns_tsi_init(card->tsq.base + j);
-	writel(0x00000000, card->membase + TSQH);
-	writel(ALIGN(card->tsq.dma, NS_TSQ_ALIGNMENT), card->membase + TSQB);
-	PRINTK("nicstar%d: TSQ base at 0x%p.\n", i, card->tsq.base);
-
-	/* Initialize RSQ */
-	card->rsq.org = dma_alloc_coherent(&card->pcidev->dev,
-					   NS_RSQSIZE + NS_RSQ_ALIGNMENT,
-					   &card->rsq.dma, GFP_KERNEL);
-	if (card->rsq.org == NULL) {
-		printk("nicstar%d: can't allocate RSQ.\n", i);
-		error = 11;
-		ns_init_card_error(card, error);
-		return error;
-	}
-	card->rsq.base = PTR_ALIGN(card->rsq.org, NS_RSQ_ALIGNMENT);
-	card->rsq.next = card->rsq.base;
-	card->rsq.last = card->rsq.base + (NS_RSQ_NUM_ENTRIES - 1);
-	for (j = 0; j < NS_RSQ_NUM_ENTRIES; j++)
-		ns_rsqe_init(card->rsq.base + j);
-	writel(0x00000000, card->membase + RSQH);
-	writel(ALIGN(card->rsq.dma, NS_RSQ_ALIGNMENT), card->membase + RSQB);
-	PRINTK("nicstar%d: RSQ base at 0x%p.\n", i, card->rsq.base);
-
-	/* Initialize SCQ0, the only VBR SCQ used */
-	card->scq1 = NULL;
-	card->scq2 = NULL;
-	card->scq0 = get_scq(card, VBR_SCQSIZE, NS_VRSCD0);
-	if (card->scq0 == NULL) {
-		printk("nicstar%d: can't get SCQ0.\n", i);
-		error = 12;
-		ns_init_card_error(card, error);
-		return error;
-	}
-	u32d[0] = scq_virt_to_bus(card->scq0, card->scq0->base);
-	u32d[1] = (u32) 0x00000000;
-	u32d[2] = (u32) 0xffffffff;
-	u32d[3] = (u32) 0x00000000;
-	ns_write_sram(card, NS_VRSCD0, u32d, 4);
-	ns_write_sram(card, NS_VRSCD1, u32d, 4);	/* These last two won't be used */
-	ns_write_sram(card, NS_VRSCD2, u32d, 4);	/* but are initialized, just in case... */
-	card->scq0->scd = NS_VRSCD0;
-	PRINTK("nicstar%d: VBR-SCQ0 base at 0x%p.\n", i, card->scq0->base);
-
-	/* Initialize TSTs */
-	card->tst_addr = NS_TST0;
-	card->tst_free_entries = NS_TST_NUM_ENTRIES;
-	data = NS_TST_OPCODE_VARIABLE;
-	for (j = 0; j < NS_TST_NUM_ENTRIES; j++)
-		ns_write_sram(card, NS_TST0 + j, &data, 1);
-	data = ns_tste_make(NS_TST_OPCODE_END, NS_TST0);
-	ns_write_sram(card, NS_TST0 + NS_TST_NUM_ENTRIES, &data, 1);
-	for (j = 0; j < NS_TST_NUM_ENTRIES; j++)
-		ns_write_sram(card, NS_TST1 + j, &data, 1);
-	data = ns_tste_make(NS_TST_OPCODE_END, NS_TST1);
-	ns_write_sram(card, NS_TST1 + NS_TST_NUM_ENTRIES, &data, 1);
-	for (j = 0; j < NS_TST_NUM_ENTRIES; j++)
-		card->tste2vc[j] = NULL;
-	writel(NS_TST0 << 2, card->membase + TSTB);
-
-	/* Initialize RCT. AAL type is set on opening the VC. */
-#ifdef RCQ_SUPPORT
-	u32d[0] = NS_RCTE_RAWCELLINTEN;
-#else
-	u32d[0] = 0x00000000;
-#endif /* RCQ_SUPPORT */
-	u32d[1] = 0x00000000;
-	u32d[2] = 0x00000000;
-	u32d[3] = 0xFFFFFFFF;
-	for (j = 0; j < card->rct_size; j++)
-		ns_write_sram(card, j * 4, u32d, 4);
-
-	memset(card->vcmap, 0, sizeof(card->vcmap));
-
-	for (j = 0; j < NS_FRSCD_NUM; j++)
-		card->scd2vc[j] = NULL;
-
-	/* Initialize buffer levels */
-	card->sbnr.min = MIN_SB;
-	card->sbnr.init = NUM_SB;
-	card->sbnr.max = MAX_SB;
-	card->lbnr.min = MIN_LB;
-	card->lbnr.init = NUM_LB;
-	card->lbnr.max = MAX_LB;
-	card->iovnr.min = MIN_IOVB;
-	card->iovnr.init = NUM_IOVB;
-	card->iovnr.max = MAX_IOVB;
-	card->hbnr.min = MIN_HB;
-	card->hbnr.init = NUM_HB;
-	card->hbnr.max = MAX_HB;
-
-	card->sm_handle = NULL;
-	card->sm_addr = 0x00000000;
-	card->lg_handle = NULL;
-	card->lg_addr = 0x00000000;
-
-	card->efbie = 1;	/* To prevent push_rxbufs from enabling the interrupt */
-
-	idr_init(&card->idr);
-
-	/* Pre-allocate some huge buffers */
-	skb_queue_head_init(&card->hbpool.queue);
-	card->hbpool.count = 0;
-	for (j = 0; j < NUM_HB; j++) {
-		struct sk_buff *hb;
-		hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL);
-		if (hb == NULL) {
-			printk
-			    ("nicstar%d: can't allocate %dth of %d huge buffers.\n",
-			     i, j, NUM_HB);
-			error = 13;
-			ns_init_card_error(card, error);
-			return error;
-		}
-		NS_PRV_BUFTYPE(hb) = BUF_NONE;
-		skb_queue_tail(&card->hbpool.queue, hb);
-		card->hbpool.count++;
-	}
-
-	/* Allocate large buffers */
-	skb_queue_head_init(&card->lbpool.queue);
-	card->lbpool.count = 0;	/* Not used */
-	for (j = 0; j < NUM_LB; j++) {
-		struct sk_buff *lb;
-		lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL);
-		if (lb == NULL) {
-			printk
-			    ("nicstar%d: can't allocate %dth of %d large buffers.\n",
-			     i, j, NUM_LB);
-			error = 14;
-			ns_init_card_error(card, error);
-			return error;
-		}
-		NS_PRV_BUFTYPE(lb) = BUF_LG;
-		skb_queue_tail(&card->lbpool.queue, lb);
-		skb_reserve(lb, NS_SMBUFSIZE);
-		push_rxbufs(card, lb);
-		/* Due to the implementation of push_rxbufs() this is 1, not 0 */
-		if (j == 1) {
-			card->rcbuf = lb;
-			card->rawcell = (struct ns_rcqe *) lb->data;
-			card->rawch = NS_PRV_DMA(lb);
-		}
-	}
-	/* Test for strange behaviour which leads to crashes */
-	if ((bcount =
-	     ns_stat_lfbqc_get(readl(card->membase + STAT))) < card->lbnr.min) {
-		printk
-		    ("nicstar%d: Strange... Just allocated %d large buffers and lfbqc = %d.\n",
-		     i, j, bcount);
-		error = 14;
-		ns_init_card_error(card, error);
-		return error;
-	}
-
-	/* Allocate small buffers */
-	skb_queue_head_init(&card->sbpool.queue);
-	card->sbpool.count = 0;	/* Not used */
-	for (j = 0; j < NUM_SB; j++) {
-		struct sk_buff *sb;
-		sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL);
-		if (sb == NULL) {
-			printk
-			    ("nicstar%d: can't allocate %dth of %d small buffers.\n",
-			     i, j, NUM_SB);
-			error = 15;
-			ns_init_card_error(card, error);
-			return error;
-		}
-		NS_PRV_BUFTYPE(sb) = BUF_SM;
-		skb_queue_tail(&card->sbpool.queue, sb);
-		skb_reserve(sb, NS_AAL0_HEADER);
-		push_rxbufs(card, sb);
-	}
-	/* Test for strange behaviour which leads to crashes */
-	if ((bcount =
-	     ns_stat_sfbqc_get(readl(card->membase + STAT))) < card->sbnr.min) {
-		printk
-		    ("nicstar%d: Strange... Just allocated %d small buffers and sfbqc = %d.\n",
-		     i, j, bcount);
-		error = 15;
-		ns_init_card_error(card, error);
-		return error;
-	}
-
-	/* Allocate iovec buffers */
-	skb_queue_head_init(&card->iovpool.queue);
-	card->iovpool.count = 0;
-	for (j = 0; j < NUM_IOVB; j++) {
-		struct sk_buff *iovb;
-		iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL);
-		if (iovb == NULL) {
-			printk
-			    ("nicstar%d: can't allocate %dth of %d iovec buffers.\n",
-			     i, j, NUM_IOVB);
-			error = 16;
-			ns_init_card_error(card, error);
-			return error;
-		}
-		NS_PRV_BUFTYPE(iovb) = BUF_NONE;
-		skb_queue_tail(&card->iovpool.queue, iovb);
-		card->iovpool.count++;
-	}
-
-	/* Configure NICStAR */
-	if (card->rct_size == 4096)
-		ns_cfg_rctsize = NS_CFG_RCTSIZE_4096_ENTRIES;
-	else			/* (card->rct_size == 16384) */
-		ns_cfg_rctsize = NS_CFG_RCTSIZE_16384_ENTRIES;
-
-	card->efbie = 1;
-
-	/* Register device */
-	card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops,
-					-1, NULL);
-	if (card->atmdev == NULL) {
-		printk("nicstar%d: can't register device.\n", i);
-		error = 17;
-		ns_init_card_error(card, error);
-		return error;
-	}
-
-	if (mac[i] == NULL || !mac_pton(mac[i], card->atmdev->esi)) {
-		nicstar_read_eprom(card->membase, NICSTAR_EPROM_MAC_ADDR_OFFSET,
-				   card->atmdev->esi, 6);
-		if (ether_addr_equal(card->atmdev->esi, "\x00\x00\x00\x00\x00\x00")) {
-			nicstar_read_eprom(card->membase,
-					   NICSTAR_EPROM_MAC_ADDR_OFFSET_ALT,
-					   card->atmdev->esi, 6);
-		}
-	}
-
-	printk("nicstar%d: MAC address %pM\n", i, card->atmdev->esi);
-
-	card->atmdev->dev_data = card;
-	card->atmdev->ci_range.vpi_bits = card->vpibits;
-	card->atmdev->ci_range.vci_bits = card->vcibits;
-	card->atmdev->link_rate = card->max_pcr;
-	card->atmdev->phy = NULL;
-
-#ifdef CONFIG_ATM_NICSTAR_USE_SUNI
-	if (card->max_pcr == ATM_OC3_PCR)
-		suni_init(card->atmdev);
-#endif /* CONFIG_ATM_NICSTAR_USE_SUNI */
-
-#ifdef CONFIG_ATM_NICSTAR_USE_IDT77105
-	if (card->max_pcr == ATM_25_PCR)
-		idt77105_init(card->atmdev);
-#endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */
-
-	if (card->atmdev->phy && card->atmdev->phy->start)
-		card->atmdev->phy->start(card->atmdev);
-
-	writel(NS_CFG_RXPATH | NS_CFG_SMBUFSIZE | NS_CFG_LGBUFSIZE | NS_CFG_EFBIE | NS_CFG_RSQSIZE | NS_CFG_VPIBITS | ns_cfg_rctsize | NS_CFG_RXINT_NODELAY | NS_CFG_RAWIE |	/* Only enabled if RCQ_SUPPORT */
-	       NS_CFG_RSQAFIE | NS_CFG_TXEN | NS_CFG_TXIE | NS_CFG_TSQFIE_OPT |	/* Only enabled if ENABLE_TSQFIE */
-	       NS_CFG_PHYIE, card->membase + CFG);
-
-	num_cards++;
-
-	return error;
-}
-
-static void ns_init_card_error(ns_dev *card, int error)
-{
-	if (error >= 17) {
-		writel(0x00000000, card->membase + CFG);
-	}
-	if (error >= 16) {
-		struct sk_buff *iovb;
-		while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL)
-			dev_kfree_skb_any(iovb);
-	}
-	if (error >= 15) {
-		struct sk_buff *sb;
-		while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL)
-			dev_kfree_skb_any(sb);
-		free_scq(card, card->scq0, NULL);
-	}
-	if (error >= 14) {
-		struct sk_buff *lb;
-		while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL)
-			dev_kfree_skb_any(lb);
-	}
-	if (error >= 13) {
-		struct sk_buff *hb;
-		while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL)
-			dev_kfree_skb_any(hb);
-	}
-	if (error >= 12) {
-		dma_free_coherent(&card->pcidev->dev, NS_RSQSIZE + NS_RSQ_ALIGNMENT,
-				card->rsq.org, card->rsq.dma);
-	}
-	if (error >= 11) {
-		dma_free_coherent(&card->pcidev->dev, NS_TSQSIZE + NS_TSQ_ALIGNMENT,
-				card->tsq.org, card->tsq.dma);
-	}
-	if (error >= 10) {
-		free_irq(card->pcidev->irq, card);
-	}
-	if (error >= 4) {
-		iounmap(card->membase);
-	}
-	if (error >= 3) {
-		pci_disable_device(card->pcidev);
-		kfree(card);
-	}
-}
-
-static scq_info *get_scq(ns_dev *card, int size, u32 scd)
-{
-	scq_info *scq;
-
-	if (size != VBR_SCQSIZE && size != CBR_SCQSIZE)
-		return NULL;
-
-	scq = kmalloc_obj(*scq);
-	if (!scq)
-		return NULL;
-        scq->org = dma_alloc_coherent(&card->pcidev->dev,
-				      2 * size,  &scq->dma, GFP_KERNEL);
-	if (!scq->org) {
-		kfree(scq);
-		return NULL;
-	}
-	scq->skb = kzalloc_objs(*scq->skb, size / NS_SCQE_SIZE);
-	if (!scq->skb) {
-		dma_free_coherent(&card->pcidev->dev,
-				  2 * size, scq->org, scq->dma);
-		kfree(scq);
-		return NULL;
-	}
-	scq->num_entries = size / NS_SCQE_SIZE;
-	scq->base = PTR_ALIGN(scq->org, size);
-	scq->next = scq->base;
-	scq->last = scq->base + (scq->num_entries - 1);
-	scq->tail = scq->last;
-	scq->scd = scd;
-	scq->tbd_count = 0;
-	init_waitqueue_head(&scq->scqfull_waitq);
-	scq->full = 0;
-	spin_lock_init(&scq->lock);
-
-	return scq;
-}
-
-/* For variable rate SCQ vcc must be NULL */
-static void free_scq(ns_dev *card, scq_info *scq, struct atm_vcc *vcc)
-{
-	int i;
-
-	if (scq->num_entries == VBR_SCQ_NUM_ENTRIES)
-		for (i = 0; i < scq->num_entries; i++) {
-			if (scq->skb[i] != NULL) {
-				vcc = ATM_SKB(scq->skb[i])->vcc;
-				if (vcc->pop != NULL)
-					vcc->pop(vcc, scq->skb[i]);
-				else
-					dev_kfree_skb_any(scq->skb[i]);
-			}
-	} else {		/* vcc must be != NULL */
-
-		if (vcc == NULL) {
-			printk
-			    ("nicstar: free_scq() called with vcc == NULL for fixed rate scq.");
-			for (i = 0; i < scq->num_entries; i++)
-				dev_kfree_skb_any(scq->skb[i]);
-		} else
-			for (i = 0; i < scq->num_entries; i++) {
-				if (scq->skb[i] != NULL) {
-					if (vcc->pop != NULL)
-						vcc->pop(vcc, scq->skb[i]);
-					else
-						dev_kfree_skb_any(scq->skb[i]);
-				}
-			}
-	}
-	kfree(scq->skb);
-	dma_free_coherent(&card->pcidev->dev,
-			  2 * (scq->num_entries == VBR_SCQ_NUM_ENTRIES ?
-			       VBR_SCQSIZE : CBR_SCQSIZE),
-			  scq->org, scq->dma);
-	kfree(scq);
-}
-
-/* The handles passed must be pointers to the sk_buff containing the small
-   or large buffer(s) cast to u32. */
-static void push_rxbufs(ns_dev * card, struct sk_buff *skb)
-{
-	struct sk_buff *handle1, *handle2;
-	int id1, id2;
-	u32 addr1, addr2;
-	u32 stat;
-	unsigned long flags;
-
-	/* *BARF* */
-	handle2 = NULL;
-	addr2 = 0;
-	handle1 = skb;
-	addr1 = dma_map_single(&card->pcidev->dev,
-			       skb->data,
-			       (NS_PRV_BUFTYPE(skb) == BUF_SM
-				? NS_SMSKBSIZE : NS_LGSKBSIZE),
-			       DMA_TO_DEVICE);
-	NS_PRV_DMA(skb) = addr1; /* save so we can unmap later */
-
-#ifdef GENERAL_DEBUG
-	if (!addr1)
-		printk("nicstar%d: push_rxbufs called with addr1 = 0.\n",
-		       card->index);
-#endif /* GENERAL_DEBUG */
-
-	stat = readl(card->membase + STAT);
-	card->sbfqc = ns_stat_sfbqc_get(stat);
-	card->lbfqc = ns_stat_lfbqc_get(stat);
-	if (NS_PRV_BUFTYPE(skb) == BUF_SM) {
-		if (!addr2) {
-			if (card->sm_addr) {
-				addr2 = card->sm_addr;
-				handle2 = card->sm_handle;
-				card->sm_addr = 0x00000000;
-				card->sm_handle = NULL;
-			} else {	/* (!sm_addr) */
-
-				card->sm_addr = addr1;
-				card->sm_handle = handle1;
-			}
-		}
-	} else {		/* buf_type == BUF_LG */
-
-		if (!addr2) {
-			if (card->lg_addr) {
-				addr2 = card->lg_addr;
-				handle2 = card->lg_handle;
-				card->lg_addr = 0x00000000;
-				card->lg_handle = NULL;
-			} else {	/* (!lg_addr) */
-
-				card->lg_addr = addr1;
-				card->lg_handle = handle1;
-			}
-		}
-	}
-
-	if (addr2) {
-		if (NS_PRV_BUFTYPE(skb) == BUF_SM) {
-			if (card->sbfqc >= card->sbnr.max) {
-				skb_unlink(handle1, &card->sbpool.queue);
-				dev_kfree_skb_any(handle1);
-				skb_unlink(handle2, &card->sbpool.queue);
-				dev_kfree_skb_any(handle2);
-				return;
-			} else
-				card->sbfqc += 2;
-		} else {	/* (buf_type == BUF_LG) */
-
-			if (card->lbfqc >= card->lbnr.max) {
-				skb_unlink(handle1, &card->lbpool.queue);
-				dev_kfree_skb_any(handle1);
-				skb_unlink(handle2, &card->lbpool.queue);
-				dev_kfree_skb_any(handle2);
-				return;
-			} else
-				card->lbfqc += 2;
-		}
-
-		id1 = idr_alloc(&card->idr, handle1, 0, 0, GFP_ATOMIC);
-		if (id1 < 0)
-			goto out;
-
-		id2 = idr_alloc(&card->idr, handle2, 0, 0, GFP_ATOMIC);
-		if (id2 < 0)
-			goto out;
-
-		spin_lock_irqsave(&card->res_lock, flags);
-		while (CMD_BUSY(card)) ;
-		writel(addr2, card->membase + DR3);
-		writel(id2, card->membase + DR2);
-		writel(addr1, card->membase + DR1);
-		writel(id1, card->membase + DR0);
-		writel(NS_CMD_WRITE_FREEBUFQ | NS_PRV_BUFTYPE(skb),
-		       card->membase + CMD);
-		spin_unlock_irqrestore(&card->res_lock, flags);
-
-		XPRINTK("nicstar%d: Pushing %s buffers at 0x%x and 0x%x.\n",
-			card->index,
-			(NS_PRV_BUFTYPE(skb) == BUF_SM ? "small" : "large"),
-			addr1, addr2);
-	}
-
-	if (!card->efbie && card->sbfqc >= card->sbnr.min &&
-	    card->lbfqc >= card->lbnr.min) {
-		card->efbie = 1;
-		writel((readl(card->membase + CFG) | NS_CFG_EFBIE),
-		       card->membase + CFG);
-	}
-
-out:
-	return;
-}
-
-static irqreturn_t ns_irq_handler(int irq, void *dev_id)
-{
-	u32 stat_r;
-	ns_dev *card;
-	struct atm_dev *dev;
-	unsigned long flags;
-
-	card = (ns_dev *) dev_id;
-	dev = card->atmdev;
-	card->intcnt++;
-
-	PRINTK("nicstar%d: NICStAR generated an interrupt\n", card->index);
-
-	spin_lock_irqsave(&card->int_lock, flags);
-
-	stat_r = readl(card->membase + STAT);
-
-	/* Transmit Status Indicator has been written to T. S. Queue */
-	if (stat_r & NS_STAT_TSIF) {
-		TXPRINTK("nicstar%d: TSI interrupt\n", card->index);
-		process_tsq(card);
-		writel(NS_STAT_TSIF, card->membase + STAT);
-	}
-
-	/* Incomplete CS-PDU has been transmitted */
-	if (stat_r & NS_STAT_TXICP) {
-		writel(NS_STAT_TXICP, card->membase + STAT);
-		TXPRINTK("nicstar%d: Incomplete CS-PDU transmitted.\n",
-			 card->index);
-	}
-
-	/* Transmit Status Queue 7/8 full */
-	if (stat_r & NS_STAT_TSQF) {
-		writel(NS_STAT_TSQF, card->membase + STAT);
-		PRINTK("nicstar%d: TSQ full.\n", card->index);
-		process_tsq(card);
-	}
-
-	/* Timer overflow */
-	if (stat_r & NS_STAT_TMROF) {
-		writel(NS_STAT_TMROF, card->membase + STAT);
-		PRINTK("nicstar%d: Timer overflow.\n", card->index);
-	}
-
-	/* PHY device interrupt signal active */
-	if (stat_r & NS_STAT_PHYI) {
-		writel(NS_STAT_PHYI, card->membase + STAT);
-		PRINTK("nicstar%d: PHY interrupt.\n", card->index);
-		if (dev->phy && dev->phy->interrupt) {
-			dev->phy->interrupt(dev);
-		}
-	}
-
-	/* Small Buffer Queue is full */
-	if (stat_r & NS_STAT_SFBQF) {
-		writel(NS_STAT_SFBQF, card->membase + STAT);
-		printk("nicstar%d: Small free buffer queue is full.\n",
-		       card->index);
-	}
-
-	/* Large Buffer Queue is full */
-	if (stat_r & NS_STAT_LFBQF) {
-		writel(NS_STAT_LFBQF, card->membase + STAT);
-		printk("nicstar%d: Large free buffer queue is full.\n",
-		       card->index);
-	}
-
-	/* Receive Status Queue is full */
-	if (stat_r & NS_STAT_RSQF) {
-		writel(NS_STAT_RSQF, card->membase + STAT);
-		printk("nicstar%d: RSQ full.\n", card->index);
-		process_rsq(card);
-	}
-
-	/* Complete CS-PDU received */
-	if (stat_r & NS_STAT_EOPDU) {
-		RXPRINTK("nicstar%d: End of CS-PDU received.\n", card->index);
-		process_rsq(card);
-		writel(NS_STAT_EOPDU, card->membase + STAT);
-	}
-
-	/* Raw cell received */
-	if (stat_r & NS_STAT_RAWCF) {
-		writel(NS_STAT_RAWCF, card->membase + STAT);
-#ifndef RCQ_SUPPORT
-		printk("nicstar%d: Raw cell received and no support yet...\n",
-		       card->index);
-#endif /* RCQ_SUPPORT */
-		/* NOTE: the following procedure may keep a raw cell pending until the
-		   next interrupt. As this preliminary support is only meant to
-		   avoid buffer leakage, this is not an issue. */
-		while (readl(card->membase + RAWCT) != card->rawch) {
-
-			if (ns_rcqe_islast(card->rawcell)) {
-				struct sk_buff *oldbuf;
-
-				oldbuf = card->rcbuf;
-				card->rcbuf = idr_find(&card->idr,
-						       ns_rcqe_nextbufhandle(card->rawcell));
-				card->rawch = NS_PRV_DMA(card->rcbuf);
-				card->rawcell = (struct ns_rcqe *)
-						card->rcbuf->data;
-				recycle_rx_buf(card, oldbuf);
-			} else {
-				card->rawch += NS_RCQE_SIZE;
-				card->rawcell++;
-			}
-		}
-	}
-
-	/* Small buffer queue is empty */
-	if (stat_r & NS_STAT_SFBQE) {
-		int i;
-		struct sk_buff *sb;
-
-		writel(NS_STAT_SFBQE, card->membase + STAT);
-		printk("nicstar%d: Small free buffer queue empty.\n",
-		       card->index);
-		for (i = 0; i < card->sbnr.min; i++) {
-			sb = dev_alloc_skb(NS_SMSKBSIZE);
-			if (sb == NULL) {
-				writel(readl(card->membase + CFG) &
-				       ~NS_CFG_EFBIE, card->membase + CFG);
-				card->efbie = 0;
-				break;
-			}
-			NS_PRV_BUFTYPE(sb) = BUF_SM;
-			skb_queue_tail(&card->sbpool.queue, sb);
-			skb_reserve(sb, NS_AAL0_HEADER);
-			push_rxbufs(card, sb);
-		}
-		card->sbfqc = i;
-		process_rsq(card);
-	}
-
-	/* Large buffer queue empty */
-	if (stat_r & NS_STAT_LFBQE) {
-		int i;
-		struct sk_buff *lb;
-
-		writel(NS_STAT_LFBQE, card->membase + STAT);
-		printk("nicstar%d: Large free buffer queue empty.\n",
-		       card->index);
-		for (i = 0; i < card->lbnr.min; i++) {
-			lb = dev_alloc_skb(NS_LGSKBSIZE);
-			if (lb == NULL) {
-				writel(readl(card->membase + CFG) &
-				       ~NS_CFG_EFBIE, card->membase + CFG);
-				card->efbie = 0;
-				break;
-			}
-			NS_PRV_BUFTYPE(lb) = BUF_LG;
-			skb_queue_tail(&card->lbpool.queue, lb);
-			skb_reserve(lb, NS_SMBUFSIZE);
-			push_rxbufs(card, lb);
-		}
-		card->lbfqc = i;
-		process_rsq(card);
-	}
-
-	/* Receive Status Queue is 7/8 full */
-	if (stat_r & NS_STAT_RSQAF) {
-		writel(NS_STAT_RSQAF, card->membase + STAT);
-		RXPRINTK("nicstar%d: RSQ almost full.\n", card->index);
-		process_rsq(card);
-	}
-
-	spin_unlock_irqrestore(&card->int_lock, flags);
-	PRINTK("nicstar%d: end of interrupt service\n", card->index);
-	return IRQ_HANDLED;
-}
-
-static int ns_open(struct atm_vcc *vcc)
-{
-	ns_dev *card;
-	vc_map *vc;
-	unsigned long tmpl, modl;
-	int tcr, tcra;		/* target cell rate, and absolute value */
-	int n = 0;		/* Number of entries in the TST. Initialized to remove
-				   the compiler warning. */
-	u32 u32d[4];
-	int frscdi = 0;		/* Index of the SCD. Initialized to remove the compiler
-				   warning. How I wish compilers were clever enough to
-				   tell which variables can truly be used
-				   uninitialized... */
-	int inuse;		/* tx or rx vc already in use by another vcc */
-	short vpi = vcc->vpi;
-	int vci = vcc->vci;
-
-	card = (ns_dev *) vcc->dev->dev_data;
-	PRINTK("nicstar%d: opening vpi.vci %d.%d \n", card->index, (int)vpi,
-	       vci);
-	if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0) {
-		PRINTK("nicstar%d: unsupported AAL.\n", card->index);
-		return -EINVAL;
-	}
-
-	vc = &(card->vcmap[vpi << card->vcibits | vci]);
-	vcc->dev_data = vc;
-
-	inuse = 0;
-	if (vcc->qos.txtp.traffic_class != ATM_NONE && vc->tx)
-		inuse = 1;
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE && vc->rx)
-		inuse += 2;
-	if (inuse) {
-		printk("nicstar%d: %s vci already in use.\n", card->index,
-		       inuse == 1 ? "tx" : inuse == 2 ? "rx" : "tx and rx");
-		return -EINVAL;
-	}
-
-	set_bit(ATM_VF_ADDR, &vcc->flags);
-
-	/* NOTE: You are not allowed to modify an open connection's QOS. To change
-	   that, remove the ATM_VF_PARTIAL flag checking. There may be other changes
-	   needed to do that. */
-	if (!test_bit(ATM_VF_PARTIAL, &vcc->flags)) {
-		scq_info *scq;
-
-		set_bit(ATM_VF_PARTIAL, &vcc->flags);
-		if (vcc->qos.txtp.traffic_class == ATM_CBR) {
-			/* Check requested cell rate and availability of SCD */
-			if (vcc->qos.txtp.max_pcr == 0 && vcc->qos.txtp.pcr == 0
-			    && vcc->qos.txtp.min_pcr == 0) {
-				PRINTK
-				    ("nicstar%d: trying to open a CBR vc with cell rate = 0 \n",
-				     card->index);
-				clear_bit(ATM_VF_PARTIAL, &vcc->flags);
-				clear_bit(ATM_VF_ADDR, &vcc->flags);
-				return -EINVAL;
-			}
-
-			tcr = atm_pcr_goal(&(vcc->qos.txtp));
-			tcra = tcr >= 0 ? tcr : -tcr;
-
-			PRINTK("nicstar%d: target cell rate = %d.\n",
-			       card->index, vcc->qos.txtp.max_pcr);
-
-			tmpl =
-			    (unsigned long)tcra *(unsigned long)
-			    NS_TST_NUM_ENTRIES;
-			modl = tmpl % card->max_pcr;
-
-			n = (int)(tmpl / card->max_pcr);
-			if (tcr > 0) {
-				if (modl > 0)
-					n++;
-			} else if (tcr == 0) {
-				if ((n =
-				     (card->tst_free_entries -
-				      NS_TST_RESERVED)) <= 0) {
-					PRINTK
-					    ("nicstar%d: no CBR bandwidth free.\n",
-					     card->index);
-					clear_bit(ATM_VF_PARTIAL, &vcc->flags);
-					clear_bit(ATM_VF_ADDR, &vcc->flags);
-					return -EINVAL;
-				}
-			}
-
-			if (n == 0) {
-				printk
-				    ("nicstar%d: selected bandwidth < granularity.\n",
-				     card->index);
-				clear_bit(ATM_VF_PARTIAL, &vcc->flags);
-				clear_bit(ATM_VF_ADDR, &vcc->flags);
-				return -EINVAL;
-			}
-
-			if (n > (card->tst_free_entries - NS_TST_RESERVED)) {
-				PRINTK
-				    ("nicstar%d: not enough free CBR bandwidth.\n",
-				     card->index);
-				clear_bit(ATM_VF_PARTIAL, &vcc->flags);
-				clear_bit(ATM_VF_ADDR, &vcc->flags);
-				return -EINVAL;
-			} else
-				card->tst_free_entries -= n;
-
-			XPRINTK("nicstar%d: writing %d tst entries.\n",
-				card->index, n);
-			for (frscdi = 0; frscdi < NS_FRSCD_NUM; frscdi++) {
-				if (card->scd2vc[frscdi] == NULL) {
-					card->scd2vc[frscdi] = vc;
-					break;
-				}
-			}
-			if (frscdi == NS_FRSCD_NUM) {
-				PRINTK
-				    ("nicstar%d: no SCD available for CBR channel.\n",
-				     card->index);
-				card->tst_free_entries += n;
-				clear_bit(ATM_VF_PARTIAL, &vcc->flags);
-				clear_bit(ATM_VF_ADDR, &vcc->flags);
-				return -EBUSY;
-			}
-
-			vc->cbr_scd = NS_FRSCD + frscdi * NS_FRSCD_SIZE;
-
-			scq = get_scq(card, CBR_SCQSIZE, vc->cbr_scd);
-			if (scq == NULL) {
-				PRINTK("nicstar%d: can't get fixed rate SCQ.\n",
-				       card->index);
-				card->scd2vc[frscdi] = NULL;
-				card->tst_free_entries += n;
-				clear_bit(ATM_VF_PARTIAL, &vcc->flags);
-				clear_bit(ATM_VF_ADDR, &vcc->flags);
-				return -ENOMEM;
-			}
-			vc->scq = scq;
-			u32d[0] = scq_virt_to_bus(scq, scq->base);
-			u32d[1] = (u32) 0x00000000;
-			u32d[2] = (u32) 0xffffffff;
-			u32d[3] = (u32) 0x00000000;
-			ns_write_sram(card, vc->cbr_scd, u32d, 4);
-
-			fill_tst(card, n, vc);
-		} else if (vcc->qos.txtp.traffic_class == ATM_UBR) {
-			vc->cbr_scd = 0x00000000;
-			vc->scq = card->scq0;
-		}
-
-		if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-			vc->tx = 1;
-			vc->tx_vcc = vcc;
-			vc->tbd_count = 0;
-		}
-		if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
-			u32 status;
-
-			vc->rx = 1;
-			vc->rx_vcc = vcc;
-			vc->rx_iov = NULL;
-
-			/* Open the connection in hardware */
-			if (vcc->qos.aal == ATM_AAL5)
-				status = NS_RCTE_AAL5 | NS_RCTE_CONNECTOPEN;
-			else	/* vcc->qos.aal == ATM_AAL0 */
-				status = NS_RCTE_AAL0 | NS_RCTE_CONNECTOPEN;
-#ifdef RCQ_SUPPORT
-			status |= NS_RCTE_RAWCELLINTEN;
-#endif /* RCQ_SUPPORT */
-			ns_write_sram(card,
-				      NS_RCT +
-				      (vpi << card->vcibits | vci) *
-				      NS_RCT_ENTRY_SIZE, &status, 1);
-		}
-
-	}
-
-	set_bit(ATM_VF_READY, &vcc->flags);
-	return 0;
-}
-
-static void ns_close(struct atm_vcc *vcc)
-{
-	vc_map *vc;
-	ns_dev *card;
-	u32 data;
-	int i;
-
-	vc = vcc->dev_data;
-	card = vcc->dev->dev_data;
-	PRINTK("nicstar%d: closing vpi.vci %d.%d \n", card->index,
-	       (int)vcc->vpi, vcc->vci);
-
-	clear_bit(ATM_VF_READY, &vcc->flags);
-
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
-		u32 addr;
-		unsigned long flags;
-
-		addr =
-		    NS_RCT +
-		    (vcc->vpi << card->vcibits | vcc->vci) * NS_RCT_ENTRY_SIZE;
-		spin_lock_irqsave(&card->res_lock, flags);
-		while (CMD_BUSY(card)) ;
-		writel(NS_CMD_CLOSE_CONNECTION | addr << 2,
-		       card->membase + CMD);
-		spin_unlock_irqrestore(&card->res_lock, flags);
-
-		vc->rx = 0;
-		if (vc->rx_iov != NULL) {
-			struct sk_buff *iovb;
-			u32 stat;
-
-			stat = readl(card->membase + STAT);
-			card->sbfqc = ns_stat_sfbqc_get(stat);
-			card->lbfqc = ns_stat_lfbqc_get(stat);
-
-			PRINTK
-			    ("nicstar%d: closing a VC with pending rx buffers.\n",
-			     card->index);
-			iovb = vc->rx_iov;
-			recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
-					      NS_PRV_IOVCNT(iovb));
-			NS_PRV_IOVCNT(iovb) = 0;
-			spin_lock_irqsave(&card->int_lock, flags);
-			recycle_iov_buf(card, iovb);
-			spin_unlock_irqrestore(&card->int_lock, flags);
-			vc->rx_iov = NULL;
-		}
-	}
-
-	if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-		vc->tx = 0;
-	}
-
-	if (vcc->qos.txtp.traffic_class == ATM_CBR) {
-		unsigned long flags;
-		ns_scqe *scqep;
-		scq_info *scq;
-
-		scq = vc->scq;
-
-		for (;;) {
-			spin_lock_irqsave(&scq->lock, flags);
-			scqep = scq->next;
-			if (scqep == scq->base)
-				scqep = scq->last;
-			else
-				scqep--;
-			if (scqep == scq->tail) {
-				spin_unlock_irqrestore(&scq->lock, flags);
-				break;
-			}
-			/* If the last entry is not a TSR, place one in the SCQ in order to
-			   be able to completely drain it and then close. */
-			if (!ns_scqe_is_tsr(scqep) && scq->tail != scq->next) {
-				ns_scqe tsr;
-				u32 scdi, scqi;
-				u32 data;
-				int index;
-
-				tsr.word_1 = ns_tsr_mkword_1(NS_TSR_INTENABLE);
-				scdi = (vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE;
-				scqi = scq->next - scq->base;
-				tsr.word_2 = ns_tsr_mkword_2(scdi, scqi);
-				tsr.word_3 = 0x00000000;
-				tsr.word_4 = 0x00000000;
-				*scq->next = tsr;
-				index = (int)scqi;
-				scq->skb[index] = NULL;
-				if (scq->next == scq->last)
-					scq->next = scq->base;
-				else
-					scq->next++;
-				data = scq_virt_to_bus(scq, scq->next);
-				ns_write_sram(card, scq->scd, &data, 1);
-			}
-			spin_unlock_irqrestore(&scq->lock, flags);
-			schedule();
-		}
-
-		/* Free all TST entries */
-		data = NS_TST_OPCODE_VARIABLE;
-		for (i = 0; i < NS_TST_NUM_ENTRIES; i++) {
-			if (card->tste2vc[i] == vc) {
-				ns_write_sram(card, card->tst_addr + i, &data,
-					      1);
-				card->tste2vc[i] = NULL;
-				card->tst_free_entries++;
-			}
-		}
-
-		card->scd2vc[(vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE] = NULL;
-		free_scq(card, vc->scq, vcc);
-	}
-
-	/* remove all references to vcc before deleting it */
-	if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-		unsigned long flags;
-		scq_info *scq = card->scq0;
-
-		spin_lock_irqsave(&scq->lock, flags);
-
-		for (i = 0; i < scq->num_entries; i++) {
-			if (scq->skb[i] && ATM_SKB(scq->skb[i])->vcc == vcc) {
-				ATM_SKB(scq->skb[i])->vcc = NULL;
-				atm_return(vcc, scq->skb[i]->truesize);
-				PRINTK
-				    ("nicstar: deleted pending vcc mapping\n");
-			}
-		}
-
-		spin_unlock_irqrestore(&scq->lock, flags);
-	}
-
-	vcc->dev_data = NULL;
-	clear_bit(ATM_VF_PARTIAL, &vcc->flags);
-	clear_bit(ATM_VF_ADDR, &vcc->flags);
-
-#ifdef RX_DEBUG
-	{
-		u32 stat, cfg;
-		stat = readl(card->membase + STAT);
-		cfg = readl(card->membase + CFG);
-		printk("STAT = 0x%08X  CFG = 0x%08X  \n", stat, cfg);
-		printk
-		    ("TSQ: base = 0x%p  next = 0x%p  last = 0x%p  TSQT = 0x%08X \n",
-		     card->tsq.base, card->tsq.next,
-		     card->tsq.last, readl(card->membase + TSQT));
-		printk
-		    ("RSQ: base = 0x%p  next = 0x%p  last = 0x%p  RSQT = 0x%08X \n",
-		     card->rsq.base, card->rsq.next,
-		     card->rsq.last, readl(card->membase + RSQT));
-		printk("Empty free buffer queue interrupt %s \n",
-		       card->efbie ? "enabled" : "disabled");
-		printk("SBCNT = %d  count = %d   LBCNT = %d count = %d \n",
-		       ns_stat_sfbqc_get(stat), card->sbpool.count,
-		       ns_stat_lfbqc_get(stat), card->lbpool.count);
-		printk("hbpool.count = %d  iovpool.count = %d \n",
-		       card->hbpool.count, card->iovpool.count);
-	}
-#endif /* RX_DEBUG */
-}
-
-static void fill_tst(ns_dev * card, int n, vc_map * vc)
-{
-	u32 new_tst;
-	unsigned long cl;
-	int e, r;
-	u32 data;
-
-	/* It would be very complicated to keep the two TSTs synchronized while
-	   assuring that writes are only made to the inactive TST. So, for now I
-	   will use only one TST. If problems occur, I will change this again */
-
-	new_tst = card->tst_addr;
-
-	/* Fill procedure */
-
-	for (e = 0; e < NS_TST_NUM_ENTRIES; e++) {
-		if (card->tste2vc[e] == NULL)
-			break;
-	}
-	if (e == NS_TST_NUM_ENTRIES) {
-		printk("nicstar%d: No free TST entries found. \n", card->index);
-		return;
-	}
-
-	r = n;
-	cl = NS_TST_NUM_ENTRIES;
-	data = ns_tste_make(NS_TST_OPCODE_FIXED, vc->cbr_scd);
-
-	while (r > 0) {
-		if (cl >= NS_TST_NUM_ENTRIES && card->tste2vc[e] == NULL) {
-			card->tste2vc[e] = vc;
-			ns_write_sram(card, new_tst + e, &data, 1);
-			cl -= NS_TST_NUM_ENTRIES;
-			r--;
-		}
-
-		if (++e == NS_TST_NUM_ENTRIES) {
-			e = 0;
-		}
-		cl += n;
-	}
-
-	/* End of fill procedure */
-
-	data = ns_tste_make(NS_TST_OPCODE_END, new_tst);
-	ns_write_sram(card, new_tst + NS_TST_NUM_ENTRIES, &data, 1);
-	ns_write_sram(card, card->tst_addr + NS_TST_NUM_ENTRIES, &data, 1);
-	card->tst_addr = new_tst;
-}
-
-static int _ns_send(struct atm_vcc *vcc, struct sk_buff *skb, bool may_sleep)
-{
-	ns_dev *card;
-	vc_map *vc;
-	scq_info *scq;
-	unsigned long buflen;
-	ns_scqe scqe;
-	u32 flags;		/* TBD flags, not CPU flags */
-
-	card = vcc->dev->dev_data;
-	TXPRINTK("nicstar%d: ns_send() called.\n", card->index);
-	if ((vc = (vc_map *) vcc->dev_data) == NULL) {
-		printk("nicstar%d: vcc->dev_data == NULL on ns_send().\n",
-		       card->index);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb_any(skb);
-		return -EINVAL;
-	}
-
-	if (!vc->tx) {
-		printk("nicstar%d: Trying to transmit on a non-tx VC.\n",
-		       card->index);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb_any(skb);
-		return -EINVAL;
-	}
-
-	if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0) {
-		printk("nicstar%d: Only AAL0 and AAL5 are supported.\n",
-		       card->index);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb_any(skb);
-		return -EINVAL;
-	}
-
-	if (skb_shinfo(skb)->nr_frags != 0) {
-		printk("nicstar%d: No scatter-gather yet.\n", card->index);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb_any(skb);
-		return -EINVAL;
-	}
-
-	ATM_SKB(skb)->vcc = vcc;
-
-	NS_PRV_DMA(skb) = dma_map_single(&card->pcidev->dev, skb->data,
-					 skb->len, DMA_TO_DEVICE);
-
-	if (vcc->qos.aal == ATM_AAL5) {
-		buflen = (skb->len + 47 + 8) / 48 * 48;	/* Multiple of 48 */
-		flags = NS_TBD_AAL5;
-		scqe.word_2 = cpu_to_le32(NS_PRV_DMA(skb));
-		scqe.word_3 = cpu_to_le32(skb->len);
-		scqe.word_4 =
-		    ns_tbd_mkword_4(0, (u32) vcc->vpi, (u32) vcc->vci, 0,
-				    ATM_SKB(skb)->
-				    atm_options & ATM_ATMOPT_CLP ? 1 : 0);
-		flags |= NS_TBD_EOPDU;
-	} else {		/* (vcc->qos.aal == ATM_AAL0) */
-
-		buflen = ATM_CELL_PAYLOAD;	/* i.e., 48 bytes */
-		flags = NS_TBD_AAL0;
-		scqe.word_2 = cpu_to_le32(NS_PRV_DMA(skb) + NS_AAL0_HEADER);
-		scqe.word_3 = cpu_to_le32(0x00000000);
-		if (*skb->data & 0x02)	/* Payload type 1 - end of pdu */
-			flags |= NS_TBD_EOPDU;
-		scqe.word_4 =
-		    cpu_to_le32(*((u32 *) skb->data) & ~NS_TBD_VC_MASK);
-		/* Force the VPI/VCI to be the same as in VCC struct */
-		scqe.word_4 |=
-		    cpu_to_le32((((u32) vcc->
-				  vpi) << NS_TBD_VPI_SHIFT | ((u32) vcc->
-							      vci) <<
-				 NS_TBD_VCI_SHIFT) & NS_TBD_VC_MASK);
-	}
-
-	if (vcc->qos.txtp.traffic_class == ATM_CBR) {
-		scqe.word_1 = ns_tbd_mkword_1_novbr(flags, (u32) buflen);
-		scq = ((vc_map *) vcc->dev_data)->scq;
-	} else {
-		scqe.word_1 =
-		    ns_tbd_mkword_1(flags, (u32) 1, (u32) 1, (u32) buflen);
-		scq = card->scq0;
-	}
-
-	if (push_scqe(card, vc, scq, &scqe, skb, may_sleep) != 0) {
-		atomic_inc(&vcc->stats->tx_err);
-		dma_unmap_single(&card->pcidev->dev, NS_PRV_DMA(skb), skb->len,
-				 DMA_TO_DEVICE);
-		dev_kfree_skb_any(skb);
-		return -EIO;
-	}
-	atomic_inc(&vcc->stats->tx);
-
-	return 0;
-}
-
-static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	return _ns_send(vcc, skb, true);
-}
-
-static int ns_send_bh(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	return _ns_send(vcc, skb, false);
-}
-
-static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd,
-		     struct sk_buff *skb, bool may_sleep)
-{
-	unsigned long flags;
-	ns_scqe tsr;
-	u32 scdi, scqi;
-	int scq_is_vbr;
-	u32 data;
-	int index;
-
-	spin_lock_irqsave(&scq->lock, flags);
-	while (scq->tail == scq->next) {
-		if (!may_sleep) {
-			spin_unlock_irqrestore(&scq->lock, flags);
-			printk("nicstar%d: Error pushing TBD.\n", card->index);
-			return 1;
-		}
-
-		scq->full = 1;
-		wait_event_interruptible_lock_irq_timeout(scq->scqfull_waitq,
-							  scq->tail != scq->next,
-							  scq->lock,
-							  SCQFULL_TIMEOUT);
-
-		if (scq->full) {
-			spin_unlock_irqrestore(&scq->lock, flags);
-			printk("nicstar%d: Timeout pushing TBD.\n",
-			       card->index);
-			return 1;
-		}
-	}
-	*scq->next = *tbd;
-	index = (int)(scq->next - scq->base);
-	scq->skb[index] = skb;
-	XPRINTK("nicstar%d: sending skb at 0x%p (pos %d).\n",
-		card->index, skb, index);
-	XPRINTK("nicstar%d: TBD written:\n0x%x\n0x%x\n0x%x\n0x%x\n at 0x%p.\n",
-		card->index, le32_to_cpu(tbd->word_1), le32_to_cpu(tbd->word_2),
-		le32_to_cpu(tbd->word_3), le32_to_cpu(tbd->word_4),
-		scq->next);
-	if (scq->next == scq->last)
-		scq->next = scq->base;
-	else
-		scq->next++;
-
-	vc->tbd_count++;
-	if (scq->num_entries == VBR_SCQ_NUM_ENTRIES) {
-		scq->tbd_count++;
-		scq_is_vbr = 1;
-	} else
-		scq_is_vbr = 0;
-
-	if (vc->tbd_count >= MAX_TBD_PER_VC
-	    || scq->tbd_count >= MAX_TBD_PER_SCQ) {
-		int has_run = 0;
-
-		while (scq->tail == scq->next) {
-			if (!may_sleep) {
-				data = scq_virt_to_bus(scq, scq->next);
-				ns_write_sram(card, scq->scd, &data, 1);
-				spin_unlock_irqrestore(&scq->lock, flags);
-				printk("nicstar%d: Error pushing TSR.\n",
-				       card->index);
-				return 0;
-			}
-
-			scq->full = 1;
-			if (has_run++)
-				break;
-			wait_event_interruptible_lock_irq_timeout(scq->scqfull_waitq,
-								  scq->tail != scq->next,
-								  scq->lock,
-								  SCQFULL_TIMEOUT);
-		}
-
-		if (!scq->full) {
-			tsr.word_1 = ns_tsr_mkword_1(NS_TSR_INTENABLE);
-			if (scq_is_vbr)
-				scdi = NS_TSR_SCDISVBR;
-			else
-				scdi = (vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE;
-			scqi = scq->next - scq->base;
-			tsr.word_2 = ns_tsr_mkword_2(scdi, scqi);
-			tsr.word_3 = 0x00000000;
-			tsr.word_4 = 0x00000000;
-
-			*scq->next = tsr;
-			index = (int)scqi;
-			scq->skb[index] = NULL;
-			XPRINTK
-			    ("nicstar%d: TSR written:\n0x%x\n0x%x\n0x%x\n0x%x\n at 0x%p.\n",
-			     card->index, le32_to_cpu(tsr.word_1),
-			     le32_to_cpu(tsr.word_2), le32_to_cpu(tsr.word_3),
-			     le32_to_cpu(tsr.word_4), scq->next);
-			if (scq->next == scq->last)
-				scq->next = scq->base;
-			else
-				scq->next++;
-			vc->tbd_count = 0;
-			scq->tbd_count = 0;
-		} else
-			PRINTK("nicstar%d: Timeout pushing TSR.\n",
-			       card->index);
-	}
-	data = scq_virt_to_bus(scq, scq->next);
-	ns_write_sram(card, scq->scd, &data, 1);
-
-	spin_unlock_irqrestore(&scq->lock, flags);
-
-	return 0;
-}
-
-static void process_tsq(ns_dev * card)
-{
-	u32 scdi;
-	scq_info *scq;
-	ns_tsi *previous = NULL, *one_ahead, *two_ahead;
-	int serviced_entries;	/* flag indicating at least on entry was serviced */
-
-	serviced_entries = 0;
-
-	if (card->tsq.next == card->tsq.last)
-		one_ahead = card->tsq.base;
-	else
-		one_ahead = card->tsq.next + 1;
-
-	if (one_ahead == card->tsq.last)
-		two_ahead = card->tsq.base;
-	else
-		two_ahead = one_ahead + 1;
-
-	while (!ns_tsi_isempty(card->tsq.next) || !ns_tsi_isempty(one_ahead) ||
-	       !ns_tsi_isempty(two_ahead))
-		/* At most two empty, as stated in the 77201 errata */
-	{
-		serviced_entries = 1;
-
-		/* Skip the one or two possible empty entries */
-		while (ns_tsi_isempty(card->tsq.next)) {
-			if (card->tsq.next == card->tsq.last)
-				card->tsq.next = card->tsq.base;
-			else
-				card->tsq.next++;
-		}
-
-		if (!ns_tsi_tmrof(card->tsq.next)) {
-			scdi = ns_tsi_getscdindex(card->tsq.next);
-			if (scdi == NS_TSI_SCDISVBR)
-				scq = card->scq0;
-			else {
-				if (card->scd2vc[scdi] == NULL) {
-					printk
-					    ("nicstar%d: could not find VC from SCD index.\n",
-					     card->index);
-					ns_tsi_init(card->tsq.next);
-					return;
-				}
-				scq = card->scd2vc[scdi]->scq;
-			}
-			drain_scq(card, scq, ns_tsi_getscqpos(card->tsq.next));
-			scq->full = 0;
-			wake_up_interruptible(&(scq->scqfull_waitq));
-		}
-
-		ns_tsi_init(card->tsq.next);
-		previous = card->tsq.next;
-		if (card->tsq.next == card->tsq.last)
-			card->tsq.next = card->tsq.base;
-		else
-			card->tsq.next++;
-
-		if (card->tsq.next == card->tsq.last)
-			one_ahead = card->tsq.base;
-		else
-			one_ahead = card->tsq.next + 1;
-
-		if (one_ahead == card->tsq.last)
-			two_ahead = card->tsq.base;
-		else
-			two_ahead = one_ahead + 1;
-	}
-
-	if (serviced_entries)
-		writel(PTR_DIFF(previous, card->tsq.base),
-		       card->membase + TSQH);
-}
-
-static void drain_scq(ns_dev * card, scq_info * scq, int pos)
-{
-	struct atm_vcc *vcc;
-	struct sk_buff *skb;
-	int i;
-	unsigned long flags;
-
-	XPRINTK("nicstar%d: drain_scq() called, scq at 0x%p, pos %d.\n",
-		card->index, scq, pos);
-	if (pos >= scq->num_entries) {
-		printk("nicstar%d: Bad index on drain_scq().\n", card->index);
-		return;
-	}
-
-	spin_lock_irqsave(&scq->lock, flags);
-	i = (int)(scq->tail - scq->base);
-	if (++i == scq->num_entries)
-		i = 0;
-	while (i != pos) {
-		skb = scq->skb[i];
-		XPRINTK("nicstar%d: freeing skb at 0x%p (index %d).\n",
-			card->index, skb, i);
-		if (skb != NULL) {
-			dma_unmap_single(&card->pcidev->dev,
-					 NS_PRV_DMA(skb),
-					 skb->len,
-					 DMA_TO_DEVICE);
-			vcc = ATM_SKB(skb)->vcc;
-			if (vcc && vcc->pop != NULL) {
-				vcc->pop(vcc, skb);
-			} else {
-				dev_kfree_skb_irq(skb);
-			}
-			scq->skb[i] = NULL;
-		}
-		if (++i == scq->num_entries)
-			i = 0;
-	}
-	scq->tail = scq->base + pos;
-	spin_unlock_irqrestore(&scq->lock, flags);
-}
-
-static void process_rsq(ns_dev * card)
-{
-	ns_rsqe *previous;
-
-	if (!ns_rsqe_valid(card->rsq.next))
-		return;
-	do {
-		dequeue_rx(card, card->rsq.next);
-		ns_rsqe_init(card->rsq.next);
-		previous = card->rsq.next;
-		if (card->rsq.next == card->rsq.last)
-			card->rsq.next = card->rsq.base;
-		else
-			card->rsq.next++;
-	} while (ns_rsqe_valid(card->rsq.next));
-	writel(PTR_DIFF(previous, card->rsq.base), card->membase + RSQH);
-}
-
-static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe)
-{
-	u32 vpi, vci;
-	vc_map *vc;
-	struct sk_buff *iovb;
-	struct iovec *iov;
-	struct atm_vcc *vcc;
-	struct sk_buff *skb;
-	unsigned short aal5_len;
-	int len;
-	u32 stat;
-	u32 id;
-
-	stat = readl(card->membase + STAT);
-	card->sbfqc = ns_stat_sfbqc_get(stat);
-	card->lbfqc = ns_stat_lfbqc_get(stat);
-
-	id = le32_to_cpu(rsqe->buffer_handle);
-	skb = idr_remove(&card->idr, id);
-	if (!skb) {
-		RXPRINTK(KERN_ERR
-			 "nicstar%d: skb not found!\n", card->index);
-		return;
-	}
-	dma_sync_single_for_cpu(&card->pcidev->dev,
-				NS_PRV_DMA(skb),
-				(NS_PRV_BUFTYPE(skb) == BUF_SM
-				 ? NS_SMSKBSIZE : NS_LGSKBSIZE),
-				DMA_FROM_DEVICE);
-	dma_unmap_single(&card->pcidev->dev,
-			 NS_PRV_DMA(skb),
-			 (NS_PRV_BUFTYPE(skb) == BUF_SM
-			  ? NS_SMSKBSIZE : NS_LGSKBSIZE),
-			 DMA_FROM_DEVICE);
-	vpi = ns_rsqe_vpi(rsqe);
-	vci = ns_rsqe_vci(rsqe);
-	if (vpi >= 1UL << card->vpibits || vci >= 1UL << card->vcibits) {
-		printk("nicstar%d: SDU received for out-of-range vc %d.%d.\n",
-		       card->index, vpi, vci);
-		recycle_rx_buf(card, skb);
-		return;
-	}
-
-	vc = &(card->vcmap[vpi << card->vcibits | vci]);
-	if (!vc->rx) {
-		RXPRINTK("nicstar%d: SDU received on non-rx vc %d.%d.\n",
-			 card->index, vpi, vci);
-		recycle_rx_buf(card, skb);
-		return;
-	}
-
-	vcc = vc->rx_vcc;
-
-	if (vcc->qos.aal == ATM_AAL0) {
-		struct sk_buff *sb;
-		unsigned char *cell;
-		int i;
-
-		cell = skb->data;
-		for (i = ns_rsqe_cellcount(rsqe); i; i--) {
-			sb = dev_alloc_skb(NS_SMSKBSIZE);
-			if (!sb) {
-				printk
-				    ("nicstar%d: Can't allocate buffers for aal0.\n",
-				     card->index);
-				atomic_add(i, &vcc->stats->rx_drop);
-				break;
-			}
-			if (!atm_charge(vcc, sb->truesize)) {
-				RXPRINTK
-				    ("nicstar%d: atm_charge() dropped aal0 packets.\n",
-				     card->index);
-				atomic_add(i - 1, &vcc->stats->rx_drop);	/* already increased by 1 */
-				dev_kfree_skb_any(sb);
-				break;
-			}
-			/* Rebuild the header */
-			*((u32 *) sb->data) = le32_to_cpu(rsqe->word_1) << 4 |
-			    (ns_rsqe_clp(rsqe) ? 0x00000001 : 0x00000000);
-			if (i == 1 && ns_rsqe_eopdu(rsqe))
-				*((u32 *) sb->data) |= 0x00000002;
-			skb_put(sb, NS_AAL0_HEADER);
-			memcpy(skb_tail_pointer(sb), cell, ATM_CELL_PAYLOAD);
-			skb_put(sb, ATM_CELL_PAYLOAD);
-			ATM_SKB(sb)->vcc = vcc;
-			__net_timestamp(sb);
-			vcc->push(vcc, sb);
-			atomic_inc(&vcc->stats->rx);
-			cell += ATM_CELL_PAYLOAD;
-		}
-
-		recycle_rx_buf(card, skb);
-		return;
-	}
-
-	/* To reach this point, the AAL layer can only be AAL5 */
-
-	if ((iovb = vc->rx_iov) == NULL) {
-		iovb = skb_dequeue(&(card->iovpool.queue));
-		if (iovb == NULL) {	/* No buffers in the queue */
-			iovb = alloc_skb(NS_IOVBUFSIZE, GFP_ATOMIC);
-			if (iovb == NULL) {
-				printk("nicstar%d: Out of iovec buffers.\n",
-				       card->index);
-				atomic_inc(&vcc->stats->rx_drop);
-				recycle_rx_buf(card, skb);
-				return;
-			}
-			NS_PRV_BUFTYPE(iovb) = BUF_NONE;
-		} else if (--card->iovpool.count < card->iovnr.min) {
-			struct sk_buff *new_iovb;
-			if ((new_iovb =
-			     alloc_skb(NS_IOVBUFSIZE, GFP_ATOMIC)) != NULL) {
-				NS_PRV_BUFTYPE(iovb) = BUF_NONE;
-				skb_queue_tail(&card->iovpool.queue, new_iovb);
-				card->iovpool.count++;
-			}
-		}
-		vc->rx_iov = iovb;
-		NS_PRV_IOVCNT(iovb) = 0;
-		iovb->len = 0;
-		iovb->data = iovb->head;
-		skb_reset_tail_pointer(iovb);
-		/* IMPORTANT: a pointer to the sk_buff containing the small or large
-		   buffer is stored as iovec base, NOT a pointer to the
-		   small or large buffer itself. */
-	} else if (NS_PRV_IOVCNT(iovb) >= NS_MAX_IOVECS) {
-		printk("nicstar%d: received too big AAL5 SDU.\n", card->index);
-		atomic_inc(&vcc->stats->rx_err);
-		recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
-				      NS_MAX_IOVECS);
-		NS_PRV_IOVCNT(iovb) = 0;
-		iovb->len = 0;
-		iovb->data = iovb->head;
-		skb_reset_tail_pointer(iovb);
-	}
-	iov = &((struct iovec *)iovb->data)[NS_PRV_IOVCNT(iovb)++];
-	iov->iov_base = (void *)skb;
-	iov->iov_len = ns_rsqe_cellcount(rsqe) * 48;
-	iovb->len += iov->iov_len;
-
-#ifdef EXTRA_DEBUG
-	if (NS_PRV_IOVCNT(iovb) == 1) {
-		if (NS_PRV_BUFTYPE(skb) != BUF_SM) {
-			printk
-			    ("nicstar%d: Expected a small buffer, and this is not one.\n",
-			     card->index);
-			which_list(card, skb);
-			atomic_inc(&vcc->stats->rx_err);
-			recycle_rx_buf(card, skb);
-			vc->rx_iov = NULL;
-			recycle_iov_buf(card, iovb);
-			return;
-		}
-	} else {		/* NS_PRV_IOVCNT(iovb) >= 2 */
-
-		if (NS_PRV_BUFTYPE(skb) != BUF_LG) {
-			printk
-			    ("nicstar%d: Expected a large buffer, and this is not one.\n",
-			     card->index);
-			which_list(card, skb);
-			atomic_inc(&vcc->stats->rx_err);
-			recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
-					      NS_PRV_IOVCNT(iovb));
-			vc->rx_iov = NULL;
-			recycle_iov_buf(card, iovb);
-			return;
-		}
-	}
-#endif /* EXTRA_DEBUG */
-
-	if (ns_rsqe_eopdu(rsqe)) {
-		/* This works correctly regardless of the endianness of the host */
-		unsigned char *L1L2 = (unsigned char *)
-						(skb->data + iov->iov_len - 6);
-		aal5_len = L1L2[0] << 8 | L1L2[1];
-		len = (aal5_len == 0x0000) ? 0x10000 : aal5_len;
-		if (ns_rsqe_crcerr(rsqe) ||
-		    len + 8 > iovb->len || len + (47 + 8) < iovb->len) {
-			printk("nicstar%d: AAL5 CRC error", card->index);
-			if (len + 8 > iovb->len || len + (47 + 8) < iovb->len)
-				printk(" - PDU size mismatch.\n");
-			else
-				printk(".\n");
-			atomic_inc(&vcc->stats->rx_err);
-			recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
-					      NS_PRV_IOVCNT(iovb));
-			vc->rx_iov = NULL;
-			recycle_iov_buf(card, iovb);
-			return;
-		}
-
-		/* By this point we (hopefully) have a complete SDU without errors. */
-
-		if (NS_PRV_IOVCNT(iovb) == 1) {	/* Just a small buffer */
-			/* skb points to a small buffer */
-			if (!atm_charge(vcc, skb->truesize)) {
-				push_rxbufs(card, skb);
-				atomic_inc(&vcc->stats->rx_drop);
-			} else {
-				skb_put(skb, len);
-				dequeue_sm_buf(card, skb);
-				ATM_SKB(skb)->vcc = vcc;
-				__net_timestamp(skb);
-				vcc->push(vcc, skb);
-				atomic_inc(&vcc->stats->rx);
-			}
-		} else if (NS_PRV_IOVCNT(iovb) == 2) {	/* One small plus one large buffer */
-			struct sk_buff *sb;
-
-			sb = (struct sk_buff *)(iov - 1)->iov_base;
-			/* skb points to a large buffer */
-
-			if (len <= NS_SMBUFSIZE) {
-				if (!atm_charge(vcc, sb->truesize)) {
-					push_rxbufs(card, sb);
-					atomic_inc(&vcc->stats->rx_drop);
-				} else {
-					skb_put(sb, len);
-					dequeue_sm_buf(card, sb);
-					ATM_SKB(sb)->vcc = vcc;
-					__net_timestamp(sb);
-					vcc->push(vcc, sb);
-					atomic_inc(&vcc->stats->rx);
-				}
-
-				push_rxbufs(card, skb);
-
-			} else {	/* len > NS_SMBUFSIZE, the usual case */
-
-				if (!atm_charge(vcc, skb->truesize)) {
-					push_rxbufs(card, skb);
-					atomic_inc(&vcc->stats->rx_drop);
-				} else {
-					dequeue_lg_buf(card, skb);
-					skb_push(skb, NS_SMBUFSIZE);
-					skb_copy_from_linear_data(sb, skb->data,
-								  NS_SMBUFSIZE);
-					skb_put(skb, len - NS_SMBUFSIZE);
-					ATM_SKB(skb)->vcc = vcc;
-					__net_timestamp(skb);
-					vcc->push(vcc, skb);
-					atomic_inc(&vcc->stats->rx);
-				}
-
-				push_rxbufs(card, sb);
-
-			}
-
-		} else {	/* Must push a huge buffer */
-
-			struct sk_buff *hb, *sb, *lb;
-			int remaining, tocopy;
-			int j;
-
-			hb = skb_dequeue(&(card->hbpool.queue));
-			if (hb == NULL) {	/* No buffers in the queue */
-
-				hb = dev_alloc_skb(NS_HBUFSIZE);
-				if (hb == NULL) {
-					printk
-					    ("nicstar%d: Out of huge buffers.\n",
-					     card->index);
-					atomic_inc(&vcc->stats->rx_drop);
-					recycle_iovec_rx_bufs(card,
-							      (struct iovec *)
-							      iovb->data,
-							      NS_PRV_IOVCNT(iovb));
-					vc->rx_iov = NULL;
-					recycle_iov_buf(card, iovb);
-					return;
-				} else if (card->hbpool.count < card->hbnr.min) {
-					struct sk_buff *new_hb;
-					if ((new_hb =
-					     dev_alloc_skb(NS_HBUFSIZE)) !=
-					    NULL) {
-						skb_queue_tail(&card->hbpool.
-							       queue, new_hb);
-						card->hbpool.count++;
-					}
-				}
-				NS_PRV_BUFTYPE(hb) = BUF_NONE;
-			} else if (--card->hbpool.count < card->hbnr.min) {
-				struct sk_buff *new_hb;
-				if ((new_hb =
-				     dev_alloc_skb(NS_HBUFSIZE)) != NULL) {
-					NS_PRV_BUFTYPE(new_hb) = BUF_NONE;
-					skb_queue_tail(&card->hbpool.queue,
-						       new_hb);
-					card->hbpool.count++;
-				}
-				if (card->hbpool.count < card->hbnr.min) {
-					if ((new_hb =
-					     dev_alloc_skb(NS_HBUFSIZE)) !=
-					    NULL) {
-						NS_PRV_BUFTYPE(new_hb) =
-						    BUF_NONE;
-						skb_queue_tail(&card->hbpool.
-							       queue, new_hb);
-						card->hbpool.count++;
-					}
-				}
-			}
-
-			iov = (struct iovec *)iovb->data;
-
-			if (!atm_charge(vcc, hb->truesize)) {
-				recycle_iovec_rx_bufs(card, iov,
-						      NS_PRV_IOVCNT(iovb));
-				if (card->hbpool.count < card->hbnr.max) {
-					skb_queue_tail(&card->hbpool.queue, hb);
-					card->hbpool.count++;
-				} else
-					dev_kfree_skb_any(hb);
-				atomic_inc(&vcc->stats->rx_drop);
-			} else {
-				/* Copy the small buffer to the huge buffer */
-				sb = (struct sk_buff *)iov->iov_base;
-				skb_copy_from_linear_data(sb, hb->data,
-							  iov->iov_len);
-				skb_put(hb, iov->iov_len);
-				remaining = len - iov->iov_len;
-				iov++;
-				/* Free the small buffer */
-				push_rxbufs(card, sb);
-
-				/* Copy all large buffers to the huge buffer and free them */
-				for (j = 1; j < NS_PRV_IOVCNT(iovb); j++) {
-					lb = (struct sk_buff *)iov->iov_base;
-					tocopy =
-					    min_t(int, remaining, iov->iov_len);
-					skb_copy_from_linear_data(lb,
-								  skb_tail_pointer
-								  (hb), tocopy);
-					skb_put(hb, tocopy);
-					iov++;
-					remaining -= tocopy;
-					push_rxbufs(card, lb);
-				}
-#ifdef EXTRA_DEBUG
-				if (remaining != 0 || hb->len != len)
-					printk
-					    ("nicstar%d: Huge buffer len mismatch.\n",
-					     card->index);
-#endif /* EXTRA_DEBUG */
-				ATM_SKB(hb)->vcc = vcc;
-				__net_timestamp(hb);
-				vcc->push(vcc, hb);
-				atomic_inc(&vcc->stats->rx);
-			}
-		}
-
-		vc->rx_iov = NULL;
-		recycle_iov_buf(card, iovb);
-	}
-
-}
-
-static void recycle_rx_buf(ns_dev * card, struct sk_buff *skb)
-{
-	if (unlikely(NS_PRV_BUFTYPE(skb) == BUF_NONE)) {
-		printk("nicstar%d: What kind of rx buffer is this?\n",
-		       card->index);
-		dev_kfree_skb_any(skb);
-	} else
-		push_rxbufs(card, skb);
-}
-
-static void recycle_iovec_rx_bufs(ns_dev * card, struct iovec *iov, int count)
-{
-	while (count-- > 0)
-		recycle_rx_buf(card, (struct sk_buff *)(iov++)->iov_base);
-}
-
-static void recycle_iov_buf(ns_dev * card, struct sk_buff *iovb)
-{
-	if (card->iovpool.count < card->iovnr.max) {
-		skb_queue_tail(&card->iovpool.queue, iovb);
-		card->iovpool.count++;
-	} else
-		dev_kfree_skb_any(iovb);
-}
-
-static void dequeue_sm_buf(ns_dev * card, struct sk_buff *sb)
-{
-	skb_unlink(sb, &card->sbpool.queue);
-	if (card->sbfqc < card->sbnr.init) {
-		struct sk_buff *new_sb;
-		if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) {
-			NS_PRV_BUFTYPE(new_sb) = BUF_SM;
-			skb_queue_tail(&card->sbpool.queue, new_sb);
-			skb_reserve(new_sb, NS_AAL0_HEADER);
-			push_rxbufs(card, new_sb);
-		}
-	}
-	if (card->sbfqc < card->sbnr.init)
-	{
-		struct sk_buff *new_sb;
-		if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) {
-			NS_PRV_BUFTYPE(new_sb) = BUF_SM;
-			skb_queue_tail(&card->sbpool.queue, new_sb);
-			skb_reserve(new_sb, NS_AAL0_HEADER);
-			push_rxbufs(card, new_sb);
-		}
-	}
-}
-
-static void dequeue_lg_buf(ns_dev * card, struct sk_buff *lb)
-{
-	skb_unlink(lb, &card->lbpool.queue);
-	if (card->lbfqc < card->lbnr.init) {
-		struct sk_buff *new_lb;
-		if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) {
-			NS_PRV_BUFTYPE(new_lb) = BUF_LG;
-			skb_queue_tail(&card->lbpool.queue, new_lb);
-			skb_reserve(new_lb, NS_SMBUFSIZE);
-			push_rxbufs(card, new_lb);
-		}
-	}
-	if (card->lbfqc < card->lbnr.init)
-	{
-		struct sk_buff *new_lb;
-		if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) {
-			NS_PRV_BUFTYPE(new_lb) = BUF_LG;
-			skb_queue_tail(&card->lbpool.queue, new_lb);
-			skb_reserve(new_lb, NS_SMBUFSIZE);
-			push_rxbufs(card, new_lb);
-		}
-	}
-}
-
-static int ns_proc_read(struct atm_dev *dev, loff_t * pos, char *page)
-{
-	u32 stat;
-	ns_dev *card;
-	int left;
-
-	left = (int)*pos;
-	card = (ns_dev *) dev->dev_data;
-	stat = readl(card->membase + STAT);
-	if (!left--)
-		return sprintf(page, "Pool   count    min   init    max \n");
-	if (!left--)
-		return sprintf(page, "Small  %5d  %5d  %5d  %5d \n",
-			       ns_stat_sfbqc_get(stat), card->sbnr.min,
-			       card->sbnr.init, card->sbnr.max);
-	if (!left--)
-		return sprintf(page, "Large  %5d  %5d  %5d  %5d \n",
-			       ns_stat_lfbqc_get(stat), card->lbnr.min,
-			       card->lbnr.init, card->lbnr.max);
-	if (!left--)
-		return sprintf(page, "Huge   %5d  %5d  %5d  %5d \n",
-			       card->hbpool.count, card->hbnr.min,
-			       card->hbnr.init, card->hbnr.max);
-	if (!left--)
-		return sprintf(page, "Iovec  %5d  %5d  %5d  %5d \n",
-			       card->iovpool.count, card->iovnr.min,
-			       card->iovnr.init, card->iovnr.max);
-	if (!left--) {
-		int retval;
-		retval =
-		    sprintf(page, "Interrupt counter: %u \n", card->intcnt);
-		card->intcnt = 0;
-		return retval;
-	}
-#if 0
-	/* Dump 25.6 Mbps PHY registers */
-	/* Now there's a 25.6 Mbps PHY driver this code isn't needed. I left it
-	   here just in case it's needed for debugging. */
-	if (card->max_pcr == ATM_25_PCR && !left--) {
-		u32 phy_regs[4];
-		u32 i;
-
-		for (i = 0; i < 4; i++) {
-			while (CMD_BUSY(card)) ;
-			writel(NS_CMD_READ_UTILITY | 0x00000200 | i,
-			       card->membase + CMD);
-			while (CMD_BUSY(card)) ;
-			phy_regs[i] = readl(card->membase + DR0) & 0x000000FF;
-		}
-
-		return sprintf(page, "PHY regs: 0x%02X 0x%02X 0x%02X 0x%02X \n",
-			       phy_regs[0], phy_regs[1], phy_regs[2],
-			       phy_regs[3]);
-	}
-#endif /* 0 - Dump 25.6 Mbps PHY registers */
-#if 0
-	/* Dump TST */
-	if (left-- < NS_TST_NUM_ENTRIES) {
-		if (card->tste2vc[left + 1] == NULL)
-			return sprintf(page, "%5d - VBR/UBR \n", left + 1);
-		else
-			return sprintf(page, "%5d - %d %d \n", left + 1,
-				       card->tste2vc[left + 1]->tx_vcc->vpi,
-				       card->tste2vc[left + 1]->tx_vcc->vci);
-	}
-#endif /* 0 */
-	return 0;
-}
-
-static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user * arg)
-{
-	ns_dev *card;
-	pool_levels pl;
-	long btype;
-	unsigned long flags;
-
-	card = dev->dev_data;
-	switch (cmd) {
-	case NS_GETPSTAT:
-		if (get_user
-		    (pl.buftype, &((pool_levels __user *) arg)->buftype))
-			return -EFAULT;
-		switch (pl.buftype) {
-		case NS_BUFTYPE_SMALL:
-			pl.count =
-			    ns_stat_sfbqc_get(readl(card->membase + STAT));
-			pl.level.min = card->sbnr.min;
-			pl.level.init = card->sbnr.init;
-			pl.level.max = card->sbnr.max;
-			break;
-
-		case NS_BUFTYPE_LARGE:
-			pl.count =
-			    ns_stat_lfbqc_get(readl(card->membase + STAT));
-			pl.level.min = card->lbnr.min;
-			pl.level.init = card->lbnr.init;
-			pl.level.max = card->lbnr.max;
-			break;
-
-		case NS_BUFTYPE_HUGE:
-			pl.count = card->hbpool.count;
-			pl.level.min = card->hbnr.min;
-			pl.level.init = card->hbnr.init;
-			pl.level.max = card->hbnr.max;
-			break;
-
-		case NS_BUFTYPE_IOVEC:
-			pl.count = card->iovpool.count;
-			pl.level.min = card->iovnr.min;
-			pl.level.init = card->iovnr.init;
-			pl.level.max = card->iovnr.max;
-			break;
-
-		default:
-			return -ENOIOCTLCMD;
-
-		}
-		if (!copy_to_user((pool_levels __user *) arg, &pl, sizeof(pl)))
-			return (sizeof(pl));
-		else
-			return -EFAULT;
-
-	case NS_SETBUFLEV:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		if (copy_from_user(&pl, (pool_levels __user *) arg, sizeof(pl)))
-			return -EFAULT;
-		if (pl.level.min >= pl.level.init
-		    || pl.level.init >= pl.level.max)
-			return -EINVAL;
-		if (pl.level.min == 0)
-			return -EINVAL;
-		switch (pl.buftype) {
-		case NS_BUFTYPE_SMALL:
-			if (pl.level.max > TOP_SB)
-				return -EINVAL;
-			card->sbnr.min = pl.level.min;
-			card->sbnr.init = pl.level.init;
-			card->sbnr.max = pl.level.max;
-			break;
-
-		case NS_BUFTYPE_LARGE:
-			if (pl.level.max > TOP_LB)
-				return -EINVAL;
-			card->lbnr.min = pl.level.min;
-			card->lbnr.init = pl.level.init;
-			card->lbnr.max = pl.level.max;
-			break;
-
-		case NS_BUFTYPE_HUGE:
-			if (pl.level.max > TOP_HB)
-				return -EINVAL;
-			card->hbnr.min = pl.level.min;
-			card->hbnr.init = pl.level.init;
-			card->hbnr.max = pl.level.max;
-			break;
-
-		case NS_BUFTYPE_IOVEC:
-			if (pl.level.max > TOP_IOVB)
-				return -EINVAL;
-			card->iovnr.min = pl.level.min;
-			card->iovnr.init = pl.level.init;
-			card->iovnr.max = pl.level.max;
-			break;
-
-		default:
-			return -EINVAL;
-
-		}
-		return 0;
-
-	case NS_ADJBUFLEV:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		btype = (long)arg;	/* a long is the same size as a pointer or bigger */
-		switch (btype) {
-		case NS_BUFTYPE_SMALL:
-			while (card->sbfqc < card->sbnr.init) {
-				struct sk_buff *sb;
-
-				sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL);
-				if (sb == NULL)
-					return -ENOMEM;
-				NS_PRV_BUFTYPE(sb) = BUF_SM;
-				skb_queue_tail(&card->sbpool.queue, sb);
-				skb_reserve(sb, NS_AAL0_HEADER);
-				push_rxbufs(card, sb);
-			}
-			break;
-
-		case NS_BUFTYPE_LARGE:
-			while (card->lbfqc < card->lbnr.init) {
-				struct sk_buff *lb;
-
-				lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL);
-				if (lb == NULL)
-					return -ENOMEM;
-				NS_PRV_BUFTYPE(lb) = BUF_LG;
-				skb_queue_tail(&card->lbpool.queue, lb);
-				skb_reserve(lb, NS_SMBUFSIZE);
-				push_rxbufs(card, lb);
-			}
-			break;
-
-		case NS_BUFTYPE_HUGE:
-			while (card->hbpool.count > card->hbnr.init) {
-				struct sk_buff *hb;
-
-				spin_lock_irqsave(&card->int_lock, flags);
-				hb = skb_dequeue(&card->hbpool.queue);
-				card->hbpool.count--;
-				spin_unlock_irqrestore(&card->int_lock, flags);
-				if (hb == NULL)
-					printk
-					    ("nicstar%d: huge buffer count inconsistent.\n",
-					     card->index);
-				else
-					dev_kfree_skb_any(hb);
-
-			}
-			while (card->hbpool.count < card->hbnr.init) {
-				struct sk_buff *hb;
-
-				hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL);
-				if (hb == NULL)
-					return -ENOMEM;
-				NS_PRV_BUFTYPE(hb) = BUF_NONE;
-				spin_lock_irqsave(&card->int_lock, flags);
-				skb_queue_tail(&card->hbpool.queue, hb);
-				card->hbpool.count++;
-				spin_unlock_irqrestore(&card->int_lock, flags);
-			}
-			break;
-
-		case NS_BUFTYPE_IOVEC:
-			while (card->iovpool.count > card->iovnr.init) {
-				struct sk_buff *iovb;
-
-				spin_lock_irqsave(&card->int_lock, flags);
-				iovb = skb_dequeue(&card->iovpool.queue);
-				card->iovpool.count--;
-				spin_unlock_irqrestore(&card->int_lock, flags);
-				if (iovb == NULL)
-					printk
-					    ("nicstar%d: iovec buffer count inconsistent.\n",
-					     card->index);
-				else
-					dev_kfree_skb_any(iovb);
-
-			}
-			while (card->iovpool.count < card->iovnr.init) {
-				struct sk_buff *iovb;
-
-				iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL);
-				if (iovb == NULL)
-					return -ENOMEM;
-				NS_PRV_BUFTYPE(iovb) = BUF_NONE;
-				spin_lock_irqsave(&card->int_lock, flags);
-				skb_queue_tail(&card->iovpool.queue, iovb);
-				card->iovpool.count++;
-				spin_unlock_irqrestore(&card->int_lock, flags);
-			}
-			break;
-
-		default:
-			return -EINVAL;
-
-		}
-		return 0;
-
-	default:
-		if (dev->phy && dev->phy->ioctl) {
-			return dev->phy->ioctl(dev, cmd, arg);
-		} else {
-			printk("nicstar%d: %s == NULL \n", card->index,
-			       dev->phy ? "dev->phy->ioctl" : "dev->phy");
-			return -ENOIOCTLCMD;
-		}
-	}
-}
-
-#ifdef EXTRA_DEBUG
-static void which_list(ns_dev * card, struct sk_buff *skb)
-{
-	printk("skb buf_type: 0x%08x\n", NS_PRV_BUFTYPE(skb));
-}
-#endif /* EXTRA_DEBUG */
-
-static void ns_poll(struct timer_list *unused)
-{
-	int i;
-	ns_dev *card;
-	unsigned long flags;
-	u32 stat_r, stat_w;
-
-	PRINTK("nicstar: Entering ns_poll().\n");
-	for (i = 0; i < num_cards; i++) {
-		card = cards[i];
-		if (!spin_trylock_irqsave(&card->int_lock, flags)) {
-			/* Probably it isn't worth spinning */
-			continue;
-		}
-
-		stat_w = 0;
-		stat_r = readl(card->membase + STAT);
-		if (stat_r & NS_STAT_TSIF)
-			stat_w |= NS_STAT_TSIF;
-		if (stat_r & NS_STAT_EOPDU)
-			stat_w |= NS_STAT_EOPDU;
-
-		process_tsq(card);
-		process_rsq(card);
-
-		writel(stat_w, card->membase + STAT);
-		spin_unlock_irqrestore(&card->int_lock, flags);
-	}
-	mod_timer(&ns_timer, jiffies + NS_POLL_PERIOD);
-	PRINTK("nicstar: Leaving ns_poll().\n");
-}
-
-static void ns_phy_put(struct atm_dev *dev, unsigned char value,
-		       unsigned long addr)
-{
-	ns_dev *card;
-	unsigned long flags;
-
-	card = dev->dev_data;
-	spin_lock_irqsave(&card->res_lock, flags);
-	while (CMD_BUSY(card)) ;
-	writel((u32) value, card->membase + DR0);
-	writel(NS_CMD_WRITE_UTILITY | 0x00000200 | (addr & 0x000000FF),
-	       card->membase + CMD);
-	spin_unlock_irqrestore(&card->res_lock, flags);
-}
-
-static unsigned char ns_phy_get(struct atm_dev *dev, unsigned long addr)
-{
-	ns_dev *card;
-	unsigned long flags;
-	u32 data;
-
-	card = dev->dev_data;
-	spin_lock_irqsave(&card->res_lock, flags);
-	while (CMD_BUSY(card)) ;
-	writel(NS_CMD_READ_UTILITY | 0x00000200 | (addr & 0x000000FF),
-	       card->membase + CMD);
-	while (CMD_BUSY(card)) ;
-	data = readl(card->membase + DR0) & 0x000000FF;
-	spin_unlock_irqrestore(&card->res_lock, flags);
-	return (unsigned char)data;
-}
-
-module_init(nicstar_init);
-module_exit(nicstar_cleanup);
diff --git a/drivers/atm/nicstarmac.c b/drivers/atm/nicstarmac.c
deleted file mode 100644
index 791f69a07ddf..000000000000
--- a/drivers/atm/nicstarmac.c
+++ /dev/null
@@ -1,244 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * this file included by nicstar.c
- */
-
-/*
- * nicstarmac.c
- * Read this ForeRunner's MAC address from eprom/eeprom
- */
-
-#include <linux/kernel.h>
-
-typedef void __iomem *virt_addr_t;
-
-#define CYCLE_DELAY 5
-
-#define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \
-                                  udelay((useconds));}
-/*
- * The following tables represent the timing diagrams found in
- * the Data Sheet for the Xicor X25020 EEProm.  The #defines below
- * represent the bits in the NICStAR's General Purpose register
- * that must be toggled for the corresponding actions on the EEProm
- * to occur.
- */
-
-/* Write Data To EEProm from SI line on rising edge of CLK */
-/* Read Data From EEProm on falling edge of CLK */
-
-#define CS_HIGH		0x0002	/* Chip select high */
-#define CS_LOW		0x0000	/* Chip select low (active low) */
-#define CLK_HIGH	0x0004	/* Clock high */
-#define CLK_LOW		0x0000	/* Clock low  */
-#define SI_HIGH		0x0001	/* Serial input data high */
-#define SI_LOW		0x0000	/* Serial input data low */
-
-/* Read Status Register = 0000 0101b */
-#if 0
-static u_int32_t rdsrtab[] = {
-	CS_HIGH | CLK_HIGH,
-	CS_LOW | CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW | SI_HIGH,
-	CLK_HIGH | SI_HIGH,	/* 1 */
-	CLK_LOW | SI_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW | SI_HIGH,
-	CLK_HIGH | SI_HIGH	/* 1 */
-};
-#endif /*  0  */
-
-/* Read from EEPROM = 0000 0011b */
-static u_int32_t readtab[] = {
-	/*
-	   CS_HIGH | CLK_HIGH,
-	 */
-	CS_LOW | CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW | SI_HIGH,
-	CLK_HIGH | SI_HIGH,	/* 1 */
-	CLK_LOW | SI_HIGH,
-	CLK_HIGH | SI_HIGH	/* 1 */
-};
-
-/* Clock to read from/write to the eeprom */
-static u_int32_t clocktab[] = {
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW
-};
-
-#define NICSTAR_REG_WRITE(bs, reg, val) \
-	while ( readl(bs + STAT) & 0x0200 ) ; \
-	writel((val),(base)+(reg))
-#define NICSTAR_REG_READ(bs, reg) \
-	readl((base)+(reg))
-#define NICSTAR_REG_GENERAL_PURPOSE GP
-
-/*
- * This routine will clock the Read_Status_reg function into the X2520
- * eeprom, then pull the result from bit 16 of the NicSTaR's General Purpose 
- * register.  
- */
-#if 0
-u_int32_t nicstar_read_eprom_status(virt_addr_t base)
-{
-	u_int32_t val;
-	u_int32_t rbyte;
-	int32_t i, j;
-
-	/* Send read instruction */
-	val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
-
-	for (i = 0; i < ARRAY_SIZE(rdsrtab); i++) {
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | rdsrtab[i]));
-		osp_MicroDelay(CYCLE_DELAY);
-	}
-
-	/* Done sending instruction - now pull data off of bit 16, MSB first */
-	/* Data clocked out of eeprom on falling edge of clock */
-
-	rbyte = 0;
-	for (i = 7, j = 0; i >= 0; i--) {
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | clocktab[j++]));
-		rbyte |= (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
-			    & 0x00010000) >> 16) << i);
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | clocktab[j++]));
-		osp_MicroDelay(CYCLE_DELAY);
-	}
-	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
-	osp_MicroDelay(CYCLE_DELAY);
-	return rbyte;
-}
-#endif /*  0  */
-
-/*
- * This routine will clock the Read_data function into the X2520
- * eeprom, followed by the address to read from, through the NicSTaR's General
- * Purpose register.  
- */
-
-static u_int8_t read_eprom_byte(virt_addr_t base, u_int8_t offset)
-{
-	u_int32_t val = 0;
-	int i, j = 0;
-	u_int8_t tempread = 0;
-
-	val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
-
-	/* Send READ instruction */
-	for (i = 0; i < ARRAY_SIZE(readtab); i++) {
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | readtab[i]));
-		osp_MicroDelay(CYCLE_DELAY);
-	}
-
-	/* Next, we need to send the byte address to read from */
-	for (i = 7; i >= 0; i--) {
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | clocktab[j++] | ((offset >> i) & 1)));
-		osp_MicroDelay(CYCLE_DELAY);
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | clocktab[j++] | ((offset >> i) & 1)));
-		osp_MicroDelay(CYCLE_DELAY);
-	}
-
-	j = 0;
-
-	/* Now, we can read data from the eeprom by clocking it in */
-	for (i = 7; i >= 0; i--) {
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | clocktab[j++]));
-		osp_MicroDelay(CYCLE_DELAY);
-		tempread |=
-		    (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
-		       & 0x00010000) >> 16) << i);
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | clocktab[j++]));
-		osp_MicroDelay(CYCLE_DELAY);
-	}
-
-	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
-	osp_MicroDelay(CYCLE_DELAY);
-	return tempread;
-}
-
-static void nicstar_init_eprom(virt_addr_t base)
-{
-	u_int32_t val;
-
-	/*
-	 * turn chip select off
-	 */
-	val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
-
-	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-			  (val | CS_HIGH | CLK_HIGH));
-	osp_MicroDelay(CYCLE_DELAY);
-
-	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-			  (val | CS_HIGH | CLK_LOW));
-	osp_MicroDelay(CYCLE_DELAY);
-
-	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-			  (val | CS_HIGH | CLK_HIGH));
-	osp_MicroDelay(CYCLE_DELAY);
-
-	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-			  (val | CS_HIGH | CLK_LOW));
-	osp_MicroDelay(CYCLE_DELAY);
-}
-
-/*
- * This routine will be the interface to the ReadPromByte function
- * above.
- */
-
-static void
-nicstar_read_eprom(virt_addr_t base,
-		   u_int8_t prom_offset, u_int8_t * buffer, u_int32_t nbytes)
-{
-	u_int i;
-
-	for (i = 0; i < nbytes; i++) {
-		buffer[i] = read_eprom_byte(base, prom_offset);
-		++prom_offset;
-		osp_MicroDelay(CYCLE_DELAY);
-	}
-}
diff --git a/drivers/atm/solos-attrlist.c b/drivers/atm/solos-attrlist.c
deleted file mode 100644
index 1830d1b8619f..000000000000
--- a/drivers/atm/solos-attrlist.c
+++ /dev/null
@@ -1,83 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-SOLOS_ATTR_RO(DriverVersion)
-SOLOS_ATTR_RO(APIVersion)
-SOLOS_ATTR_RO(FirmwareVersion)
-SOLOS_ATTR_RO(Version)
-// SOLOS_ATTR_RO(DspVersion)
-// SOLOS_ATTR_RO(CommonHandshake)
-SOLOS_ATTR_RO(Connected)
-SOLOS_ATTR_RO(OperationalMode)
-SOLOS_ATTR_RO(State)
-SOLOS_ATTR_RO(Watchdog)
-SOLOS_ATTR_RO(OperationProgress)
-SOLOS_ATTR_RO(LastFailed)
-SOLOS_ATTR_RO(TxBitRate)
-SOLOS_ATTR_RO(RxBitRate)
-// SOLOS_ATTR_RO(DeltACTATPds)
-// SOLOS_ATTR_RO(DeltACTATPus)
-SOLOS_ATTR_RO(TxATTNDR)
-SOLOS_ATTR_RO(RxATTNDR)
-SOLOS_ATTR_RO(AnnexType)
-SOLOS_ATTR_RO(GeneralFailure)
-SOLOS_ATTR_RO(InterleaveDpDn)
-SOLOS_ATTR_RO(InterleaveDpUp)
-SOLOS_ATTR_RO(RSCorrectedErrorsDn)
-SOLOS_ATTR_RO(RSUnCorrectedErrorsDn)
-SOLOS_ATTR_RO(RSCorrectedErrorsUp)
-SOLOS_ATTR_RO(RSUnCorrectedErrorsUp)
-SOLOS_ATTR_RO(InterleaveRDn)
-SOLOS_ATTR_RO(InterleaveRUp)
-SOLOS_ATTR_RO(BisRDn)
-SOLOS_ATTR_RO(BisRUp)
-SOLOS_ATTR_RO(INPdown)
-SOLOS_ATTR_RO(INPup)
-SOLOS_ATTR_RO(ShowtimeStart)
-SOLOS_ATTR_RO(ATURVendor)
-SOLOS_ATTR_RO(ATUCCountry)
-SOLOS_ATTR_RO(ATURANSIRev)
-SOLOS_ATTR_RO(ATURANSISTD)
-SOLOS_ATTR_RO(ATUCANSIRev)
-SOLOS_ATTR_RO(ATUCANSIId)
-SOLOS_ATTR_RO(ATUCANSISTD)
-SOLOS_ATTR_RO(DataBoost)
-SOLOS_ATTR_RO(LocalITUCountryCode)
-SOLOS_ATTR_RO(LocalSEF)
-SOLOS_ATTR_RO(LocalEndLOS)
-SOLOS_ATTR_RO(LocalSNRMargin)
-SOLOS_ATTR_RO(LocalLineAttn)
-SOLOS_ATTR_RO(RawAttn)
-SOLOS_ATTR_RO(LocalTxPower)
-SOLOS_ATTR_RO(RemoteTxPower)
-SOLOS_ATTR_RO(RemoteSEF)
-SOLOS_ATTR_RO(RemoteLOS)
-SOLOS_ATTR_RO(RemoteLineAttn)
-SOLOS_ATTR_RO(RemoteSNRMargin)
-SOLOS_ATTR_RO(LineUpCount)
-SOLOS_ATTR_RO(SRACnt)
-SOLOS_ATTR_RO(SRACntUp)
-SOLOS_ATTR_RO(ProfileStatus)
-SOLOS_ATTR_RW(Action)
-SOLOS_ATTR_RW(ActivateLine)
-SOLOS_ATTR_RO(LineStatus)
-SOLOS_ATTR_RW(HostControl)
-SOLOS_ATTR_RW(AutoStart)
-SOLOS_ATTR_RW(Failsafe)
-SOLOS_ATTR_RW(ShowtimeLed)
-SOLOS_ATTR_RW(Retrain)
-SOLOS_ATTR_RW(Defaults)
-SOLOS_ATTR_RW(LineMode)
-SOLOS_ATTR_RW(Profile)
-SOLOS_ATTR_RW(DetectNoise)
-SOLOS_ATTR_RW(BisAForceSNRMarginDn)
-SOLOS_ATTR_RW(BisMForceSNRMarginDn)
-SOLOS_ATTR_RW(BisAMaxMargin)
-SOLOS_ATTR_RW(BisMMaxMargin)
-SOLOS_ATTR_RW(AnnexAForceSNRMarginDn)
-SOLOS_ATTR_RW(AnnexAMaxMargin)
-SOLOS_ATTR_RW(AnnexMMaxMargin)
-SOLOS_ATTR_RO(SupportedAnnexes)
-SOLOS_ATTR_RO(Status)
-SOLOS_ATTR_RO(TotalStart)
-SOLOS_ATTR_RO(RecentShowtimeStart)
-SOLOS_ATTR_RO(TotalRxBlocks)
-SOLOS_ATTR_RO(TotalTxBlocks)
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
deleted file mode 100644
index 24c764664c24..000000000000
--- a/drivers/atm/solos-pci.c
+++ /dev/null
@@ -1,1496 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Driver for the Solos PCI ADSL2+ card, designed to support Linux by
- *  Traverse Technologies -- https://www.traverse.com.au/
- *  Xrio Limited          -- http://www.xrio.com/
- *
- * Copyright © 2008 Traverse Technologies
- * Copyright © 2008 Intel Corporation
- *
- * Authors: Nathan Williams <nathan@traverse.com.au>
- *          David Woodhouse <dwmw2@infradead.org>
- *          Treker Chen <treker@xrio.com>
- */
-
-#define DEBUG
-#define VERBOSE_DEBUG
-
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <linux/skbuff.h>
-#include <linux/sysfs.h>
-#include <linux/device.h>
-#include <linux/kobject.h>
-#include <linux/firmware.h>
-#include <linux/ctype.h>
-#include <linux/swab.h>
-#include <linux/slab.h>
-
-#define VERSION "1.04"
-#define DRIVER_VERSION 0x01
-#define PTAG "solos-pci"
-
-#define CONFIG_RAM_SIZE	128
-#define FLAGS_ADDR	0x7C
-#define IRQ_EN_ADDR	0x78
-#define FPGA_VER	0x74
-#define IRQ_CLEAR	0x70
-#define WRITE_FLASH	0x6C
-#define PORTS		0x68
-#define FLASH_BLOCK	0x64
-#define FLASH_BUSY	0x60
-#define FPGA_MODE	0x5C
-#define FLASH_MODE	0x58
-#define GPIO_STATUS	0x54
-#define DRIVER_VER	0x50
-#define TX_DMA_ADDR(port)	(0x40 + (4 * (port)))
-#define RX_DMA_ADDR(port)	(0x30 + (4 * (port)))
-
-#define DATA_RAM_SIZE	32768
-#define BUF_SIZE	2048
-#define OLD_BUF_SIZE	4096 /* For FPGA versions <= 2*/
-/* Old boards use ATMEL AD45DB161D flash */
-#define ATMEL_FPGA_PAGE	528 /* FPGA flash page size*/
-#define ATMEL_SOLOS_PAGE	512 /* Solos flash page size*/
-#define ATMEL_FPGA_BLOCK	(ATMEL_FPGA_PAGE * 8) /* FPGA block size*/
-#define ATMEL_SOLOS_BLOCK	(ATMEL_SOLOS_PAGE * 8) /* Solos block size*/
-/* Current boards use M25P/M25PE SPI flash */
-#define SPI_FLASH_BLOCK	(256 * 64)
-
-#define RX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2)
-#define TX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2 + (card->buffer_size))
-#define FLASH_BUF ((card->buffers) + 4*(card->buffer_size)*2)
-
-#define RX_DMA_SIZE	2048
-
-#define FPGA_VERSION(a,b) (((a) << 8) + (b))
-#define LEGACY_BUFFERS	2
-#define DMA_SUPPORTED	4
-
-static int reset = 0;
-static int atmdebug = 0;
-static int firmware_upgrade = 0;
-static int fpga_upgrade = 0;
-static int db_firmware_upgrade = 0;
-static int db_fpga_upgrade = 0;
-
-struct pkt_hdr {
-	__le16 size;
-	__le16 vpi;
-	__le16 vci;
-	__le16 type;
-};
-
-struct solos_skb_cb {
-	struct atm_vcc *vcc;
-	uint32_t dma_addr;
-};
-
-
-#define SKB_CB(skb)		((struct solos_skb_cb *)skb->cb)
-
-#define PKT_DATA	0
-#define PKT_COMMAND	1
-#define PKT_POPEN	3
-#define PKT_PCLOSE	4
-#define PKT_STATUS	5
-
-struct solos_card {
-	void __iomem *config_regs;
-	void __iomem *buffers;
-	int nr_ports;
-	int tx_mask;
-	struct pci_dev *dev;
-	struct atm_dev *atmdev[4];
-	struct tasklet_struct tlet;
-	spinlock_t tx_lock;
-	spinlock_t tx_queue_lock;
-	spinlock_t cli_queue_lock;
-	spinlock_t param_queue_lock;
-	struct list_head param_queue;
-	struct sk_buff_head tx_queue[4];
-	struct sk_buff_head cli_queue[4];
-	struct sk_buff *tx_skb[4];
-	struct sk_buff *rx_skb[4];
-	unsigned char *dma_bounce;
-	wait_queue_head_t param_wq;
-	wait_queue_head_t fw_wq;
-	int using_dma;
-	int dma_alignment;
-	int fpga_version;
-	int buffer_size;
-	int atmel_flash;
-};
-
-
-struct solos_param {
-	struct list_head list;
-	pid_t pid;
-	int port;
-	struct sk_buff *response;
-};
-
-#define SOLOS_CHAN(atmdev) ((int)(unsigned long)(atmdev)->phy_data)
-
-MODULE_AUTHOR("Traverse Technologies <support@traverse.com.au>");
-MODULE_DESCRIPTION("Solos PCI driver");
-MODULE_VERSION(VERSION);
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE("solos-FPGA.bin");
-MODULE_FIRMWARE("solos-Firmware.bin");
-MODULE_FIRMWARE("solos-db-FPGA.bin");
-MODULE_PARM_DESC(reset, "Reset Solos chips on startup");
-MODULE_PARM_DESC(atmdebug, "Print ATM data");
-MODULE_PARM_DESC(firmware_upgrade, "Initiate Solos firmware upgrade");
-MODULE_PARM_DESC(fpga_upgrade, "Initiate FPGA upgrade");
-MODULE_PARM_DESC(db_firmware_upgrade, "Initiate daughter board Solos firmware upgrade");
-MODULE_PARM_DESC(db_fpga_upgrade, "Initiate daughter board FPGA upgrade");
-module_param(reset, int, 0444);
-module_param(atmdebug, int, 0644);
-module_param(firmware_upgrade, int, 0444);
-module_param(fpga_upgrade, int, 0444);
-module_param(db_firmware_upgrade, int, 0444);
-module_param(db_fpga_upgrade, int, 0444);
-
-static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
-		       struct atm_vcc *vcc);
-static uint32_t fpga_tx(struct solos_card *);
-static irqreturn_t solos_irq(int irq, void *dev_id);
-static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
-static int atm_init(struct solos_card *, struct device *);
-static void atm_remove(struct solos_card *);
-static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
-static void solos_bh(unsigned long);
-static int print_buffer(struct sk_buff *buf);
-
-static inline void solos_pop(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-        if (vcc->pop)
-                vcc->pop(vcc, skb);
-        else
-                dev_kfree_skb_any(skb);
-}
-
-static ssize_t solos_param_show(struct device *dev, struct device_attribute *attr,
-				char *buf)
-{
-	struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev);
-	struct solos_card *card = atmdev->dev_data;
-	struct solos_param prm;
-	struct sk_buff *skb;
-	struct pkt_hdr *header;
-	int buflen;
-
-	buflen = strlen(attr->attr.name) + 10;
-
-	skb = alloc_skb(sizeof(*header) + buflen, GFP_KERNEL);
-	if (!skb) {
-		dev_warn(&card->dev->dev, "Failed to allocate sk_buff in solos_param_show()\n");
-		return -ENOMEM;
-	}
-
-	header = skb_put(skb, sizeof(*header));
-
-	buflen = snprintf((void *)&header[1], buflen - 1,
-			  "L%05d\n%s\n", current->pid, attr->attr.name);
-	skb_put(skb, buflen);
-
-	header->size = cpu_to_le16(buflen);
-	header->vpi = cpu_to_le16(0);
-	header->vci = cpu_to_le16(0);
-	header->type = cpu_to_le16(PKT_COMMAND);
-
-	prm.pid = current->pid;
-	prm.response = NULL;
-	prm.port = SOLOS_CHAN(atmdev);
-
-	spin_lock_irq(&card->param_queue_lock);
-	list_add(&prm.list, &card->param_queue);
-	spin_unlock_irq(&card->param_queue_lock);
-
-	fpga_queue(card, prm.port, skb, NULL);
-
-	wait_event_timeout(card->param_wq, prm.response, 5 * HZ);
-
-	spin_lock_irq(&card->param_queue_lock);
-	list_del(&prm.list);
-	spin_unlock_irq(&card->param_queue_lock);
-
-	if (!prm.response)
-		return -EIO;
-
-	buflen = prm.response->len;
-	memcpy(buf, prm.response->data, buflen);
-	kfree_skb(prm.response);
-
-	return buflen;
-}
-
-static ssize_t solos_param_store(struct device *dev, struct device_attribute *attr,
-				 const char *buf, size_t count)
-{
-	struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev);
-	struct solos_card *card = atmdev->dev_data;
-	struct solos_param prm;
-	struct sk_buff *skb;
-	struct pkt_hdr *header;
-	int buflen;
-	ssize_t ret;
-
-	buflen = strlen(attr->attr.name) + 11 + count;
-
-	skb = alloc_skb(sizeof(*header) + buflen, GFP_KERNEL);
-	if (!skb) {
-		dev_warn(&card->dev->dev, "Failed to allocate sk_buff in solos_param_store()\n");
-		return -ENOMEM;
-	}
-
-	header = skb_put(skb, sizeof(*header));
-
-	buflen = snprintf((void *)&header[1], buflen - 1,
-			  "L%05d\n%s\n%s\n", current->pid, attr->attr.name, buf);
-
-	skb_put(skb, buflen);
-	header->size = cpu_to_le16(buflen);
-	header->vpi = cpu_to_le16(0);
-	header->vci = cpu_to_le16(0);
-	header->type = cpu_to_le16(PKT_COMMAND);
-
-	prm.pid = current->pid;
-	prm.response = NULL;
-	prm.port = SOLOS_CHAN(atmdev);
-
-	spin_lock_irq(&card->param_queue_lock);
-	list_add(&prm.list, &card->param_queue);
-	spin_unlock_irq(&card->param_queue_lock);
-
-	fpga_queue(card, prm.port, skb, NULL);
-
-	wait_event_timeout(card->param_wq, prm.response, 5 * HZ);
-
-	spin_lock_irq(&card->param_queue_lock);
-	list_del(&prm.list);
-	spin_unlock_irq(&card->param_queue_lock);
-
-	skb = prm.response;
-
-	if (!skb)
-		return -EIO;
-
-	buflen = skb->len;
-
-	/* Sometimes it has a newline, sometimes it doesn't. */
-	if (skb->data[buflen - 1] == '\n')
-		buflen--;
-
-	if (buflen == 2 && !strncmp(skb->data, "OK", 2))
-		ret = count;
-	else if (buflen == 5 && !strncmp(skb->data, "ERROR", 5))
-		ret = -EIO;
-	else {
-		/* We know we have enough space allocated for this; we allocated 
-		   it ourselves */
-		skb->data[buflen] = 0;
-	
-		dev_warn(&card->dev->dev, "Unexpected parameter response: '%s'\n",
-			 skb->data);
-		ret = -EIO;
-	}
-	kfree_skb(skb);
-
-	return ret;
-}
-
-static char *next_string(struct sk_buff *skb)
-{
-	int i = 0;
-	char *this = skb->data;
-	
-	for (i = 0; i < skb->len; i++) {
-		if (this[i] == '\n') {
-			this[i] = 0;
-			skb_pull(skb, i + 1);
-			return this;
-		}
-		if (!isprint(this[i]))
-			return NULL;
-	}
-	return NULL;
-}
-
-/*
- * Status packet has fields separated by \n, starting with a version number
- * for the information therein. Fields are....
- *
- *     packet version
- *     RxBitRate	(version >= 1)
- *     TxBitRate	(version >= 1)
- *     State		(version >= 1)
- *     LocalSNRMargin	(version >= 1)
- *     LocalLineAttn	(version >= 1)
- */       
-static int process_status(struct solos_card *card, int port, struct sk_buff *skb)
-{
-	char *str, *state_str, *snr, *attn;
-	int ver, rate_up, rate_down, err;
-
-	if (!card->atmdev[port])
-		return -ENODEV;
-
-	str = next_string(skb);
-	if (!str)
-		return -EIO;
-
-	err = kstrtoint(str, 10, &ver);
-	if (err) {
-		dev_warn(&card->dev->dev, "Unexpected status interrupt version\n");
-		return err;
-	}
-	if (ver < 1) {
-		dev_warn(&card->dev->dev, "Unexpected status interrupt version %d\n",
-			 ver);
-		return -EIO;
-	}
-
-	str = next_string(skb);
-	if (!str)
-		return -EIO;
-	if (!strcmp(str, "ERROR")) {
-		dev_dbg(&card->dev->dev, "Status packet indicated Solos error on port %d (starting up?)\n",
-			 port);
-		return 0;
-	}
-
-	err = kstrtoint(str, 10, &rate_down);
-	if (err)
-		return err;
-
-	str = next_string(skb);
-	if (!str)
-		return -EIO;
-	err = kstrtoint(str, 10, &rate_up);
-	if (err)
-		return err;
-
-	state_str = next_string(skb);
-	if (!state_str)
-		return -EIO;
-
-	/* Anything but 'Showtime' is down */
-	if (strcmp(state_str, "Showtime")) {
-		atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_LOST);
-		dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str);
-		return 0;
-	}
-
-	snr = next_string(skb);
-	if (!snr)
-		return -EIO;
-	attn = next_string(skb);
-	if (!attn)
-		return -EIO;
-
-	dev_info(&card->dev->dev, "Port %d: %s @%d/%d kb/s%s%s%s%s\n",
-		 port, state_str, rate_down/1000, rate_up/1000,
-		 snr[0]?", SNR ":"", snr, attn[0]?", Attn ":"", attn);
-	
-	card->atmdev[port]->link_rate = rate_down / 424;
-	atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_FOUND);
-
-	return 0;
-}
-
-static int process_command(struct solos_card *card, int port, struct sk_buff *skb)
-{
-	struct solos_param *prm;
-	unsigned long flags;
-	int cmdpid;
-	int found = 0, err;
-
-	if (skb->len < 7)
-		return 0;
-
-	if (skb->data[0] != 'L'    || !isdigit(skb->data[1]) ||
-	    !isdigit(skb->data[2]) || !isdigit(skb->data[3]) ||
-	    !isdigit(skb->data[4]) || !isdigit(skb->data[5]) ||
-	    skb->data[6] != '\n')
-		return 0;
-
-	err = kstrtoint(&skb->data[1], 10, &cmdpid);
-	if (err)
-		return err;
-
-	spin_lock_irqsave(&card->param_queue_lock, flags);
-	list_for_each_entry(prm, &card->param_queue, list) {
-		if (prm->port == port && prm->pid == cmdpid) {
-			prm->response = skb;
-			skb_pull(skb, 7);
-			wake_up(&card->param_wq);
-			found = 1;
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&card->param_queue_lock, flags);
-	return found;
-}
-
-static ssize_t console_show(struct device *dev, struct device_attribute *attr,
-			    char *buf)
-{
-	struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev);
-	struct solos_card *card = atmdev->dev_data;
-	struct sk_buff *skb;
-	unsigned int len;
-
-	spin_lock_bh(&card->cli_queue_lock);
-	skb = skb_dequeue(&card->cli_queue[SOLOS_CHAN(atmdev)]);
-	spin_unlock_bh(&card->cli_queue_lock);
-	if(skb == NULL)
-		return sprintf(buf, "No data.\n");
-
-	len = skb->len;
-	memcpy(buf, skb->data, len);
-
-	kfree_skb(skb);
-	return len;
-}
-
-static int send_command(struct solos_card *card, int dev, const char *buf, size_t size)
-{
-	struct sk_buff *skb;
-	struct pkt_hdr *header;
-
-	if (size > (BUF_SIZE - sizeof(*header))) {
-		dev_dbg(&card->dev->dev, "Command is too big.  Dropping request\n");
-		return 0;
-	}
-	skb = alloc_skb(size + sizeof(*header), GFP_ATOMIC);
-	if (!skb) {
-		dev_warn(&card->dev->dev, "Failed to allocate sk_buff in send_command()\n");
-		return 0;
-	}
-
-	header = skb_put(skb, sizeof(*header));
-
-	header->size = cpu_to_le16(size);
-	header->vpi = cpu_to_le16(0);
-	header->vci = cpu_to_le16(0);
-	header->type = cpu_to_le16(PKT_COMMAND);
-
-	skb_put_data(skb, buf, size);
-
-	fpga_queue(card, dev, skb, NULL);
-
-	return 0;
-}
-
-static ssize_t console_store(struct device *dev, struct device_attribute *attr,
-			     const char *buf, size_t count)
-{
-	struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev);
-	struct solos_card *card = atmdev->dev_data;
-	int err;
-
-	err = send_command(card, SOLOS_CHAN(atmdev), buf, count);
-
-	return err?:count;
-}
-
-struct geos_gpio_attr {
-	struct device_attribute attr;
-	int offset;
-};
-
-#define SOLOS_GPIO_ATTR(_name, _mode, _show, _store, _offset)	\
-	struct geos_gpio_attr gpio_attr_##_name = {		\
-		.attr = __ATTR(_name, _mode, _show, _store),	\
-		.offset = _offset }
-
-static ssize_t geos_gpio_store(struct device *dev, struct device_attribute *attr,
-			       const char *buf, size_t count)
-{
-	struct geos_gpio_attr *gattr = container_of(attr, struct geos_gpio_attr, attr);
-	struct solos_card *card = dev_get_drvdata(dev);
-	uint32_t data32;
-
-	if (count != 1 && (count != 2 || buf[1] != '\n'))
-		return -EINVAL;
-
-	spin_lock_irq(&card->param_queue_lock);
-	data32 = ioread32(card->config_regs + GPIO_STATUS);
-	if (buf[0] == '1') {
-		data32 |= 1 << gattr->offset;
-		iowrite32(data32, card->config_regs + GPIO_STATUS);
-	} else if (buf[0] == '0') {
-		data32 &= ~(1 << gattr->offset);
-		iowrite32(data32, card->config_regs + GPIO_STATUS);
-	} else {
-		count = -EINVAL;
-	}
-	spin_unlock_irq(&card->param_queue_lock);
-	return count;
-}
-
-static ssize_t geos_gpio_show(struct device *dev, struct device_attribute *attr,
-			      char *buf)
-{
-	struct geos_gpio_attr *gattr = container_of(attr, struct geos_gpio_attr, attr);
-	struct solos_card *card = dev_get_drvdata(dev);
-	uint32_t data32;
-
-	data32 = ioread32(card->config_regs + GPIO_STATUS);
-	data32 = (data32 >> gattr->offset) & 1;
-
-	return sprintf(buf, "%d\n", data32);
-}
-
-static ssize_t hardware_show(struct device *dev, struct device_attribute *attr,
-			     char *buf)
-{
-	struct geos_gpio_attr *gattr = container_of(attr, struct geos_gpio_attr, attr);
-	struct solos_card *card = dev_get_drvdata(dev);
-	uint32_t data32;
-
-	data32 = ioread32(card->config_regs + GPIO_STATUS);
-	switch (gattr->offset) {
-	case 0:
-		/* HardwareVersion */
-		data32 = data32 & 0x1F;
-		break;
-	case 1:
-		/* HardwareVariant */
-		data32 = (data32 >> 5) & 0x0F;
-		break;
-	}
-	return sprintf(buf, "%d\n", data32);
-}
-
-static DEVICE_ATTR_RW(console);
-
-
-#define SOLOS_ATTR_RO(x) static DEVICE_ATTR(x, 0444, solos_param_show, NULL);
-#define SOLOS_ATTR_RW(x) static DEVICE_ATTR(x, 0644, solos_param_show, solos_param_store);
-
-#include "solos-attrlist.c"
-
-static SOLOS_GPIO_ATTR(GPIO1, 0644, geos_gpio_show, geos_gpio_store, 9);
-static SOLOS_GPIO_ATTR(GPIO2, 0644, geos_gpio_show, geos_gpio_store, 10);
-static SOLOS_GPIO_ATTR(GPIO3, 0644, geos_gpio_show, geos_gpio_store, 11);
-static SOLOS_GPIO_ATTR(GPIO4, 0644, geos_gpio_show, geos_gpio_store, 12);
-static SOLOS_GPIO_ATTR(GPIO5, 0644, geos_gpio_show, geos_gpio_store, 13);
-static SOLOS_GPIO_ATTR(PushButton, 0444, geos_gpio_show, NULL, 14);
-static SOLOS_GPIO_ATTR(HardwareVersion, 0444, hardware_show, NULL, 0);
-static SOLOS_GPIO_ATTR(HardwareVariant, 0444, hardware_show, NULL, 1);
-#undef SOLOS_ATTR_RO
-#undef SOLOS_ATTR_RW
-
-#define SOLOS_ATTR_RO(x) &dev_attr_##x.attr,
-#define SOLOS_ATTR_RW(x) &dev_attr_##x.attr,
-
-static struct attribute *solos_attrs[] = {
-#include "solos-attrlist.c"
-	NULL
-};
-
-static const struct attribute_group solos_attr_group = {
-	.attrs = solos_attrs,
-	.name = "parameters",
-};
-
-static struct attribute *gpio_attrs[] = {
-	&gpio_attr_GPIO1.attr.attr,
-	&gpio_attr_GPIO2.attr.attr,
-	&gpio_attr_GPIO3.attr.attr,
-	&gpio_attr_GPIO4.attr.attr,
-	&gpio_attr_GPIO5.attr.attr,
-	&gpio_attr_PushButton.attr.attr,
-	&gpio_attr_HardwareVersion.attr.attr,
-	&gpio_attr_HardwareVariant.attr.attr,
-	NULL
-};
-
-static const struct attribute_group gpio_attr_group = {
-	.attrs = gpio_attrs,
-	.name = "gpio",
-};
-
-static int flash_upgrade(struct solos_card *card, int chip)
-{
-	const struct firmware *fw;
-	const char *fw_name;
-	int blocksize = 0;
-	int numblocks = 0;
-	int offset;
-
-	switch (chip) {
-	case 0:
-		fw_name = "solos-FPGA.bin";
-		if (card->atmel_flash)
-			blocksize = ATMEL_FPGA_BLOCK;
-		else
-			blocksize = SPI_FLASH_BLOCK;
-		break;
-	case 1:
-		fw_name = "solos-Firmware.bin";
-		if (card->atmel_flash)
-			blocksize = ATMEL_SOLOS_BLOCK;
-		else
-			blocksize = SPI_FLASH_BLOCK;
-		break;
-	case 2:
-		if (card->fpga_version > LEGACY_BUFFERS){
-			fw_name = "solos-db-FPGA.bin";
-			if (card->atmel_flash)
-				blocksize = ATMEL_FPGA_BLOCK;
-			else
-				blocksize = SPI_FLASH_BLOCK;
-		} else {
-			dev_info(&card->dev->dev, "FPGA version doesn't support"
-					" daughter board upgrades\n");
-			return -EPERM;
-		}
-		break;
-	case 3:
-		if (card->fpga_version > LEGACY_BUFFERS){
-			fw_name = "solos-Firmware.bin";
-			if (card->atmel_flash)
-				blocksize = ATMEL_SOLOS_BLOCK;
-			else
-				blocksize = SPI_FLASH_BLOCK;
-		} else {
-			dev_info(&card->dev->dev, "FPGA version doesn't support"
-					" daughter board upgrades\n");
-			return -EPERM;
-		}
-		break;
-	default:
-		return -ENODEV;
-	}
-
-	if (request_firmware(&fw, fw_name, &card->dev->dev))
-		return -ENOENT;
-
-	dev_info(&card->dev->dev, "Flash upgrade starting\n");
-
-	/* New FPGAs require driver version before permitting flash upgrades */
-	iowrite32(DRIVER_VERSION, card->config_regs + DRIVER_VER);
-
-	numblocks = fw->size / blocksize;
-	dev_info(&card->dev->dev, "Firmware size: %zd\n", fw->size);
-	dev_info(&card->dev->dev, "Number of blocks: %d\n", numblocks);
-	
-	dev_info(&card->dev->dev, "Changing FPGA to Update mode\n");
-	iowrite32(1, card->config_regs + FPGA_MODE);
-	(void) ioread32(card->config_regs + FPGA_MODE); 
-
-	/* Set mode to Chip Erase */
-	if(chip == 0 || chip == 2)
-		dev_info(&card->dev->dev, "Set FPGA Flash mode to FPGA Chip Erase\n");
-	if(chip == 1 || chip == 3)
-		dev_info(&card->dev->dev, "Set FPGA Flash mode to Solos Chip Erase\n");
-	iowrite32((chip * 2), card->config_regs + FLASH_MODE);
-
-
-	iowrite32(1, card->config_regs + WRITE_FLASH);
-	wait_event(card->fw_wq, !ioread32(card->config_regs + FLASH_BUSY));
-
-	for (offset = 0; offset < fw->size; offset += blocksize) {
-		int i;
-
-		/* Clear write flag */
-		iowrite32(0, card->config_regs + WRITE_FLASH);
-
-		/* Set mode to Block Write */
-		/* dev_info(&card->dev->dev, "Set FPGA Flash mode to Block Write\n"); */
-		iowrite32(((chip * 2) + 1), card->config_regs + FLASH_MODE);
-
-		/* Copy block to buffer, swapping each 16 bits for Atmel flash */
-		for(i = 0; i < blocksize; i += 4) {
-			uint32_t word;
-			if (card->atmel_flash)
-				word = swahb32p((uint32_t *)(fw->data + offset + i));
-			else
-				word = *(uint32_t *)(fw->data + offset + i);
-			if(card->fpga_version > LEGACY_BUFFERS)
-				iowrite32(word, FLASH_BUF + i);
-			else
-				iowrite32(word, RX_BUF(card, 3) + i);
-		}
-
-		/* Specify block number and then trigger flash write */
-		iowrite32(offset / blocksize, card->config_regs + FLASH_BLOCK);
-		iowrite32(1, card->config_regs + WRITE_FLASH);
-		wait_event(card->fw_wq, !ioread32(card->config_regs + FLASH_BUSY));
-	}
-
-	release_firmware(fw);
-	iowrite32(0, card->config_regs + WRITE_FLASH);
-	iowrite32(0, card->config_regs + FPGA_MODE);
-	iowrite32(0, card->config_regs + FLASH_MODE);
-	dev_info(&card->dev->dev, "Returning FPGA to Data mode\n");
-	return 0;
-}
-
-static irqreturn_t solos_irq(int irq, void *dev_id)
-{
-	struct solos_card *card = dev_id;
-	int handled = 1;
-
-	iowrite32(0, card->config_regs + IRQ_CLEAR);
-
-	/* If we're up and running, just kick the tasklet to process TX/RX */
-	if (card->atmdev[0])
-		tasklet_schedule(&card->tlet);
-	else
-		wake_up(&card->fw_wq);
-
-	return IRQ_RETVAL(handled);
-}
-
-static void solos_bh(unsigned long card_arg)
-{
-	struct solos_card *card = (void *)card_arg;
-	uint32_t card_flags;
-	uint32_t rx_done = 0;
-	int port;
-
-	/*
-	 * Since fpga_tx() is going to need to read the flags under its lock,
-	 * it can return them to us so that we don't have to hit PCI MMIO
-	 * again for the same information
-	 */
-	card_flags = fpga_tx(card);
-
-	for (port = 0; port < card->nr_ports; port++) {
-		if (card_flags & (0x10 << port)) {
-			struct pkt_hdr _hdr, *header;
-			struct sk_buff *skb;
-			struct atm_vcc *vcc;
-			int size;
-
-			if (card->using_dma) {
-				skb = card->rx_skb[port];
-				card->rx_skb[port] = NULL;
-
-				dma_unmap_single(&card->dev->dev, SKB_CB(skb)->dma_addr,
-						 RX_DMA_SIZE, DMA_FROM_DEVICE);
-
-				header = (void *)skb->data;
-				size = le16_to_cpu(header->size);
-				skb_put(skb, size + sizeof(*header));
-				skb_pull(skb, sizeof(*header));
-			} else {
-				header = &_hdr;
-
-				rx_done |= 0x10 << port;
-
-				memcpy_fromio(header, RX_BUF(card, port), sizeof(*header));
-
-				size = le16_to_cpu(header->size);
-				if (size > (card->buffer_size - sizeof(*header))){
-					dev_warn(&card->dev->dev, "Invalid buffer size\n");
-					continue;
-				}
-
-				/* Use netdev_alloc_skb() because it adds NET_SKB_PAD of
-				 * headroom, and ensures we can route packets back out an
-				 * Ethernet interface (for example) without having to
-				 * reallocate. Adding NET_IP_ALIGN also ensures that both
-				 * PPPoATM and PPPoEoBR2684 packets end up aligned. */
-				skb = netdev_alloc_skb_ip_align(NULL, size + 1);
-				if (!skb) {
-					if (net_ratelimit())
-						dev_warn(&card->dev->dev, "Failed to allocate sk_buff for RX\n");
-					continue;
-				}
-
-				memcpy_fromio(skb_put(skb, size),
-					      RX_BUF(card, port) + sizeof(*header),
-					      size);
-			}
-			if (atmdebug) {
-				dev_info(&card->dev->dev, "Received: port %d\n", port);
-				dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
-					 size, le16_to_cpu(header->vpi),
-					 le16_to_cpu(header->vci));
-				print_buffer(skb);
-			}
-
-			switch (le16_to_cpu(header->type)) {
-			case PKT_DATA:
-				vcc = find_vcc(card->atmdev[port], le16_to_cpu(header->vpi),
-					       le16_to_cpu(header->vci));
-				if (!vcc) {
-					if (net_ratelimit())
-						dev_warn(&card->dev->dev, "Received packet for unknown VPI.VCI %d.%d on port %d\n",
-							 le16_to_cpu(header->vpi), le16_to_cpu(header->vci),
-							 port);
-					dev_kfree_skb_any(skb);
-					break;
-				}
-				atm_charge(vcc, skb->truesize);
-				vcc->push(vcc, skb);
-				atomic_inc(&vcc->stats->rx);
-				break;
-
-			case PKT_STATUS:
-				if (process_status(card, port, skb) &&
-				    net_ratelimit()) {
-					dev_warn(&card->dev->dev, "Bad status packet of %d bytes on port %d:\n", skb->len, port);
-					print_buffer(skb);
-				}
-				dev_kfree_skb_any(skb);
-				break;
-
-			case PKT_COMMAND:
-			default: /* FIXME: Not really, surely? */
-				if (process_command(card, port, skb))
-					break;
-				spin_lock(&card->cli_queue_lock);
-				if (skb_queue_len(&card->cli_queue[port]) > 10) {
-					if (net_ratelimit())
-						dev_warn(&card->dev->dev, "Dropping console response on port %d\n",
-							 port);
-					dev_kfree_skb_any(skb);
-				} else
-					skb_queue_tail(&card->cli_queue[port], skb);
-				spin_unlock(&card->cli_queue_lock);
-				break;
-			}
-		}
-		/* Allocate RX skbs for any ports which need them */
-		if (card->using_dma && card->atmdev[port] &&
-		    !card->rx_skb[port]) {
-			/* Unlike the MMIO case (qv) we can't add NET_IP_ALIGN
-			 * here; the FPGA can only DMA to addresses which are
-			 * aligned to 4 bytes. */
-			struct sk_buff *skb = dev_alloc_skb(RX_DMA_SIZE);
-			if (skb) {
-				SKB_CB(skb)->dma_addr =
-					dma_map_single(&card->dev->dev, skb->data,
-						       RX_DMA_SIZE, DMA_FROM_DEVICE);
-				iowrite32(SKB_CB(skb)->dma_addr,
-					  card->config_regs + RX_DMA_ADDR(port));
-				card->rx_skb[port] = skb;
-			} else {
-				if (net_ratelimit())
-					dev_warn(&card->dev->dev, "Failed to allocate RX skb");
-
-				/* We'll have to try again later */
-				tasklet_schedule(&card->tlet);
-			}
-		}
-	}
-	if (rx_done)
-		iowrite32(rx_done, card->config_regs + FLAGS_ADDR);
-
-	return;
-}
-
-static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
-{
-	struct hlist_head *head;
-	struct atm_vcc *vcc = NULL;
-	struct sock *s;
-
-	read_lock(&vcc_sklist_lock);
-	head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)];
-	sk_for_each(s, head) {
-		vcc = atm_sk(s);
-		if (vcc->dev == dev && vcc->vci == vci &&
-		    vcc->vpi == vpi && vcc->qos.rxtp.traffic_class != ATM_NONE &&
-		    test_bit(ATM_VF_READY, &vcc->flags))
-			goto out;
-	}
-	vcc = NULL;
- out:
-	read_unlock(&vcc_sklist_lock);
-	return vcc;
-}
-
-static int popen(struct atm_vcc *vcc)
-{
-	struct solos_card *card = vcc->dev->dev_data;
-	struct sk_buff *skb;
-	struct pkt_hdr *header;
-
-	if (vcc->qos.aal != ATM_AAL5) {
-		dev_warn(&card->dev->dev, "Unsupported ATM type %d\n",
-			 vcc->qos.aal);
-		return -EINVAL;
-	}
-
-	skb = alloc_skb(sizeof(*header), GFP_KERNEL);
-	if (!skb) {
-		if (net_ratelimit())
-			dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n");
-		return -ENOMEM;
-	}
-	header = skb_put(skb, sizeof(*header));
-
-	header->size = cpu_to_le16(0);
-	header->vpi = cpu_to_le16(vcc->vpi);
-	header->vci = cpu_to_le16(vcc->vci);
-	header->type = cpu_to_le16(PKT_POPEN);
-
-	fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, NULL);
-
-	set_bit(ATM_VF_ADDR, &vcc->flags);
-	set_bit(ATM_VF_READY, &vcc->flags);
-
-	return 0;
-}
-
-static void pclose(struct atm_vcc *vcc)
-{
-	struct solos_card *card = vcc->dev->dev_data;
-	unsigned char port = SOLOS_CHAN(vcc->dev);
-	struct sk_buff *skb, *tmpskb;
-	struct pkt_hdr *header;
-
-	/* Remove any yet-to-be-transmitted packets from the pending queue */
-	spin_lock_bh(&card->tx_queue_lock);
-	skb_queue_walk_safe(&card->tx_queue[port], skb, tmpskb) {
-		if (SKB_CB(skb)->vcc == vcc) {
-			skb_unlink(skb, &card->tx_queue[port]);
-			solos_pop(vcc, skb);
-		}
-	}
-	spin_unlock_bh(&card->tx_queue_lock);
-
-	skb = alloc_skb(sizeof(*header), GFP_KERNEL);
-	if (!skb) {
-		dev_warn(&card->dev->dev, "Failed to allocate sk_buff in pclose()\n");
-		return;
-	}
-	header = skb_put(skb, sizeof(*header));
-
-	header->size = cpu_to_le16(0);
-	header->vpi = cpu_to_le16(vcc->vpi);
-	header->vci = cpu_to_le16(vcc->vci);
-	header->type = cpu_to_le16(PKT_PCLOSE);
-
-	skb_get(skb);
-	fpga_queue(card, port, skb, NULL);
-
-	if (!wait_event_timeout(card->param_wq, !skb_shared(skb), 5 * HZ))
-		dev_warn(&card->dev->dev,
-			 "Timeout waiting for VCC close on port %d\n", port);
-
-	dev_kfree_skb(skb);
-
-	/* Hold up vcc_destroy_socket() (our caller) until solos_bh() in the
-	   tasklet has finished processing any incoming packets (and, more to
-	   the point, using the vcc pointer). */
-	tasklet_unlock_wait(&card->tlet);
-
-	clear_bit(ATM_VF_ADDR, &vcc->flags);
-
-	return;
-}
-
-static int print_buffer(struct sk_buff *buf)
-{
-	int len,i;
-	char msg[500];
-	char item[10];
-
-	len = buf->len;
-	for (i = 0; i < len; i++){
-		if(i % 8 == 0)
-			sprintf(msg, "%02X: ", i);
-
-		sprintf(item,"%02X ",*(buf->data + i));
-		strcat(msg, item);
-		if(i % 8 == 7) {
-			sprintf(item, "\n");
-			strcat(msg, item);
-			printk(KERN_DEBUG "%s", msg);
-		}
-	}
-	if (i % 8 != 0) {
-		sprintf(item, "\n");
-		strcat(msg, item);
-		printk(KERN_DEBUG "%s", msg);
-	}
-	printk(KERN_DEBUG "\n");
-
-	return 0;
-}
-
-static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
-		       struct atm_vcc *vcc)
-{
-	int old_len;
-	unsigned long flags;
-
-	SKB_CB(skb)->vcc = vcc;
-
-	spin_lock_irqsave(&card->tx_queue_lock, flags);
-	old_len = skb_queue_len(&card->tx_queue[port]);
-	skb_queue_tail(&card->tx_queue[port], skb);
-	if (!old_len)
-		card->tx_mask |= (1 << port);
-	spin_unlock_irqrestore(&card->tx_queue_lock, flags);
-
-	/* Theoretically we could just schedule the tasklet here, but
-	   that introduces latency we don't want -- it's noticeable */
-	if (!old_len)
-		fpga_tx(card);
-}
-
-static uint32_t fpga_tx(struct solos_card *card)
-{
-	uint32_t tx_pending, card_flags;
-	uint32_t tx_started = 0;
-	struct sk_buff *skb;
-	struct atm_vcc *vcc;
-	unsigned char port;
-	unsigned long flags;
-
-	spin_lock_irqsave(&card->tx_lock, flags);
-	
-	card_flags = ioread32(card->config_regs + FLAGS_ADDR);
-	/*
-	 * The queue lock is required for _writing_ to tx_mask, but we're
-	 * OK to read it here without locking. The only potential update
-	 * that we could race with is in fpga_queue() where it sets a bit
-	 * for a new port... but it's going to call this function again if
-	 * it's doing that, anyway.
-	 */
-	tx_pending = card->tx_mask & ~card_flags;
-
-	for (port = 0; tx_pending; tx_pending >>= 1, port++) {
-		if (tx_pending & 1) {
-			struct sk_buff *oldskb = card->tx_skb[port];
-			if (oldskb) {
-				dma_unmap_single(&card->dev->dev, SKB_CB(oldskb)->dma_addr,
-						 oldskb->len, DMA_TO_DEVICE);
-				card->tx_skb[port] = NULL;
-			}
-			spin_lock(&card->tx_queue_lock);
-			skb = skb_dequeue(&card->tx_queue[port]);
-			if (!skb)
-				card->tx_mask &= ~(1 << port);
-			spin_unlock(&card->tx_queue_lock);
-
-			if (skb && !card->using_dma) {
-				memcpy_toio(TX_BUF(card, port), skb->data, skb->len);
-				tx_started |= 1 << port;
-				oldskb = skb; /* We're done with this skb already */
-			} else if (skb && card->using_dma) {
-				unsigned char *data = skb->data;
-				if ((unsigned long)data & card->dma_alignment) {
-					data = card->dma_bounce + (BUF_SIZE * port);
-					memcpy(data, skb->data, skb->len);
-				}
-				SKB_CB(skb)->dma_addr = dma_map_single(&card->dev->dev, data,
-								       skb->len, DMA_TO_DEVICE);
-				card->tx_skb[port] = skb;
-				iowrite32(SKB_CB(skb)->dma_addr,
-					  card->config_regs + TX_DMA_ADDR(port));
-			}
-
-			if (!oldskb)
-				continue;
-
-			/* Clean up and free oldskb now it's gone */
-			if (atmdebug) {
-				struct pkt_hdr *header = (void *)oldskb->data;
-				int size = le16_to_cpu(header->size);
-
-				skb_pull(oldskb, sizeof(*header));
-				dev_info(&card->dev->dev, "Transmitted: port %d\n",
-					 port);
-				dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
-					 size, le16_to_cpu(header->vpi),
-					 le16_to_cpu(header->vci));
-				print_buffer(oldskb);
-			}
-
-			vcc = SKB_CB(oldskb)->vcc;
-
-			if (vcc) {
-				atomic_inc(&vcc->stats->tx);
-				solos_pop(vcc, oldskb);
-			} else {
-				dev_kfree_skb_irq(oldskb);
-				wake_up(&card->param_wq);
-			}
-		}
-	}
-	/* For non-DMA TX, write the 'TX start' bit for all four ports simultaneously */
-	if (tx_started)
-		iowrite32(tx_started, card->config_regs + FLAGS_ADDR);
-
-	spin_unlock_irqrestore(&card->tx_lock, flags);
-	return card_flags;
-}
-
-static int psend(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	struct solos_card *card = vcc->dev->dev_data;
-	struct pkt_hdr *header;
-	int pktlen;
-
-	pktlen = skb->len;
-	if (pktlen > (BUF_SIZE - sizeof(*header))) {
-		dev_warn(&card->dev->dev, "Length of PDU is too large. Dropping PDU.\n");
-		solos_pop(vcc, skb);
-		return 0;
-	}
-
-	if (!skb_clone_writable(skb, sizeof(*header))) {
-		int expand_by = 0;
-		int ret;
-
-		if (skb_headroom(skb) < sizeof(*header))
-			expand_by = sizeof(*header) - skb_headroom(skb);
-
-		ret = pskb_expand_head(skb, expand_by, 0, GFP_ATOMIC);
-		if (ret) {
-			dev_warn(&card->dev->dev, "pskb_expand_head failed.\n");
-			solos_pop(vcc, skb);
-			return ret;
-		}
-	}
-
-	header = skb_push(skb, sizeof(*header));
-
-	/* This does _not_ include the size of the header */
-	header->size = cpu_to_le16(pktlen);
-	header->vpi = cpu_to_le16(vcc->vpi);
-	header->vci = cpu_to_le16(vcc->vci);
-	header->type = cpu_to_le16(PKT_DATA);
-
-	fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, vcc);
-
-	return 0;
-}
-
-static const struct atmdev_ops fpga_ops = {
-	.open =		popen,
-	.close =	pclose,
-	.ioctl =	NULL,
-	.send =		psend,
-	.send_oam =	NULL,
-	.phy_put =	NULL,
-	.phy_get =	NULL,
-	.change_qos =	NULL,
-	.proc_read =	NULL,
-	.owner =	THIS_MODULE
-};
-
-static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
-	int err;
-	uint16_t fpga_ver;
-	uint8_t major_ver, minor_ver;
-	uint32_t data32;
-	struct solos_card *card;
-
-	card = kzalloc_obj(*card);
-	if (!card)
-		return -ENOMEM;
-
-	card->dev = dev;
-	init_waitqueue_head(&card->fw_wq);
-	init_waitqueue_head(&card->param_wq);
-
-	err = pci_enable_device(dev);
-	if (err) {
-		dev_warn(&dev->dev,  "Failed to enable PCI device\n");
-		goto out;
-	}
-
-	err = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
-	if (err) {
-		dev_warn(&dev->dev, "Failed to set 32-bit DMA mask\n");
-		goto out;
-	}
-
-	err = pci_request_regions(dev, "solos");
-	if (err) {
-		dev_warn(&dev->dev, "Failed to request regions\n");
-		goto out;
-	}
-
-	card->config_regs = pci_iomap(dev, 0, CONFIG_RAM_SIZE);
-	if (!card->config_regs) {
-		dev_warn(&dev->dev, "Failed to ioremap config registers\n");
-		err = -ENOMEM;
-		goto out_release_regions;
-	}
-	card->buffers = pci_iomap(dev, 1, DATA_RAM_SIZE);
-	if (!card->buffers) {
-		dev_warn(&dev->dev, "Failed to ioremap data buffers\n");
-		err = -ENOMEM;
-		goto out_unmap_config;
-	}
-
-	if (reset) {
-		iowrite32(1, card->config_regs + FPGA_MODE);
-		ioread32(card->config_regs + FPGA_MODE);
-
-		iowrite32(0, card->config_regs + FPGA_MODE);
-		ioread32(card->config_regs + FPGA_MODE);
-	}
-
-	data32 = ioread32(card->config_regs + FPGA_VER);
-	fpga_ver = (data32 & 0x0000FFFF);
-	major_ver = ((data32 & 0xFF000000) >> 24);
-	minor_ver = ((data32 & 0x00FF0000) >> 16);
-	card->fpga_version = FPGA_VERSION(major_ver,minor_ver);
-	if (card->fpga_version > LEGACY_BUFFERS)
-		card->buffer_size = BUF_SIZE;
-	else
-		card->buffer_size = OLD_BUF_SIZE;
-	dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n",
-		 major_ver, minor_ver, fpga_ver);
-
-	if (fpga_ver < 37 && (fpga_upgrade || firmware_upgrade ||
-			      db_fpga_upgrade || db_firmware_upgrade)) {
-		dev_warn(&dev->dev,
-			 "FPGA too old; cannot upgrade flash. Use JTAG.\n");
-		fpga_upgrade = firmware_upgrade = 0;
-		db_fpga_upgrade = db_firmware_upgrade = 0;
-	}
-
-	/* Stopped using Atmel flash after 0.03-38 */
-	if (fpga_ver < 39)
-		card->atmel_flash = 1;
-	else
-		card->atmel_flash = 0;
-
-	data32 = ioread32(card->config_regs + PORTS);
-	card->nr_ports = (data32 & 0x000000FF);
-
-	if (card->fpga_version >= DMA_SUPPORTED) {
-		pci_set_master(dev);
-		card->using_dma = 1;
-		if (1) { /* All known FPGA versions so far */
-			card->dma_alignment = 3;
-			card->dma_bounce = kmalloc_array(card->nr_ports,
-							 BUF_SIZE, GFP_KERNEL);
-			if (!card->dma_bounce) {
-				dev_warn(&card->dev->dev, "Failed to allocate DMA bounce buffers\n");
-				err = -ENOMEM;
-				/* Fallback to MMIO doesn't work */
-				goto out_unmap_both;
-			}
-		}
-	} else {
-		card->using_dma = 0;
-		/* Set RX empty flag for all ports */
-		iowrite32(0xF0, card->config_regs + FLAGS_ADDR);
-	}
-
-	pci_set_drvdata(dev, card);
-
-	tasklet_init(&card->tlet, solos_bh, (unsigned long)card);
-	spin_lock_init(&card->tx_lock);
-	spin_lock_init(&card->tx_queue_lock);
-	spin_lock_init(&card->cli_queue_lock);
-	spin_lock_init(&card->param_queue_lock);
-	INIT_LIST_HEAD(&card->param_queue);
-
-	err = request_irq(dev->irq, solos_irq, IRQF_SHARED,
-			  "solos-pci", card);
-	if (err) {
-		dev_dbg(&card->dev->dev, "Failed to request interrupt IRQ: %d\n", dev->irq);
-		goto out_unmap_both;
-	}
-
-	iowrite32(1, card->config_regs + IRQ_EN_ADDR);
-
-	if (fpga_upgrade)
-		flash_upgrade(card, 0);
-
-	if (firmware_upgrade)
-		flash_upgrade(card, 1);
-
-	if (db_fpga_upgrade)
-		flash_upgrade(card, 2);
-
-	if (db_firmware_upgrade)
-		flash_upgrade(card, 3);
-
-	err = atm_init(card, &dev->dev);
-	if (err)
-		goto out_free_irq;
-
-	if (card->fpga_version >= DMA_SUPPORTED &&
-	    sysfs_create_group(&card->dev->dev.kobj, &gpio_attr_group))
-		dev_err(&card->dev->dev, "Could not register parameter group for GPIOs\n");
-
-	return 0;
-
- out_free_irq:
-	iowrite32(0, card->config_regs + IRQ_EN_ADDR);
-	free_irq(dev->irq, card);
-	tasklet_kill(&card->tlet);
-	
- out_unmap_both:
-	kfree(card->dma_bounce);
-	pci_iounmap(dev, card->buffers);
- out_unmap_config:
-	pci_iounmap(dev, card->config_regs);
- out_release_regions:
-	pci_release_regions(dev);
- out:
-	kfree(card);
-	return err;
-}
-
-static int atm_init(struct solos_card *card, struct device *parent)
-{
-	int i;
-
-	for (i = 0; i < card->nr_ports; i++) {
-		struct sk_buff *skb;
-		struct pkt_hdr *header;
-
-		skb_queue_head_init(&card->tx_queue[i]);
-		skb_queue_head_init(&card->cli_queue[i]);
-
-		card->atmdev[i] = atm_dev_register("solos-pci", parent, &fpga_ops, -1, NULL);
-		if (!card->atmdev[i]) {
-			dev_err(&card->dev->dev, "Could not register ATM device %d\n", i);
-			atm_remove(card);
-			return -ENODEV;
-		}
-		if (device_create_file(&card->atmdev[i]->class_dev, &dev_attr_console))
-			dev_err(&card->dev->dev, "Could not register console for ATM device %d\n", i);
-		if (sysfs_create_group(&card->atmdev[i]->class_dev.kobj, &solos_attr_group))
-			dev_err(&card->dev->dev, "Could not register parameter group for ATM device %d\n", i);
-
-		dev_info(&card->dev->dev, "Registered ATM device %d\n", card->atmdev[i]->number);
-
-		card->atmdev[i]->ci_range.vpi_bits = 8;
-		card->atmdev[i]->ci_range.vci_bits = 16;
-		card->atmdev[i]->dev_data = card;
-		card->atmdev[i]->phy_data = (void *)(unsigned long)i;
-		atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_FOUND);
-
-		skb = alloc_skb(sizeof(*header), GFP_KERNEL);
-		if (!skb) {
-			dev_warn(&card->dev->dev, "Failed to allocate sk_buff in atm_init()\n");
-			continue;
-		}
-
-		header = skb_put(skb, sizeof(*header));
-
-		header->size = cpu_to_le16(0);
-		header->vpi = cpu_to_le16(0);
-		header->vci = cpu_to_le16(0);
-		header->type = cpu_to_le16(PKT_STATUS);
-
-		fpga_queue(card, i, skb, NULL);
-	}
-	return 0;
-}
-
-static void atm_remove(struct solos_card *card)
-{
-	int i;
-
-	for (i = 0; i < card->nr_ports; i++) {
-		if (card->atmdev[i]) {
-			struct sk_buff *skb;
-
-			dev_info(&card->dev->dev, "Unregistering ATM device %d\n", card->atmdev[i]->number);
-
-			sysfs_remove_group(&card->atmdev[i]->class_dev.kobj, &solos_attr_group);
-			atm_dev_deregister(card->atmdev[i]);
-
-			skb = card->rx_skb[i];
-			if (skb) {
-				dma_unmap_single(&card->dev->dev, SKB_CB(skb)->dma_addr,
-						 RX_DMA_SIZE, DMA_FROM_DEVICE);
-				dev_kfree_skb(skb);
-			}
-			skb = card->tx_skb[i];
-			if (skb) {
-				dma_unmap_single(&card->dev->dev, SKB_CB(skb)->dma_addr,
-						 skb->len, DMA_TO_DEVICE);
-				dev_kfree_skb(skb);
-			}
-			while ((skb = skb_dequeue(&card->tx_queue[i])))
-				dev_kfree_skb(skb);
- 
-		}
-	}
-}
-
-static void fpga_remove(struct pci_dev *dev)
-{
-	struct solos_card *card = pci_get_drvdata(dev);
-	
-	/* Disable IRQs */
-	iowrite32(0, card->config_regs + IRQ_EN_ADDR);
-
-	/* Reset FPGA */
-	iowrite32(1, card->config_regs + FPGA_MODE);
-	(void)ioread32(card->config_regs + FPGA_MODE); 
-
-	if (card->fpga_version >= DMA_SUPPORTED)
-		sysfs_remove_group(&card->dev->dev.kobj, &gpio_attr_group);
-
-	atm_remove(card);
-
-	free_irq(dev->irq, card);
-	tasklet_kill(&card->tlet);
-
-	kfree(card->dma_bounce);
-
-	/* Release device from reset */
-	iowrite32(0, card->config_regs + FPGA_MODE);
-	(void)ioread32(card->config_regs + FPGA_MODE); 
-
-	pci_iounmap(dev, card->buffers);
-	pci_iounmap(dev, card->config_regs);
-
-	pci_release_regions(dev);
-	pci_disable_device(dev);
-
-	kfree(card);
-}
-
-static const struct pci_device_id fpga_pci_tbl[] = {
-	{ 0x10ee, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ 0, }
-};
-
-MODULE_DEVICE_TABLE(pci,fpga_pci_tbl);
-
-static struct pci_driver fpga_driver = {
-	.name =		"solos",
-	.id_table =	fpga_pci_tbl,
-	.probe =	fpga_probe,
-	.remove =	fpga_remove,
-};
-
-
-static int __init solos_pci_init(void)
-{
-	BUILD_BUG_ON(sizeof(struct solos_skb_cb) > sizeof(((struct sk_buff *)0)->cb));
-
-	printk(KERN_INFO "Solos PCI Driver Version %s\n", VERSION);
-	return pci_register_driver(&fpga_driver);
-}
-
-static void __exit solos_pci_exit(void)
-{
-	pci_unregister_driver(&fpga_driver);
-	printk(KERN_INFO "Solos PCI Driver %s Unloaded\n", VERSION);
-}
-
-module_init(solos_pci_init);
-module_exit(solos_pci_exit);
diff --git a/drivers/atm/suni.c b/drivers/atm/suni.c
deleted file mode 100644
index bb588c98216d..000000000000
--- a/drivers/atm/suni.c
+++ /dev/null
@@ -1,391 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * drivers/atm/suni.c - S/UNI PHY driver
- *
- * Supports the following:
- * 	PMC PM5346 S/UNI LITE
- * 	PMC PM5350 S/UNI 155 ULTRA
- * 	PMC PM5355 S/UNI 622
- */
- 
-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
-
-#include <linux/module.h>
-#include <linux/jiffies.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/atmdev.h>
-#include <linux/sonet.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/capability.h>
-#include <linux/slab.h>
-#include <asm/param.h>
-#include <linux/uaccess.h>
-#include <linux/atomic.h>
-
-#include "suni.h"
-
-
-#if 0
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
-#define PRIV(dev) ((struct suni_priv *) dev->phy_data)
-
-#define PUT(val,reg) dev->ops->phy_put(dev,val,SUNI_##reg)
-#define GET(reg) dev->ops->phy_get(dev,SUNI_##reg)
-#define REG_CHANGE(mask,shift,value,reg) \
-  PUT((GET(reg) & ~(mask)) | ((value) << (shift)),reg)
-
-
-static struct timer_list poll_timer;
-static struct suni_priv *sunis = NULL;
-static DEFINE_SPINLOCK(sunis_lock);
-
-
-#define ADD_LIMITED(s,v) \
-    atomic_add((v),&stats->s); \
-    if (atomic_read(&stats->s) < 0) atomic_set(&stats->s,INT_MAX);
-
-
-static void suni_hz(struct timer_list *timer)
-{
-	struct suni_priv *walk;
-	struct atm_dev *dev;
-	struct k_sonet_stats *stats;
-
-	for (walk = sunis; walk; walk = walk->next) {
-		dev = walk->dev;
-		stats = &walk->sonet_stats;
-		PUT(0,MRI); /* latch counters */
-		udelay(1);
-		ADD_LIMITED(section_bip,(GET(RSOP_SBL) & 0xff) |
-		    ((GET(RSOP_SBM) & 0xff) << 8));
-		ADD_LIMITED(line_bip,(GET(RLOP_LBL) & 0xff) |
-		    ((GET(RLOP_LB) & 0xff) << 8) |
-		    ((GET(RLOP_LBM) & 0xf) << 16));
-		ADD_LIMITED(path_bip,(GET(RPOP_PBL) & 0xff) |
-		    ((GET(RPOP_PBM) & 0xff) << 8));
-		ADD_LIMITED(line_febe,(GET(RLOP_LFL) & 0xff) |
-		    ((GET(RLOP_LF) & 0xff) << 8) |
-		    ((GET(RLOP_LFM) & 0xf) << 16));
-		ADD_LIMITED(path_febe,(GET(RPOP_PFL) & 0xff) |
-		    ((GET(RPOP_PFM) & 0xff) << 8));
-		ADD_LIMITED(corr_hcs,GET(RACP_CHEC) & 0xff);
-		ADD_LIMITED(uncorr_hcs,GET(RACP_UHEC) & 0xff);
-		ADD_LIMITED(rx_cells,(GET(RACP_RCCL) & 0xff) |
-		    ((GET(RACP_RCC) & 0xff) << 8) |
-		    ((GET(RACP_RCCM) & 7) << 16));
-		ADD_LIMITED(tx_cells,(GET(TACP_TCCL) & 0xff) |
-		    ((GET(TACP_TCC) & 0xff) << 8) |
-		    ((GET(TACP_TCCM) & 7) << 16));
-	}
-	if (timer) mod_timer(&poll_timer,jiffies+HZ);
-}
-
-
-#undef ADD_LIMITED
-
-
-static int fetch_stats(struct atm_dev *dev,struct sonet_stats __user *arg,int zero)
-{
-	struct sonet_stats tmp;
-	int error = 0;
-
-	sonet_copy_stats(&PRIV(dev)->sonet_stats,&tmp);
-	if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp));
-	if (zero && !error) sonet_subtract_stats(&PRIV(dev)->sonet_stats,&tmp);
-	return error ? -EFAULT : 0;
-}
-
-
-#define HANDLE_FLAG(flag,reg,bit) \
-  if (todo & flag) { \
-    if (set) PUT(GET(reg) | bit,reg); \
-    else PUT(GET(reg) & ~bit,reg); \
-    todo &= ~flag; \
-  }
-
-
-static int change_diag(struct atm_dev *dev,void __user *arg,int set)
-{
-	int todo;
-
-	if (get_user(todo,(int __user *)arg)) return -EFAULT;
-	HANDLE_FLAG(SONET_INS_SBIP,TSOP_DIAG,SUNI_TSOP_DIAG_DBIP8);
-	HANDLE_FLAG(SONET_INS_LBIP,TLOP_DIAG,SUNI_TLOP_DIAG_DBIP);
-	HANDLE_FLAG(SONET_INS_PBIP,TPOP_CD,SUNI_TPOP_DIAG_DB3);
-	HANDLE_FLAG(SONET_INS_FRAME,RSOP_CIE,SUNI_RSOP_CIE_FOOF);
-	HANDLE_FLAG(SONET_INS_LAIS,TSOP_CTRL,SUNI_TSOP_CTRL_LAIS);
-	HANDLE_FLAG(SONET_INS_PAIS,TPOP_CD,SUNI_TPOP_DIAG_PAIS);
-	HANDLE_FLAG(SONET_INS_LOS,TSOP_DIAG,SUNI_TSOP_DIAG_DLOS);
-	HANDLE_FLAG(SONET_INS_HCS,TACP_CS,SUNI_TACP_CS_DHCS);
-	return put_user(todo,(int __user *)arg) ? -EFAULT : 0;
-}
-
-
-#undef HANDLE_FLAG
-
-
-static int get_diag(struct atm_dev *dev,void __user *arg)
-{
-	int set;
-
-	set = 0;
-	if (GET(TSOP_DIAG) & SUNI_TSOP_DIAG_DBIP8) set |= SONET_INS_SBIP;
-	if (GET(TLOP_DIAG) & SUNI_TLOP_DIAG_DBIP) set |= SONET_INS_LBIP;
-	if (GET(TPOP_CD) & SUNI_TPOP_DIAG_DB3) set |= SONET_INS_PBIP;
-	/* SONET_INS_FRAME is one-shot only */
-	if (GET(TSOP_CTRL) & SUNI_TSOP_CTRL_LAIS) set |= SONET_INS_LAIS;
-	if (GET(TPOP_CD) & SUNI_TPOP_DIAG_PAIS) set |= SONET_INS_PAIS;
-	if (GET(TSOP_DIAG) & SUNI_TSOP_DIAG_DLOS) set |= SONET_INS_LOS;
-	if (GET(TACP_CS) & SUNI_TACP_CS_DHCS) set |= SONET_INS_HCS;
-	return put_user(set,(int __user *)arg) ? -EFAULT : 0;
-}
-
-
-static int set_loopback(struct atm_dev *dev,int mode)
-{
-	unsigned char control;
-	int reg, dle, lle;
-
-	if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) {
-		reg = SUNI_MCM;
-		dle = SUNI_MCM_DLE;
-		lle = SUNI_MCM_LLE;
-	} else {
-		reg = SUNI_MCT;
-		dle = SUNI_MCT_DLE;
-		lle = SUNI_MCT_LLE;
-	}
-
-	control = dev->ops->phy_get(dev, reg) & ~(dle | lle);
-	switch (mode) {
-		case ATM_LM_NONE:
-			break;
-		case ATM_LM_LOC_PHY:
-			control |= dle;
-			break;
-		case ATM_LM_RMT_PHY:
-			control |= lle;
-			break;
-		default:
-			return -EINVAL;
-	}
-	dev->ops->phy_put(dev, control, reg);
-	PRIV(dev)->loop_mode = mode;
-	return 0;
-}
-
-/*
- * SONET vs. SDH Configuration
- *
- * Z0INS (register 0x06): 0 for SONET, 1 for SDH
- * ENSS (register 0x3D): 0 for SONET, 1 for SDH
- * LEN16 (register 0x28): 0 for SONET, 1 for SDH (n/a for S/UNI 155 QUAD)
- * LEN16 (register 0x50): 0 for SONET, 1 for SDH (n/a for S/UNI 155 QUAD)
- * S[1:0] (register 0x46): 00 for SONET, 10 for SDH
- */
-
-static int set_sonet(struct atm_dev *dev)
-{
-	if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) {
-		PUT(GET(RPOP_RC) & ~SUNI_RPOP_RC_ENSS, RPOP_RC);
-		PUT(GET(SSTB_CTRL) & ~SUNI_SSTB_CTRL_LEN16, SSTB_CTRL);
-		PUT(GET(SPTB_CTRL) & ~SUNI_SPTB_CTRL_LEN16, SPTB_CTRL);
-	}
-
-	REG_CHANGE(SUNI_TPOP_APM_S, SUNI_TPOP_APM_S_SHIFT,
-		   SUNI_TPOP_S_SONET, TPOP_APM);
-
-	return 0;
-}
-
-static int set_sdh(struct atm_dev *dev)
-{
-	if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) {
-		PUT(GET(RPOP_RC) | SUNI_RPOP_RC_ENSS, RPOP_RC);
-		PUT(GET(SSTB_CTRL) | SUNI_SSTB_CTRL_LEN16, SSTB_CTRL);
-		PUT(GET(SPTB_CTRL) | SUNI_SPTB_CTRL_LEN16, SPTB_CTRL);
-	}
-
-	REG_CHANGE(SUNI_TPOP_APM_S, SUNI_TPOP_APM_S_SHIFT,
-		   SUNI_TPOP_S_SDH, TPOP_APM);
-
-	return 0;
-}
-
-
-static int get_framing(struct atm_dev *dev, void __user *arg)
-{
-	int framing;
-	unsigned char s;
-
-
-	s = (GET(TPOP_APM) & SUNI_TPOP_APM_S) >> SUNI_TPOP_APM_S_SHIFT;
-	if (s == SUNI_TPOP_S_SONET)
-		framing = SONET_FRAME_SONET;
-	else
-		framing = SONET_FRAME_SDH;
-
-	return put_user(framing, (int __user *) arg) ? -EFAULT : 0;
-}
-
-static int set_framing(struct atm_dev *dev, void __user *arg)
-{
-	int mode;
-
-	if (get_user(mode, (int __user *) arg))
-		return -EFAULT;
-
-	if (mode == SONET_FRAME_SONET)
-		return set_sonet(dev);
-	else if (mode == SONET_FRAME_SDH)
-		return set_sdh(dev);
-
-	return -EINVAL;
-}
-
-
-static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
-{
-	switch (cmd) {
-		case SONET_GETSTATZ:
-		case SONET_GETSTAT:
-			return fetch_stats(dev, arg, cmd == SONET_GETSTATZ);
-		case SONET_SETDIAG:
-			return change_diag(dev,arg,1);
-		case SONET_CLRDIAG:
-			return change_diag(dev,arg,0);
-		case SONET_GETDIAG:
-			return get_diag(dev,arg);
-		case SONET_SETFRAMING:
-			if (!capable(CAP_NET_ADMIN))
-				return -EPERM;
-			return set_framing(dev, arg);
-		case SONET_GETFRAMING:
-			return get_framing(dev, arg);
-		case SONET_GETFRSENSE:
-			return -EINVAL;
-		case ATM_SETLOOP:
-			if (!capable(CAP_NET_ADMIN))
-				return -EPERM;
-			return set_loopback(dev,(int)(unsigned long)arg);
-		case ATM_GETLOOP:
-			return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ?
-			    -EFAULT : 0;
-		case ATM_QUERYLOOP:
-			return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY,
-			    (int __user *) arg) ? -EFAULT : 0;
-		default:
-			return -ENOIOCTLCMD;
-	}
-}
-
-
-static void poll_los(struct atm_dev *dev)
-{
-	atm_dev_signal_change(dev,
-		GET(RSOP_SIS) & SUNI_RSOP_SIS_LOSV ?
-		ATM_PHY_SIG_LOST : ATM_PHY_SIG_FOUND);
-}
-
-
-static void suni_int(struct atm_dev *dev)
-{
-	poll_los(dev);
-	printk(KERN_NOTICE "%s(itf %d): signal %s\n",dev->type,dev->number,
-	    dev->signal == ATM_PHY_SIG_LOST ?  "lost" : "detected again");
-}
-
-
-static int suni_start(struct atm_dev *dev)
-{
-	unsigned long flags;
-	int first;
-
-	spin_lock_irqsave(&sunis_lock,flags);
-	first = !sunis;
-	PRIV(dev)->next = sunis;
-	sunis = PRIV(dev);
-	spin_unlock_irqrestore(&sunis_lock,flags);
-	memset(&PRIV(dev)->sonet_stats,0,sizeof(struct k_sonet_stats));
-	PUT(GET(RSOP_CIE) | SUNI_RSOP_CIE_LOSE,RSOP_CIE);
-		/* interrupt on loss of signal */
-	poll_los(dev); /* ... and clear SUNI interrupts */
-	if (dev->signal == ATM_PHY_SIG_LOST)
-		printk(KERN_WARNING "%s(itf %d): no signal\n",dev->type,
-		    dev->number);
-	PRIV(dev)->loop_mode = ATM_LM_NONE;
-	suni_hz(NULL); /* clear SUNI counters */
-	(void) fetch_stats(dev,NULL,1); /* clear kernel counters */
-	if (first) {
-		timer_setup(&poll_timer, suni_hz, 0);
-		poll_timer.expires = jiffies+HZ;
-#if 0
-printk(KERN_DEBUG "[u] p=0x%lx,n=0x%lx\n",(unsigned long) poll_timer.list.prev,
-    (unsigned long) poll_timer.list.next);
-#endif
-		add_timer(&poll_timer);
-	}
-	return 0;
-}
-
-
-static int suni_stop(struct atm_dev *dev)
-{
-	struct suni_priv **walk;
-	unsigned long flags;
-
-	/* let SAR driver worry about stopping interrupts */
-	spin_lock_irqsave(&sunis_lock,flags);
-	for (walk = &sunis; *walk != PRIV(dev);
-	    walk = &PRIV((*walk)->dev)->next);
-	*walk = PRIV((*walk)->dev)->next;
-	if (!sunis) timer_delete_sync(&poll_timer);
-	spin_unlock_irqrestore(&sunis_lock,flags);
-	kfree(PRIV(dev));
-
-	return 0;
-}
-
-
-static const struct atmphy_ops suni_ops = {
-	.start		= suni_start,
-	.ioctl		= suni_ioctl,
-	.interrupt	= suni_int,
-	.stop		= suni_stop,
-};
-
-
-int suni_init(struct atm_dev *dev)
-{
-	unsigned char mri;
-
-	if (!(dev->phy_data = kmalloc_obj(struct suni_priv)))
-		return -ENOMEM;
-	PRIV(dev)->dev = dev;
-
-	mri = GET(MRI); /* reset SUNI */
-	PRIV(dev)->type = (mri & SUNI_MRI_TYPE) >> SUNI_MRI_TYPE_SHIFT;
-	PUT(mri | SUNI_MRI_RESET,MRI);
-	PUT(mri,MRI);
-	PUT((GET(MT) & SUNI_MT_DS27_53),MT); /* disable all tests */
-        set_sonet(dev);
-	REG_CHANGE(SUNI_TACP_IUCHP_CLP,0,SUNI_TACP_IUCHP_CLP,
-	    TACP_IUCHP); /* idle cells */
-	PUT(SUNI_IDLE_PATTERN,TACP_IUCPOP);
-	dev->phy = &suni_ops;
-
-	return 0;
-}
-
-EXPORT_SYMBOL(suni_init);
-
-MODULE_DESCRIPTION("S/UNI PHY driver");
-MODULE_LICENSE("GPL");
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
deleted file mode 100644
index 6580d67c3456..000000000000
--- a/net/atm/br2684.c
+++ /dev/null
@@ -1,872 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Ethernet netdevice using ATM AAL5 as underlying carrier
- * (RFC1483 obsoleted by RFC2684) for Linux
- *
- * Authors: Marcell GAL, 2000, XDSL Ltd, Hungary
- *          Eric Kinzie, 2006-2007, US Naval Research Laboratory
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <linux/etherdevice.h>
-#include <linux/rtnetlink.h>
-#include <linux/ip.h>
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <net/arp.h>
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <linux/capability.h>
-#include <linux/seq_file.h>
-
-#include <linux/atmbr2684.h>
-
-#include "common.h"
-
-static void skb_debug(const struct sk_buff *skb)
-{
-#ifdef SKB_DEBUG
-#define NUM2PRINT 50
-	print_hex_dump(KERN_DEBUG, "br2684: skb: ", DUMP_OFFSET,
-		       16, 1, skb->data, min(NUM2PRINT, skb->len), true);
-#endif
-}
-
-#define BR2684_ETHERTYPE_LEN	2
-#define BR2684_PAD_LEN		2
-
-#define LLC		0xaa, 0xaa, 0x03
-#define SNAP_BRIDGED	0x00, 0x80, 0xc2
-#define SNAP_ROUTED	0x00, 0x00, 0x00
-#define PID_ETHERNET	0x00, 0x07
-#define ETHERTYPE_IPV4	0x08, 0x00
-#define ETHERTYPE_IPV6	0x86, 0xdd
-#define PAD_BRIDGED	0x00, 0x00
-
-static const unsigned char ethertype_ipv4[] = { ETHERTYPE_IPV4 };
-static const unsigned char ethertype_ipv6[] = { ETHERTYPE_IPV6 };
-static const unsigned char llc_oui_pid_pad[] =
-			{ LLC, SNAP_BRIDGED, PID_ETHERNET, PAD_BRIDGED };
-static const unsigned char pad[] = { PAD_BRIDGED };
-static const unsigned char llc_oui_ipv4[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV4 };
-static const unsigned char llc_oui_ipv6[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV6 };
-
-enum br2684_encaps {
-	e_vc = BR2684_ENCAPS_VC,
-	e_llc = BR2684_ENCAPS_LLC,
-};
-
-struct br2684_vcc {
-	struct atm_vcc *atmvcc;
-	struct net_device *device;
-	/* keep old push, pop functions for chaining */
-	void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb);
-	void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb);
-	void (*old_release_cb)(struct atm_vcc *vcc);
-	struct module *old_owner;
-	enum br2684_encaps encaps;
-	struct list_head brvccs;
-#ifdef CONFIG_ATM_BR2684_IPFILTER
-	struct br2684_filter filter;
-#endif /* CONFIG_ATM_BR2684_IPFILTER */
-	unsigned int copies_needed, copies_failed;
-	atomic_t qspace;
-};
-
-struct br2684_dev {
-	struct net_device *net_dev;
-	struct list_head br2684_devs;
-	int number;
-	struct list_head brvccs;	/* one device <=> one vcc (before xmas) */
-	int mac_was_set;
-	enum br2684_payload payload;
-};
-
-/*
- * This lock should be held for writing any time the list of devices or
- * their attached vcc's could be altered.  It should be held for reading
- * any time these are being queried.  Note that we sometimes need to
- * do read-locking under interrupting context, so write locking must block
- * the current CPU's interrupts.
- */
-static DEFINE_RWLOCK(devs_lock);
-
-static LIST_HEAD(br2684_devs);
-
-static inline struct br2684_dev *BRPRIV(const struct net_device *net_dev)
-{
-	return netdev_priv(net_dev);
-}
-
-static inline struct net_device *list_entry_brdev(const struct list_head *le)
-{
-	return list_entry(le, struct br2684_dev, br2684_devs)->net_dev;
-}
-
-static inline struct br2684_vcc *BR2684_VCC(const struct atm_vcc *atmvcc)
-{
-	return (struct br2684_vcc *)(atmvcc->user_back);
-}
-
-static inline struct br2684_vcc *list_entry_brvcc(const struct list_head *le)
-{
-	return list_entry(le, struct br2684_vcc, brvccs);
-}
-
-/* Caller should hold read_lock(&devs_lock) */
-static struct net_device *br2684_find_dev(const struct br2684_if_spec *s)
-{
-	struct list_head *lh;
-	struct net_device *net_dev;
-	switch (s->method) {
-	case BR2684_FIND_BYNUM:
-		list_for_each(lh, &br2684_devs) {
-			net_dev = list_entry_brdev(lh);
-			if (BRPRIV(net_dev)->number == s->spec.devnum)
-				return net_dev;
-		}
-		break;
-	case BR2684_FIND_BYIFNAME:
-		list_for_each(lh, &br2684_devs) {
-			net_dev = list_entry_brdev(lh);
-			if (!strncmp(net_dev->name, s->spec.ifname, IFNAMSIZ))
-				return net_dev;
-		}
-		break;
-	}
-	return NULL;
-}
-
-static int atm_dev_event(struct notifier_block *this, unsigned long event,
-		 void *arg)
-{
-	struct atm_dev *atm_dev = arg;
-	struct list_head *lh;
-	struct net_device *net_dev;
-	struct br2684_vcc *brvcc;
-	struct atm_vcc *atm_vcc;
-	unsigned long flags;
-
-	pr_debug("event=%ld dev=%p\n", event, atm_dev);
-
-	read_lock_irqsave(&devs_lock, flags);
-	list_for_each(lh, &br2684_devs) {
-		net_dev = list_entry_brdev(lh);
-
-		list_for_each_entry(brvcc, &BRPRIV(net_dev)->brvccs, brvccs) {
-			atm_vcc = brvcc->atmvcc;
-			if (atm_vcc && brvcc->atmvcc->dev == atm_dev) {
-
-				if (atm_vcc->dev->signal == ATM_PHY_SIG_LOST)
-					netif_carrier_off(net_dev);
-				else
-					netif_carrier_on(net_dev);
-
-			}
-		}
-	}
-	read_unlock_irqrestore(&devs_lock, flags);
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block atm_dev_notifier = {
-	.notifier_call = atm_dev_event,
-};
-
-/* chained vcc->pop function.  Check if we should wake the netif_queue */
-static void br2684_pop(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	struct br2684_vcc *brvcc = BR2684_VCC(vcc);
-
-	pr_debug("(vcc %p ; net_dev %p )\n", vcc, brvcc->device);
-	brvcc->old_pop(vcc, skb);
-
-	/* If the queue space just went up from zero, wake */
-	if (atomic_inc_return(&brvcc->qspace) == 1)
-		netif_wake_queue(brvcc->device);
-}
-
-/*
- * Send a packet out a particular vcc.  Not to useful right now, but paves
- * the way for multiple vcc's per itf.  Returns true if we can send,
- * otherwise false
- */
-static int br2684_xmit_vcc(struct sk_buff *skb, struct net_device *dev,
-			   struct br2684_vcc *brvcc)
-{
-	struct br2684_dev *brdev = BRPRIV(dev);
-	struct atm_vcc *atmvcc;
-	int minheadroom = (brvcc->encaps == e_llc) ?
-		((brdev->payload == p_bridged) ?
-			sizeof(llc_oui_pid_pad) : sizeof(llc_oui_ipv4)) :
-		((brdev->payload == p_bridged) ? BR2684_PAD_LEN : 0);
-
-	if (skb_headroom(skb) < minheadroom) {
-		struct sk_buff *skb2 = skb_realloc_headroom(skb, minheadroom);
-		brvcc->copies_needed++;
-		dev_kfree_skb(skb);
-		if (skb2 == NULL) {
-			brvcc->copies_failed++;
-			return 0;
-		}
-		skb = skb2;
-	}
-
-	if (brvcc->encaps == e_llc) {
-		if (brdev->payload == p_bridged) {
-			skb_push(skb, sizeof(llc_oui_pid_pad));
-			skb_copy_to_linear_data(skb, llc_oui_pid_pad,
-						sizeof(llc_oui_pid_pad));
-		} else if (brdev->payload == p_routed) {
-			unsigned short prot = ntohs(skb->protocol);
-
-			skb_push(skb, sizeof(llc_oui_ipv4));
-			switch (prot) {
-			case ETH_P_IP:
-				skb_copy_to_linear_data(skb, llc_oui_ipv4,
-							sizeof(llc_oui_ipv4));
-				break;
-			case ETH_P_IPV6:
-				skb_copy_to_linear_data(skb, llc_oui_ipv6,
-							sizeof(llc_oui_ipv6));
-				break;
-			default:
-				dev_kfree_skb(skb);
-				return 0;
-			}
-		}
-	} else { /* e_vc */
-		if (brdev->payload == p_bridged) {
-			skb_push(skb, 2);
-			memset(skb->data, 0, 2);
-		}
-	}
-	skb_debug(skb);
-
-	ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc;
-	pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, atmvcc->dev);
-	atm_account_tx(atmvcc, skb);
-	dev->stats.tx_packets++;
-	dev->stats.tx_bytes += skb->len;
-
-	if (atomic_dec_return(&brvcc->qspace) < 1) {
-		/* No more please! */
-		netif_stop_queue(brvcc->device);
-		/* We might have raced with br2684_pop() */
-		if (unlikely(atomic_read(&brvcc->qspace) > 0))
-			netif_wake_queue(brvcc->device);
-	}
-
-	/* If this fails immediately, the skb will be freed and br2684_pop()
-	   will wake the queue if appropriate. Just return an error so that
-	   the stats are updated correctly */
-	return !atmvcc->send(atmvcc, skb);
-}
-
-static void br2684_release_cb(struct atm_vcc *atmvcc)
-{
-	struct br2684_vcc *brvcc = BR2684_VCC(atmvcc);
-
-	if (atomic_read(&brvcc->qspace) > 0)
-		netif_wake_queue(brvcc->device);
-
-	if (brvcc->old_release_cb)
-		brvcc->old_release_cb(atmvcc);
-}
-
-static inline struct br2684_vcc *pick_outgoing_vcc(const struct sk_buff *skb,
-						   const struct br2684_dev *brdev)
-{
-	return list_empty(&brdev->brvccs) ? NULL : list_entry_brvcc(brdev->brvccs.next);	/* 1 vcc/dev right now */
-}
-
-static netdev_tx_t br2684_start_xmit(struct sk_buff *skb,
-				     struct net_device *dev)
-{
-	struct br2684_dev *brdev = BRPRIV(dev);
-	struct br2684_vcc *brvcc;
-	struct atm_vcc *atmvcc;
-	netdev_tx_t ret = NETDEV_TX_OK;
-
-	pr_debug("skb_dst(skb)=%p\n", skb_dst(skb));
-	read_lock(&devs_lock);
-	brvcc = pick_outgoing_vcc(skb, brdev);
-	if (brvcc == NULL) {
-		pr_debug("no vcc attached to dev %s\n", dev->name);
-		dev->stats.tx_errors++;
-		dev->stats.tx_carrier_errors++;
-		/* netif_stop_queue(dev); */
-		dev_kfree_skb(skb);
-		goto out_devs;
-	}
-	atmvcc = brvcc->atmvcc;
-
-	bh_lock_sock(sk_atm(atmvcc));
-
-	if (test_bit(ATM_VF_RELEASED, &atmvcc->flags) ||
-	    test_bit(ATM_VF_CLOSE, &atmvcc->flags) ||
-	    !test_bit(ATM_VF_READY, &atmvcc->flags)) {
-		dev->stats.tx_dropped++;
-		dev_kfree_skb(skb);
-		goto out;
-	}
-
-	if (sock_owned_by_user(sk_atm(atmvcc))) {
-		netif_stop_queue(brvcc->device);
-		ret = NETDEV_TX_BUSY;
-		goto out;
-	}
-
-	if (!br2684_xmit_vcc(skb, dev, brvcc)) {
-		/*
-		 * We should probably use netif_*_queue() here, but that
-		 * involves added complication.  We need to walk before
-		 * we can run.
-		 *
-		 * Don't free here! this pointer might be no longer valid!
-		 */
-		dev->stats.tx_errors++;
-		dev->stats.tx_fifo_errors++;
-	}
- out:
-	bh_unlock_sock(sk_atm(atmvcc));
- out_devs:
-	read_unlock(&devs_lock);
-	return ret;
-}
-
-/*
- * We remember when the MAC gets set, so we don't override it later with
- * the ESI of the ATM card of the first VC
- */
-static int br2684_mac_addr(struct net_device *dev, void *p)
-{
-	int err = eth_mac_addr(dev, p);
-	if (!err)
-		BRPRIV(dev)->mac_was_set = 1;
-	return err;
-}
-
-#ifdef CONFIG_ATM_BR2684_IPFILTER
-/* this IOCTL is experimental. */
-static int br2684_setfilt(struct atm_vcc *atmvcc, void __user * arg)
-{
-	struct br2684_vcc *brvcc;
-	struct br2684_filter_set fs;
-
-	if (copy_from_user(&fs, arg, sizeof fs))
-		return -EFAULT;
-	if (fs.ifspec.method != BR2684_FIND_BYNOTHING) {
-		/*
-		 * This is really a per-vcc thing, but we can also search
-		 * by device.
-		 */
-		struct br2684_dev *brdev;
-		read_lock(&devs_lock);
-		brdev = BRPRIV(br2684_find_dev(&fs.ifspec));
-		if (brdev == NULL || list_empty(&brdev->brvccs) ||
-		    brdev->brvccs.next != brdev->brvccs.prev)	/* >1 VCC */
-			brvcc = NULL;
-		else
-			brvcc = list_entry_brvcc(brdev->brvccs.next);
-		read_unlock(&devs_lock);
-		if (brvcc == NULL)
-			return -ESRCH;
-	} else
-		brvcc = BR2684_VCC(atmvcc);
-	memcpy(&brvcc->filter, &fs.filter, sizeof(brvcc->filter));
-	return 0;
-}
-
-/* Returns 1 if packet should be dropped */
-static inline int
-packet_fails_filter(__be16 type, struct br2684_vcc *brvcc, struct sk_buff *skb)
-{
-	if (brvcc->filter.netmask == 0)
-		return 0;	/* no filter in place */
-	if (type == htons(ETH_P_IP) &&
-	    (((struct iphdr *)(skb->data))->daddr & brvcc->filter.
-	     netmask) == brvcc->filter.prefix)
-		return 0;
-	if (type == htons(ETH_P_ARP))
-		return 0;
-	/*
-	 * TODO: we should probably filter ARPs too.. don't want to have
-	 * them returning values that don't make sense, or is that ok?
-	 */
-	return 1;		/* drop */
-}
-#endif /* CONFIG_ATM_BR2684_IPFILTER */
-
-static void br2684_close_vcc(struct br2684_vcc *brvcc)
-{
-	pr_debug("removing VCC %p from dev %p\n", brvcc, brvcc->device);
-	write_lock_irq(&devs_lock);
-	list_del(&brvcc->brvccs);
-	write_unlock_irq(&devs_lock);
-	brvcc->atmvcc->user_back = NULL;	/* what about vcc->recvq ??? */
-	brvcc->atmvcc->release_cb = brvcc->old_release_cb;
-	brvcc->old_push(brvcc->atmvcc, NULL);	/* pass on the bad news */
-	module_put(brvcc->old_owner);
-	kfree(brvcc);
-}
-
-/* when AAL5 PDU comes in: */
-static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
-{
-	struct br2684_vcc *brvcc = BR2684_VCC(atmvcc);
-	struct net_device *net_dev = brvcc->device;
-	struct br2684_dev *brdev = BRPRIV(net_dev);
-
-	pr_debug("\n");
-
-	if (unlikely(skb == NULL)) {
-		/* skb==NULL means VCC is being destroyed */
-		br2684_close_vcc(brvcc);
-		if (list_empty(&brdev->brvccs)) {
-			write_lock_irq(&devs_lock);
-			list_del(&brdev->br2684_devs);
-			write_unlock_irq(&devs_lock);
-			unregister_netdev(net_dev);
-			free_netdev(net_dev);
-		}
-		return;
-	}
-
-	skb_debug(skb);
-	atm_return(atmvcc, skb->truesize);
-	pr_debug("skb from brdev %p\n", brdev);
-	if (brvcc->encaps == e_llc) {
-
-		if (skb->len > 7 && skb->data[7] == 0x01)
-			__skb_trim(skb, skb->len - 4);
-
-		/* accept packets that have "ipv[46]" in the snap header */
-		if ((skb->len >= (sizeof(llc_oui_ipv4))) &&
-		    (memcmp(skb->data, llc_oui_ipv4,
-			    sizeof(llc_oui_ipv4) - BR2684_ETHERTYPE_LEN) == 0)) {
-			if (memcmp(skb->data + 6, ethertype_ipv6,
-				   sizeof(ethertype_ipv6)) == 0)
-				skb->protocol = htons(ETH_P_IPV6);
-			else if (memcmp(skb->data + 6, ethertype_ipv4,
-					sizeof(ethertype_ipv4)) == 0)
-				skb->protocol = htons(ETH_P_IP);
-			else
-				goto error;
-			skb_pull(skb, sizeof(llc_oui_ipv4));
-			skb_reset_network_header(skb);
-			skb->pkt_type = PACKET_HOST;
-		/*
-		 * Let us waste some time for checking the encapsulation.
-		 * Note, that only 7 char is checked so frames with a valid FCS
-		 * are also accepted (but FCS is not checked of course).
-		 */
-		} else if ((skb->len >= sizeof(llc_oui_pid_pad)) &&
-			   (memcmp(skb->data, llc_oui_pid_pad, 7) == 0)) {
-			skb_pull(skb, sizeof(llc_oui_pid_pad));
-			skb->protocol = eth_type_trans(skb, net_dev);
-		} else
-			goto error;
-
-	} else { /* e_vc */
-		if (brdev->payload == p_routed) {
-			struct iphdr *iph;
-
-			skb_reset_network_header(skb);
-			iph = ip_hdr(skb);
-			if (iph->version == 4)
-				skb->protocol = htons(ETH_P_IP);
-			else if (iph->version == 6)
-				skb->protocol = htons(ETH_P_IPV6);
-			else
-				goto error;
-			skb->pkt_type = PACKET_HOST;
-		} else { /* p_bridged */
-			/* first 2 chars should be 0 */
-			if (memcmp(skb->data, pad, BR2684_PAD_LEN) != 0)
-				goto error;
-			skb_pull(skb, BR2684_PAD_LEN);
-			skb->protocol = eth_type_trans(skb, net_dev);
-		}
-	}
-
-#ifdef CONFIG_ATM_BR2684_IPFILTER
-	if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb)))
-		goto dropped;
-#endif /* CONFIG_ATM_BR2684_IPFILTER */
-	skb->dev = net_dev;
-	ATM_SKB(skb)->vcc = atmvcc;	/* needed ? */
-	pr_debug("received packet's protocol: %x\n", ntohs(skb->protocol));
-	skb_debug(skb);
-	/* sigh, interface is down? */
-	if (unlikely(!(net_dev->flags & IFF_UP)))
-		goto dropped;
-	net_dev->stats.rx_packets++;
-	net_dev->stats.rx_bytes += skb->len;
-	memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
-	netif_rx(skb);
-	return;
-
-dropped:
-	net_dev->stats.rx_dropped++;
-	goto free_skb;
-error:
-	net_dev->stats.rx_errors++;
-free_skb:
-	dev_kfree_skb(skb);
-}
-
-/*
- * Assign a vcc to a dev
- * Note: we do not have explicit unassign, but look at _push()
- */
-static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
-{
-	struct br2684_vcc *brvcc;
-	struct br2684_dev *brdev;
-	struct net_device *net_dev;
-	struct atm_backend_br2684 be;
-	int err;
-
-	if (copy_from_user(&be, arg, sizeof be))
-		return -EFAULT;
-	brvcc = kzalloc_obj(struct br2684_vcc);
-	if (!brvcc)
-		return -ENOMEM;
-	/*
-	 * Allow two packets in the ATM queue. One actually being sent, and one
-	 * for the ATM 'TX done' handler to send. It shouldn't take long to get
-	 * the next one from the netdev queue, when we need it. More than that
-	 * would be bufferbloat.
-	 */
-	atomic_set(&brvcc->qspace, 2);
-	write_lock_irq(&devs_lock);
-	net_dev = br2684_find_dev(&be.ifspec);
-	if (net_dev == NULL) {
-		pr_err("tried to attach to non-existent device\n");
-		err = -ENXIO;
-		goto error;
-	}
-	brdev = BRPRIV(net_dev);
-	if (atmvcc->push == NULL) {
-		err = -EBADFD;
-		goto error;
-	}
-	if (!list_empty(&brdev->brvccs)) {
-		/* Only 1 VCC/dev right now */
-		err = -EEXIST;
-		goto error;
-	}
-	if (be.fcs_in != BR2684_FCSIN_NO ||
-	    be.fcs_out != BR2684_FCSOUT_NO ||
-	    be.fcs_auto || be.has_vpiid || be.send_padding ||
-	    (be.encaps != BR2684_ENCAPS_VC &&
-	     be.encaps != BR2684_ENCAPS_LLC) ||
-	    be.min_size != 0) {
-		err = -EINVAL;
-		goto error;
-	}
-	pr_debug("vcc=%p, encaps=%d, brvcc=%p\n", atmvcc, be.encaps, brvcc);
-	if (list_empty(&brdev->brvccs) && !brdev->mac_was_set) {
-		unsigned char *esi = atmvcc->dev->esi;
-		const u8 one = 1;
-
-		if (esi[0] | esi[1] | esi[2] | esi[3] | esi[4] | esi[5])
-			dev_addr_set(net_dev, esi);
-		else
-			dev_addr_mod(net_dev, 2, &one, 1);
-	}
-	list_add(&brvcc->brvccs, &brdev->brvccs);
-	write_unlock_irq(&devs_lock);
-	brvcc->device = net_dev;
-	brvcc->atmvcc = atmvcc;
-	atmvcc->user_back = brvcc;
-	brvcc->encaps = (enum br2684_encaps)be.encaps;
-	brvcc->old_push = atmvcc->push;
-	brvcc->old_pop = atmvcc->pop;
-	brvcc->old_release_cb = atmvcc->release_cb;
-	brvcc->old_owner = atmvcc->owner;
-	barrier();
-	atmvcc->push = br2684_push;
-	atmvcc->pop = br2684_pop;
-	atmvcc->release_cb = br2684_release_cb;
-	atmvcc->owner = THIS_MODULE;
-
-	/* initialize netdev carrier state */
-	if (atmvcc->dev->signal == ATM_PHY_SIG_LOST)
-		netif_carrier_off(net_dev);
-	else
-		netif_carrier_on(net_dev);
-
-	__module_get(THIS_MODULE);
-
-	/* re-process everything received between connection setup and
-	   backend setup */
-	vcc_process_recv_queue(atmvcc);
-	return 0;
-
-error:
-	write_unlock_irq(&devs_lock);
-	kfree(brvcc);
-	return err;
-}
-
-static const struct net_device_ops br2684_netdev_ops = {
-	.ndo_start_xmit 	= br2684_start_xmit,
-	.ndo_set_mac_address	= br2684_mac_addr,
-	.ndo_validate_addr	= eth_validate_addr,
-};
-
-static const struct net_device_ops br2684_netdev_ops_routed = {
-	.ndo_start_xmit 	= br2684_start_xmit,
-	.ndo_set_mac_address	= br2684_mac_addr,
-};
-
-static void br2684_setup(struct net_device *netdev)
-{
-	struct br2684_dev *brdev = BRPRIV(netdev);
-
-	ether_setup(netdev);
-	netdev->hard_header_len += sizeof(llc_oui_pid_pad); /* worst case */
-	brdev->net_dev = netdev;
-
-	netdev->netdev_ops = &br2684_netdev_ops;
-
-	INIT_LIST_HEAD(&brdev->brvccs);
-}
-
-static void br2684_setup_routed(struct net_device *netdev)
-{
-	struct br2684_dev *brdev = BRPRIV(netdev);
-
-	brdev->net_dev = netdev;
-	netdev->hard_header_len = sizeof(llc_oui_ipv4); /* worst case */
-	netdev->netdev_ops = &br2684_netdev_ops_routed;
-	netdev->addr_len = 0;
-	netdev->mtu = ETH_DATA_LEN;
-	netdev->min_mtu = 0;
-	netdev->max_mtu = ETH_MAX_MTU;
-	netdev->type = ARPHRD_PPP;
-	netdev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
-	netdev->tx_queue_len = 100;
-	INIT_LIST_HEAD(&brdev->brvccs);
-}
-
-static int br2684_create(void __user *arg)
-{
-	int err;
-	struct net_device *netdev;
-	struct br2684_dev *brdev;
-	struct atm_newif_br2684 ni;
-	enum br2684_payload payload;
-
-	pr_debug("\n");
-
-	if (copy_from_user(&ni, arg, sizeof ni))
-		return -EFAULT;
-
-	if (ni.media & BR2684_FLAG_ROUTED)
-		payload = p_routed;
-	else
-		payload = p_bridged;
-	ni.media &= 0xffff;	/* strip flags */
-
-	if (ni.media != BR2684_MEDIA_ETHERNET || ni.mtu != 1500)
-		return -EINVAL;
-
-	netdev = alloc_netdev(sizeof(struct br2684_dev),
-			      ni.ifname[0] ? ni.ifname : "nas%d",
-			      NET_NAME_UNKNOWN,
-			      (payload == p_routed) ? br2684_setup_routed : br2684_setup);
-	if (!netdev)
-		return -ENOMEM;
-
-	brdev = BRPRIV(netdev);
-
-	pr_debug("registered netdev %s\n", netdev->name);
-	/* open, stop, do_ioctl ? */
-	err = register_netdev(netdev);
-	if (err < 0) {
-		pr_err("register_netdev failed\n");
-		free_netdev(netdev);
-		return err;
-	}
-
-	write_lock_irq(&devs_lock);
-
-	brdev->payload = payload;
-
-	if (list_empty(&br2684_devs)) {
-		/* 1st br2684 device */
-		brdev->number = 1;
-	} else
-		brdev->number = BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1;
-
-	list_add_tail(&brdev->br2684_devs, &br2684_devs);
-	write_unlock_irq(&devs_lock);
-	return 0;
-}
-
-/*
- * This handles ioctls actually performed on our vcc - we must return
- * -ENOIOCTLCMD for any unrecognized ioctl
- */
-static int br2684_ioctl(struct socket *sock, unsigned int cmd,
-			unsigned long arg)
-{
-	struct atm_vcc *atmvcc = ATM_SD(sock);
-	void __user *argp = (void __user *)arg;
-	atm_backend_t b;
-
-	int err;
-	switch (cmd) {
-	case ATM_SETBACKEND:
-	case ATM_NEWBACKENDIF:
-		err = get_user(b, (atm_backend_t __user *) argp);
-		if (err)
-			return -EFAULT;
-		if (b != ATM_BACKEND_BR2684)
-			return -ENOIOCTLCMD;
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		if (cmd == ATM_SETBACKEND) {
-			if (sock->state != SS_CONNECTED)
-				return -EINVAL;
-			return br2684_regvcc(atmvcc, argp);
-		} else {
-			return br2684_create(argp);
-		}
-#ifdef CONFIG_ATM_BR2684_IPFILTER
-	case BR2684_SETFILT:
-		if (atmvcc->push != br2684_push)
-			return -ENOIOCTLCMD;
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		err = br2684_setfilt(atmvcc, argp);
-
-		return err;
-#endif /* CONFIG_ATM_BR2684_IPFILTER */
-	}
-	return -ENOIOCTLCMD;
-}
-
-static struct atm_ioctl br2684_ioctl_ops = {
-	.owner = THIS_MODULE,
-	.ioctl = br2684_ioctl,
-};
-
-#ifdef CONFIG_PROC_FS
-static void *br2684_seq_start(struct seq_file *seq, loff_t * pos)
-	__acquires(devs_lock)
-{
-	read_lock(&devs_lock);
-	return seq_list_start(&br2684_devs, *pos);
-}
-
-static void *br2684_seq_next(struct seq_file *seq, void *v, loff_t * pos)
-{
-	return seq_list_next(v, &br2684_devs, pos);
-}
-
-static void br2684_seq_stop(struct seq_file *seq, void *v)
-	__releases(devs_lock)
-{
-	read_unlock(&devs_lock);
-}
-
-static int br2684_seq_show(struct seq_file *seq, void *v)
-{
-	const struct br2684_dev *brdev = list_entry(v, struct br2684_dev,
-						    br2684_devs);
-	const struct net_device *net_dev = brdev->net_dev;
-	const struct br2684_vcc *brvcc;
-
-	seq_printf(seq, "dev %.16s: num=%d, mac=%pM (%s)\n",
-		   net_dev->name,
-		   brdev->number,
-		   net_dev->dev_addr,
-		   brdev->mac_was_set ? "set" : "auto");
-
-	list_for_each_entry(brvcc, &brdev->brvccs, brvccs) {
-		seq_printf(seq, "  vcc %d.%d.%d: encaps=%s payload=%s"
-			   ", failed copies %u/%u"
-			   "\n", brvcc->atmvcc->dev->number,
-			   brvcc->atmvcc->vpi, brvcc->atmvcc->vci,
-			   (brvcc->encaps == e_llc) ? "LLC" : "VC",
-			   (brdev->payload == p_bridged) ? "bridged" : "routed",
-			   brvcc->copies_failed, brvcc->copies_needed);
-#ifdef CONFIG_ATM_BR2684_IPFILTER
-		if (brvcc->filter.netmask != 0)
-			seq_printf(seq, "    filter=%pI4/%pI4\n",
-				   &brvcc->filter.prefix,
-				   &brvcc->filter.netmask);
-#endif /* CONFIG_ATM_BR2684_IPFILTER */
-	}
-	return 0;
-}
-
-static const struct seq_operations br2684_seq_ops = {
-	.start = br2684_seq_start,
-	.next = br2684_seq_next,
-	.stop = br2684_seq_stop,
-	.show = br2684_seq_show,
-};
-
-extern struct proc_dir_entry *atm_proc_root;	/* from proc.c */
-#endif /* CONFIG_PROC_FS */
-
-static int __init br2684_init(void)
-{
-#ifdef CONFIG_PROC_FS
-	struct proc_dir_entry *p;
-	p = proc_create_seq("br2684", 0, atm_proc_root, &br2684_seq_ops);
-	if (p == NULL)
-		return -ENOMEM;
-#endif
-	register_atm_ioctl(&br2684_ioctl_ops);
-	register_atmdevice_notifier(&atm_dev_notifier);
-	return 0;
-}
-
-static void __exit br2684_exit(void)
-{
-	struct net_device *net_dev;
-	struct br2684_dev *brdev;
-	struct br2684_vcc *brvcc;
-	deregister_atm_ioctl(&br2684_ioctl_ops);
-
-#ifdef CONFIG_PROC_FS
-	remove_proc_entry("br2684", atm_proc_root);
-#endif
-
-
-	unregister_atmdevice_notifier(&atm_dev_notifier);
-
-	while (!list_empty(&br2684_devs)) {
-		net_dev = list_entry_brdev(br2684_devs.next);
-		brdev = BRPRIV(net_dev);
-		while (!list_empty(&brdev->brvccs)) {
-			brvcc = list_entry_brvcc(brdev->brvccs.next);
-			br2684_close_vcc(brvcc);
-		}
-
-		list_del(&brdev->br2684_devs);
-		unregister_netdev(net_dev);
-		free_netdev(net_dev);
-	}
-}
-
-module_init(br2684_init);
-module_exit(br2684_exit);
-
-MODULE_AUTHOR("Marcell GAL");
-MODULE_DESCRIPTION("RFC2684 bridged protocols over ATM/AAL5");
-MODULE_LICENSE("GPL");
diff --git a/net/atm/clip.c b/net/atm/clip.c
deleted file mode 100644
index 516b2214680b..000000000000
--- a/net/atm/clip.c
+++ /dev/null
@@ -1,960 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* net/atm/clip.c - RFC1577 Classical IP over ATM */
-
-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
-
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/kernel.h> /* for UINT_MAX */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <linux/wait.h>
-#include <linux/timer.h>
-#include <linux/if_arp.h> /* for some manifest constants */
-#include <linux/notifier.h>
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <linux/atmclip.h>
-#include <linux/atmarp.h>
-#include <linux/capability.h>
-#include <linux/ip.h> /* for net/route.h */
-#include <linux/in.h> /* for struct sockaddr_in */
-#include <linux/if.h> /* for IFF_UP */
-#include <linux/inetdevice.h>
-#include <linux/bitops.h>
-#include <linux/poison.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/rcupdate.h>
-#include <linux/jhash.h>
-#include <linux/slab.h>
-#include <net/route.h> /* for struct rtable and routing */
-#include <net/icmp.h> /* icmp_send */
-#include <net/arp.h>
-#include <linux/param.h> /* for HZ */
-#include <linux/uaccess.h>
-#include <asm/byteorder.h> /* for htons etc. */
-#include <linux/atomic.h>
-
-#include "common.h"
-#include "resources.h"
-#include <net/atmclip.h>
-
-static struct net_device *clip_devs;
-static struct atm_vcc __rcu *atmarpd;
-static DEFINE_MUTEX(atmarpd_lock);
-static struct timer_list idle_timer;
-static const struct neigh_ops clip_neigh_ops;
-
-static int to_atmarpd(enum atmarp_ctrl_type type, int itf, __be32 ip)
-{
-	struct sock *sk;
-	struct atmarp_ctrl *ctrl;
-	struct atm_vcc *vcc;
-	struct sk_buff *skb;
-	int err = 0;
-
-	pr_debug("(%d)\n", type);
-
-	rcu_read_lock();
-	vcc = rcu_dereference(atmarpd);
-	if (!vcc) {
-		err = -EUNATCH;
-		goto unlock;
-	}
-	skb = alloc_skb(sizeof(struct atmarp_ctrl), GFP_ATOMIC);
-	if (!skb) {
-		err = -ENOMEM;
-		goto unlock;
-	}
-	ctrl = skb_put(skb, sizeof(struct atmarp_ctrl));
-	ctrl->type = type;
-	ctrl->itf_num = itf;
-	ctrl->ip = ip;
-	atm_force_charge(vcc, skb->truesize);
-
-	sk = sk_atm(vcc);
-	skb_queue_tail(&sk->sk_receive_queue, skb);
-	sk->sk_data_ready(sk);
-unlock:
-	rcu_read_unlock();
-	return err;
-}
-
-static void link_vcc(struct clip_vcc *clip_vcc, struct atmarp_entry *entry)
-{
-	pr_debug("%p to entry %p (neigh %p)\n", clip_vcc, entry, entry->neigh);
-	clip_vcc->entry = entry;
-	clip_vcc->xoff = 0;	/* @@@ may overrun buffer by one packet */
-	clip_vcc->next = entry->vccs;
-	entry->vccs = clip_vcc;
-	entry->neigh->used = jiffies;
-}
-
-static void unlink_clip_vcc(struct clip_vcc *clip_vcc)
-{
-	struct atmarp_entry *entry = clip_vcc->entry;
-	struct clip_vcc **walk;
-
-	if (!entry) {
-		pr_err("!clip_vcc->entry (clip_vcc %p)\n", clip_vcc);
-		return;
-	}
-	netif_tx_lock_bh(entry->neigh->dev);	/* block clip_start_xmit() */
-	entry->neigh->used = jiffies;
-	for (walk = &entry->vccs; *walk; walk = &(*walk)->next)
-		if (*walk == clip_vcc) {
-			int error;
-
-			*walk = clip_vcc->next;	/* atomic */
-			clip_vcc->entry = NULL;
-			if (clip_vcc->xoff)
-				netif_wake_queue(entry->neigh->dev);
-			if (entry->vccs)
-				goto out;
-			entry->expires = jiffies - 1;
-			/* force resolution or expiration */
-			error = neigh_update(entry->neigh, NULL, NUD_NONE,
-					     NEIGH_UPDATE_F_ADMIN, 0);
-			if (error)
-				pr_err("neigh_update failed with %d\n", error);
-			goto out;
-		}
-	pr_err("ATMARP: failed (entry %p, vcc 0x%p)\n", entry, clip_vcc);
-out:
-	netif_tx_unlock_bh(entry->neigh->dev);
-}
-
-/* The neighbour entry n->lock is held. */
-static int neigh_check_cb(struct neighbour *n)
-{
-	struct atmarp_entry *entry = neighbour_priv(n);
-	struct clip_vcc *cv;
-
-	if (n->ops != &clip_neigh_ops)
-		return 0;
-	for (cv = entry->vccs; cv; cv = cv->next) {
-		unsigned long exp = cv->last_use + cv->idle_timeout;
-
-		if (cv->idle_timeout && time_after(jiffies, exp)) {
-			pr_debug("releasing vcc %p->%p of entry %p\n",
-				 cv, cv->vcc, entry);
-			vcc_release_async(cv->vcc, -ETIMEDOUT);
-		}
-	}
-
-	if (entry->vccs || time_before(jiffies, entry->expires))
-		return 0;
-
-	if (refcount_read(&n->refcnt) > 1) {
-		struct sk_buff *skb;
-
-		pr_debug("destruction postponed with ref %d\n",
-			 refcount_read(&n->refcnt));
-
-		while ((skb = skb_dequeue(&n->arp_queue)) != NULL)
-			dev_kfree_skb(skb);
-
-		return 0;
-	}
-
-	pr_debug("expired neigh %p\n", n);
-	return 1;
-}
-
-static void idle_timer_check(struct timer_list *unused)
-{
-	spin_lock(&arp_tbl.lock);
-	__neigh_for_each_release(&arp_tbl, neigh_check_cb);
-	mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ);
-	spin_unlock(&arp_tbl.lock);
-}
-
-static int clip_arp_rcv(struct sk_buff *skb)
-{
-	struct atm_vcc *vcc;
-
-	pr_debug("\n");
-	vcc = ATM_SKB(skb)->vcc;
-	if (!vcc || !atm_charge(vcc, skb->truesize)) {
-		dev_kfree_skb_any(skb);
-		return 0;
-	}
-	pr_debug("pushing to %p\n", vcc);
-	pr_debug("using %p\n", CLIP_VCC(vcc)->old_push);
-	CLIP_VCC(vcc)->old_push(vcc, skb);
-	return 0;
-}
-
-static const unsigned char llc_oui[] = {
-	0xaa,	/* DSAP: non-ISO */
-	0xaa,	/* SSAP: non-ISO */
-	0x03,	/* Ctrl: Unnumbered Information Command PDU */
-	0x00,	/* OUI: EtherType */
-	0x00,
-	0x00
-};
-
-static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
-
-	pr_debug("\n");
-
-	if (!skb) {
-		pr_debug("removing VCC %p\n", clip_vcc);
-		if (clip_vcc->entry)
-			unlink_clip_vcc(clip_vcc);
-		clip_vcc->old_push(vcc, NULL);	/* pass on the bad news */
-		kfree(clip_vcc);
-		return;
-	}
-	atm_return(vcc, skb->truesize);
-	if (!clip_devs) {
-		kfree_skb(skb);
-		return;
-	}
-
-	skb->dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : clip_devs;
-	/* clip_vcc->entry == NULL if we don't have an IP address yet */
-	if (!skb->dev) {
-		dev_kfree_skb_any(skb);
-		return;
-	}
-	ATM_SKB(skb)->vcc = vcc;
-	skb_reset_mac_header(skb);
-	if (!clip_vcc->encap ||
-	    skb->len < RFC1483LLC_LEN ||
-	    memcmp(skb->data, llc_oui, sizeof(llc_oui)))
-		skb->protocol = htons(ETH_P_IP);
-	else {
-		skb->protocol = ((__be16 *)skb->data)[3];
-		skb_pull(skb, RFC1483LLC_LEN);
-		if (skb->protocol == htons(ETH_P_ARP)) {
-			skb->dev->stats.rx_packets++;
-			skb->dev->stats.rx_bytes += skb->len;
-			clip_arp_rcv(skb);
-			return;
-		}
-	}
-	clip_vcc->last_use = jiffies;
-	skb->dev->stats.rx_packets++;
-	skb->dev->stats.rx_bytes += skb->len;
-	memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
-	netif_rx(skb);
-}
-
-/*
- * Note: these spinlocks _must_not_ block on non-SMP. The only goal is that
- * clip_pop is atomic with respect to the critical section in clip_start_xmit.
- */
-
-static void clip_pop(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
-	struct net_device *dev = skb->dev;
-	int old;
-	unsigned long flags;
-
-	pr_debug("(vcc %p)\n", vcc);
-	clip_vcc->old_pop(vcc, skb);
-	/* skb->dev == NULL in outbound ARP packets */
-	if (!dev)
-		return;
-	spin_lock_irqsave(&PRIV(dev)->xoff_lock, flags);
-	if (atm_may_send(vcc, 0)) {
-		old = xchg(&clip_vcc->xoff, 0);
-		if (old)
-			netif_wake_queue(dev);
-	}
-	spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags);
-}
-
-static void clip_neigh_solicit(struct neighbour *neigh, struct sk_buff *skb)
-{
-	__be32 *ip = (__be32 *) neigh->primary_key;
-
-	pr_debug("(neigh %p, skb %p)\n", neigh, skb);
-	to_atmarpd(act_need, PRIV(neigh->dev)->number, *ip);
-}
-
-static void clip_neigh_error(struct neighbour *neigh, struct sk_buff *skb)
-{
-#ifndef CONFIG_ATM_CLIP_NO_ICMP
-	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
-#endif
-	kfree_skb(skb);
-}
-
-static const struct neigh_ops clip_neigh_ops = {
-	.family =		AF_INET,
-	.solicit =		clip_neigh_solicit,
-	.error_report =		clip_neigh_error,
-	.output =		neigh_direct_output,
-	.connected_output =	neigh_direct_output,
-};
-
-static int clip_constructor(struct net_device *dev, struct neighbour *neigh)
-{
-	struct atmarp_entry *entry = neighbour_priv(neigh);
-
-	if (neigh->tbl->family != AF_INET)
-		return -EINVAL;
-
-	if (neigh->type != RTN_UNICAST)
-		return -EINVAL;
-
-	neigh->nud_state = NUD_NONE;
-	neigh->ops = &clip_neigh_ops;
-	neigh->output = neigh->ops->output;
-	entry->neigh = neigh;
-	entry->vccs = NULL;
-	entry->expires = jiffies - 1;
-
-	return 0;
-}
-
-/* @@@ copy bh locking from arp.c -- need to bh-enable atm code before */
-
-/*
- * We play with the resolve flag: 0 and 1 have the usual meaning, but -1 means
- * to allocate the neighbour entry but not to ask atmarpd for resolution. Also,
- * don't increment the usage count. This is used to create entries in
- * clip_setentry.
- */
-
-static int clip_encap(struct atm_vcc *vcc, int mode)
-{
-	if (!CLIP_VCC(vcc))
-		return -EBADFD;
-
-	CLIP_VCC(vcc)->encap = mode;
-	return 0;
-}
-
-static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
-				   struct net_device *dev)
-{
-	struct clip_priv *clip_priv = PRIV(dev);
-	struct dst_entry *dst = skb_dst(skb);
-	struct atmarp_entry *entry;
-	struct neighbour *n;
-	struct atm_vcc *vcc;
-	struct rtable *rt;
-	__be32 *daddr;
-	int old;
-	unsigned long flags;
-
-	pr_debug("(skb %p)\n", skb);
-	if (!dst) {
-		pr_err("skb_dst(skb) == NULL\n");
-		dev_kfree_skb(skb);
-		dev->stats.tx_dropped++;
-		return NETDEV_TX_OK;
-	}
-	rt = dst_rtable(dst);
-	if (rt->rt_gw_family == AF_INET)
-		daddr = &rt->rt_gw4;
-	else
-		daddr = &ip_hdr(skb)->daddr;
-	n = dst_neigh_lookup(dst, daddr);
-	if (!n) {
-		pr_err("NO NEIGHBOUR !\n");
-		dev_kfree_skb(skb);
-		dev->stats.tx_dropped++;
-		return NETDEV_TX_OK;
-	}
-	entry = neighbour_priv(n);
-	if (!entry->vccs) {
-		if (time_after(jiffies, entry->expires)) {
-			/* should be resolved */
-			entry->expires = jiffies + ATMARP_RETRY_DELAY * HZ;
-			to_atmarpd(act_need, PRIV(dev)->number, *((__be32 *)n->primary_key));
-		}
-		if (entry->neigh->arp_queue.qlen < ATMARP_MAX_UNRES_PACKETS)
-			skb_queue_tail(&entry->neigh->arp_queue, skb);
-		else {
-			dev_kfree_skb(skb);
-			dev->stats.tx_dropped++;
-		}
-		goto out_release_neigh;
-	}
-	pr_debug("neigh %p, vccs %p\n", entry, entry->vccs);
-	ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc;
-	pr_debug("using neighbour %p, vcc %p\n", n, vcc);
-	if (entry->vccs->encap) {
-		void *here;
-
-		here = skb_push(skb, RFC1483LLC_LEN);
-		memcpy(here, llc_oui, sizeof(llc_oui));
-		((__be16 *) here)[3] = skb->protocol;
-	}
-	atm_account_tx(vcc, skb);
-	entry->vccs->last_use = jiffies;
-	pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, vcc, vcc->dev);
-	old = xchg(&entry->vccs->xoff, 1);	/* assume XOFF ... */
-	if (old) {
-		pr_warn("XOFF->XOFF transition\n");
-		goto out_release_neigh;
-	}
-	dev->stats.tx_packets++;
-	dev->stats.tx_bytes += skb->len;
-	vcc->send(vcc, skb);
-	if (atm_may_send(vcc, 0)) {
-		entry->vccs->xoff = 0;
-		goto out_release_neigh;
-	}
-	spin_lock_irqsave(&clip_priv->xoff_lock, flags);
-	netif_stop_queue(dev);	/* XOFF -> throttle immediately */
-	barrier();
-	if (!entry->vccs->xoff)
-		netif_start_queue(dev);
-	/* Oh, we just raced with clip_pop. netif_start_queue should be
-	   good enough, because nothing should really be asleep because
-	   of the brief netif_stop_queue. If this isn't true or if it
-	   changes, use netif_wake_queue instead. */
-	spin_unlock_irqrestore(&clip_priv->xoff_lock, flags);
-out_release_neigh:
-	neigh_release(n);
-	return NETDEV_TX_OK;
-}
-
-static int clip_mkip(struct atm_vcc *vcc, int timeout)
-{
-	struct clip_vcc *clip_vcc;
-
-	if (!vcc->push)
-		return -EBADFD;
-	if (vcc->user_back)
-		return -EINVAL;
-	clip_vcc = kmalloc_obj(struct clip_vcc);
-	if (!clip_vcc)
-		return -ENOMEM;
-	pr_debug("%p vcc %p\n", clip_vcc, vcc);
-	clip_vcc->vcc = vcc;
-	vcc->user_back = clip_vcc;
-	set_bit(ATM_VF_IS_CLIP, &vcc->flags);
-	clip_vcc->entry = NULL;
-	clip_vcc->xoff = 0;
-	clip_vcc->encap = 1;
-	clip_vcc->last_use = jiffies;
-	clip_vcc->idle_timeout = timeout * HZ;
-	clip_vcc->old_push = vcc->push;
-	clip_vcc->old_pop = vcc->pop;
-	vcc->push = clip_push;
-	vcc->pop = clip_pop;
-
-	/* re-process everything received between connection setup and MKIP */
-	vcc_process_recv_queue(vcc);
-
-	return 0;
-}
-
-static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
-{
-	struct neighbour *neigh;
-	struct atmarp_entry *entry;
-	int error;
-	struct clip_vcc *clip_vcc;
-	struct rtable *rt;
-
-	if (vcc->push != clip_push) {
-		pr_warn("non-CLIP VCC\n");
-		return -EBADF;
-	}
-	clip_vcc = CLIP_VCC(vcc);
-	if (!ip) {
-		if (!clip_vcc->entry) {
-			pr_err("hiding hidden ATMARP entry\n");
-			return 0;
-		}
-		pr_debug("remove\n");
-		unlink_clip_vcc(clip_vcc);
-		return 0;
-	}
-	rt = ip_route_output(&init_net, ip, 0, 0, 0, RT_SCOPE_LINK);
-	if (IS_ERR(rt))
-		return PTR_ERR(rt);
-	neigh = __neigh_lookup(&arp_tbl, &ip, rt->dst.dev, 1);
-	ip_rt_put(rt);
-	if (!neigh)
-		return -ENOMEM;
-	entry = neighbour_priv(neigh);
-	if (entry != clip_vcc->entry) {
-		if (!clip_vcc->entry)
-			pr_debug("add\n");
-		else {
-			pr_debug("update\n");
-			unlink_clip_vcc(clip_vcc);
-		}
-		link_vcc(clip_vcc, entry);
-	}
-	error = neigh_update(neigh, llc_oui, NUD_PERMANENT,
-			     NEIGH_UPDATE_F_OVERRIDE | NEIGH_UPDATE_F_ADMIN, 0);
-	neigh_release(neigh);
-	return error;
-}
-
-static const struct net_device_ops clip_netdev_ops = {
-	.ndo_start_xmit		= clip_start_xmit,
-	.ndo_neigh_construct	= clip_constructor,
-};
-
-static void clip_setup(struct net_device *dev)
-{
-	dev->netdev_ops = &clip_netdev_ops;
-	dev->type = ARPHRD_ATM;
-	dev->neigh_priv_len = sizeof(struct atmarp_entry);
-	dev->hard_header_len = RFC1483LLC_LEN;
-	dev->mtu = RFC1626_MTU;
-	dev->tx_queue_len = 100;	/* "normal" queue (packets) */
-	/* When using a "real" qdisc, the qdisc determines the queue */
-	/* length. tx_queue_len is only used for the default case, */
-	/* without any more elaborate queuing. 100 is a reasonable */
-	/* compromise between decent burst-tolerance and protection */
-	/* against memory hogs. */
-	netif_keep_dst(dev);
-}
-
-static int clip_create(int number)
-{
-	struct net_device *dev;
-	struct clip_priv *clip_priv;
-	int error;
-
-	if (number != -1) {
-		for (dev = clip_devs; dev; dev = PRIV(dev)->next)
-			if (PRIV(dev)->number == number)
-				return -EEXIST;
-	} else {
-		number = 0;
-		for (dev = clip_devs; dev; dev = PRIV(dev)->next)
-			if (PRIV(dev)->number >= number)
-				number = PRIV(dev)->number + 1;
-	}
-	dev = alloc_netdev(sizeof(struct clip_priv), "", NET_NAME_UNKNOWN,
-			   clip_setup);
-	if (!dev)
-		return -ENOMEM;
-	clip_priv = PRIV(dev);
-	sprintf(dev->name, "atm%d", number);
-	spin_lock_init(&clip_priv->xoff_lock);
-	clip_priv->number = number;
-	error = register_netdev(dev);
-	if (error) {
-		free_netdev(dev);
-		return error;
-	}
-	clip_priv->next = clip_devs;
-	clip_devs = dev;
-	pr_debug("registered (net:%s)\n", dev->name);
-	return number;
-}
-
-static int clip_device_event(struct notifier_block *this, unsigned long event,
-			     void *ptr)
-{
-	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
-
-	if (!net_eq(dev_net(dev), &init_net))
-		return NOTIFY_DONE;
-
-	if (event == NETDEV_UNREGISTER)
-		return NOTIFY_DONE;
-
-	/* ignore non-CLIP devices */
-	if (dev->type != ARPHRD_ATM || dev->netdev_ops != &clip_netdev_ops)
-		return NOTIFY_DONE;
-
-	switch (event) {
-	case NETDEV_UP:
-		pr_debug("NETDEV_UP\n");
-		to_atmarpd(act_up, PRIV(dev)->number, 0);
-		break;
-	case NETDEV_GOING_DOWN:
-		pr_debug("NETDEV_DOWN\n");
-		to_atmarpd(act_down, PRIV(dev)->number, 0);
-		break;
-	case NETDEV_CHANGE:
-	case NETDEV_CHANGEMTU:
-		pr_debug("NETDEV_CHANGE*\n");
-		to_atmarpd(act_change, PRIV(dev)->number, 0);
-		break;
-	}
-	return NOTIFY_DONE;
-}
-
-static int clip_inet_event(struct notifier_block *this, unsigned long event,
-			   void *ifa)
-{
-	struct in_device *in_dev;
-	struct netdev_notifier_info info;
-
-	in_dev = ((struct in_ifaddr *)ifa)->ifa_dev;
-	/*
-	 * Transitions are of the down-change-up type, so it's sufficient to
-	 * handle the change on up.
-	 */
-	if (event != NETDEV_UP)
-		return NOTIFY_DONE;
-	netdev_notifier_info_init(&info, in_dev->dev);
-	return clip_device_event(this, NETDEV_CHANGE, &info);
-}
-
-static struct notifier_block clip_dev_notifier = {
-	.notifier_call = clip_device_event,
-};
-
-
-
-static struct notifier_block clip_inet_notifier = {
-	.notifier_call = clip_inet_event,
-};
-
-
-
-static void atmarpd_close(struct atm_vcc *vcc)
-{
-	pr_debug("\n");
-
-	mutex_lock(&atmarpd_lock);
-	RCU_INIT_POINTER(atmarpd, NULL);
-	mutex_unlock(&atmarpd_lock);
-
-	synchronize_rcu();
-	skb_queue_purge(&sk_atm(vcc)->sk_receive_queue);
-
-	pr_debug("(done)\n");
-	module_put(THIS_MODULE);
-}
-
-static int atmarpd_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	atm_return_tx(vcc, skb);
-	dev_kfree_skb_any(skb);
-	return 0;
-}
-
-static const struct atmdev_ops atmarpd_dev_ops = {
-	.close = atmarpd_close,
-	.send = atmarpd_send
-};
-
-
-static struct atm_dev atmarpd_dev = {
-	.ops =			&atmarpd_dev_ops,
-	.type =			"arpd",
-	.number = 		999,
-	.lock =			__SPIN_LOCK_UNLOCKED(atmarpd_dev.lock)
-};
-
-
-static int atm_init_atmarp(struct atm_vcc *vcc)
-{
-	if (vcc->push == clip_push)
-		return -EINVAL;
-
-	mutex_lock(&atmarpd_lock);
-	if (atmarpd) {
-		mutex_unlock(&atmarpd_lock);
-		return -EADDRINUSE;
-	}
-
-	mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ);
-
-	rcu_assign_pointer(atmarpd, vcc);
-	set_bit(ATM_VF_META, &vcc->flags);
-	set_bit(ATM_VF_READY, &vcc->flags);
-	    /* allow replies and avoid getting closed if signaling dies */
-	vcc->dev = &atmarpd_dev;
-	vcc_insert_socket(sk_atm(vcc));
-	vcc->push = NULL;
-	vcc->pop = NULL; /* crash */
-	vcc->push_oam = NULL; /* crash */
-	mutex_unlock(&atmarpd_lock);
-	return 0;
-}
-
-static int clip_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
-	struct atm_vcc *vcc = ATM_SD(sock);
-	struct sock *sk = sock->sk;
-	int err = 0;
-
-	switch (cmd) {
-	case SIOCMKCLIP:
-	case ATMARPD_CTRL:
-	case ATMARP_MKIP:
-	case ATMARP_SETENTRY:
-	case ATMARP_ENCAP:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		break;
-	default:
-		return -ENOIOCTLCMD;
-	}
-
-	switch (cmd) {
-	case SIOCMKCLIP:
-		err = clip_create(arg);
-		break;
-	case ATMARPD_CTRL:
-		lock_sock(sk);
-		err = atm_init_atmarp(vcc);
-		if (!err) {
-			sock->state = SS_CONNECTED;
-			__module_get(THIS_MODULE);
-		}
-		release_sock(sk);
-		break;
-	case ATMARP_MKIP:
-		lock_sock(sk);
-		err = clip_mkip(vcc, arg);
-		release_sock(sk);
-		break;
-	case ATMARP_SETENTRY:
-		err = clip_setentry(vcc, (__force __be32)arg);
-		break;
-	case ATMARP_ENCAP:
-		err = clip_encap(vcc, arg);
-		break;
-	}
-	return err;
-}
-
-static struct atm_ioctl clip_ioctl_ops = {
-	.owner = THIS_MODULE,
-	.ioctl = clip_ioctl,
-};
-
-#ifdef CONFIG_PROC_FS
-
-static void svc_addr(struct seq_file *seq, struct sockaddr_atmsvc *addr)
-{
-	static int code[] = { 1, 2, 10, 6, 1, 0 };
-	static int e164[] = { 1, 8, 4, 6, 1, 0 };
-
-	if (*addr->sas_addr.pub) {
-		seq_printf(seq, "%s", addr->sas_addr.pub);
-		if (*addr->sas_addr.prv)
-			seq_putc(seq, '+');
-	} else if (!*addr->sas_addr.prv) {
-		seq_printf(seq, "%s", "(none)");
-		return;
-	}
-	if (*addr->sas_addr.prv) {
-		unsigned char *prv = addr->sas_addr.prv;
-		int *fields;
-		int i, j;
-
-		fields = *prv == ATM_AFI_E164 ? e164 : code;
-		for (i = 0; fields[i]; i++) {
-			for (j = fields[i]; j; j--)
-				seq_printf(seq, "%02X", *prv++);
-			if (fields[i + 1])
-				seq_putc(seq, '.');
-		}
-	}
-}
-
-/* This means the neighbour entry has no attached VCC objects. */
-#define SEQ_NO_VCC_TOKEN	((void *) 2)
-
-static void atmarp_info(struct seq_file *seq, struct neighbour *n,
-			struct atmarp_entry *entry, struct clip_vcc *clip_vcc)
-{
-	struct net_device *dev = n->dev;
-	unsigned long exp;
-	char buf[17];
-	int svc, llc, off;
-
-	svc = ((clip_vcc == SEQ_NO_VCC_TOKEN) ||
-	       (sk_atm(clip_vcc->vcc)->sk_family == AF_ATMSVC));
-
-	llc = ((clip_vcc == SEQ_NO_VCC_TOKEN) || clip_vcc->encap);
-
-	if (clip_vcc == SEQ_NO_VCC_TOKEN)
-		exp = entry->neigh->used;
-	else
-		exp = clip_vcc->last_use;
-
-	exp = (jiffies - exp) / HZ;
-
-	seq_printf(seq, "%-6s%-4s%-4s%5ld ",
-		   dev->name, svc ? "SVC" : "PVC", llc ? "LLC" : "NULL", exp);
-
-	off = scnprintf(buf, sizeof(buf) - 1, "%pI4", n->primary_key);
-	while (off < 16)
-		buf[off++] = ' ';
-	buf[off] = '\0';
-	seq_printf(seq, "%s", buf);
-
-	if (clip_vcc == SEQ_NO_VCC_TOKEN) {
-		if (time_before(jiffies, entry->expires))
-			seq_printf(seq, "(resolving)\n");
-		else
-			seq_printf(seq, "(expired, ref %d)\n",
-				   refcount_read(&entry->neigh->refcnt));
-	} else if (!svc) {
-		seq_printf(seq, "%d.%d.%d\n",
-			   clip_vcc->vcc->dev->number,
-			   clip_vcc->vcc->vpi, clip_vcc->vcc->vci);
-	} else {
-		svc_addr(seq, &clip_vcc->vcc->remote);
-		seq_putc(seq, '\n');
-	}
-}
-
-struct clip_seq_state {
-	/* This member must be first. */
-	struct neigh_seq_state ns;
-
-	/* Local to clip specific iteration. */
-	struct clip_vcc *vcc;
-};
-
-static struct clip_vcc *clip_seq_next_vcc(struct atmarp_entry *e,
-					  struct clip_vcc *curr)
-{
-	if (!curr) {
-		curr = e->vccs;
-		if (!curr)
-			return SEQ_NO_VCC_TOKEN;
-		return curr;
-	}
-	if (curr == SEQ_NO_VCC_TOKEN)
-		return NULL;
-
-	curr = curr->next;
-
-	return curr;
-}
-
-static void *clip_seq_vcc_walk(struct clip_seq_state *state,
-			       struct atmarp_entry *e, loff_t * pos)
-{
-	struct clip_vcc *vcc = state->vcc;
-
-	vcc = clip_seq_next_vcc(e, vcc);
-	if (vcc && pos != NULL) {
-		while (*pos) {
-			vcc = clip_seq_next_vcc(e, vcc);
-			if (!vcc)
-				break;
-			--(*pos);
-		}
-	}
-	state->vcc = vcc;
-
-	return vcc;
-}
-
-static void *clip_seq_sub_iter(struct neigh_seq_state *_state,
-			       struct neighbour *n, loff_t * pos)
-{
-	struct clip_seq_state *state = (struct clip_seq_state *)_state;
-
-	if (n->dev->type != ARPHRD_ATM)
-		return NULL;
-
-	return clip_seq_vcc_walk(state, neighbour_priv(n), pos);
-}
-
-static void *clip_seq_start(struct seq_file *seq, loff_t * pos)
-{
-	struct clip_seq_state *state = seq->private;
-	state->ns.neigh_sub_iter = clip_seq_sub_iter;
-	return neigh_seq_start(seq, pos, &arp_tbl, NEIGH_SEQ_NEIGH_ONLY);
-}
-
-static int clip_seq_show(struct seq_file *seq, void *v)
-{
-	static char atm_arp_banner[] =
-	    "IPitf TypeEncp Idle IP address      ATM address\n";
-
-	if (v == SEQ_START_TOKEN) {
-		seq_puts(seq, atm_arp_banner);
-	} else {
-		struct clip_seq_state *state = seq->private;
-		struct clip_vcc *vcc = state->vcc;
-		struct neighbour *n = v;
-
-		atmarp_info(seq, n, neighbour_priv(n), vcc);
-	}
-	return 0;
-}
-
-static const struct seq_operations arp_seq_ops = {
-	.start	= clip_seq_start,
-	.next	= neigh_seq_next,
-	.stop	= neigh_seq_stop,
-	.show	= clip_seq_show,
-};
-#endif
-
-static void atm_clip_exit_noproc(void);
-
-static int __init atm_clip_init(void)
-{
-	register_atm_ioctl(&clip_ioctl_ops);
-	register_netdevice_notifier(&clip_dev_notifier);
-	register_inetaddr_notifier(&clip_inet_notifier);
-
-	timer_setup(&idle_timer, idle_timer_check, 0);
-
-#ifdef CONFIG_PROC_FS
-	{
-		struct proc_dir_entry *p;
-
-		p = proc_create_net("arp", 0444, atm_proc_root, &arp_seq_ops,
-				sizeof(struct clip_seq_state));
-		if (!p) {
-			pr_err("Unable to initialize /proc/net/atm/arp\n");
-			atm_clip_exit_noproc();
-			return -ENOMEM;
-		}
-	}
-#endif
-
-	return 0;
-}
-
-static void atm_clip_exit_noproc(void)
-{
-	struct net_device *dev, *next;
-
-	unregister_inetaddr_notifier(&clip_inet_notifier);
-	unregister_netdevice_notifier(&clip_dev_notifier);
-
-	deregister_atm_ioctl(&clip_ioctl_ops);
-
-	/* First, stop the idle timer, so it stops banging
-	 * on the table.
-	 */
-	timer_delete_sync(&idle_timer);
-
-	dev = clip_devs;
-	while (dev) {
-		next = PRIV(dev)->next;
-		unregister_netdev(dev);
-		free_netdev(dev);
-		dev = next;
-	}
-}
-
-static void __exit atm_clip_exit(void)
-{
-	remove_proc_entry("arp", atm_proc_root);
-
-	atm_clip_exit_noproc();
-}
-
-module_init(atm_clip_init);
-module_exit(atm_clip_exit);
-MODULE_AUTHOR("Werner Almesberger");
-MODULE_DESCRIPTION("Classical/IP over ATM interface");
-MODULE_LICENSE("GPL");
diff --git a/net/atm/lec.c b/net/atm/lec.c
deleted file mode 100644
index 10e260acf602..000000000000
--- a/net/atm/lec.c
+++ /dev/null
@@ -1,2274 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * lec.c: Lan Emulation driver
- *
- * Marko Kiiskila <mkiiskila@yahoo.com>
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
-
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/bitops.h>
-#include <linux/capability.h>
-
-/* We are ethernet device */
-#include <linux/if_ether.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <net/sock.h>
-#include <linux/skbuff.h>
-#include <linux/ip.h>
-#include <asm/byteorder.h>
-#include <linux/uaccess.h>
-#include <net/arp.h>
-#include <net/dst.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-#include <linux/seq_file.h>
-
-/* And atm device */
-#include <linux/atmdev.h>
-#include <linux/atmlec.h>
-
-/* Proxy LEC knows about bridging */
-#if IS_ENABLED(CONFIG_BRIDGE)
-#include "../bridge/br_private.h"
-
-static unsigned char bridge_ula_lec[] = { 0x01, 0x80, 0xc2, 0x00, 0x00 };
-#endif
-
-/* Modular too */
-#include <linux/module.h>
-#include <linux/init.h>
-
-/* Hardening for Spectre-v1 */
-#include <linux/nospec.h>
-
-#include "lec.h"
-#include "lec_arpc.h"
-#include "resources.h"
-
-#define DUMP_PACKETS 0		/*
-				 * 0 = None,
-				 * 1 = 30 first bytes
-				 * 2 = Whole packet
-				 */
-
-#define LEC_UNRES_QUE_LEN 8	/*
-				 * number of tx packets to queue for a
-				 * single destination while waiting for SVC
-				 */
-
-static int lec_open(struct net_device *dev);
-static netdev_tx_t lec_start_xmit(struct sk_buff *skb,
-				  struct net_device *dev);
-static int lec_close(struct net_device *dev);
-static struct lec_arp_table *lec_arp_find(struct lec_priv *priv,
-					  const unsigned char *mac_addr);
-static int lec_arp_remove(struct lec_priv *priv,
-			  struct lec_arp_table *to_remove);
-/* LANE2 functions */
-static void lane2_associate_ind(struct net_device *dev, const u8 *mac_address,
-				const u8 *tlvs, u32 sizeoftlvs);
-static int lane2_resolve(struct net_device *dev, const u8 *dst_mac, int force,
-			 u8 **tlvs, u32 *sizeoftlvs);
-static int lane2_associate_req(struct net_device *dev, const u8 *lan_dst,
-			       const u8 *tlvs, u32 sizeoftlvs);
-
-static int lec_addr_delete(struct lec_priv *priv, const unsigned char *atm_addr,
-			   unsigned long permanent);
-static void lec_arp_check_empties(struct lec_priv *priv,
-				  struct atm_vcc *vcc, struct sk_buff *skb);
-static void lec_arp_destroy(struct lec_priv *priv);
-static void lec_arp_init(struct lec_priv *priv);
-static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv,
-				       const unsigned char *mac_to_find,
-				       int is_rdesc,
-				       struct lec_arp_table **ret_entry);
-static void lec_arp_update(struct lec_priv *priv, const unsigned char *mac_addr,
-			   const unsigned char *atm_addr,
-			   unsigned long remoteflag,
-			   unsigned int targetless_le_arp);
-static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id);
-static int lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc);
-static void lec_set_flush_tran_id(struct lec_priv *priv,
-				  const unsigned char *atm_addr,
-				  unsigned long tran_id);
-static void lec_vcc_added(struct lec_priv *priv,
-			  const struct atmlec_ioc *ioc_data,
-			  struct atm_vcc *vcc,
-			  void (*old_push)(struct atm_vcc *vcc,
-					   struct sk_buff *skb));
-static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc);
-
-/* must be done under lec_arp_lock */
-static inline void lec_arp_hold(struct lec_arp_table *entry)
-{
-	refcount_inc(&entry->usage);
-}
-
-static inline void lec_arp_put(struct lec_arp_table *entry)
-{
-	if (refcount_dec_and_test(&entry->usage))
-		kfree(entry);
-}
-
-static struct lane2_ops lane2_ops = {
-	.resolve = lane2_resolve,		/* spec 3.1.3 */
-	.associate_req = lane2_associate_req,	/* spec 3.1.4 */
-	.associate_indicator = NULL             /* spec 3.1.5 */
-};
-
-static unsigned char bus_mac[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-/* Device structures */
-static struct net_device *dev_lec[MAX_LEC_ITF];
-static DEFINE_MUTEX(lec_mutex);
-
-#if IS_ENABLED(CONFIG_BRIDGE)
-static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev)
-{
-	char *buff;
-	struct lec_priv *priv;
-
-	/*
-	 * Check if this is a BPDU. If so, ask zeppelin to send
-	 * LE_TOPOLOGY_REQUEST with the same value of Topology Change bit
-	 * as the Config BPDU has
-	 */
-	buff = skb->data + skb->dev->hard_header_len;
-	if (*buff++ == 0x42 && *buff++ == 0x42 && *buff++ == 0x03) {
-		struct sock *sk;
-		struct sk_buff *skb2;
-		struct atmlec_msg *mesg;
-
-		skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
-		if (skb2 == NULL)
-			return;
-		skb2->len = sizeof(struct atmlec_msg);
-		mesg = (struct atmlec_msg *)skb2->data;
-		mesg->type = l_topology_change;
-		buff += 4;
-		mesg->content.normal.flag = *buff & 0x01;
-					/* 0x01 is topology change */
-
-		priv = netdev_priv(dev);
-		struct atm_vcc *vcc;
-
-		rcu_read_lock();
-		vcc = rcu_dereference(priv->lecd);
-		if (vcc) {
-			atm_force_charge(vcc, skb2->truesize);
-			sk = sk_atm(vcc);
-			skb_queue_tail(&sk->sk_receive_queue, skb2);
-			sk->sk_data_ready(sk);
-		} else {
-			dev_kfree_skb(skb2);
-		}
-		rcu_read_unlock();
-	}
-}
-#endif /* IS_ENABLED(CONFIG_BRIDGE) */
-
-/*
- * Open/initialize the netdevice. This is called (in the current kernel)
- * sometime after booting when the 'ifconfig' program is run.
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is non-reboot way to recover if something goes wrong.
- */
-
-static int lec_open(struct net_device *dev)
-{
-	netif_start_queue(dev);
-
-	return 0;
-}
-
-static void
-lec_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	struct net_device *dev = skb->dev;
-	unsigned int len = skb->len;
-
-	ATM_SKB(skb)->vcc = vcc;
-	atm_account_tx(vcc, skb);
-
-	if (vcc->send(vcc, skb) < 0) {
-		dev->stats.tx_dropped++;
-		return;
-	}
-
-	dev->stats.tx_packets++;
-	dev->stats.tx_bytes += len;
-}
-
-static void lec_tx_timeout(struct net_device *dev, unsigned int txqueue)
-{
-	pr_info("%s\n", dev->name);
-	netif_trans_update(dev);
-	netif_wake_queue(dev);
-}
-
-static netdev_tx_t lec_start_xmit(struct sk_buff *skb,
-				  struct net_device *dev)
-{
-	struct sk_buff *skb2;
-	struct lec_priv *priv = netdev_priv(dev);
-	struct lecdatahdr_8023 *lec_h;
-	struct atm_vcc *vcc;
-	struct lec_arp_table *entry;
-	unsigned char *dst;
-	int min_frame_size;
-	int is_rdesc;
-
-	pr_debug("called\n");
-	if (!rcu_access_pointer(priv->lecd)) {
-		pr_info("%s:No lecd attached\n", dev->name);
-		dev->stats.tx_errors++;
-		netif_stop_queue(dev);
-		kfree_skb(skb);
-		return NETDEV_TX_OK;
-	}
-
-	pr_debug("skbuff head:%lx data:%lx tail:%lx end:%lx\n",
-		 (long)skb->head, (long)skb->data, (long)skb_tail_pointer(skb),
-		 (long)skb_end_pointer(skb));
-#if IS_ENABLED(CONFIG_BRIDGE)
-	if (memcmp(skb->data, bridge_ula_lec, sizeof(bridge_ula_lec)) == 0)
-		lec_handle_bridge(skb, dev);
-#endif
-
-	/* Make sure we have room for lec_id */
-	if (skb_headroom(skb) < 2) {
-		pr_debug("reallocating skb\n");
-		skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
-		if (unlikely(!skb2)) {
-			kfree_skb(skb);
-			return NETDEV_TX_OK;
-		}
-		consume_skb(skb);
-		skb = skb2;
-	}
-	skb_push(skb, 2);
-
-	/* Put le header to place */
-	lec_h = (struct lecdatahdr_8023 *)skb->data;
-	lec_h->le_header = htons(priv->lecid);
-
-#if DUMP_PACKETS >= 2
-#define MAX_DUMP_SKB 99
-#elif DUMP_PACKETS >= 1
-#define MAX_DUMP_SKB 30
-#endif
-#if DUMP_PACKETS >= 1
-	printk(KERN_DEBUG "%s: send datalen:%ld lecid:%4.4x\n",
-	       dev->name, skb->len, priv->lecid);
-	print_hex_dump(KERN_DEBUG, "", DUMP_OFFSET, 16, 1,
-		       skb->data, min(skb->len, MAX_DUMP_SKB), true);
-#endif /* DUMP_PACKETS >= 1 */
-
-	/* Minimum ethernet-frame size */
-	min_frame_size = LEC_MINIMUM_8023_SIZE;
-	if (skb->len < min_frame_size) {
-		if ((skb->len + skb_tailroom(skb)) < min_frame_size) {
-			skb2 = skb_copy_expand(skb, 0,
-					       min_frame_size - skb->truesize,
-					       GFP_ATOMIC);
-			dev_kfree_skb(skb);
-			if (skb2 == NULL) {
-				dev->stats.tx_dropped++;
-				return NETDEV_TX_OK;
-			}
-			skb = skb2;
-		}
-		skb_put(skb, min_frame_size - skb->len);
-	}
-
-	/* Send to right vcc */
-	is_rdesc = 0;
-	dst = lec_h->h_dest;
-	entry = NULL;
-	vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry);
-	pr_debug("%s:vcc:%p vcc_flags:%lx, entry:%p\n",
-		 dev->name, vcc, vcc ? vcc->flags : 0, entry);
-	if (!vcc || !test_bit(ATM_VF_READY, &vcc->flags)) {
-		if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) {
-			pr_debug("%s:queuing packet, MAC address %pM\n",
-				 dev->name, lec_h->h_dest);
-			skb_queue_tail(&entry->tx_wait, skb);
-		} else {
-			pr_debug("%s:tx queue full or no arp entry, dropping, MAC address: %pM\n",
-				 dev->name, lec_h->h_dest);
-			dev->stats.tx_dropped++;
-			dev_kfree_skb(skb);
-		}
-		goto out;
-	}
-#if DUMP_PACKETS > 0
-	printk(KERN_DEBUG "%s:sending to vpi:%d vci:%d\n",
-	       dev->name, vcc->vpi, vcc->vci);
-#endif /* DUMP_PACKETS > 0 */
-
-	while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) {
-		pr_debug("emptying tx queue, MAC address %pM\n", lec_h->h_dest);
-		lec_send(vcc, skb2);
-	}
-
-	lec_send(vcc, skb);
-
-	if (!atm_may_send(vcc, 0)) {
-		struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
-
-		vpriv->xoff = 1;
-		netif_stop_queue(dev);
-
-		/*
-		 * vcc->pop() might have occurred in between, making
-		 * the vcc usuable again.  Since xmit is serialized,
-		 * this is the only situation we have to re-test.
-		 */
-
-		if (atm_may_send(vcc, 0))
-			netif_wake_queue(dev);
-	}
-
-out:
-	if (entry)
-		lec_arp_put(entry);
-	netif_trans_update(dev);
-	return NETDEV_TX_OK;
-}
-
-/* The inverse routine to net_open(). */
-static int lec_close(struct net_device *dev)
-{
-	netif_stop_queue(dev);
-	return 0;
-}
-
-static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	static const u8 zero_addr[ETH_ALEN] = {};
-	unsigned long flags;
-	struct net_device *dev = (struct net_device *)vcc->proto_data;
-	struct lec_priv *priv = netdev_priv(dev);
-	struct atmlec_msg *mesg;
-	struct lec_arp_table *entry;
-	char *tmp;		/* FIXME */
-
-	WARN_ON(refcount_sub_and_test(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc));
-	mesg = (struct atmlec_msg *)skb->data;
-	tmp = skb->data;
-	tmp += sizeof(struct atmlec_msg);
-	pr_debug("%s: msg from zeppelin:%d\n", dev->name, mesg->type);
-	switch (mesg->type) {
-	case l_set_mac_addr:
-		eth_hw_addr_set(dev, mesg->content.normal.mac_addr);
-		break;
-	case l_del_mac_addr:
-		eth_hw_addr_set(dev, zero_addr);
-		break;
-	case l_addr_delete:
-		lec_addr_delete(priv, mesg->content.normal.atm_addr,
-				mesg->content.normal.flag);
-		break;
-	case l_topology_change:
-		priv->topology_change = mesg->content.normal.flag;
-		break;
-	case l_flush_complete:
-		lec_flush_complete(priv, mesg->content.normal.flag);
-		break;
-	case l_narp_req:	/* LANE2: see 7.1.35 in the lane2 spec */
-		spin_lock_irqsave(&priv->lec_arp_lock, flags);
-		entry = lec_arp_find(priv, mesg->content.normal.mac_addr);
-		lec_arp_remove(priv, entry);
-		spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-
-		if (mesg->content.normal.no_source_le_narp)
-			break;
-		fallthrough;
-	case l_arp_update:
-		lec_arp_update(priv, mesg->content.normal.mac_addr,
-			       mesg->content.normal.atm_addr,
-			       mesg->content.normal.flag,
-			       mesg->content.normal.targetless_le_arp);
-		pr_debug("in l_arp_update\n");
-		if (mesg->sizeoftlvs != 0) {	/* LANE2 3.1.5 */
-			pr_debug("LANE2 3.1.5, got tlvs, size %d\n",
-				 mesg->sizeoftlvs);
-			lane2_associate_ind(dev, mesg->content.normal.mac_addr,
-					    tmp, mesg->sizeoftlvs);
-		}
-		break;
-	case l_config:
-		priv->maximum_unknown_frame_count =
-		    mesg->content.config.maximum_unknown_frame_count;
-		priv->max_unknown_frame_time =
-		    (mesg->content.config.max_unknown_frame_time * HZ);
-		priv->max_retry_count = mesg->content.config.max_retry_count;
-		priv->aging_time = (mesg->content.config.aging_time * HZ);
-		priv->forward_delay_time =
-		    (mesg->content.config.forward_delay_time * HZ);
-		priv->arp_response_time =
-		    (mesg->content.config.arp_response_time * HZ);
-		priv->flush_timeout = (mesg->content.config.flush_timeout * HZ);
-		priv->path_switching_delay =
-		    (mesg->content.config.path_switching_delay * HZ);
-		priv->lane_version = mesg->content.config.lane_version;
-					/* LANE2 */
-		priv->lane2_ops = NULL;
-		if (priv->lane_version > 1)
-			priv->lane2_ops = &lane2_ops;
-		rtnl_lock();
-		if (dev_set_mtu(dev, mesg->content.config.mtu))
-			pr_info("%s: change_mtu to %d failed\n",
-				dev->name, mesg->content.config.mtu);
-		rtnl_unlock();
-		priv->is_proxy = mesg->content.config.is_proxy;
-		break;
-	case l_flush_tran_id:
-		lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr,
-				      mesg->content.normal.flag);
-		break;
-	case l_set_lecid:
-		priv->lecid =
-		    (unsigned short)(0xffff & mesg->content.normal.flag);
-		break;
-	case l_should_bridge:
-#if IS_ENABLED(CONFIG_BRIDGE)
-	{
-		pr_debug("%s: bridge zeppelin asks about %pM\n",
-			 dev->name, mesg->content.proxy.mac_addr);
-
-		if (br_fdb_test_addr_hook == NULL)
-			break;
-
-		if (br_fdb_test_addr_hook(dev, mesg->content.proxy.mac_addr)) {
-			/* hit from bridge table, send LE_ARP_RESPONSE */
-			struct sk_buff *skb2;
-			struct sock *sk;
-
-			pr_debug("%s: entry found, responding to zeppelin\n",
-				 dev->name);
-			skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
-			if (skb2 == NULL)
-				break;
-			skb2->len = sizeof(struct atmlec_msg);
-			skb_copy_to_linear_data(skb2, mesg, sizeof(*mesg));
-			struct atm_vcc *vcc;
-
-			rcu_read_lock();
-			vcc = rcu_dereference(priv->lecd);
-			if (vcc) {
-				atm_force_charge(vcc, skb2->truesize);
-				sk = sk_atm(vcc);
-				skb_queue_tail(&sk->sk_receive_queue, skb2);
-				sk->sk_data_ready(sk);
-			} else {
-				dev_kfree_skb(skb2);
-			}
-			rcu_read_unlock();
-		}
-	}
-#endif /* IS_ENABLED(CONFIG_BRIDGE) */
-		break;
-	default:
-		pr_info("%s: Unknown message type %d\n", dev->name, mesg->type);
-		dev_kfree_skb(skb);
-		return -EINVAL;
-	}
-	dev_kfree_skb(skb);
-	return 0;
-}
-
-static void lec_atm_close(struct atm_vcc *vcc)
-{
-	struct net_device *dev = (struct net_device *)vcc->proto_data;
-	struct lec_priv *priv = netdev_priv(dev);
-
-	rcu_assign_pointer(priv->lecd, NULL);
-	synchronize_rcu();
-	/* Do something needful? */
-
-	netif_stop_queue(dev);
-	lec_arp_destroy(priv);
-
-	pr_info("%s: Shut down!\n", dev->name);
-	module_put(THIS_MODULE);
-}
-
-static const struct atmdev_ops lecdev_ops = {
-	.close = lec_atm_close,
-	.send = lec_atm_send
-};
-
-static struct atm_dev lecatm_dev = {
-	.ops = &lecdev_ops,
-	.type = "lec",
-	.number = 999,		/* dummy device number */
-	.lock = __SPIN_LOCK_UNLOCKED(lecatm_dev.lock)
-};
-
-/*
- * LANE2: new argument struct sk_buff *data contains
- * the LE_ARP based TLVs introduced in the LANE2 spec
- */
-static int
-send_to_lecd(struct lec_priv *priv, atmlec_msg_type type,
-	     const unsigned char *mac_addr, const unsigned char *atm_addr,
-	     struct sk_buff *data)
-{
-	struct atm_vcc *vcc;
-	struct sock *sk;
-	struct sk_buff *skb;
-	struct atmlec_msg *mesg;
-
-	if (!priv || !rcu_access_pointer(priv->lecd))
-		return -1;
-
-	skb = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
-	if (!skb)
-		return -1;
-	skb->len = sizeof(struct atmlec_msg);
-	mesg = (struct atmlec_msg *)skb->data;
-	memset(mesg, 0, sizeof(struct atmlec_msg));
-	mesg->type = type;
-	if (data != NULL)
-		mesg->sizeoftlvs = data->len;
-	if (mac_addr)
-		ether_addr_copy(mesg->content.normal.mac_addr, mac_addr);
-	else
-		mesg->content.normal.targetless_le_arp = 1;
-	if (atm_addr)
-		memcpy(&mesg->content.normal.atm_addr, atm_addr, ATM_ESA_LEN);
-
-	rcu_read_lock();
-	vcc = rcu_dereference(priv->lecd);
-	if (!vcc) {
-		rcu_read_unlock();
-		kfree_skb(skb);
-		return -1;
-	}
-
-	atm_force_charge(vcc, skb->truesize);
-	sk = sk_atm(vcc);
-	skb_queue_tail(&sk->sk_receive_queue, skb);
-	sk->sk_data_ready(sk);
-
-	if (data != NULL) {
-		pr_debug("about to send %d bytes of data\n", data->len);
-		atm_force_charge(vcc, data->truesize);
-		skb_queue_tail(&sk->sk_receive_queue, data);
-		sk->sk_data_ready(sk);
-	}
-
-	rcu_read_unlock();
-	return 0;
-}
-
-static void lec_set_multicast_list(struct net_device *dev)
-{
-	/*
-	 * by default, all multicast frames arrive over the bus.
-	 * eventually support selective multicast service
-	 */
-}
-
-static const struct net_device_ops lec_netdev_ops = {
-	.ndo_open		= lec_open,
-	.ndo_stop		= lec_close,
-	.ndo_start_xmit		= lec_start_xmit,
-	.ndo_tx_timeout		= lec_tx_timeout,
-	.ndo_set_rx_mode	= lec_set_multicast_list,
-};
-
-static const unsigned char lec_ctrl_magic[] = {
-	0xff,
-	0x00,
-	0x01,
-	0x01
-};
-
-#define LEC_DATA_DIRECT_8023  2
-#define LEC_DATA_DIRECT_8025  3
-
-static int lec_is_data_direct(struct atm_vcc *vcc)
-{
-	return ((vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8023) ||
-		(vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8025));
-}
-
-static void lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	unsigned long flags;
-	struct net_device *dev = (struct net_device *)vcc->proto_data;
-	struct lec_priv *priv = netdev_priv(dev);
-
-#if DUMP_PACKETS > 0
-	printk(KERN_DEBUG "%s: vcc vpi:%d vci:%d\n",
-	       dev->name, vcc->vpi, vcc->vci);
-#endif
-	if (!skb) {
-		pr_debug("%s: null skb\n", dev->name);
-		lec_vcc_close(priv, vcc);
-		return;
-	}
-#if DUMP_PACKETS >= 2
-#define MAX_SKB_DUMP 99
-#elif DUMP_PACKETS >= 1
-#define MAX_SKB_DUMP 30
-#endif
-#if DUMP_PACKETS > 0
-	printk(KERN_DEBUG "%s: rcv datalen:%ld lecid:%4.4x\n",
-	       dev->name, skb->len, priv->lecid);
-	print_hex_dump(KERN_DEBUG, "", DUMP_OFFSET, 16, 1,
-		       skb->data, min(MAX_SKB_DUMP, skb->len), true);
-#endif /* DUMP_PACKETS > 0 */
-	if (memcmp(skb->data, lec_ctrl_magic, 4) == 0) {
-				/* Control frame, to daemon */
-		struct sock *sk = sk_atm(vcc);
-
-		pr_debug("%s: To daemon\n", dev->name);
-		skb_queue_tail(&sk->sk_receive_queue, skb);
-		sk->sk_data_ready(sk);
-	} else {		/* Data frame, queue to protocol handlers */
-		struct lec_arp_table *entry;
-		unsigned char *src, *dst;
-
-		atm_return(vcc, skb->truesize);
-		if (*(__be16 *) skb->data == htons(priv->lecid) ||
-		    !rcu_access_pointer(priv->lecd) || !(dev->flags & IFF_UP)) {
-			/*
-			 * Probably looping back, or if lecd is missing,
-			 * lecd has gone down
-			 */
-			pr_debug("Ignoring frame...\n");
-			dev_kfree_skb(skb);
-			return;
-		}
-		dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest;
-
-		/*
-		 * If this is a Data Direct VCC, and the VCC does not match
-		 * the LE_ARP cache entry, delete the LE_ARP cache entry.
-		 */
-		spin_lock_irqsave(&priv->lec_arp_lock, flags);
-		if (lec_is_data_direct(vcc)) {
-			src = ((struct lecdatahdr_8023 *)skb->data)->h_source;
-			entry = lec_arp_find(priv, src);
-			if (entry && entry->vcc != vcc) {
-				lec_arp_remove(priv, entry);
-				lec_arp_put(entry);
-			}
-		}
-		spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-
-		if (!(dst[0] & 0x01) &&	/* Never filter Multi/Broadcast */
-		    !priv->is_proxy &&	/* Proxy wants all the packets */
-		    memcmp(dst, dev->dev_addr, dev->addr_len)) {
-			dev_kfree_skb(skb);
-			return;
-		}
-		if (!hlist_empty(&priv->lec_arp_empty_ones))
-			lec_arp_check_empties(priv, vcc, skb);
-		skb_pull(skb, 2);	/* skip lec_id */
-		skb->protocol = eth_type_trans(skb, dev);
-		dev->stats.rx_packets++;
-		dev->stats.rx_bytes += skb->len;
-		memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
-		netif_rx(skb);
-	}
-}
-
-static void lec_pop(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
-	struct net_device *dev = skb->dev;
-
-	if (vpriv == NULL) {
-		pr_info("vpriv = NULL!?!?!?\n");
-		return;
-	}
-
-	vpriv->old_pop(vcc, skb);
-
-	if (vpriv->xoff && atm_may_send(vcc, 0)) {
-		vpriv->xoff = 0;
-		if (netif_running(dev) && netif_queue_stopped(dev))
-			netif_wake_queue(dev);
-	}
-}
-
-static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg)
-{
-	struct lec_vcc_priv *vpriv;
-	int bytes_left;
-	struct atmlec_ioc ioc_data;
-
-	lockdep_assert_held(&lec_mutex);
-	/* Lecd must be up in this case */
-	bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc));
-	if (bytes_left != 0)
-		pr_info("copy from user failed for %d bytes\n", bytes_left);
-	if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF)
-		return -EINVAL;
-	ioc_data.dev_num = array_index_nospec(ioc_data.dev_num, MAX_LEC_ITF);
-	if (!dev_lec[ioc_data.dev_num])
-		return -EINVAL;
-	vpriv = kmalloc_obj(struct lec_vcc_priv);
-	if (!vpriv)
-		return -ENOMEM;
-	vpriv->xoff = 0;
-	vpriv->old_pop = vcc->pop;
-	vcc->user_back = vpriv;
-	vcc->pop = lec_pop;
-	lec_vcc_added(netdev_priv(dev_lec[ioc_data.dev_num]),
-		      &ioc_data, vcc, vcc->push);
-	vcc->proto_data = dev_lec[ioc_data.dev_num];
-	vcc->push = lec_push;
-	return 0;
-}
-
-static int lec_mcast_attach(struct atm_vcc *vcc, int arg)
-{
-	lockdep_assert_held(&lec_mutex);
-	if (arg < 0 || arg >= MAX_LEC_ITF)
-		return -EINVAL;
-	arg = array_index_nospec(arg, MAX_LEC_ITF);
-	if (!dev_lec[arg])
-		return -EINVAL;
-	vcc->proto_data = dev_lec[arg];
-	return lec_mcast_make(netdev_priv(dev_lec[arg]), vcc);
-}
-
-/* Initialize device. */
-static int lecd_attach(struct atm_vcc *vcc, int arg)
-{
-	int i;
-	struct lec_priv *priv;
-
-	lockdep_assert_held(&lec_mutex);
-	if (arg < 0)
-		arg = 0;
-	if (arg >= MAX_LEC_ITF)
-		return -EINVAL;
-	i = array_index_nospec(arg, MAX_LEC_ITF);
-	if (!dev_lec[i]) {
-		int size;
-
-		size = sizeof(struct lec_priv);
-		dev_lec[i] = alloc_etherdev(size);
-		if (!dev_lec[i])
-			return -ENOMEM;
-		dev_lec[i]->netdev_ops = &lec_netdev_ops;
-		dev_lec[i]->max_mtu = 18190;
-		snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i);
-		if (register_netdev(dev_lec[i])) {
-			free_netdev(dev_lec[i]);
-			dev_lec[i] = NULL;
-			return -EINVAL;
-		}
-
-		priv = netdev_priv(dev_lec[i]);
-	} else {
-		priv = netdev_priv(dev_lec[i]);
-		if (rcu_access_pointer(priv->lecd))
-			return -EADDRINUSE;
-	}
-	lec_arp_init(priv);
-	priv->itfnum = i;	/* LANE2 addition */
-	rcu_assign_pointer(priv->lecd, vcc);
-	vcc->dev = &lecatm_dev;
-	vcc_insert_socket(sk_atm(vcc));
-
-	vcc->proto_data = dev_lec[i];
-	set_bit(ATM_VF_META, &vcc->flags);
-	set_bit(ATM_VF_READY, &vcc->flags);
-
-	/* Set default values to these variables */
-	priv->maximum_unknown_frame_count = 1;
-	priv->max_unknown_frame_time = (1 * HZ);
-	priv->vcc_timeout_period = (1200 * HZ);
-	priv->max_retry_count = 1;
-	priv->aging_time = (300 * HZ);
-	priv->forward_delay_time = (15 * HZ);
-	priv->topology_change = 0;
-	priv->arp_response_time = (1 * HZ);
-	priv->flush_timeout = (4 * HZ);
-	priv->path_switching_delay = (6 * HZ);
-
-	if (dev_lec[i]->flags & IFF_UP)
-		netif_start_queue(dev_lec[i]);
-	__module_get(THIS_MODULE);
-	return i;
-}
-
-#ifdef CONFIG_PROC_FS
-static const char *lec_arp_get_status_string(unsigned char status)
-{
-	static const char *const lec_arp_status_string[] = {
-		"ESI_UNKNOWN       ",
-		"ESI_ARP_PENDING   ",
-		"ESI_VC_PENDING    ",
-		"<Undefined>       ",
-		"ESI_FLUSH_PENDING ",
-		"ESI_FORWARD_DIRECT"
-	};
-
-	if (status > ESI_FORWARD_DIRECT)
-		status = 3;	/* ESI_UNDEFINED */
-	return lec_arp_status_string[status];
-}
-
-static void lec_info(struct seq_file *seq, struct lec_arp_table *entry)
-{
-	seq_printf(seq, "%pM ", entry->mac_addr);
-	seq_printf(seq, "%*phN ", ATM_ESA_LEN, entry->atm_addr);
-	seq_printf(seq, "%s %4.4x", lec_arp_get_status_string(entry->status),
-		   entry->flags & 0xffff);
-	if (entry->vcc)
-		seq_printf(seq, "%3d %3d ", entry->vcc->vpi, entry->vcc->vci);
-	else
-		seq_printf(seq, "        ");
-	if (entry->recv_vcc) {
-		seq_printf(seq, "     %3d %3d", entry->recv_vcc->vpi,
-			   entry->recv_vcc->vci);
-	}
-	seq_putc(seq, '\n');
-}
-
-struct lec_state {
-	unsigned long flags;
-	struct lec_priv *locked;
-	struct hlist_node *node;
-	struct net_device *dev;
-	int itf;
-	int arp_table;
-	int misc_table;
-};
-
-static void *lec_tbl_walk(struct lec_state *state, struct hlist_head *tbl,
-			  loff_t *l)
-{
-	struct hlist_node *e = state->node;
-
-	if (!e)
-		e = tbl->first;
-	if (e == SEQ_START_TOKEN) {
-		e = tbl->first;
-		--*l;
-	}
-
-	for (; e; e = e->next) {
-		if (--*l < 0)
-			break;
-	}
-	state->node = e;
-
-	return (*l < 0) ? state : NULL;
-}
-
-static void *lec_arp_walk(struct lec_state *state, loff_t *l,
-			  struct lec_priv *priv)
-{
-	void *v = NULL;
-	int p;
-
-	for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) {
-		v = lec_tbl_walk(state, &priv->lec_arp_tables[p], l);
-		if (v)
-			break;
-	}
-	state->arp_table = p;
-	return v;
-}
-
-static void *lec_misc_walk(struct lec_state *state, loff_t *l,
-			   struct lec_priv *priv)
-{
-	struct hlist_head *lec_misc_tables[] = {
-		&priv->lec_arp_empty_ones,
-		&priv->lec_no_forward,
-		&priv->mcast_fwds
-	};
-	void *v = NULL;
-	int q;
-
-	for (q = state->misc_table; q < ARRAY_SIZE(lec_misc_tables); q++) {
-		v = lec_tbl_walk(state, lec_misc_tables[q], l);
-		if (v)
-			break;
-	}
-	state->misc_table = q;
-	return v;
-}
-
-static void *lec_priv_walk(struct lec_state *state, loff_t *l,
-			   struct lec_priv *priv)
-{
-	if (!state->locked) {
-		state->locked = priv;
-		spin_lock_irqsave(&priv->lec_arp_lock, state->flags);
-	}
-	if (!lec_arp_walk(state, l, priv) && !lec_misc_walk(state, l, priv)) {
-		spin_unlock_irqrestore(&priv->lec_arp_lock, state->flags);
-		state->locked = NULL;
-		/* Partial state reset for the next time we get called */
-		state->arp_table = state->misc_table = 0;
-	}
-	return state->locked;
-}
-
-static void *lec_itf_walk(struct lec_state *state, loff_t *l)
-{
-	struct net_device *dev;
-	void *v;
-
-	dev = state->dev ? state->dev : dev_lec[state->itf];
-	v = (dev && netdev_priv(dev)) ?
-		lec_priv_walk(state, l, netdev_priv(dev)) : NULL;
-	if (!v && dev) {
-		/* Partial state reset for the next time we get called */
-		dev = NULL;
-	}
-	state->dev = dev;
-	return v;
-}
-
-static void *lec_get_idx(struct lec_state *state, loff_t l)
-{
-	void *v = NULL;
-
-	for (; state->itf < MAX_LEC_ITF; state->itf++) {
-		v = lec_itf_walk(state, &l);
-		if (v)
-			break;
-	}
-	return v;
-}
-
-static void *lec_seq_start(struct seq_file *seq, loff_t *pos)
-{
-	struct lec_state *state = seq->private;
-
-	mutex_lock(&lec_mutex);
-	state->itf = 0;
-	state->dev = NULL;
-	state->locked = NULL;
-	state->arp_table = 0;
-	state->misc_table = 0;
-	state->node = SEQ_START_TOKEN;
-
-	return *pos ? lec_get_idx(state, *pos) : SEQ_START_TOKEN;
-}
-
-static void lec_seq_stop(struct seq_file *seq, void *v)
-{
-	struct lec_state *state = seq->private;
-
-	if (state->dev) {
-		spin_unlock_irqrestore(&state->locked->lec_arp_lock,
-				       state->flags);
-		state->dev = NULL;
-	}
-	mutex_unlock(&lec_mutex);
-}
-
-static void *lec_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	struct lec_state *state = seq->private;
-
-	++*pos;
-	return lec_get_idx(state, 1);
-}
-
-static int lec_seq_show(struct seq_file *seq, void *v)
-{
-	static const char lec_banner[] =
-	    "Itf  MAC          ATM destination"
-	    "                          Status            Flags "
-	    "VPI/VCI Recv VPI/VCI\n";
-
-	if (v == SEQ_START_TOKEN)
-		seq_puts(seq, lec_banner);
-	else {
-		struct lec_state *state = seq->private;
-		struct net_device *dev = state->dev;
-		struct lec_arp_table *entry = hlist_entry(state->node,
-							  struct lec_arp_table,
-							  next);
-
-		seq_printf(seq, "%s ", dev->name);
-		lec_info(seq, entry);
-	}
-	return 0;
-}
-
-static const struct seq_operations lec_seq_ops = {
-	.start = lec_seq_start,
-	.next = lec_seq_next,
-	.stop = lec_seq_stop,
-	.show = lec_seq_show,
-};
-#endif
-
-static int lane_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
-	struct atm_vcc *vcc = ATM_SD(sock);
-	int err = 0;
-
-	switch (cmd) {
-	case ATMLEC_CTRL:
-	case ATMLEC_MCAST:
-	case ATMLEC_DATA:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		break;
-	default:
-		return -ENOIOCTLCMD;
-	}
-
-	mutex_lock(&lec_mutex);
-	switch (cmd) {
-	case ATMLEC_CTRL:
-		err = lecd_attach(vcc, (int)arg);
-		if (err >= 0)
-			sock->state = SS_CONNECTED;
-		break;
-	case ATMLEC_MCAST:
-		err = lec_mcast_attach(vcc, (int)arg);
-		break;
-	case ATMLEC_DATA:
-		err = lec_vcc_attach(vcc, (void __user *)arg);
-		break;
-	}
-
-	mutex_unlock(&lec_mutex);
-	return err;
-}
-
-static struct atm_ioctl lane_ioctl_ops = {
-	.owner = THIS_MODULE,
-	.ioctl = lane_ioctl,
-};
-
-static int __init lane_module_init(void)
-{
-#ifdef CONFIG_PROC_FS
-	struct proc_dir_entry *p;
-
-	p = proc_create_seq_private("lec", 0444, atm_proc_root, &lec_seq_ops,
-			sizeof(struct lec_state), NULL);
-	if (!p) {
-		pr_err("Unable to initialize /proc/net/atm/lec\n");
-		return -ENOMEM;
-	}
-#endif
-
-	register_atm_ioctl(&lane_ioctl_ops);
-	pr_info("lec.c: initialized\n");
-	return 0;
-}
-
-static void __exit lane_module_cleanup(void)
-{
-	int i;
-
-#ifdef CONFIG_PROC_FS
-	remove_proc_entry("lec", atm_proc_root);
-#endif
-
-	deregister_atm_ioctl(&lane_ioctl_ops);
-
-	for (i = 0; i < MAX_LEC_ITF; i++) {
-		if (dev_lec[i] != NULL) {
-			unregister_netdev(dev_lec[i]);
-			free_netdev(dev_lec[i]);
-			dev_lec[i] = NULL;
-		}
-	}
-}
-
-module_init(lane_module_init);
-module_exit(lane_module_cleanup);
-
-/*
- * LANE2: 3.1.3, LE_RESOLVE.request
- * Non force allocates memory and fills in *tlvs, fills in *sizeoftlvs.
- * If sizeoftlvs == NULL the default TLVs associated with this
- * lec will be used.
- * If dst_mac == NULL, targetless LE_ARP will be sent
- */
-static int lane2_resolve(struct net_device *dev, const u8 *dst_mac, int force,
-			 u8 **tlvs, u32 *sizeoftlvs)
-{
-	unsigned long flags;
-	struct lec_priv *priv = netdev_priv(dev);
-	struct lec_arp_table *table;
-	struct sk_buff *skb;
-	int retval;
-
-	if (force == 0) {
-		spin_lock_irqsave(&priv->lec_arp_lock, flags);
-		table = lec_arp_find(priv, dst_mac);
-		spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-		if (table == NULL)
-			return -1;
-
-		*tlvs = kmemdup(table->tlvs, table->sizeoftlvs, GFP_ATOMIC);
-		if (*tlvs == NULL)
-			return -1;
-
-		*sizeoftlvs = table->sizeoftlvs;
-
-		return 0;
-	}
-
-	if (sizeoftlvs == NULL)
-		retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, NULL);
-
-	else {
-		skb = alloc_skb(*sizeoftlvs, GFP_ATOMIC);
-		if (skb == NULL)
-			return -1;
-		skb->len = *sizeoftlvs;
-		skb_copy_to_linear_data(skb, *tlvs, *sizeoftlvs);
-		retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, skb);
-	}
-	return retval;
-}
-
-/*
- * LANE2: 3.1.4, LE_ASSOCIATE.request
- * Associate the *tlvs with the *lan_dst address.
- * Will overwrite any previous association
- * Returns 1 for success, 0 for failure (out of memory)
- *
- */
-static int lane2_associate_req(struct net_device *dev, const u8 *lan_dst,
-			       const u8 *tlvs, u32 sizeoftlvs)
-{
-	int retval;
-	struct sk_buff *skb;
-	struct lec_priv *priv = netdev_priv(dev);
-
-	if (!ether_addr_equal(lan_dst, dev->dev_addr))
-		return 0;	/* not our mac address */
-
-	kfree(priv->tlvs);	/* NULL if there was no previous association */
-
-	priv->tlvs = kmemdup(tlvs, sizeoftlvs, GFP_KERNEL);
-	if (priv->tlvs == NULL)
-		return 0;
-	priv->sizeoftlvs = sizeoftlvs;
-
-	skb = alloc_skb(sizeoftlvs, GFP_ATOMIC);
-	if (skb == NULL)
-		return 0;
-	skb->len = sizeoftlvs;
-	skb_copy_to_linear_data(skb, tlvs, sizeoftlvs);
-	retval = send_to_lecd(priv, l_associate_req, NULL, NULL, skb);
-	if (retval != 0)
-		pr_info("lec.c: lane2_associate_req() failed\n");
-	/*
-	 * If the previous association has changed we must
-	 * somehow notify other LANE entities about the change
-	 */
-	return 1;
-}
-
-/*
- * LANE2: 3.1.5, LE_ASSOCIATE.indication
- *
- */
-static void lane2_associate_ind(struct net_device *dev, const u8 *mac_addr,
-				const u8 *tlvs, u32 sizeoftlvs)
-{
-#if 0
-	int i = 0;
-#endif
-	struct lec_priv *priv = netdev_priv(dev);
-#if 0				/*
-				 * Why have the TLVs in LE_ARP entries
-				 * since we do not use them? When you
-				 * uncomment this code, make sure the
-				 * TLVs get freed when entry is killed
-				 */
-	struct lec_arp_table *entry = lec_arp_find(priv, mac_addr);
-
-	if (entry == NULL)
-		return;		/* should not happen */
-
-	kfree(entry->tlvs);
-
-	entry->tlvs = kmemdup(tlvs, sizeoftlvs, GFP_KERNEL);
-	if (entry->tlvs == NULL)
-		return;
-	entry->sizeoftlvs = sizeoftlvs;
-#endif
-#if 0
-	pr_info("\n");
-	pr_info("dump of tlvs, sizeoftlvs=%d\n", sizeoftlvs);
-	while (i < sizeoftlvs)
-		pr_cont("%02x ", tlvs[i++]);
-
-	pr_cont("\n");
-#endif
-
-	/* tell MPOA about the TLVs we saw */
-	if (priv->lane2_ops && priv->lane2_ops->associate_indicator) {
-		priv->lane2_ops->associate_indicator(dev, mac_addr,
-						     tlvs, sizeoftlvs);
-	}
-}
-
-/*
- * Here starts what used to lec_arpc.c
- *
- * lec_arpc.c was added here when making
- * lane client modular. October 1997
- */
-
-#include <linux/types.h>
-#include <linux/timer.h>
-#include <linux/param.h>
-#include <linux/atomic.h>
-#include <linux/inetdevice.h>
-#include <net/route.h>
-
-#if 0
-#define pr_debug(format, args...)
-/*
-  #define pr_debug printk
-*/
-#endif
-#define DEBUG_ARP_TABLE 0
-
-#define LEC_ARP_REFRESH_INTERVAL (3*HZ)
-
-static void lec_arp_check_expire(struct work_struct *work);
-static void lec_arp_expire_arp(struct timer_list *t);
-
-/*
- * Arp table funcs
- */
-
-#define HASH(ch) (ch & (LEC_ARP_TABLE_SIZE - 1))
-
-/*
- * Initialization of arp-cache
- */
-static void lec_arp_init(struct lec_priv *priv)
-{
-	unsigned short i;
-
-	for (i = 0; i < LEC_ARP_TABLE_SIZE; i++)
-		INIT_HLIST_HEAD(&priv->lec_arp_tables[i]);
-	INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
-	INIT_HLIST_HEAD(&priv->lec_no_forward);
-	INIT_HLIST_HEAD(&priv->mcast_fwds);
-	spin_lock_init(&priv->lec_arp_lock);
-	INIT_DELAYED_WORK(&priv->lec_arp_work, lec_arp_check_expire);
-	schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL);
-}
-
-static void lec_arp_clear_vccs(struct lec_arp_table *entry)
-{
-	if (entry->vcc) {
-		struct atm_vcc *vcc = entry->vcc;
-		struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
-		struct net_device *dev = (struct net_device *)vcc->proto_data;
-
-		if (vpriv) {
-			vcc->pop = vpriv->old_pop;
-			if (vpriv->xoff)
-				netif_wake_queue(dev);
-			kfree(vpriv);
-			vcc->user_back = NULL;
-			vcc->push = entry->old_push;
-			vcc_release_async(vcc, -EPIPE);
-		}
-		entry->vcc = NULL;
-	}
-	if (entry->recv_vcc) {
-		struct atm_vcc *vcc = entry->recv_vcc;
-		struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
-
-		if (vpriv) {
-			kfree(vpriv);
-			vcc->user_back = NULL;
-
-			entry->recv_vcc->push = entry->old_recv_push;
-			vcc_release_async(entry->recv_vcc, -EPIPE);
-		}
-		entry->recv_vcc = NULL;
-	}
-}
-
-/*
- * Insert entry to lec_arp_table
- * LANE2: Add to the end of the list to satisfy 8.1.13
- */
-static inline void
-lec_arp_add(struct lec_priv *priv, struct lec_arp_table *entry)
-{
-	struct hlist_head *tmp;
-
-	tmp = &priv->lec_arp_tables[HASH(entry->mac_addr[ETH_ALEN - 1])];
-	hlist_add_head(&entry->next, tmp);
-
-	pr_debug("Added entry:%pM\n", entry->mac_addr);
-}
-
-/*
- * Remove entry from lec_arp_table
- */
-static int
-lec_arp_remove(struct lec_priv *priv, struct lec_arp_table *to_remove)
-{
-	struct lec_arp_table *entry;
-	int i, remove_vcc = 1;
-
-	if (!to_remove)
-		return -1;
-
-	hlist_del(&to_remove->next);
-	timer_delete(&to_remove->timer);
-
-	/*
-	 * If this is the only MAC connected to this VCC,
-	 * also tear down the VCC
-	 */
-	if (to_remove->status >= ESI_FLUSH_PENDING) {
-		/*
-		 * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT
-		 */
-		for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-			hlist_for_each_entry(entry,
-					     &priv->lec_arp_tables[i], next) {
-				if (memcmp(to_remove->atm_addr,
-					   entry->atm_addr, ATM_ESA_LEN) == 0) {
-					remove_vcc = 0;
-					break;
-				}
-			}
-		}
-		if (remove_vcc)
-			lec_arp_clear_vccs(to_remove);
-	}
-	skb_queue_purge(&to_remove->tx_wait);	/* FIXME: good place for this? */
-
-	pr_debug("Removed entry:%pM\n", to_remove->mac_addr);
-	return 0;
-}
-
-#if DEBUG_ARP_TABLE
-static const char *get_status_string(unsigned char st)
-{
-	switch (st) {
-	case ESI_UNKNOWN:
-		return "ESI_UNKNOWN";
-	case ESI_ARP_PENDING:
-		return "ESI_ARP_PENDING";
-	case ESI_VC_PENDING:
-		return "ESI_VC_PENDING";
-	case ESI_FLUSH_PENDING:
-		return "ESI_FLUSH_PENDING";
-	case ESI_FORWARD_DIRECT:
-		return "ESI_FORWARD_DIRECT";
-	}
-	return "<UNKNOWN>";
-}
-
-static void dump_arp_table(struct lec_priv *priv)
-{
-	struct lec_arp_table *rulla;
-	char buf[256];
-	int i, offset;
-
-	pr_info("Dump %p:\n", priv);
-	for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-		hlist_for_each_entry(rulla,
-				     &priv->lec_arp_tables[i], next) {
-			offset = 0;
-			offset += sprintf(buf, "%d: %p\n", i, rulla);
-			offset += sprintf(buf + offset, "Mac: %pM ",
-					  rulla->mac_addr);
-			offset += sprintf(buf + offset, "Atm: %*ph ", ATM_ESA_LEN,
-					  rulla->atm_addr);
-			offset += sprintf(buf + offset,
-					  "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
-					  rulla->vcc ? rulla->vcc->vpi : 0,
-					  rulla->vcc ? rulla->vcc->vci : 0,
-					  rulla->recv_vcc ? rulla->recv_vcc->
-					  vpi : 0,
-					  rulla->recv_vcc ? rulla->recv_vcc->
-					  vci : 0, rulla->last_used,
-					  rulla->timestamp, rulla->no_tries);
-			offset +=
-			    sprintf(buf + offset,
-				    "Flags:%x, Packets_flooded:%x, Status: %s ",
-				    rulla->flags, rulla->packets_flooded,
-				    get_status_string(rulla->status));
-			pr_info("%s\n", buf);
-		}
-	}
-
-	if (!hlist_empty(&priv->lec_no_forward))
-		pr_info("No forward\n");
-	hlist_for_each_entry(rulla, &priv->lec_no_forward, next) {
-		offset = 0;
-		offset += sprintf(buf + offset, "Mac: %pM ", rulla->mac_addr);
-		offset += sprintf(buf + offset, "Atm: %*ph ", ATM_ESA_LEN,
-				  rulla->atm_addr);
-		offset += sprintf(buf + offset,
-				  "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
-				  rulla->vcc ? rulla->vcc->vpi : 0,
-				  rulla->vcc ? rulla->vcc->vci : 0,
-				  rulla->recv_vcc ? rulla->recv_vcc->vpi : 0,
-				  rulla->recv_vcc ? rulla->recv_vcc->vci : 0,
-				  rulla->last_used,
-				  rulla->timestamp, rulla->no_tries);
-		offset += sprintf(buf + offset,
-				  "Flags:%x, Packets_flooded:%x, Status: %s ",
-				  rulla->flags, rulla->packets_flooded,
-				  get_status_string(rulla->status));
-		pr_info("%s\n", buf);
-	}
-
-	if (!hlist_empty(&priv->lec_arp_empty_ones))
-		pr_info("Empty ones\n");
-	hlist_for_each_entry(rulla, &priv->lec_arp_empty_ones, next) {
-		offset = 0;
-		offset += sprintf(buf + offset, "Mac: %pM ", rulla->mac_addr);
-		offset += sprintf(buf + offset, "Atm: %*ph ", ATM_ESA_LEN,
-				  rulla->atm_addr);
-		offset += sprintf(buf + offset,
-				  "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
-				  rulla->vcc ? rulla->vcc->vpi : 0,
-				  rulla->vcc ? rulla->vcc->vci : 0,
-				  rulla->recv_vcc ? rulla->recv_vcc->vpi : 0,
-				  rulla->recv_vcc ? rulla->recv_vcc->vci : 0,
-				  rulla->last_used,
-				  rulla->timestamp, rulla->no_tries);
-		offset += sprintf(buf + offset,
-				  "Flags:%x, Packets_flooded:%x, Status: %s ",
-				  rulla->flags, rulla->packets_flooded,
-				  get_status_string(rulla->status));
-		pr_info("%s", buf);
-	}
-
-	if (!hlist_empty(&priv->mcast_fwds))
-		pr_info("Multicast Forward VCCs\n");
-	hlist_for_each_entry(rulla, &priv->mcast_fwds, next) {
-		offset = 0;
-		offset += sprintf(buf + offset, "Mac: %pM ", rulla->mac_addr);
-		offset += sprintf(buf + offset, "Atm: %*ph ", ATM_ESA_LEN,
-				  rulla->atm_addr);
-		offset += sprintf(buf + offset,
-				  "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
-				  rulla->vcc ? rulla->vcc->vpi : 0,
-				  rulla->vcc ? rulla->vcc->vci : 0,
-				  rulla->recv_vcc ? rulla->recv_vcc->vpi : 0,
-				  rulla->recv_vcc ? rulla->recv_vcc->vci : 0,
-				  rulla->last_used,
-				  rulla->timestamp, rulla->no_tries);
-		offset += sprintf(buf + offset,
-				  "Flags:%x, Packets_flooded:%x, Status: %s ",
-				  rulla->flags, rulla->packets_flooded,
-				  get_status_string(rulla->status));
-		pr_info("%s\n", buf);
-	}
-
-}
-#else
-#define dump_arp_table(priv) do { } while (0)
-#endif
-
-/*
- * Destruction of arp-cache
- */
-static void lec_arp_destroy(struct lec_priv *priv)
-{
-	unsigned long flags;
-	struct hlist_node *next;
-	struct lec_arp_table *entry;
-	int i;
-
-	cancel_delayed_work_sync(&priv->lec_arp_work);
-
-	/*
-	 * Remove all entries
-	 */
-
-	spin_lock_irqsave(&priv->lec_arp_lock, flags);
-	for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-		hlist_for_each_entry_safe(entry, next,
-					  &priv->lec_arp_tables[i], next) {
-			lec_arp_remove(priv, entry);
-			lec_arp_put(entry);
-		}
-		INIT_HLIST_HEAD(&priv->lec_arp_tables[i]);
-	}
-
-	hlist_for_each_entry_safe(entry, next,
-				  &priv->lec_arp_empty_ones, next) {
-		timer_delete_sync(&entry->timer);
-		lec_arp_clear_vccs(entry);
-		hlist_del(&entry->next);
-		lec_arp_put(entry);
-	}
-	INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
-
-	hlist_for_each_entry_safe(entry, next,
-				  &priv->lec_no_forward, next) {
-		timer_delete_sync(&entry->timer);
-		lec_arp_clear_vccs(entry);
-		hlist_del(&entry->next);
-		lec_arp_put(entry);
-	}
-	INIT_HLIST_HEAD(&priv->lec_no_forward);
-
-	hlist_for_each_entry_safe(entry, next, &priv->mcast_fwds, next) {
-		/* No timer, LANEv2 7.1.20 and 2.3.5.3 */
-		lec_arp_clear_vccs(entry);
-		hlist_del(&entry->next);
-		lec_arp_put(entry);
-	}
-	INIT_HLIST_HEAD(&priv->mcast_fwds);
-	priv->mcast_vcc = NULL;
-	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-}
-
-/*
- * Find entry by mac_address
- */
-static struct lec_arp_table *lec_arp_find(struct lec_priv *priv,
-					  const unsigned char *mac_addr)
-{
-	struct hlist_head *head;
-	struct lec_arp_table *entry;
-
-	pr_debug("%pM\n", mac_addr);
-
-	head = &priv->lec_arp_tables[HASH(mac_addr[ETH_ALEN - 1])];
-	hlist_for_each_entry(entry, head, next) {
-		if (ether_addr_equal(mac_addr, entry->mac_addr))
-			return entry;
-	}
-	return NULL;
-}
-
-static struct lec_arp_table *make_entry(struct lec_priv *priv,
-					const unsigned char *mac_addr)
-{
-	struct lec_arp_table *to_return;
-
-	to_return = kzalloc_obj(struct lec_arp_table, GFP_ATOMIC);
-	if (!to_return)
-		return NULL;
-	ether_addr_copy(to_return->mac_addr, mac_addr);
-	INIT_HLIST_NODE(&to_return->next);
-	timer_setup(&to_return->timer, lec_arp_expire_arp, 0);
-	to_return->last_used = jiffies;
-	to_return->priv = priv;
-	skb_queue_head_init(&to_return->tx_wait);
-	refcount_set(&to_return->usage, 1);
-	return to_return;
-}
-
-/* Arp sent timer expired */
-static void lec_arp_expire_arp(struct timer_list *t)
-{
-	struct lec_arp_table *entry;
-
-	entry = timer_container_of(entry, t, timer);
-
-	pr_debug("\n");
-	if (entry->status == ESI_ARP_PENDING) {
-		if (entry->no_tries <= entry->priv->max_retry_count) {
-			if (entry->is_rdesc)
-				send_to_lecd(entry->priv, l_rdesc_arp_xmt,
-					     entry->mac_addr, NULL, NULL);
-			else
-				send_to_lecd(entry->priv, l_arp_xmt,
-					     entry->mac_addr, NULL, NULL);
-			entry->no_tries++;
-		}
-		mod_timer(&entry->timer, jiffies + (1 * HZ));
-	}
-}
-
-/* Unknown/unused vcc expire, remove associated entry */
-static void lec_arp_expire_vcc(struct timer_list *t)
-{
-	unsigned long flags;
-	struct lec_arp_table *to_remove = timer_container_of(to_remove, t,
-							     timer);
-	struct lec_priv *priv = to_remove->priv;
-
-	timer_delete(&to_remove->timer);
-
-	pr_debug("%p %p: vpi:%d vci:%d\n",
-		 to_remove, priv,
-		 to_remove->vcc ? to_remove->recv_vcc->vpi : 0,
-		 to_remove->vcc ? to_remove->recv_vcc->vci : 0);
-
-	spin_lock_irqsave(&priv->lec_arp_lock, flags);
-	hlist_del(&to_remove->next);
-	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-
-	lec_arp_clear_vccs(to_remove);
-	lec_arp_put(to_remove);
-}
-
-static bool __lec_arp_check_expire(struct lec_arp_table *entry,
-				   unsigned long now,
-				   struct lec_priv *priv)
-{
-	unsigned long time_to_check;
-
-	if ((entry->flags) & LEC_REMOTE_FLAG && priv->topology_change)
-		time_to_check = priv->forward_delay_time;
-	else
-		time_to_check = priv->aging_time;
-
-	pr_debug("About to expire: %lx - %lx > %lx\n",
-		 now, entry->last_used, time_to_check);
-	if (time_after(now, entry->last_used + time_to_check) &&
-	    !(entry->flags & LEC_PERMANENT_FLAG) &&
-	    !(entry->mac_addr[0] & 0x01)) {	/* LANE2: 7.1.20 */
-		/* Remove entry */
-		pr_debug("Entry timed out\n");
-		lec_arp_remove(priv, entry);
-		lec_arp_put(entry);
-	} else {
-		/* Something else */
-		if ((entry->status == ESI_VC_PENDING ||
-		     entry->status == ESI_ARP_PENDING) &&
-		    time_after_eq(now, entry->timestamp +
-				       priv->max_unknown_frame_time)) {
-			entry->timestamp = jiffies;
-			entry->packets_flooded = 0;
-			if (entry->status == ESI_VC_PENDING)
-				send_to_lecd(priv, l_svc_setup,
-					     entry->mac_addr,
-					     entry->atm_addr,
-					     NULL);
-		}
-		if (entry->status == ESI_FLUSH_PENDING &&
-		    time_after_eq(now, entry->timestamp +
-				       priv->path_switching_delay)) {
-			lec_arp_hold(entry);
-			return true;
-		}
-	}
-
-	return false;
-}
-/*
- * Expire entries.
- * 1. Re-set timer
- * 2. For each entry, delete entries that have aged past the age limit.
- * 3. For each entry, depending on the status of the entry, perform
- *    the following maintenance.
- *    a. If status is ESI_VC_PENDING or ESI_ARP_PENDING then if the
- *       tick_count is above the max_unknown_frame_time, clear
- *       the tick_count to zero and clear the packets_flooded counter
- *       to zero. This supports the packet rate limit per address
- *       while flooding unknowns.
- *    b. If the status is ESI_FLUSH_PENDING and the tick_count is greater
- *       than or equal to the path_switching_delay, change the status
- *       to ESI_FORWARD_DIRECT. This causes the flush period to end
- *       regardless of the progress of the flush protocol.
- */
-static void lec_arp_check_expire(struct work_struct *work)
-{
-	unsigned long flags;
-	struct lec_priv *priv =
-		container_of(work, struct lec_priv, lec_arp_work.work);
-	struct hlist_node *next;
-	struct lec_arp_table *entry;
-	unsigned long now;
-	int i;
-
-	pr_debug("%p\n", priv);
-	now = jiffies;
-restart:
-	spin_lock_irqsave(&priv->lec_arp_lock, flags);
-	for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-		hlist_for_each_entry_safe(entry, next,
-					  &priv->lec_arp_tables[i], next) {
-			if (__lec_arp_check_expire(entry, now, priv)) {
-				struct sk_buff *skb;
-				struct atm_vcc *vcc = entry->vcc;
-
-				spin_unlock_irqrestore(&priv->lec_arp_lock,
-						       flags);
-				while ((skb = skb_dequeue(&entry->tx_wait)))
-					lec_send(vcc, skb);
-				entry->last_used = jiffies;
-				entry->status = ESI_FORWARD_DIRECT;
-				lec_arp_put(entry);
-
-				goto restart;
-			}
-		}
-	}
-	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-
-	schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL);
-}
-
-/*
- * Try to find vcc where mac_address is attached.
- *
- */
-static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv,
-				       const unsigned char *mac_to_find,
-				       int is_rdesc,
-				       struct lec_arp_table **ret_entry)
-{
-	unsigned long flags;
-	struct lec_arp_table *entry;
-	struct atm_vcc *found;
-
-	if (mac_to_find[0] & 0x01) {
-		switch (priv->lane_version) {
-		case 1:
-			return priv->mcast_vcc;
-		case 2:	/* LANE2 wants arp for multicast addresses */
-			if (ether_addr_equal(mac_to_find, bus_mac))
-				return priv->mcast_vcc;
-			break;
-		default:
-			break;
-		}
-	}
-
-	spin_lock_irqsave(&priv->lec_arp_lock, flags);
-	entry = lec_arp_find(priv, mac_to_find);
-
-	if (entry) {
-		if (entry->status == ESI_FORWARD_DIRECT) {
-			/* Connection Ok */
-			entry->last_used = jiffies;
-			lec_arp_hold(entry);
-			*ret_entry = entry;
-			found = entry->vcc;
-			goto out;
-		}
-		/*
-		 * If the LE_ARP cache entry is still pending, reset count to 0
-		 * so another LE_ARP request can be made for this frame.
-		 */
-		if (entry->status == ESI_ARP_PENDING)
-			entry->no_tries = 0;
-		/*
-		 * Data direct VC not yet set up, check to see if the unknown
-		 * frame count is greater than the limit. If the limit has
-		 * not been reached, allow the caller to send packet to
-		 * BUS.
-		 */
-		if (entry->status != ESI_FLUSH_PENDING &&
-		    entry->packets_flooded <
-		    priv->maximum_unknown_frame_count) {
-			entry->packets_flooded++;
-			pr_debug("Flooding..\n");
-			found = priv->mcast_vcc;
-			goto out;
-		}
-		/*
-		 * We got here because entry->status == ESI_FLUSH_PENDING
-		 * or BUS flood limit was reached for an entry which is
-		 * in ESI_ARP_PENDING or ESI_VC_PENDING state.
-		 */
-		lec_arp_hold(entry);
-		*ret_entry = entry;
-		pr_debug("entry->status %d entry->vcc %p\n", entry->status,
-			 entry->vcc);
-		found = NULL;
-	} else {
-		/* No matching entry was found */
-		entry = make_entry(priv, mac_to_find);
-		pr_debug("Making entry\n");
-		if (!entry) {
-			found = priv->mcast_vcc;
-			goto out;
-		}
-		lec_arp_add(priv, entry);
-		/* We want arp-request(s) to be sent */
-		entry->packets_flooded = 1;
-		entry->status = ESI_ARP_PENDING;
-		entry->no_tries = 1;
-		entry->last_used = entry->timestamp = jiffies;
-		entry->is_rdesc = is_rdesc;
-		if (entry->is_rdesc)
-			send_to_lecd(priv, l_rdesc_arp_xmt, mac_to_find, NULL,
-				     NULL);
-		else
-			send_to_lecd(priv, l_arp_xmt, mac_to_find, NULL, NULL);
-		entry->timer.expires = jiffies + (1 * HZ);
-		entry->timer.function = lec_arp_expire_arp;
-		add_timer(&entry->timer);
-		found = priv->mcast_vcc;
-	}
-
-out:
-	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-	return found;
-}
-
-static int
-lec_addr_delete(struct lec_priv *priv, const unsigned char *atm_addr,
-		unsigned long permanent)
-{
-	unsigned long flags;
-	struct hlist_node *next;
-	struct lec_arp_table *entry;
-	int i;
-
-	pr_debug("\n");
-	spin_lock_irqsave(&priv->lec_arp_lock, flags);
-	for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-		hlist_for_each_entry_safe(entry, next,
-					  &priv->lec_arp_tables[i], next) {
-			if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN) &&
-			    (permanent ||
-			     !(entry->flags & LEC_PERMANENT_FLAG))) {
-				lec_arp_remove(priv, entry);
-				lec_arp_put(entry);
-			}
-			spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-			return 0;
-		}
-	}
-	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-	return -1;
-}
-
-/*
- * Notifies:  Response to arp_request (atm_addr != NULL)
- */
-static void
-lec_arp_update(struct lec_priv *priv, const unsigned char *mac_addr,
-	       const unsigned char *atm_addr, unsigned long remoteflag,
-	       unsigned int targetless_le_arp)
-{
-	unsigned long flags;
-	struct hlist_node *next;
-	struct lec_arp_table *entry, *tmp;
-	int i;
-
-	pr_debug("%smac:%pM\n",
-		 (targetless_le_arp) ? "targetless " : "", mac_addr);
-
-	spin_lock_irqsave(&priv->lec_arp_lock, flags);
-	entry = lec_arp_find(priv, mac_addr);
-	if (entry == NULL && targetless_le_arp)
-		goto out;	/*
-				 * LANE2: ignore targetless LE_ARPs for which
-				 * we have no entry in the cache. 7.1.30
-				 */
-	if (!hlist_empty(&priv->lec_arp_empty_ones)) {
-		hlist_for_each_entry_safe(entry, next,
-					  &priv->lec_arp_empty_ones, next) {
-			if (memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN) == 0) {
-				hlist_del(&entry->next);
-				timer_delete(&entry->timer);
-				tmp = lec_arp_find(priv, mac_addr);
-				if (tmp) {
-					timer_delete(&tmp->timer);
-					tmp->status = ESI_FORWARD_DIRECT;
-					memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN);
-					tmp->vcc = entry->vcc;
-					tmp->old_push = entry->old_push;
-					tmp->last_used = jiffies;
-					timer_delete(&entry->timer);
-					lec_arp_put(entry);
-					entry = tmp;
-				} else {
-					entry->status = ESI_FORWARD_DIRECT;
-					ether_addr_copy(entry->mac_addr,
-							mac_addr);
-					entry->last_used = jiffies;
-					lec_arp_add(priv, entry);
-				}
-				if (remoteflag)
-					entry->flags |= LEC_REMOTE_FLAG;
-				else
-					entry->flags &= ~LEC_REMOTE_FLAG;
-				pr_debug("After update\n");
-				dump_arp_table(priv);
-				goto out;
-			}
-		}
-	}
-
-	entry = lec_arp_find(priv, mac_addr);
-	if (!entry) {
-		entry = make_entry(priv, mac_addr);
-		if (!entry)
-			goto out;
-		entry->status = ESI_UNKNOWN;
-		lec_arp_add(priv, entry);
-		/* Temporary, changes before end of function */
-	}
-	memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN);
-	timer_delete(&entry->timer);
-	for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-		hlist_for_each_entry(tmp,
-				     &priv->lec_arp_tables[i], next) {
-			if (entry != tmp &&
-			    !memcmp(tmp->atm_addr, atm_addr, ATM_ESA_LEN)) {
-				/* Vcc to this host exists */
-				if (tmp->status > ESI_VC_PENDING) {
-					/*
-					 * ESI_FLUSH_PENDING,
-					 * ESI_FORWARD_DIRECT
-					 */
-					entry->vcc = tmp->vcc;
-					entry->old_push = tmp->old_push;
-				}
-				entry->status = tmp->status;
-				break;
-			}
-		}
-	}
-	if (remoteflag)
-		entry->flags |= LEC_REMOTE_FLAG;
-	else
-		entry->flags &= ~LEC_REMOTE_FLAG;
-	if (entry->status == ESI_ARP_PENDING || entry->status == ESI_UNKNOWN) {
-		entry->status = ESI_VC_PENDING;
-		send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, NULL);
-	}
-	pr_debug("After update2\n");
-	dump_arp_table(priv);
-out:
-	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-}
-
-/*
- * Notifies: Vcc setup ready
- */
-static void
-lec_vcc_added(struct lec_priv *priv, const struct atmlec_ioc *ioc_data,
-	      struct atm_vcc *vcc,
-	      void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb))
-{
-	unsigned long flags;
-	struct lec_arp_table *entry;
-	int i, found_entry = 0;
-
-	spin_lock_irqsave(&priv->lec_arp_lock, flags);
-	/* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */
-	if (ioc_data->receive == 2) {
-		pr_debug("LEC_ARP: Attaching mcast forward\n");
-#if 0
-		entry = lec_arp_find(priv, bus_mac);
-		if (!entry) {
-			pr_info("LEC_ARP: Multicast entry not found!\n");
-			goto out;
-		}
-		memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
-		entry->recv_vcc = vcc;
-		entry->old_recv_push = old_push;
-#endif
-		entry = make_entry(priv, bus_mac);
-		if (entry == NULL)
-			goto out;
-		timer_delete(&entry->timer);
-		memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
-		entry->recv_vcc = vcc;
-		entry->old_recv_push = old_push;
-		hlist_add_head(&entry->next, &priv->mcast_fwds);
-		goto out;
-	} else if (ioc_data->receive == 1) {
-		/*
-		 * Vcc which we don't want to make default vcc,
-		 * attach it anyway.
-		 */
-		pr_debug("LEC_ARP:Attaching data direct, not default: %*phN\n",
-			 ATM_ESA_LEN, ioc_data->atm_addr);
-		entry = make_entry(priv, bus_mac);
-		if (entry == NULL)
-			goto out;
-		memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
-		eth_zero_addr(entry->mac_addr);
-		entry->recv_vcc = vcc;
-		entry->old_recv_push = old_push;
-		entry->status = ESI_UNKNOWN;
-		entry->timer.expires = jiffies + priv->vcc_timeout_period;
-		entry->timer.function = lec_arp_expire_vcc;
-		hlist_add_head(&entry->next, &priv->lec_no_forward);
-		add_timer(&entry->timer);
-		dump_arp_table(priv);
-		goto out;
-	}
-	pr_debug("LEC_ARP:Attaching data direct, default: %*phN\n",
-		 ATM_ESA_LEN, ioc_data->atm_addr);
-	for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-		hlist_for_each_entry(entry,
-				     &priv->lec_arp_tables[i], next) {
-			if (memcmp
-			    (ioc_data->atm_addr, entry->atm_addr,
-			     ATM_ESA_LEN) == 0) {
-				pr_debug("LEC_ARP: Attaching data direct\n");
-				pr_debug("Currently -> Vcc: %d, Rvcc:%d\n",
-					 entry->vcc ? entry->vcc->vci : 0,
-					 entry->recv_vcc ? entry->recv_vcc->
-					 vci : 0);
-				found_entry = 1;
-				timer_delete(&entry->timer);
-				entry->vcc = vcc;
-				entry->old_push = old_push;
-				if (entry->status == ESI_VC_PENDING) {
-					if (priv->maximum_unknown_frame_count
-					    == 0)
-						entry->status =
-						    ESI_FORWARD_DIRECT;
-					else {
-						entry->timestamp = jiffies;
-						entry->status =
-						    ESI_FLUSH_PENDING;
-#if 0
-						send_to_lecd(priv, l_flush_xmt,
-							     NULL,
-							     entry->atm_addr,
-							     NULL);
-#endif
-					}
-				} else {
-					/*
-					 * They were forming a connection
-					 * to us, and we to them. Our
-					 * ATM address is numerically lower
-					 * than theirs, so we make connection
-					 * we formed into default VCC (8.1.11).
-					 * Connection they made gets torn
-					 * down. This might confuse some
-					 * clients. Can be changed if
-					 * someone reports trouble...
-					 */
-					;
-				}
-			}
-		}
-	}
-	if (found_entry) {
-		pr_debug("After vcc was added\n");
-		dump_arp_table(priv);
-		goto out;
-	}
-	/*
-	 * Not found, snatch address from first data packet that arrives
-	 * from this vcc
-	 */
-	entry = make_entry(priv, bus_mac);
-	if (!entry)
-		goto out;
-	entry->vcc = vcc;
-	entry->old_push = old_push;
-	memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
-	eth_zero_addr(entry->mac_addr);
-	entry->status = ESI_UNKNOWN;
-	hlist_add_head(&entry->next, &priv->lec_arp_empty_ones);
-	entry->timer.expires = jiffies + priv->vcc_timeout_period;
-	entry->timer.function = lec_arp_expire_vcc;
-	add_timer(&entry->timer);
-	pr_debug("After vcc was added\n");
-	dump_arp_table(priv);
-out:
-	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-}
-
-static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id)
-{
-	unsigned long flags;
-	struct lec_arp_table *entry;
-	int i;
-
-	pr_debug("%lx\n", tran_id);
-restart:
-	spin_lock_irqsave(&priv->lec_arp_lock, flags);
-	for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-		hlist_for_each_entry(entry,
-				     &priv->lec_arp_tables[i], next) {
-			if (entry->flush_tran_id == tran_id &&
-			    entry->status == ESI_FLUSH_PENDING) {
-				struct sk_buff *skb;
-				struct atm_vcc *vcc = entry->vcc;
-
-				lec_arp_hold(entry);
-				spin_unlock_irqrestore(&priv->lec_arp_lock,
-						       flags);
-				while ((skb = skb_dequeue(&entry->tx_wait)))
-					lec_send(vcc, skb);
-				entry->last_used = jiffies;
-				entry->status = ESI_FORWARD_DIRECT;
-				lec_arp_put(entry);
-				pr_debug("LEC_ARP: Flushed\n");
-				goto restart;
-			}
-		}
-	}
-	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-	dump_arp_table(priv);
-}
-
-static void
-lec_set_flush_tran_id(struct lec_priv *priv,
-		      const unsigned char *atm_addr, unsigned long tran_id)
-{
-	unsigned long flags;
-	struct lec_arp_table *entry;
-	int i;
-
-	spin_lock_irqsave(&priv->lec_arp_lock, flags);
-	for (i = 0; i < LEC_ARP_TABLE_SIZE; i++)
-		hlist_for_each_entry(entry,
-				     &priv->lec_arp_tables[i], next) {
-			if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) {
-				entry->flush_tran_id = tran_id;
-				pr_debug("Set flush transaction id to %lx for %p\n",
-					 tran_id, entry);
-			}
-		}
-	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-}
-
-static int lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc)
-{
-	unsigned long flags;
-	unsigned char mac_addr[] = {
-		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
-	};
-	struct lec_arp_table *to_add;
-	struct lec_vcc_priv *vpriv;
-	int err = 0;
-
-	vpriv = kmalloc_obj(struct lec_vcc_priv);
-	if (!vpriv)
-		return -ENOMEM;
-	vpriv->xoff = 0;
-	vpriv->old_pop = vcc->pop;
-	vcc->user_back = vpriv;
-	vcc->pop = lec_pop;
-	spin_lock_irqsave(&priv->lec_arp_lock, flags);
-	to_add = make_entry(priv, mac_addr);
-	if (!to_add) {
-		vcc->pop = vpriv->old_pop;
-		kfree(vpriv);
-		err = -ENOMEM;
-		goto out;
-	}
-	memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN);
-	to_add->status = ESI_FORWARD_DIRECT;
-	to_add->flags |= LEC_PERMANENT_FLAG;
-	to_add->vcc = vcc;
-	to_add->old_push = vcc->push;
-	vcc->push = lec_push;
-	priv->mcast_vcc = vcc;
-	lec_arp_add(priv, to_add);
-out:
-	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-	return err;
-}
-
-static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
-{
-	unsigned long flags;
-	struct hlist_node *next;
-	struct lec_arp_table *entry;
-	int i;
-
-	pr_debug("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n", vcc->vpi, vcc->vci);
-	dump_arp_table(priv);
-
-	spin_lock_irqsave(&priv->lec_arp_lock, flags);
-
-	for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-		hlist_for_each_entry_safe(entry, next,
-					  &priv->lec_arp_tables[i], next) {
-			if (vcc == entry->vcc) {
-				lec_arp_remove(priv, entry);
-				lec_arp_put(entry);
-				if (priv->mcast_vcc == vcc)
-					priv->mcast_vcc = NULL;
-			}
-		}
-	}
-
-	hlist_for_each_entry_safe(entry, next,
-				  &priv->lec_arp_empty_ones, next) {
-		if (entry->vcc == vcc) {
-			lec_arp_clear_vccs(entry);
-			timer_delete(&entry->timer);
-			hlist_del(&entry->next);
-			lec_arp_put(entry);
-		}
-	}
-
-	hlist_for_each_entry_safe(entry, next,
-				  &priv->lec_no_forward, next) {
-		if (entry->recv_vcc == vcc) {
-			lec_arp_clear_vccs(entry);
-			timer_delete(&entry->timer);
-			hlist_del(&entry->next);
-			lec_arp_put(entry);
-		}
-	}
-
-	hlist_for_each_entry_safe(entry, next, &priv->mcast_fwds, next) {
-		if (entry->recv_vcc == vcc) {
-			lec_arp_clear_vccs(entry);
-			/* No timer, LANEv2 7.1.20 and 2.3.5.3 */
-			hlist_del(&entry->next);
-			lec_arp_put(entry);
-		}
-	}
-
-	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-	dump_arp_table(priv);
-}
-
-static void
-lec_arp_check_empties(struct lec_priv *priv,
-		      struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	unsigned long flags;
-	struct hlist_node *next;
-	struct lec_arp_table *entry, *tmp;
-	struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data;
-	unsigned char *src = hdr->h_source;
-
-	spin_lock_irqsave(&priv->lec_arp_lock, flags);
-	hlist_for_each_entry_safe(entry, next,
-				  &priv->lec_arp_empty_ones, next) {
-		if (vcc == entry->vcc) {
-			timer_delete(&entry->timer);
-			ether_addr_copy(entry->mac_addr, src);
-			entry->status = ESI_FORWARD_DIRECT;
-			entry->last_used = jiffies;
-			/* We might have got an entry */
-			tmp = lec_arp_find(priv, src);
-			if (tmp) {
-				lec_arp_remove(priv, tmp);
-				lec_arp_put(tmp);
-			}
-			hlist_del(&entry->next);
-			lec_arp_add(priv, entry);
-			goto out;
-		}
-	}
-	pr_debug("LEC_ARP: Arp_check_empties: entry not found!\n");
-out:
-	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-}
-
-MODULE_DESCRIPTION("ATM LAN Emulation (LANE) support");
-MODULE_LICENSE("GPL");
diff --git a/net/atm/mpc.c b/net/atm/mpc.c
deleted file mode 100644
index ce8e9780373b..000000000000
--- a/net/atm/mpc.c
+++ /dev/null
@@ -1,1538 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-#include <linux/capability.h>
-#include <linux/seq_file.h>
-
-/* We are an ethernet device */
-#include <linux/if_ether.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <net/sock.h>
-#include <linux/skbuff.h>
-#include <linux/ip.h>
-#include <linux/uaccess.h>
-#include <asm/byteorder.h>
-#include <net/checksum.h>   /* for ip_fast_csum() */
-#include <net/arp.h>
-#include <net/dst.h>
-#include <linux/proc_fs.h>
-
-/* And atm device */
-#include <linux/atmdev.h>
-#include <linux/atmlec.h>
-#include <linux/atmmpc.h>
-/* Modular too */
-#include <linux/module.h>
-
-#include "lec.h"
-#include "mpc.h"
-#include "resources.h"
-
-/*
- * mpc.c: Implementation of MPOA client kernel part
- */
-
-#if 0
-#define dprintk(format, args...) \
-	printk(KERN_DEBUG "mpoa:%s: " format, __func__, ##args)
-#define dprintk_cont(format, args...) printk(KERN_CONT format, ##args)
-#else
-#define dprintk(format, args...)					\
-	do { if (0)							\
-		printk(KERN_DEBUG "mpoa:%s: " format, __func__, ##args);\
-	} while (0)
-#define dprintk_cont(format, args...)			\
-	do { if (0) printk(KERN_CONT format, ##args); } while (0)
-#endif
-
-#if 0
-#define ddprintk(format, args...) \
-	printk(KERN_DEBUG "mpoa:%s: " format, __func__, ##args)
-#define ddprintk_cont(format, args...) printk(KERN_CONT format, ##args)
-#else
-#define ddprintk(format, args...)					\
-	do { if (0)							\
-		printk(KERN_DEBUG "mpoa:%s: " format, __func__, ##args);\
-	} while (0)
-#define ddprintk_cont(format, args...)			\
-	do { if (0) printk(KERN_CONT format, ##args); } while (0)
-#endif
-
-/* mpc_daemon -> kernel */
-static void MPOA_trigger_rcvd(struct k_message *msg, struct mpoa_client *mpc);
-static void MPOA_res_reply_rcvd(struct k_message *msg, struct mpoa_client *mpc);
-static void ingress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc);
-static void egress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc);
-static void mps_death(struct k_message *msg, struct mpoa_client *mpc);
-static void clean_up(struct k_message *msg, struct mpoa_client *mpc,
-		     int action);
-static void MPOA_cache_impos_rcvd(struct k_message *msg,
-				  struct mpoa_client *mpc);
-static void set_mpc_ctrl_addr_rcvd(struct k_message *mesg,
-				   struct mpoa_client *mpc);
-static void set_mps_mac_addr_rcvd(struct k_message *mesg,
-				  struct mpoa_client *mpc);
-
-static const uint8_t *copy_macs(struct mpoa_client *mpc,
-				const uint8_t *router_mac,
-				const uint8_t *tlvs, uint8_t mps_macs,
-				uint8_t device_type);
-static void purge_egress_shortcut(struct atm_vcc *vcc, eg_cache_entry *entry);
-
-static void send_set_mps_ctrl_addr(const char *addr, struct mpoa_client *mpc);
-static void mpoad_close(struct atm_vcc *vcc);
-static int msg_from_mpoad(struct atm_vcc *vcc, struct sk_buff *skb);
-
-static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb);
-static netdev_tx_t mpc_send_packet(struct sk_buff *skb,
-				   struct net_device *dev);
-static int mpoa_event_listener(struct notifier_block *mpoa_notifier,
-			       unsigned long event, void *dev);
-static void mpc_timer_refresh(void);
-static void mpc_cache_check(struct timer_list *unused);
-
-static struct llc_snap_hdr llc_snap_mpoa_ctrl = {
-	0xaa, 0xaa, 0x03,
-	{0x00, 0x00, 0x5e},
-	{0x00, 0x03}         /* For MPOA control PDUs */
-};
-static struct llc_snap_hdr llc_snap_mpoa_data = {
-	0xaa, 0xaa, 0x03,
-	{0x00, 0x00, 0x00},
-	{0x08, 0x00}         /* This is for IP PDUs only */
-};
-static struct llc_snap_hdr llc_snap_mpoa_data_tagged = {
-	0xaa, 0xaa, 0x03,
-	{0x00, 0x00, 0x00},
-	{0x88, 0x4c}         /* This is for tagged data PDUs */
-};
-
-static struct notifier_block mpoa_notifier = {
-	mpoa_event_listener,
-	NULL,
-	0
-};
-
-struct mpoa_client *mpcs = NULL; /* FIXME */
-static struct atm_mpoa_qos *qos_head = NULL;
-static DEFINE_TIMER(mpc_timer, mpc_cache_check);
-
-
-static struct mpoa_client *find_mpc_by_itfnum(int itf)
-{
-	struct mpoa_client *mpc;
-
-	mpc = mpcs;  /* our global linked list */
-	while (mpc != NULL) {
-		if (mpc->dev_num == itf)
-			return mpc;
-		mpc = mpc->next;
-	}
-
-	return NULL;   /* not found */
-}
-
-static struct mpoa_client *find_mpc_by_vcc(struct atm_vcc *vcc)
-{
-	struct mpoa_client *mpc;
-
-	mpc = mpcs;  /* our global linked list */
-	while (mpc != NULL) {
-		if (mpc->mpoad_vcc == vcc)
-			return mpc;
-		mpc = mpc->next;
-	}
-
-	return NULL;   /* not found */
-}
-
-static struct mpoa_client *find_mpc_by_lec(struct net_device *dev)
-{
-	struct mpoa_client *mpc;
-
-	mpc = mpcs;  /* our global linked list */
-	while (mpc != NULL) {
-		if (mpc->dev == dev)
-			return mpc;
-		mpc = mpc->next;
-	}
-
-	return NULL;   /* not found */
-}
-
-/*
- * Functions for managing QoS list
- */
-
-/*
- * Overwrites the old entry or makes a new one.
- */
-struct atm_mpoa_qos *atm_mpoa_add_qos(__be32 dst_ip, struct atm_qos *qos)
-{
-	struct atm_mpoa_qos *entry;
-
-	entry = atm_mpoa_search_qos(dst_ip);
-	if (entry != NULL) {
-		entry->qos = *qos;
-		return entry;
-	}
-
-	entry = kmalloc_obj(struct atm_mpoa_qos);
-	if (entry == NULL) {
-		pr_info("mpoa: out of memory\n");
-		return entry;
-	}
-
-	entry->ipaddr = dst_ip;
-	entry->qos = *qos;
-
-	entry->next = qos_head;
-	qos_head = entry;
-
-	return entry;
-}
-
-struct atm_mpoa_qos *atm_mpoa_search_qos(__be32 dst_ip)
-{
-	struct atm_mpoa_qos *qos;
-
-	qos = qos_head;
-	while (qos) {
-		if (qos->ipaddr == dst_ip)
-			break;
-		qos = qos->next;
-	}
-
-	return qos;
-}
-
-/*
- * Returns 0 for failure
- */
-int atm_mpoa_delete_qos(struct atm_mpoa_qos *entry)
-{
-	struct atm_mpoa_qos *curr;
-
-	if (entry == NULL)
-		return 0;
-	if (entry == qos_head) {
-		qos_head = qos_head->next;
-		kfree(entry);
-		return 1;
-	}
-
-	curr = qos_head;
-	while (curr != NULL) {
-		if (curr->next == entry) {
-			curr->next = entry->next;
-			kfree(entry);
-			return 1;
-		}
-		curr = curr->next;
-	}
-
-	return 0;
-}
-
-/* this is buggered - we need locking for qos_head */
-void atm_mpoa_disp_qos(struct seq_file *m)
-{
-	struct atm_mpoa_qos *qos;
-
-	qos = qos_head;
-	seq_printf(m, "QoS entries for shortcuts:\n");
-	seq_printf(m, "IP address\n  TX:max_pcr pcr     min_pcr max_cdv max_sdu\n  RX:max_pcr pcr     min_pcr max_cdv max_sdu\n");
-
-	while (qos != NULL) {
-		seq_printf(m, "%pI4\n     %-7d %-7d %-7d %-7d %-7d\n     %-7d %-7d %-7d %-7d %-7d\n",
-			   &qos->ipaddr,
-			   qos->qos.txtp.max_pcr,
-			   qos->qos.txtp.pcr,
-			   qos->qos.txtp.min_pcr,
-			   qos->qos.txtp.max_cdv,
-			   qos->qos.txtp.max_sdu,
-			   qos->qos.rxtp.max_pcr,
-			   qos->qos.rxtp.pcr,
-			   qos->qos.rxtp.min_pcr,
-			   qos->qos.rxtp.max_cdv,
-			   qos->qos.rxtp.max_sdu);
-		qos = qos->next;
-	}
-}
-
-static struct net_device *find_lec_by_itfnum(int itf)
-{
-	struct net_device *dev;
-	char name[IFNAMSIZ];
-
-	sprintf(name, "lec%d", itf);
-	dev = dev_get_by_name(&init_net, name);
-
-	return dev;
-}
-
-static struct mpoa_client *alloc_mpc(void)
-{
-	struct mpoa_client *mpc;
-
-	mpc = kzalloc_obj(struct mpoa_client);
-	if (mpc == NULL)
-		return NULL;
-	rwlock_init(&mpc->ingress_lock);
-	rwlock_init(&mpc->egress_lock);
-	mpc->next = mpcs;
-	atm_mpoa_init_cache(mpc);
-
-	mpc->parameters.mpc_p1 = MPC_P1;
-	mpc->parameters.mpc_p2 = MPC_P2;
-	memset(mpc->parameters.mpc_p3, 0, sizeof(mpc->parameters.mpc_p3));
-	mpc->parameters.mpc_p4 = MPC_P4;
-	mpc->parameters.mpc_p5 = MPC_P5;
-	mpc->parameters.mpc_p6 = MPC_P6;
-
-	mpcs = mpc;
-
-	return mpc;
-}
-
-/*
- *
- * start_mpc() puts the MPC on line. All the packets destined
- * to the lec underneath us are now being monitored and
- * shortcuts will be established.
- *
- */
-static void start_mpc(struct mpoa_client *mpc, struct net_device *dev)
-{
-
-	dprintk("(%s)\n", mpc->dev->name);
-	if (!dev->netdev_ops)
-		pr_info("(%s) not starting\n", dev->name);
-	else {
-		mpc->old_ops = dev->netdev_ops;
-		mpc->new_ops = *mpc->old_ops;
-		mpc->new_ops.ndo_start_xmit = mpc_send_packet;
-		dev->netdev_ops = &mpc->new_ops;
-	}
-}
-
-static void stop_mpc(struct mpoa_client *mpc)
-{
-	struct net_device *dev = mpc->dev;
-	dprintk("(%s)", mpc->dev->name);
-
-	/* Lets not nullify lec device's dev->hard_start_xmit */
-	if (dev->netdev_ops != &mpc->new_ops) {
-		dprintk_cont(" mpc already stopped, not fatal\n");
-		return;
-	}
-	dprintk_cont("\n");
-
-	dev->netdev_ops = mpc->old_ops;
-	mpc->old_ops = NULL;
-
-	/* close_shortcuts(mpc);    ??? FIXME */
-}
-
-static const char *mpoa_device_type_string(char type) __attribute__ ((unused));
-
-static const char *mpoa_device_type_string(char type)
-{
-	switch (type) {
-	case NON_MPOA:
-		return "non-MPOA device";
-	case MPS:
-		return "MPS";
-	case MPC:
-		return "MPC";
-	case MPS_AND_MPC:
-		return "both MPS and MPC";
-	}
-
-	return "unspecified (non-MPOA) device";
-}
-
-/*
- * lec device calls this via its netdev_priv(dev)->lane2_ops
- * ->associate_indicator() when it sees a TLV in LE_ARP packet.
- * We fill in the pointer above when we see a LANE2 lec initializing
- * See LANE2 spec 3.1.5
- *
- * Quite a big and ugly function but when you look at it
- * all it does is to try to locate and parse MPOA Device
- * Type TLV.
- * We give our lec a pointer to this function and when the
- * lec sees a TLV it uses the pointer to call this function.
- *
- */
-static void lane2_assoc_ind(struct net_device *dev, const u8 *mac_addr,
-			    const u8 *tlvs, u32 sizeoftlvs)
-{
-	uint32_t type;
-	uint8_t length, mpoa_device_type, number_of_mps_macs;
-	const uint8_t *end_of_tlvs;
-	struct mpoa_client *mpc;
-
-	mpoa_device_type = number_of_mps_macs = 0; /* silence gcc */
-	dprintk("(%s) received TLV(s), ", dev->name);
-	dprintk("total length of all TLVs %d\n", sizeoftlvs);
-	mpc = find_mpc_by_lec(dev); /* Sampo-Fix: moved here from below */
-	if (mpc == NULL) {
-		pr_info("(%s) no mpc\n", dev->name);
-		return;
-	}
-	end_of_tlvs = tlvs + sizeoftlvs;
-	while (end_of_tlvs - tlvs >= 5) {
-		type = ((tlvs[0] << 24) | (tlvs[1] << 16) |
-			(tlvs[2] << 8) | tlvs[3]);
-		length = tlvs[4];
-		tlvs += 5;
-		dprintk("    type 0x%x length %02x\n", type, length);
-		if (tlvs + length > end_of_tlvs) {
-			pr_info("TLV value extends past its buffer, aborting parse\n");
-			return;
-		}
-
-		if (type == 0) {
-			pr_info("mpoa: (%s) TLV type was 0, returning\n",
-				dev->name);
-			return;
-		}
-
-		if (type != TLV_MPOA_DEVICE_TYPE) {
-			tlvs += length;
-			continue;  /* skip other TLVs */
-		}
-		mpoa_device_type = *tlvs++;
-		number_of_mps_macs = *tlvs++;
-		dprintk("(%s) MPOA device type '%s', ",
-			dev->name, mpoa_device_type_string(mpoa_device_type));
-		if (mpoa_device_type == MPS_AND_MPC &&
-		    length < (42 + number_of_mps_macs*ETH_ALEN)) { /* :) */
-			pr_info("(%s) short MPOA Device Type TLV\n",
-				dev->name);
-			continue;
-		}
-		if ((mpoa_device_type == MPS || mpoa_device_type == MPC) &&
-		    length < 22 + number_of_mps_macs*ETH_ALEN) {
-			pr_info("(%s) short MPOA Device Type TLV\n", dev->name);
-			continue;
-		}
-		if (mpoa_device_type != MPS &&
-		    mpoa_device_type != MPS_AND_MPC) {
-			dprintk("ignoring non-MPS device ");
-			if (mpoa_device_type == MPC)
-				tlvs += 20;
-			continue;  /* we are only interested in MPSs */
-		}
-		if (number_of_mps_macs == 0 &&
-		    mpoa_device_type == MPS_AND_MPC) {
-			pr_info("(%s) MPS_AND_MPC has zero MACs\n", dev->name);
-			continue;  /* someone should read the spec */
-		}
-		dprintk_cont("this MPS has %d MAC addresses\n",
-			     number_of_mps_macs);
-
-		/*
-		 * ok, now we can go and tell our daemon
-		 * the control address of MPS
-		 */
-		send_set_mps_ctrl_addr(tlvs, mpc);
-
-		tlvs = copy_macs(mpc, mac_addr, tlvs,
-				 number_of_mps_macs, mpoa_device_type);
-		if (tlvs == NULL)
-			return;
-	}
-	if (end_of_tlvs - tlvs != 0)
-		pr_info("(%s) ignoring %zd bytes of trailing TLV garbage\n",
-			dev->name, end_of_tlvs - tlvs);
-}
-
-/*
- * Store at least advertizing router's MAC address
- * plus the possible MAC address(es) to mpc->mps_macs.
- * For a freshly allocated MPOA client mpc->mps_macs == 0.
- */
-static const uint8_t *copy_macs(struct mpoa_client *mpc,
-				const uint8_t *router_mac,
-				const uint8_t *tlvs, uint8_t mps_macs,
-				uint8_t device_type)
-{
-	int num_macs;
-	num_macs = (mps_macs > 1) ? mps_macs : 1;
-
-	if (mpc->number_of_mps_macs != num_macs) { /* need to reallocate? */
-		if (mpc->number_of_mps_macs != 0)
-			kfree(mpc->mps_macs);
-		mpc->number_of_mps_macs = 0;
-		mpc->mps_macs = kmalloc_array(ETH_ALEN, num_macs, GFP_KERNEL);
-		if (mpc->mps_macs == NULL) {
-			pr_info("(%s) out of mem\n", mpc->dev->name);
-			return NULL;
-		}
-	}
-	ether_addr_copy(mpc->mps_macs, router_mac);
-	tlvs += 20; if (device_type == MPS_AND_MPC) tlvs += 20;
-	if (mps_macs > 0)
-		memcpy(mpc->mps_macs, tlvs, mps_macs*ETH_ALEN);
-	tlvs += mps_macs*ETH_ALEN;
-	mpc->number_of_mps_macs = num_macs;
-
-	return tlvs;
-}
-
-static int send_via_shortcut(struct sk_buff *skb, struct mpoa_client *mpc)
-{
-	in_cache_entry *entry;
-	struct iphdr *iph;
-	char *buff;
-	__be32 ipaddr = 0;
-
-	static struct {
-		struct llc_snap_hdr hdr;
-		__be32 tag;
-	} tagged_llc_snap_hdr = {
-		{0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}, {0x88, 0x4c}},
-		0
-	};
-
-	buff = skb->data + mpc->dev->hard_header_len;
-	iph = (struct iphdr *)buff;
-	ipaddr = iph->daddr;
-
-	ddprintk("(%s) ipaddr 0x%x\n",
-		 mpc->dev->name, ipaddr);
-
-	entry = mpc->in_ops->get(ipaddr, mpc);
-	if (entry == NULL) {
-		entry = mpc->in_ops->add_entry(ipaddr, mpc);
-		if (entry != NULL)
-			mpc->in_ops->put(entry);
-		return 1;
-	}
-	/* threshold not exceeded or VCC not ready */
-	if (mpc->in_ops->cache_hit(entry, mpc) != OPEN) {
-		ddprintk("(%s) cache_hit: returns != OPEN\n",
-			 mpc->dev->name);
-		mpc->in_ops->put(entry);
-		return 1;
-	}
-
-	ddprintk("(%s) using shortcut\n",
-		 mpc->dev->name);
-	/* MPOA spec A.1.4, MPOA client must decrement IP ttl at least by one */
-	if (iph->ttl <= 1) {
-		ddprintk("(%s) IP ttl = %u, using LANE\n",
-			 mpc->dev->name, iph->ttl);
-		mpc->in_ops->put(entry);
-		return 1;
-	}
-	iph->ttl--;
-	iph->check = 0;
-	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
-
-	if (entry->ctrl_info.tag != 0) {
-		ddprintk("(%s) adding tag 0x%x\n",
-			 mpc->dev->name, entry->ctrl_info.tag);
-		tagged_llc_snap_hdr.tag = entry->ctrl_info.tag;
-		skb_pull(skb, ETH_HLEN);	/* get rid of Eth header */
-		skb_push(skb, sizeof(tagged_llc_snap_hdr));
-						/* add LLC/SNAP header   */
-		skb_copy_to_linear_data(skb, &tagged_llc_snap_hdr,
-					sizeof(tagged_llc_snap_hdr));
-	} else {
-		skb_pull(skb, ETH_HLEN);	/* get rid of Eth header */
-		skb_push(skb, sizeof(struct llc_snap_hdr));
-						/* add LLC/SNAP header + tag  */
-		skb_copy_to_linear_data(skb, &llc_snap_mpoa_data,
-					sizeof(struct llc_snap_hdr));
-	}
-
-	atm_account_tx(entry->shortcut, skb);
-	entry->shortcut->send(entry->shortcut, skb);
-	entry->packets_fwded++;
-	mpc->in_ops->put(entry);
-
-	return 0;
-}
-
-/*
- * Probably needs some error checks and locking, not sure...
- */
-static netdev_tx_t mpc_send_packet(struct sk_buff *skb,
-					 struct net_device *dev)
-{
-	struct mpoa_client *mpc;
-	struct ethhdr *eth;
-	int i = 0;
-
-	mpc = find_mpc_by_lec(dev); /* this should NEVER fail */
-	if (mpc == NULL) {
-		pr_info("(%s) no MPC found\n", dev->name);
-		goto non_ip;
-	}
-
-	eth = (struct ethhdr *)skb->data;
-	if (eth->h_proto != htons(ETH_P_IP))
-		goto non_ip; /* Multi-Protocol Over ATM :-) */
-
-	/* Weed out funny packets (e.g., AF_PACKET or raw). */
-	if (skb->len < ETH_HLEN + sizeof(struct iphdr))
-		goto non_ip;
-	skb_set_network_header(skb, ETH_HLEN);
-	if (skb->len < ETH_HLEN + ip_hdr(skb)->ihl * 4 || ip_hdr(skb)->ihl < 5)
-		goto non_ip;
-
-	while (i < mpc->number_of_mps_macs) {
-		if (ether_addr_equal(eth->h_dest, mpc->mps_macs + i * ETH_ALEN))
-			if (send_via_shortcut(skb, mpc) == 0) /* try shortcut */
-				return NETDEV_TX_OK;
-		i++;
-	}
-
-non_ip:
-	return __netdev_start_xmit(mpc->old_ops, skb, dev, false);
-}
-
-static int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg)
-{
-	int bytes_left;
-	struct mpoa_client *mpc;
-	struct atmmpc_ioc ioc_data;
-	in_cache_entry *in_entry;
-	__be32  ipaddr;
-
-	bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmmpc_ioc));
-	if (bytes_left != 0) {
-		pr_info("mpoa:Short read (missed %d bytes) from userland\n",
-			bytes_left);
-		return -EFAULT;
-	}
-	ipaddr = ioc_data.ipaddr;
-	if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF)
-		return -EINVAL;
-
-	mpc = find_mpc_by_itfnum(ioc_data.dev_num);
-	if (mpc == NULL)
-		return -EINVAL;
-
-	if (ioc_data.type == MPC_SOCKET_INGRESS) {
-		in_entry = mpc->in_ops->get(ipaddr, mpc);
-		if (in_entry == NULL ||
-		    in_entry->entry_state < INGRESS_RESOLVED) {
-			pr_info("(%s) did not find RESOLVED entry from ingress cache\n",
-				mpc->dev->name);
-			if (in_entry != NULL)
-				mpc->in_ops->put(in_entry);
-			return -EINVAL;
-		}
-		pr_info("(%s) attaching ingress SVC, entry = %pI4\n",
-			mpc->dev->name, &in_entry->ctrl_info.in_dst_ip);
-		in_entry->shortcut = vcc;
-		mpc->in_ops->put(in_entry);
-	} else {
-		pr_info("(%s) attaching egress SVC\n", mpc->dev->name);
-	}
-
-	vcc->proto_data = mpc->dev;
-	vcc->push = mpc_push;
-
-	return 0;
-}
-
-/*
- *
- */
-static void mpc_vcc_close(struct atm_vcc *vcc, struct net_device *dev)
-{
-	struct mpoa_client *mpc;
-	in_cache_entry *in_entry;
-	eg_cache_entry *eg_entry;
-
-	mpc = find_mpc_by_lec(dev);
-	if (mpc == NULL) {
-		pr_info("(%s) close for unknown MPC\n", dev->name);
-		return;
-	}
-
-	dprintk("(%s)\n", dev->name);
-	in_entry = mpc->in_ops->get_by_vcc(vcc, mpc);
-	if (in_entry) {
-		dprintk("(%s) ingress SVC closed ip = %pI4\n",
-			mpc->dev->name, &in_entry->ctrl_info.in_dst_ip);
-		in_entry->shortcut = NULL;
-		mpc->in_ops->put(in_entry);
-	}
-	eg_entry = mpc->eg_ops->get_by_vcc(vcc, mpc);
-	if (eg_entry) {
-		dprintk("(%s) egress SVC closed\n", mpc->dev->name);
-		eg_entry->shortcut = NULL;
-		mpc->eg_ops->put(eg_entry);
-	}
-
-	if (in_entry == NULL && eg_entry == NULL)
-		dprintk("(%s) unused vcc closed\n", dev->name);
-}
-
-static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	struct net_device *dev = (struct net_device *)vcc->proto_data;
-	struct sk_buff *new_skb;
-	eg_cache_entry *eg;
-	struct mpoa_client *mpc;
-	__be32 tag;
-	char *tmp;
-
-	ddprintk("(%s)\n", dev->name);
-	if (skb == NULL) {
-		dprintk("(%s) null skb, closing VCC\n", dev->name);
-		mpc_vcc_close(vcc, dev);
-		return;
-	}
-
-	skb->dev = dev;
-	if (memcmp(skb->data, &llc_snap_mpoa_ctrl,
-		   sizeof(struct llc_snap_hdr)) == 0) {
-		struct sock *sk = sk_atm(vcc);
-
-		dprintk("(%s) control packet arrived\n", dev->name);
-		/* Pass control packets to daemon */
-		skb_queue_tail(&sk->sk_receive_queue, skb);
-		sk->sk_data_ready(sk);
-		return;
-	}
-
-	/* data coming over the shortcut */
-	atm_return(vcc, skb->truesize);
-
-	mpc = find_mpc_by_lec(dev);
-	if (mpc == NULL) {
-		pr_info("(%s) unknown MPC\n", dev->name);
-		return;
-	}
-
-	if (memcmp(skb->data, &llc_snap_mpoa_data_tagged,
-		   sizeof(struct llc_snap_hdr)) == 0) { /* MPOA tagged data */
-		ddprintk("(%s) tagged data packet arrived\n", dev->name);
-
-	} else if (memcmp(skb->data, &llc_snap_mpoa_data,
-			  sizeof(struct llc_snap_hdr)) == 0) { /* MPOA data */
-		pr_info("(%s) Unsupported non-tagged data packet arrived.  Purging\n",
-			dev->name);
-		dev_kfree_skb_any(skb);
-		return;
-	} else {
-		pr_info("(%s) garbage arrived, purging\n", dev->name);
-		dev_kfree_skb_any(skb);
-		return;
-	}
-
-	tmp = skb->data + sizeof(struct llc_snap_hdr);
-	tag = *(__be32 *)tmp;
-
-	eg = mpc->eg_ops->get_by_tag(tag, mpc);
-	if (eg == NULL) {
-		pr_info("mpoa: (%s) Didn't find egress cache entry, tag = %u\n",
-			dev->name, tag);
-		purge_egress_shortcut(vcc, NULL);
-		dev_kfree_skb_any(skb);
-		return;
-	}
-
-	/*
-	 * See if ingress MPC is using shortcut we opened as a return channel.
-	 * This means we have a bi-directional vcc opened by us.
-	 */
-	if (eg->shortcut == NULL) {
-		eg->shortcut = vcc;
-		pr_info("(%s) egress SVC in use\n", dev->name);
-	}
-
-	skb_pull(skb, sizeof(struct llc_snap_hdr) + sizeof(tag));
-					/* get rid of LLC/SNAP header */
-	new_skb = skb_realloc_headroom(skb, eg->ctrl_info.DH_length);
-					/* LLC/SNAP is shorter than MAC header :( */
-	dev_kfree_skb_any(skb);
-	if (new_skb == NULL) {
-		mpc->eg_ops->put(eg);
-		return;
-	}
-	skb_push(new_skb, eg->ctrl_info.DH_length);     /* add MAC header */
-	skb_copy_to_linear_data(new_skb, eg->ctrl_info.DLL_header,
-				eg->ctrl_info.DH_length);
-	new_skb->protocol = eth_type_trans(new_skb, dev);
-	skb_reset_network_header(new_skb);
-
-	eg->latest_ip_addr = ip_hdr(new_skb)->saddr;
-	eg->packets_rcvd++;
-	mpc->eg_ops->put(eg);
-
-	memset(ATM_SKB(new_skb), 0, sizeof(struct atm_skb_data));
-	netif_rx(new_skb);
-}
-
-static const struct atmdev_ops mpc_ops = { /* only send is required */
-	.close	= mpoad_close,
-	.send	= msg_from_mpoad
-};
-
-static struct atm_dev mpc_dev = {
-	.ops	= &mpc_ops,
-	.type	= "mpc",
-	.number	= 42,
-	.lock	= __SPIN_LOCK_UNLOCKED(mpc_dev.lock)
-	/* members not explicitly initialised will be 0 */
-};
-
-static int atm_mpoa_mpoad_attach(struct atm_vcc *vcc, int arg)
-{
-	struct mpoa_client *mpc;
-	struct lec_priv *priv;
-	int err;
-
-	if (mpcs == NULL) {
-		mpc_timer_refresh();
-
-		/* This lets us now how our LECs are doing */
-		err = register_netdevice_notifier(&mpoa_notifier);
-		if (err < 0) {
-			timer_delete(&mpc_timer);
-			return err;
-		}
-	}
-
-	mpc = find_mpc_by_itfnum(arg);
-	if (mpc == NULL) {
-		dprintk("allocating new mpc for itf %d\n", arg);
-		mpc = alloc_mpc();
-		if (mpc == NULL)
-			return -ENOMEM;
-		mpc->dev_num = arg;
-		mpc->dev = find_lec_by_itfnum(arg);
-					/* NULL if there was no lec */
-	}
-	if (mpc->mpoad_vcc) {
-		pr_info("mpoad is already present for itf %d\n", arg);
-		return -EADDRINUSE;
-	}
-
-	if (mpc->dev) { /* check if the lec is LANE2 capable */
-		priv = netdev_priv(mpc->dev);
-		if (priv->lane_version < 2) {
-			dev_put(mpc->dev);
-			mpc->dev = NULL;
-		} else
-			priv->lane2_ops->associate_indicator = lane2_assoc_ind;
-	}
-
-	mpc->mpoad_vcc = vcc;
-	vcc->dev = &mpc_dev;
-	vcc_insert_socket(sk_atm(vcc));
-	set_bit(ATM_VF_META, &vcc->flags);
-	set_bit(ATM_VF_READY, &vcc->flags);
-
-	if (mpc->dev) {
-		char empty[ATM_ESA_LEN];
-		memset(empty, 0, ATM_ESA_LEN);
-
-		start_mpc(mpc, mpc->dev);
-		/* set address if mpcd e.g. gets killed and restarted.
-		 * If we do not do it now we have to wait for the next LE_ARP
-		 */
-		if (memcmp(mpc->mps_ctrl_addr, empty, ATM_ESA_LEN) != 0)
-			send_set_mps_ctrl_addr(mpc->mps_ctrl_addr, mpc);
-	}
-
-	__module_get(THIS_MODULE);
-	return arg;
-}
-
-static void send_set_mps_ctrl_addr(const char *addr, struct mpoa_client *mpc)
-{
-	struct k_message mesg;
-
-	memcpy(mpc->mps_ctrl_addr, addr, ATM_ESA_LEN);
-
-	mesg.type = SET_MPS_CTRL_ADDR;
-	memcpy(mesg.MPS_ctrl, addr, ATM_ESA_LEN);
-	msg_to_mpoad(&mesg, mpc);
-}
-
-static void mpoad_close(struct atm_vcc *vcc)
-{
-	struct mpoa_client *mpc;
-	struct sk_buff *skb;
-
-	mpc = find_mpc_by_vcc(vcc);
-	if (mpc == NULL) {
-		pr_info("did not find MPC\n");
-		return;
-	}
-	if (!mpc->mpoad_vcc) {
-		pr_info("close for non-present mpoad\n");
-		return;
-	}
-
-	mpc->mpoad_vcc = NULL;
-	if (mpc->dev) {
-		struct lec_priv *priv = netdev_priv(mpc->dev);
-		priv->lane2_ops->associate_indicator = NULL;
-		stop_mpc(mpc);
-		dev_put(mpc->dev);
-	}
-
-	mpc->in_ops->destroy_cache(mpc);
-	mpc->eg_ops->destroy_cache(mpc);
-
-	while ((skb = skb_dequeue(&sk_atm(vcc)->sk_receive_queue))) {
-		atm_return(vcc, skb->truesize);
-		kfree_skb(skb);
-	}
-
-	pr_info("(%s) going down\n",
-		(mpc->dev) ? mpc->dev->name : "<unknown>");
-	module_put(THIS_MODULE);
-}
-
-/*
- *
- */
-static int msg_from_mpoad(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-
-	struct mpoa_client *mpc = find_mpc_by_vcc(vcc);
-	struct k_message *mesg = (struct k_message *)skb->data;
-	WARN_ON(refcount_sub_and_test(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc));
-
-	if (mpc == NULL) {
-		pr_info("no mpc found\n");
-		return 0;
-	}
-	dprintk("(%s)", mpc->dev ? mpc->dev->name : "<unknown>");
-	switch (mesg->type) {
-	case MPOA_RES_REPLY_RCVD:
-		dprintk_cont("mpoa_res_reply_rcvd\n");
-		MPOA_res_reply_rcvd(mesg, mpc);
-		break;
-	case MPOA_TRIGGER_RCVD:
-		dprintk_cont("mpoa_trigger_rcvd\n");
-		MPOA_trigger_rcvd(mesg, mpc);
-		break;
-	case INGRESS_PURGE_RCVD:
-		dprintk_cont("nhrp_purge_rcvd\n");
-		ingress_purge_rcvd(mesg, mpc);
-		break;
-	case EGRESS_PURGE_RCVD:
-		dprintk_cont("egress_purge_reply_rcvd\n");
-		egress_purge_rcvd(mesg, mpc);
-		break;
-	case MPS_DEATH:
-		dprintk_cont("mps_death\n");
-		mps_death(mesg, mpc);
-		break;
-	case CACHE_IMPOS_RCVD:
-		dprintk_cont("cache_impos_rcvd\n");
-		MPOA_cache_impos_rcvd(mesg, mpc);
-		break;
-	case SET_MPC_CTRL_ADDR:
-		dprintk_cont("set_mpc_ctrl_addr\n");
-		set_mpc_ctrl_addr_rcvd(mesg, mpc);
-		break;
-	case SET_MPS_MAC_ADDR:
-		dprintk_cont("set_mps_mac_addr\n");
-		set_mps_mac_addr_rcvd(mesg, mpc);
-		break;
-	case CLEAN_UP_AND_EXIT:
-		dprintk_cont("clean_up_and_exit\n");
-		clean_up(mesg, mpc, DIE);
-		break;
-	case RELOAD:
-		dprintk_cont("reload\n");
-		clean_up(mesg, mpc, RELOAD);
-		break;
-	case SET_MPC_PARAMS:
-		dprintk_cont("set_mpc_params\n");
-		mpc->parameters = mesg->content.params;
-		break;
-	default:
-		dprintk_cont("unknown message %d\n", mesg->type);
-		break;
-	}
-	kfree_skb(skb);
-
-	return 0;
-}
-
-/* Remember that this function may not do things that sleep */
-int msg_to_mpoad(struct k_message *mesg, struct mpoa_client *mpc)
-{
-	struct sk_buff *skb;
-	struct sock *sk;
-
-	if (mpc == NULL || !mpc->mpoad_vcc) {
-		pr_info("mesg %d to a non-existent mpoad\n", mesg->type);
-		return -ENXIO;
-	}
-
-	skb = alloc_skb(sizeof(struct k_message), GFP_ATOMIC);
-	if (skb == NULL)
-		return -ENOMEM;
-	skb_put(skb, sizeof(struct k_message));
-	skb_copy_to_linear_data(skb, mesg, sizeof(*mesg));
-	atm_force_charge(mpc->mpoad_vcc, skb->truesize);
-
-	sk = sk_atm(mpc->mpoad_vcc);
-	skb_queue_tail(&sk->sk_receive_queue, skb);
-	sk->sk_data_ready(sk);
-
-	return 0;
-}
-
-static int mpoa_event_listener(struct notifier_block *mpoa_notifier,
-			       unsigned long event, void *ptr)
-{
-	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
-	struct mpoa_client *mpc;
-	struct lec_priv *priv;
-
-	if (!net_eq(dev_net(dev), &init_net))
-		return NOTIFY_DONE;
-
-	if (strncmp(dev->name, "lec", 3))
-		return NOTIFY_DONE; /* we are only interested in lec:s */
-
-	switch (event) {
-	case NETDEV_REGISTER:       /* a new lec device was allocated */
-		priv = netdev_priv(dev);
-		if (priv->lane_version < 2)
-			break;
-		priv->lane2_ops->associate_indicator = lane2_assoc_ind;
-		mpc = find_mpc_by_itfnum(priv->itfnum);
-		if (mpc == NULL) {
-			dprintk("allocating new mpc for %s\n", dev->name);
-			mpc = alloc_mpc();
-			if (mpc == NULL) {
-				pr_info("no new mpc");
-				break;
-			}
-		}
-		mpc->dev_num = priv->itfnum;
-		mpc->dev = dev;
-		dev_hold(dev);
-		dprintk("(%s) was initialized\n", dev->name);
-		break;
-	case NETDEV_UNREGISTER:
-		/* the lec device was deallocated */
-		mpc = find_mpc_by_lec(dev);
-		if (mpc == NULL)
-			break;
-		dprintk("device (%s) was deallocated\n", dev->name);
-		stop_mpc(mpc);
-		dev_put(mpc->dev);
-		mpc->dev = NULL;
-		break;
-	case NETDEV_UP:
-		/* the dev was ifconfig'ed up */
-		mpc = find_mpc_by_lec(dev);
-		if (mpc == NULL)
-			break;
-		if (mpc->mpoad_vcc != NULL)
-			start_mpc(mpc, dev);
-		break;
-	case NETDEV_DOWN:
-		/* the dev was ifconfig'ed down */
-		/* this means that the flow of packets from the
-		 * upper layer stops
-		 */
-		mpc = find_mpc_by_lec(dev);
-		if (mpc == NULL)
-			break;
-		if (mpc->mpoad_vcc != NULL)
-			stop_mpc(mpc);
-		break;
-	case NETDEV_REBOOT:
-	case NETDEV_CHANGE:
-	case NETDEV_CHANGEMTU:
-	case NETDEV_CHANGEADDR:
-	case NETDEV_GOING_DOWN:
-		break;
-	default:
-		break;
-	}
-
-	return NOTIFY_DONE;
-}
-
-/*
- * Functions which are called after a message is received from mpcd.
- * Msg is reused on purpose.
- */
-
-
-static void MPOA_trigger_rcvd(struct k_message *msg, struct mpoa_client *mpc)
-{
-	__be32 dst_ip = msg->content.in_info.in_dst_ip;
-	in_cache_entry *entry;
-
-	entry = mpc->in_ops->get(dst_ip, mpc);
-	if (entry == NULL) {
-		entry = mpc->in_ops->add_entry(dst_ip, mpc);
-		entry->entry_state = INGRESS_RESOLVING;
-		msg->type = SND_MPOA_RES_RQST;
-		msg->content.in_info = entry->ctrl_info;
-		msg_to_mpoad(msg, mpc);
-		entry->reply_wait = ktime_get_seconds();
-		mpc->in_ops->put(entry);
-		return;
-	}
-
-	if (entry->entry_state == INGRESS_INVALID) {
-		entry->entry_state = INGRESS_RESOLVING;
-		msg->type = SND_MPOA_RES_RQST;
-		msg->content.in_info = entry->ctrl_info;
-		msg_to_mpoad(msg, mpc);
-		entry->reply_wait = ktime_get_seconds();
-		mpc->in_ops->put(entry);
-		return;
-	}
-
-	pr_info("(%s) entry already in resolving state\n",
-		(mpc->dev) ? mpc->dev->name : "<unknown>");
-	mpc->in_ops->put(entry);
-}
-
-/*
- * Things get complicated because we have to check if there's an egress
- * shortcut with suitable traffic parameters we could use.
- */
-static void check_qos_and_open_shortcut(struct k_message *msg,
-					struct mpoa_client *client,
-					in_cache_entry *entry)
-{
-	__be32 dst_ip = msg->content.in_info.in_dst_ip;
-	struct atm_mpoa_qos *qos = atm_mpoa_search_qos(dst_ip);
-	eg_cache_entry *eg_entry = client->eg_ops->get_by_src_ip(dst_ip, client);
-
-	if (eg_entry && eg_entry->shortcut) {
-		if (eg_entry->shortcut->qos.txtp.traffic_class &
-		    msg->qos.txtp.traffic_class &
-		    (qos ? qos->qos.txtp.traffic_class : ATM_UBR | ATM_CBR)) {
-			if (eg_entry->shortcut->qos.txtp.traffic_class == ATM_UBR)
-				entry->shortcut = eg_entry->shortcut;
-			else if (eg_entry->shortcut->qos.txtp.max_pcr > 0)
-				entry->shortcut = eg_entry->shortcut;
-		}
-		if (entry->shortcut) {
-			dprintk("(%s) using egress SVC to reach %pI4\n",
-				client->dev->name, &dst_ip);
-			client->eg_ops->put(eg_entry);
-			return;
-		}
-	}
-	if (eg_entry != NULL)
-		client->eg_ops->put(eg_entry);
-
-	/* No luck in the egress cache we must open an ingress SVC */
-	msg->type = OPEN_INGRESS_SVC;
-	if (qos &&
-	    (qos->qos.txtp.traffic_class == msg->qos.txtp.traffic_class)) {
-		msg->qos = qos->qos;
-		pr_info("(%s) trying to get a CBR shortcut\n",
-			client->dev->name);
-	} else
-		memset(&msg->qos, 0, sizeof(struct atm_qos));
-	msg_to_mpoad(msg, client);
-}
-
-static void MPOA_res_reply_rcvd(struct k_message *msg, struct mpoa_client *mpc)
-{
-	__be32 dst_ip = msg->content.in_info.in_dst_ip;
-	in_cache_entry *entry = mpc->in_ops->get(dst_ip, mpc);
-
-	dprintk("(%s) ip %pI4\n",
-		mpc->dev->name, &dst_ip);
-	ddprintk("(%s) entry = %p",
-		 mpc->dev->name, entry);
-	if (entry == NULL) {
-		pr_info("(%s) ARGH, received res. reply for an entry that doesn't exist.\n",
-			mpc->dev->name);
-		return;
-	}
-	ddprintk_cont(" entry_state = %d ", entry->entry_state);
-
-	if (entry->entry_state == INGRESS_RESOLVED) {
-		pr_info("(%s) RESOLVED entry!\n", mpc->dev->name);
-		mpc->in_ops->put(entry);
-		return;
-	}
-
-	entry->ctrl_info = msg->content.in_info;
-	entry->time = ktime_get_seconds();
-	/* Used in refreshing func from now on */
-	entry->reply_wait = ktime_get_seconds();
-	entry->refresh_time = 0;
-	ddprintk_cont("entry->shortcut = %p\n", entry->shortcut);
-
-	if (entry->entry_state == INGRESS_RESOLVING &&
-	    entry->shortcut != NULL) {
-		entry->entry_state = INGRESS_RESOLVED;
-		mpc->in_ops->put(entry);
-		return; /* Shortcut already open... */
-	}
-
-	if (entry->shortcut != NULL) {
-		pr_info("(%s) entry->shortcut != NULL, impossible!\n",
-			mpc->dev->name);
-		mpc->in_ops->put(entry);
-		return;
-	}
-
-	check_qos_and_open_shortcut(msg, mpc, entry);
-	entry->entry_state = INGRESS_RESOLVED;
-	mpc->in_ops->put(entry);
-
-	return;
-
-}
-
-static void ingress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc)
-{
-	__be32 dst_ip = msg->content.in_info.in_dst_ip;
-	__be32 mask = msg->ip_mask;
-	in_cache_entry *entry = mpc->in_ops->get_with_mask(dst_ip, mpc, mask);
-
-	if (entry == NULL) {
-		pr_info("(%s) purge for a non-existing entry, ip = %pI4\n",
-			mpc->dev->name, &dst_ip);
-		return;
-	}
-
-	do {
-		dprintk("(%s) removing an ingress entry, ip = %pI4\n",
-			mpc->dev->name, &dst_ip);
-		write_lock_bh(&mpc->ingress_lock);
-		mpc->in_ops->remove_entry(entry, mpc);
-		write_unlock_bh(&mpc->ingress_lock);
-		mpc->in_ops->put(entry);
-		entry = mpc->in_ops->get_with_mask(dst_ip, mpc, mask);
-	} while (entry != NULL);
-}
-
-static void egress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc)
-{
-	__be32 cache_id = msg->content.eg_info.cache_id;
-	eg_cache_entry *entry = mpc->eg_ops->get_by_cache_id(cache_id, mpc);
-
-	if (entry == NULL) {
-		dprintk("(%s) purge for a non-existing entry\n",
-			mpc->dev->name);
-		return;
-	}
-
-	write_lock_irq(&mpc->egress_lock);
-	mpc->eg_ops->remove_entry(entry, mpc);
-	write_unlock_irq(&mpc->egress_lock);
-
-	mpc->eg_ops->put(entry);
-}
-
-static void purge_egress_shortcut(struct atm_vcc *vcc, eg_cache_entry *entry)
-{
-	struct sock *sk;
-	struct k_message *purge_msg;
-	struct sk_buff *skb;
-
-	dprintk("entering\n");
-	if (vcc == NULL) {
-		pr_info("vcc == NULL\n");
-		return;
-	}
-
-	skb = alloc_skb(sizeof(struct k_message), GFP_ATOMIC);
-	if (skb == NULL) {
-		pr_info("out of memory\n");
-		return;
-	}
-
-	skb_put(skb, sizeof(struct k_message));
-	memset(skb->data, 0, sizeof(struct k_message));
-	purge_msg = (struct k_message *)skb->data;
-	purge_msg->type = DATA_PLANE_PURGE;
-	if (entry != NULL)
-		purge_msg->content.eg_info = entry->ctrl_info;
-
-	atm_force_charge(vcc, skb->truesize);
-
-	sk = sk_atm(vcc);
-	skb_queue_tail(&sk->sk_receive_queue, skb);
-	sk->sk_data_ready(sk);
-	dprintk("exiting\n");
-}
-
-/*
- * Our MPS died. Tell our daemon to send NHRP data plane purge to each
- * of the egress shortcuts we have.
- */
-static void mps_death(struct k_message *msg, struct mpoa_client *mpc)
-{
-	eg_cache_entry *entry;
-
-	dprintk("(%s)\n", mpc->dev->name);
-
-	if (memcmp(msg->MPS_ctrl, mpc->mps_ctrl_addr, ATM_ESA_LEN)) {
-		pr_info("(%s) wrong MPS\n", mpc->dev->name);
-		return;
-	}
-
-	/* FIXME: This knows too much of the cache structure */
-	read_lock_irq(&mpc->egress_lock);
-	entry = mpc->eg_cache;
-	while (entry != NULL) {
-		purge_egress_shortcut(entry->shortcut, entry);
-		entry = entry->next;
-	}
-	read_unlock_irq(&mpc->egress_lock);
-
-	mpc->in_ops->destroy_cache(mpc);
-	mpc->eg_ops->destroy_cache(mpc);
-}
-
-static void MPOA_cache_impos_rcvd(struct k_message *msg,
-				  struct mpoa_client *mpc)
-{
-	uint16_t holding_time;
-	eg_cache_entry *entry = mpc->eg_ops->get_by_cache_id(msg->content.eg_info.cache_id, mpc);
-
-	holding_time = msg->content.eg_info.holding_time;
-	dprintk("(%s) entry = %p, holding_time = %u\n",
-		mpc->dev->name, entry, holding_time);
-	if (entry == NULL && !holding_time)
-		return;
-	if (entry == NULL && holding_time) {
-		entry = mpc->eg_ops->add_entry(msg, mpc);
-		mpc->eg_ops->put(entry);
-		return;
-	}
-	if (holding_time) {
-		mpc->eg_ops->update(entry, holding_time);
-		return;
-	}
-
-	write_lock_irq(&mpc->egress_lock);
-	mpc->eg_ops->remove_entry(entry, mpc);
-	write_unlock_irq(&mpc->egress_lock);
-
-	mpc->eg_ops->put(entry);
-}
-
-static void set_mpc_ctrl_addr_rcvd(struct k_message *mesg,
-				   struct mpoa_client *mpc)
-{
-	struct lec_priv *priv;
-	int i, retval ;
-
-	uint8_t tlv[4 + 1 + 1 + 1 + ATM_ESA_LEN];
-
-	tlv[0] = 00; tlv[1] = 0xa0; tlv[2] = 0x3e; tlv[3] = 0x2a; /* type  */
-	tlv[4] = 1 + 1 + ATM_ESA_LEN;  /* length                           */
-	tlv[5] = 0x02;                 /* MPOA client                      */
-	tlv[6] = 0x00;                 /* number of MPS MAC addresses      */
-
-	memcpy(&tlv[7], mesg->MPS_ctrl, ATM_ESA_LEN); /* MPC ctrl ATM addr */
-	memcpy(mpc->our_ctrl_addr, mesg->MPS_ctrl, ATM_ESA_LEN);
-
-	dprintk("(%s) setting MPC ctrl ATM address to",
-		mpc->dev ? mpc->dev->name : "<unknown>");
-	for (i = 7; i < sizeof(tlv); i++)
-		dprintk_cont(" %02x", tlv[i]);
-	dprintk_cont("\n");
-
-	if (mpc->dev) {
-		priv = netdev_priv(mpc->dev);
-		retval = priv->lane2_ops->associate_req(mpc->dev,
-							mpc->dev->dev_addr,
-							tlv, sizeof(tlv));
-		if (retval == 0)
-			pr_info("(%s) MPOA device type TLV association failed\n",
-				mpc->dev->name);
-		retval = priv->lane2_ops->resolve(mpc->dev, NULL, 1, NULL, NULL);
-		if (retval < 0)
-			pr_info("(%s) targetless LE_ARP request failed\n",
-				mpc->dev->name);
-	}
-}
-
-static void set_mps_mac_addr_rcvd(struct k_message *msg,
-				  struct mpoa_client *client)
-{
-
-	if (client->number_of_mps_macs)
-		kfree(client->mps_macs);
-	client->number_of_mps_macs = 0;
-	client->mps_macs = kmemdup(msg->MPS_ctrl, ETH_ALEN, GFP_KERNEL);
-	if (client->mps_macs == NULL) {
-		pr_info("out of memory\n");
-		return;
-	}
-	client->number_of_mps_macs = 1;
-}
-
-/*
- * purge egress cache and tell daemon to 'action' (DIE, RELOAD)
- */
-static void clean_up(struct k_message *msg, struct mpoa_client *mpc, int action)
-{
-
-	eg_cache_entry *entry;
-	msg->type = SND_EGRESS_PURGE;
-
-
-	/* FIXME: This knows too much of the cache structure */
-	read_lock_irq(&mpc->egress_lock);
-	entry = mpc->eg_cache;
-	while (entry != NULL) {
-		msg->content.eg_info = entry->ctrl_info;
-		dprintk("cache_id %u\n", entry->ctrl_info.cache_id);
-		msg_to_mpoad(msg, mpc);
-		entry = entry->next;
-	}
-	read_unlock_irq(&mpc->egress_lock);
-
-	msg->type = action;
-	msg_to_mpoad(msg, mpc);
-}
-
-static unsigned long checking_time;
-
-static void mpc_timer_refresh(void)
-{
-	mpc_timer.expires = jiffies + (MPC_P2 * HZ);
-	checking_time = mpc_timer.expires;
-	add_timer(&mpc_timer);
-}
-
-static void mpc_cache_check(struct timer_list *unused)
-{
-	struct mpoa_client *mpc = mpcs;
-	static unsigned long previous_resolving_check_time;
-	static unsigned long previous_refresh_time;
-
-	while (mpc != NULL) {
-		mpc->in_ops->clear_count(mpc);
-		mpc->eg_ops->clear_expired(mpc);
-		if (checking_time - previous_resolving_check_time >
-		    mpc->parameters.mpc_p4 * HZ) {
-			mpc->in_ops->check_resolving(mpc);
-			previous_resolving_check_time = checking_time;
-		}
-		if (checking_time - previous_refresh_time >
-		    mpc->parameters.mpc_p5 * HZ) {
-			mpc->in_ops->refresh(mpc);
-			previous_refresh_time = checking_time;
-		}
-		mpc = mpc->next;
-	}
-	mpc_timer_refresh();
-}
-
-static int atm_mpoa_ioctl(struct socket *sock, unsigned int cmd,
-			  unsigned long arg)
-{
-	int err = 0;
-	struct atm_vcc *vcc = ATM_SD(sock);
-
-	if (cmd != ATMMPC_CTRL && cmd != ATMMPC_DATA)
-		return -ENOIOCTLCMD;
-
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
-	switch (cmd) {
-	case ATMMPC_CTRL:
-		err = atm_mpoa_mpoad_attach(vcc, (int)arg);
-		if (err >= 0)
-			sock->state = SS_CONNECTED;
-		break;
-	case ATMMPC_DATA:
-		err = atm_mpoa_vcc_attach(vcc, (void __user *)arg);
-		break;
-	default:
-		break;
-	}
-	return err;
-}
-
-static struct atm_ioctl atm_ioctl_ops = {
-	.owner	= THIS_MODULE,
-	.ioctl	= atm_mpoa_ioctl,
-};
-
-static __init int atm_mpoa_init(void)
-{
-	register_atm_ioctl(&atm_ioctl_ops);
-
-	if (mpc_proc_init() != 0)
-		pr_info("failed to initialize /proc/mpoa\n");
-
-	pr_info("mpc.c: initialized\n");
-
-	return 0;
-}
-
-static void __exit atm_mpoa_cleanup(void)
-{
-	struct mpoa_client *mpc, *tmp;
-	struct atm_mpoa_qos *qos, *nextqos;
-	struct lec_priv *priv;
-
-	mpc_proc_clean();
-
-	timer_delete_sync(&mpc_timer);
-	unregister_netdevice_notifier(&mpoa_notifier);
-	deregister_atm_ioctl(&atm_ioctl_ops);
-
-	mpc = mpcs;
-	mpcs = NULL;
-	while (mpc != NULL) {
-		tmp = mpc->next;
-		if (mpc->dev != NULL) {
-			stop_mpc(mpc);
-			priv = netdev_priv(mpc->dev);
-			if (priv->lane2_ops != NULL)
-				priv->lane2_ops->associate_indicator = NULL;
-		}
-		ddprintk("about to clear caches\n");
-		mpc->in_ops->destroy_cache(mpc);
-		mpc->eg_ops->destroy_cache(mpc);
-		ddprintk("caches cleared\n");
-		kfree(mpc->mps_macs);
-		memset(mpc, 0, sizeof(struct mpoa_client));
-		ddprintk("about to kfree %p\n", mpc);
-		kfree(mpc);
-		ddprintk("next mpc is at %p\n", tmp);
-		mpc = tmp;
-	}
-
-	qos = qos_head;
-	qos_head = NULL;
-	while (qos != NULL) {
-		nextqos = qos->next;
-		dprintk("freeing qos entry %p\n", qos);
-		kfree(qos);
-		qos = nextqos;
-	}
-}
-
-module_init(atm_mpoa_init);
-module_exit(atm_mpoa_cleanup);
-
-MODULE_DESCRIPTION("Multi-Protocol Over ATM (MPOA) driver");
-MODULE_LICENSE("GPL");
diff --git a/net/atm/mpoa_caches.c b/net/atm/mpoa_caches.c
deleted file mode 100644
index c8d4e6f2e831..000000000000
--- a/net/atm/mpoa_caches.c
+++ /dev/null
@@ -1,565 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/types.h>
-#include <linux/atmmpc.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-
-#include "mpoa_caches.h"
-#include "mpc.h"
-
-/*
- * mpoa_caches.c: Implementation of ingress and egress cache
- * handling functions
- */
-
-#if 0
-#define dprintk(format, args...)					\
-	printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args)  /* debug */
-#else
-#define dprintk(format, args...)					\
-	do { if (0)							\
-		printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args);\
-	} while (0)
-#endif
-
-#if 0
-#define ddprintk(format, args...)					\
-	printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args)  /* debug */
-#else
-#define ddprintk(format, args...)					\
-	do { if (0)							\
-		printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args);\
-	} while (0)
-#endif
-
-static in_cache_entry *in_cache_get(__be32 dst_ip,
-				    struct mpoa_client *client)
-{
-	in_cache_entry *entry;
-
-	read_lock_bh(&client->ingress_lock);
-	entry = client->in_cache;
-	while (entry != NULL) {
-		if (entry->ctrl_info.in_dst_ip == dst_ip) {
-			refcount_inc(&entry->use);
-			read_unlock_bh(&client->ingress_lock);
-			return entry;
-		}
-		entry = entry->next;
-	}
-	read_unlock_bh(&client->ingress_lock);
-
-	return NULL;
-}
-
-static in_cache_entry *in_cache_get_with_mask(__be32 dst_ip,
-					      struct mpoa_client *client,
-					      __be32 mask)
-{
-	in_cache_entry *entry;
-
-	read_lock_bh(&client->ingress_lock);
-	entry = client->in_cache;
-	while (entry != NULL) {
-		if ((entry->ctrl_info.in_dst_ip & mask) == (dst_ip & mask)) {
-			refcount_inc(&entry->use);
-			read_unlock_bh(&client->ingress_lock);
-			return entry;
-		}
-		entry = entry->next;
-	}
-	read_unlock_bh(&client->ingress_lock);
-
-	return NULL;
-
-}
-
-static in_cache_entry *in_cache_get_by_vcc(struct atm_vcc *vcc,
-					   struct mpoa_client *client)
-{
-	in_cache_entry *entry;
-
-	read_lock_bh(&client->ingress_lock);
-	entry = client->in_cache;
-	while (entry != NULL) {
-		if (entry->shortcut == vcc) {
-			refcount_inc(&entry->use);
-			read_unlock_bh(&client->ingress_lock);
-			return entry;
-		}
-		entry = entry->next;
-	}
-	read_unlock_bh(&client->ingress_lock);
-
-	return NULL;
-}
-
-static in_cache_entry *in_cache_add_entry(__be32 dst_ip,
-					  struct mpoa_client *client)
-{
-	in_cache_entry *entry = kzalloc_obj(in_cache_entry);
-
-	if (entry == NULL) {
-		pr_info("mpoa: mpoa_caches.c: new_in_cache_entry: out of memory\n");
-		return NULL;
-	}
-
-	dprintk("adding an ingress entry, ip = %pI4\n", &dst_ip);
-
-	refcount_set(&entry->use, 1);
-	dprintk("new_in_cache_entry: about to lock\n");
-	write_lock_bh(&client->ingress_lock);
-	entry->next = client->in_cache;
-	entry->prev = NULL;
-	if (client->in_cache != NULL)
-		client->in_cache->prev = entry;
-	client->in_cache = entry;
-
-	memcpy(entry->MPS_ctrl_ATM_addr, client->mps_ctrl_addr, ATM_ESA_LEN);
-	entry->ctrl_info.in_dst_ip = dst_ip;
-	entry->time = ktime_get_seconds();
-	entry->retry_time = client->parameters.mpc_p4;
-	entry->count = 1;
-	entry->entry_state = INGRESS_INVALID;
-	entry->ctrl_info.holding_time = HOLDING_TIME_DEFAULT;
-	refcount_inc(&entry->use);
-
-	write_unlock_bh(&client->ingress_lock);
-	dprintk("new_in_cache_entry: unlocked\n");
-
-	return entry;
-}
-
-static int cache_hit(in_cache_entry *entry, struct mpoa_client *mpc)
-{
-	struct atm_mpoa_qos *qos;
-	struct k_message msg;
-
-	entry->count++;
-	if (entry->entry_state == INGRESS_RESOLVED && entry->shortcut != NULL)
-		return OPEN;
-
-	if (entry->entry_state == INGRESS_REFRESHING) {
-		if (entry->count > mpc->parameters.mpc_p1) {
-			msg.type = SND_MPOA_RES_RQST;
-			msg.content.in_info = entry->ctrl_info;
-			memcpy(msg.MPS_ctrl, mpc->mps_ctrl_addr, ATM_ESA_LEN);
-			qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);
-			if (qos != NULL)
-				msg.qos = qos->qos;
-			msg_to_mpoad(&msg, mpc);
-			entry->reply_wait = ktime_get_seconds();
-			entry->entry_state = INGRESS_RESOLVING;
-		}
-		if (entry->shortcut != NULL)
-			return OPEN;
-		return CLOSED;
-	}
-
-	if (entry->entry_state == INGRESS_RESOLVING && entry->shortcut != NULL)
-		return OPEN;
-
-	if (entry->count > mpc->parameters.mpc_p1 &&
-	    entry->entry_state == INGRESS_INVALID) {
-		dprintk("(%s) threshold exceeded for ip %pI4, sending MPOA res req\n",
-			mpc->dev->name, &entry->ctrl_info.in_dst_ip);
-		entry->entry_state = INGRESS_RESOLVING;
-		msg.type = SND_MPOA_RES_RQST;
-		memcpy(msg.MPS_ctrl, mpc->mps_ctrl_addr, ATM_ESA_LEN);
-		msg.content.in_info = entry->ctrl_info;
-		qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);
-		if (qos != NULL)
-			msg.qos = qos->qos;
-		msg_to_mpoad(&msg, mpc);
-		entry->reply_wait = ktime_get_seconds();
-	}
-
-	return CLOSED;
-}
-
-static void in_cache_put(in_cache_entry *entry)
-{
-	if (refcount_dec_and_test(&entry->use)) {
-		kfree_sensitive(entry);
-	}
-}
-
-/*
- * This should be called with write lock on
- */
-static void in_cache_remove_entry(in_cache_entry *entry,
-				  struct mpoa_client *client)
-{
-	struct atm_vcc *vcc;
-	struct k_message msg;
-
-	vcc = entry->shortcut;
-	dprintk("removing an ingress entry, ip = %pI4\n",
-		&entry->ctrl_info.in_dst_ip);
-
-	if (entry->prev != NULL)
-		entry->prev->next = entry->next;
-	else
-		client->in_cache = entry->next;
-	if (entry->next != NULL)
-		entry->next->prev = entry->prev;
-	client->in_ops->put(entry);
-	if (client->in_cache == NULL && client->eg_cache == NULL) {
-		msg.type = STOP_KEEP_ALIVE_SM;
-		msg_to_mpoad(&msg, client);
-	}
-
-	/* Check if the egress side still uses this VCC */
-	if (vcc != NULL) {
-		eg_cache_entry *eg_entry = client->eg_ops->get_by_vcc(vcc,
-								      client);
-		if (eg_entry != NULL) {
-			client->eg_ops->put(eg_entry);
-			return;
-		}
-		vcc_release_async(vcc, -EPIPE);
-	}
-}
-
-/* Call this every MPC-p2 seconds... Not exactly correct solution,
-   but an easy one... */
-static void clear_count_and_expired(struct mpoa_client *client)
-{
-	in_cache_entry *entry, *next_entry;
-	time64_t now;
-
-	now = ktime_get_seconds();
-
-	write_lock_bh(&client->ingress_lock);
-	entry = client->in_cache;
-	while (entry != NULL) {
-		entry->count = 0;
-		next_entry = entry->next;
-		if ((now - entry->time) > entry->ctrl_info.holding_time) {
-			dprintk("holding time expired, ip = %pI4\n",
-				&entry->ctrl_info.in_dst_ip);
-			client->in_ops->remove_entry(entry, client);
-		}
-		entry = next_entry;
-	}
-	write_unlock_bh(&client->ingress_lock);
-}
-
-/* Call this every MPC-p4 seconds. */
-static void check_resolving_entries(struct mpoa_client *client)
-{
-
-	struct atm_mpoa_qos *qos;
-	in_cache_entry *entry;
-	time64_t now;
-	struct k_message msg;
-
-	now = ktime_get_seconds();
-
-	read_lock_bh(&client->ingress_lock);
-	entry = client->in_cache;
-	while (entry != NULL) {
-		if (entry->entry_state == INGRESS_RESOLVING) {
-
-			if ((now - entry->hold_down)
-					< client->parameters.mpc_p6) {
-				entry = entry->next;	/* Entry in hold down */
-				continue;
-			}
-			if ((now - entry->reply_wait) > entry->retry_time) {
-				entry->retry_time = MPC_C1 * (entry->retry_time);
-				/*
-				 * Retry time maximum exceeded,
-				 * put entry in hold down.
-				 */
-				if (entry->retry_time > client->parameters.mpc_p5) {
-					entry->hold_down = ktime_get_seconds();
-					entry->retry_time = client->parameters.mpc_p4;
-					entry = entry->next;
-					continue;
-				}
-				/* Ask daemon to send a resolution request. */
-				memset(&entry->hold_down, 0, sizeof(time64_t));
-				msg.type = SND_MPOA_RES_RTRY;
-				memcpy(msg.MPS_ctrl, client->mps_ctrl_addr, ATM_ESA_LEN);
-				msg.content.in_info = entry->ctrl_info;
-				qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);
-				if (qos != NULL)
-					msg.qos = qos->qos;
-				msg_to_mpoad(&msg, client);
-				entry->reply_wait = ktime_get_seconds();
-			}
-		}
-		entry = entry->next;
-	}
-	read_unlock_bh(&client->ingress_lock);
-}
-
-/* Call this every MPC-p5 seconds. */
-static void refresh_entries(struct mpoa_client *client)
-{
-	time64_t now;
-	struct in_cache_entry *entry = client->in_cache;
-
-	ddprintk("refresh_entries\n");
-	now = ktime_get_seconds();
-
-	read_lock_bh(&client->ingress_lock);
-	while (entry != NULL) {
-		if (entry->entry_state == INGRESS_RESOLVED) {
-			if (!(entry->refresh_time))
-				entry->refresh_time = (2 * (entry->ctrl_info.holding_time))/3;
-			if ((now - entry->reply_wait) >
-			    entry->refresh_time) {
-				dprintk("refreshing an entry.\n");
-				entry->entry_state = INGRESS_REFRESHING;
-
-			}
-		}
-		entry = entry->next;
-	}
-	read_unlock_bh(&client->ingress_lock);
-}
-
-static void in_destroy_cache(struct mpoa_client *mpc)
-{
-	write_lock_irq(&mpc->ingress_lock);
-	while (mpc->in_cache != NULL)
-		mpc->in_ops->remove_entry(mpc->in_cache, mpc);
-	write_unlock_irq(&mpc->ingress_lock);
-}
-
-static eg_cache_entry *eg_cache_get_by_cache_id(__be32 cache_id,
-						struct mpoa_client *mpc)
-{
-	eg_cache_entry *entry;
-
-	read_lock_irq(&mpc->egress_lock);
-	entry = mpc->eg_cache;
-	while (entry != NULL) {
-		if (entry->ctrl_info.cache_id == cache_id) {
-			refcount_inc(&entry->use);
-			read_unlock_irq(&mpc->egress_lock);
-			return entry;
-		}
-		entry = entry->next;
-	}
-	read_unlock_irq(&mpc->egress_lock);
-
-	return NULL;
-}
-
-/* This can be called from any context since it saves CPU flags */
-static eg_cache_entry *eg_cache_get_by_tag(__be32 tag, struct mpoa_client *mpc)
-{
-	unsigned long flags;
-	eg_cache_entry *entry;
-
-	read_lock_irqsave(&mpc->egress_lock, flags);
-	entry = mpc->eg_cache;
-	while (entry != NULL) {
-		if (entry->ctrl_info.tag == tag) {
-			refcount_inc(&entry->use);
-			read_unlock_irqrestore(&mpc->egress_lock, flags);
-			return entry;
-		}
-		entry = entry->next;
-	}
-	read_unlock_irqrestore(&mpc->egress_lock, flags);
-
-	return NULL;
-}
-
-/* This can be called from any context since it saves CPU flags */
-static eg_cache_entry *eg_cache_get_by_vcc(struct atm_vcc *vcc,
-					   struct mpoa_client *mpc)
-{
-	unsigned long flags;
-	eg_cache_entry *entry;
-
-	read_lock_irqsave(&mpc->egress_lock, flags);
-	entry = mpc->eg_cache;
-	while (entry != NULL) {
-		if (entry->shortcut == vcc) {
-			refcount_inc(&entry->use);
-			read_unlock_irqrestore(&mpc->egress_lock, flags);
-			return entry;
-		}
-		entry = entry->next;
-	}
-	read_unlock_irqrestore(&mpc->egress_lock, flags);
-
-	return NULL;
-}
-
-static eg_cache_entry *eg_cache_get_by_src_ip(__be32 ipaddr,
-					      struct mpoa_client *mpc)
-{
-	eg_cache_entry *entry;
-
-	read_lock_irq(&mpc->egress_lock);
-	entry = mpc->eg_cache;
-	while (entry != NULL) {
-		if (entry->latest_ip_addr == ipaddr) {
-			refcount_inc(&entry->use);
-			read_unlock_irq(&mpc->egress_lock);
-			return entry;
-		}
-		entry = entry->next;
-	}
-	read_unlock_irq(&mpc->egress_lock);
-
-	return NULL;
-}
-
-static void eg_cache_put(eg_cache_entry *entry)
-{
-	if (refcount_dec_and_test(&entry->use)) {
-		kfree_sensitive(entry);
-	}
-}
-
-/*
- * This should be called with write lock on
- */
-static void eg_cache_remove_entry(eg_cache_entry *entry,
-				  struct mpoa_client *client)
-{
-	struct atm_vcc *vcc;
-	struct k_message msg;
-
-	vcc = entry->shortcut;
-	dprintk("removing an egress entry.\n");
-	if (entry->prev != NULL)
-		entry->prev->next = entry->next;
-	else
-		client->eg_cache = entry->next;
-	if (entry->next != NULL)
-		entry->next->prev = entry->prev;
-	client->eg_ops->put(entry);
-	if (client->in_cache == NULL && client->eg_cache == NULL) {
-		msg.type = STOP_KEEP_ALIVE_SM;
-		msg_to_mpoad(&msg, client);
-	}
-
-	/* Check if the ingress side still uses this VCC */
-	if (vcc != NULL) {
-		in_cache_entry *in_entry = client->in_ops->get_by_vcc(vcc, client);
-		if (in_entry != NULL) {
-			client->in_ops->put(in_entry);
-			return;
-		}
-		vcc_release_async(vcc, -EPIPE);
-	}
-}
-
-static eg_cache_entry *eg_cache_add_entry(struct k_message *msg,
-					  struct mpoa_client *client)
-{
-	eg_cache_entry *entry = kzalloc_obj(eg_cache_entry);
-
-	if (entry == NULL) {
-		pr_info("out of memory\n");
-		return NULL;
-	}
-
-	dprintk("adding an egress entry, ip = %pI4, this should be our IP\n",
-		&msg->content.eg_info.eg_dst_ip);
-
-	refcount_set(&entry->use, 1);
-	dprintk("new_eg_cache_entry: about to lock\n");
-	write_lock_irq(&client->egress_lock);
-	entry->next = client->eg_cache;
-	entry->prev = NULL;
-	if (client->eg_cache != NULL)
-		client->eg_cache->prev = entry;
-	client->eg_cache = entry;
-
-	memcpy(entry->MPS_ctrl_ATM_addr, client->mps_ctrl_addr, ATM_ESA_LEN);
-	entry->ctrl_info = msg->content.eg_info;
-	entry->time = ktime_get_seconds();
-	entry->entry_state = EGRESS_RESOLVED;
-	dprintk("new_eg_cache_entry cache_id %u\n",
-		ntohl(entry->ctrl_info.cache_id));
-	dprintk("mps_ip = %pI4\n", &entry->ctrl_info.mps_ip);
-	refcount_inc(&entry->use);
-
-	write_unlock_irq(&client->egress_lock);
-	dprintk("new_eg_cache_entry: unlocked\n");
-
-	return entry;
-}
-
-static void update_eg_cache_entry(eg_cache_entry *entry, uint16_t holding_time)
-{
-	entry->time = ktime_get_seconds();
-	entry->entry_state = EGRESS_RESOLVED;
-	entry->ctrl_info.holding_time = holding_time;
-}
-
-static void clear_expired(struct mpoa_client *client)
-{
-	eg_cache_entry *entry, *next_entry;
-	time64_t now;
-	struct k_message msg;
-
-	now = ktime_get_seconds();
-
-	write_lock_irq(&client->egress_lock);
-	entry = client->eg_cache;
-	while (entry != NULL) {
-		next_entry = entry->next;
-		if ((now - entry->time) > entry->ctrl_info.holding_time) {
-			msg.type = SND_EGRESS_PURGE;
-			msg.content.eg_info = entry->ctrl_info;
-			dprintk("egress_cache: holding time expired, cache_id = %u.\n",
-				ntohl(entry->ctrl_info.cache_id));
-			msg_to_mpoad(&msg, client);
-			client->eg_ops->remove_entry(entry, client);
-		}
-		entry = next_entry;
-	}
-	write_unlock_irq(&client->egress_lock);
-}
-
-static void eg_destroy_cache(struct mpoa_client *mpc)
-{
-	write_lock_irq(&mpc->egress_lock);
-	while (mpc->eg_cache != NULL)
-		mpc->eg_ops->remove_entry(mpc->eg_cache, mpc);
-	write_unlock_irq(&mpc->egress_lock);
-}
-
-
-static const struct in_cache_ops ingress_ops = {
-	.add_entry = in_cache_add_entry,
-	.get = in_cache_get,
-	.get_with_mask = in_cache_get_with_mask,
-	.get_by_vcc = in_cache_get_by_vcc,
-	.put = in_cache_put,
-	.remove_entry = in_cache_remove_entry,
-	.cache_hit = cache_hit,
-	.clear_count = clear_count_and_expired,
-	.check_resolving = check_resolving_entries,
-	.refresh = refresh_entries,
-	.destroy_cache = in_destroy_cache
-};
-
-static const struct eg_cache_ops egress_ops = {
-	.add_entry = eg_cache_add_entry,
-	.get_by_cache_id = eg_cache_get_by_cache_id,
-	.get_by_tag = eg_cache_get_by_tag,
-	.get_by_vcc = eg_cache_get_by_vcc,
-	.get_by_src_ip = eg_cache_get_by_src_ip,
-	.put = eg_cache_put,
-	.remove_entry = eg_cache_remove_entry,
-	.update = update_eg_cache_entry,
-	.clear_expired = clear_expired,
-	.destroy_cache = eg_destroy_cache
-};
-
-void atm_mpoa_init_cache(struct mpoa_client *mpc)
-{
-	mpc->in_ops = &ingress_ops;
-	mpc->eg_ops = &egress_ops;
-}
diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c
deleted file mode 100644
index aaf64b953915..000000000000
--- a/net/atm/mpoa_proc.c
+++ /dev/null
@@ -1,307 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
-
-#ifdef CONFIG_PROC_FS
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/proc_fs.h>
-#include <linux/ktime.h>
-#include <linux/seq_file.h>
-#include <linux/uaccess.h>
-#include <linux/atmmpc.h>
-#include <linux/atm.h>
-#include <linux/gfp.h>
-#include "mpc.h"
-#include "mpoa_caches.h"
-
-/*
- * mpoa_proc.c: Implementation MPOA client's proc
- * file system statistics
- */
-
-#if 1
-#define dprintk(format, args...)					\
-	printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args)  /* debug */
-#else
-#define dprintk(format, args...)					\
-	do { if (0)							\
-		printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args);\
-	} while (0)
-#endif
-
-#if 0
-#define ddprintk(format, args...)					\
-	printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args)  /* debug */
-#else
-#define ddprintk(format, args...)					\
-	do { if (0)							\
-		printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args);\
-	} while (0)
-#endif
-
-#define STAT_FILE_NAME "mpc"     /* Our statistic file's name */
-
-extern struct mpoa_client *mpcs;
-extern struct proc_dir_entry *atm_proc_root;  /* from proc.c. */
-
-static int proc_mpc_open(struct inode *inode, struct file *file);
-static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
-			      size_t nbytes, loff_t *ppos);
-
-static int parse_qos(const char *buff);
-
-static const struct proc_ops mpc_proc_ops = {
-	.proc_open	= proc_mpc_open,
-	.proc_read	= seq_read,
-	.proc_lseek	= seq_lseek,
-	.proc_write	= proc_mpc_write,
-	.proc_release	= seq_release,
-};
-
-/*
- * Returns the state of an ingress cache entry as a string
- */
-static const char *ingress_state_string(int state)
-{
-	switch (state) {
-	case INGRESS_RESOLVING:
-		return "resolving  ";
-	case INGRESS_RESOLVED:
-		return "resolved   ";
-	case INGRESS_INVALID:
-		return "invalid    ";
-	case INGRESS_REFRESHING:
-		return "refreshing ";
-	}
-
-	return "";
-}
-
-/*
- * Returns the state of an egress cache entry as a string
- */
-static const char *egress_state_string(int state)
-{
-	switch (state) {
-	case EGRESS_RESOLVED:
-		return "resolved   ";
-	case EGRESS_PURGE:
-		return "purge      ";
-	case EGRESS_INVALID:
-		return "invalid    ";
-	}
-
-	return "";
-}
-
-/*
- * FIXME: mpcs (and per-mpc lists) have no locking whatsoever.
- */
-
-static void *mpc_start(struct seq_file *m, loff_t *pos)
-{
-	loff_t l = *pos;
-	struct mpoa_client *mpc;
-
-	if (!l--)
-		return SEQ_START_TOKEN;
-	for (mpc = mpcs; mpc; mpc = mpc->next)
-		if (!l--)
-			return mpc;
-	return NULL;
-}
-
-static void *mpc_next(struct seq_file *m, void *v, loff_t *pos)
-{
-	struct mpoa_client *p = v;
-	(*pos)++;
-	return v == SEQ_START_TOKEN ? mpcs : p->next;
-}
-
-static void mpc_stop(struct seq_file *m, void *v)
-{
-}
-
-/*
- * READING function - called when the /proc/atm/mpoa file is read from.
- */
-static int mpc_show(struct seq_file *m, void *v)
-{
-	struct mpoa_client *mpc = v;
-	int i;
-	in_cache_entry *in_entry;
-	eg_cache_entry *eg_entry;
-	time64_t now;
-	unsigned char ip_string[16];
-
-	if (v == SEQ_START_TOKEN) {
-		atm_mpoa_disp_qos(m);
-		return 0;
-	}
-
-	seq_printf(m, "\nInterface %d:\n\n", mpc->dev_num);
-	seq_printf(m, "Ingress Entries:\nIP address      State      Holding time  Packets fwded  VPI  VCI\n");
-	now = ktime_get_seconds();
-
-	for (in_entry = mpc->in_cache; in_entry; in_entry = in_entry->next) {
-		unsigned long seconds_delta = now - in_entry->time;
-
-		sprintf(ip_string, "%pI4", &in_entry->ctrl_info.in_dst_ip);
-		seq_printf(m, "%-16s%s%-14lu%-12u",
-			   ip_string,
-			   ingress_state_string(in_entry->entry_state),
-			   in_entry->ctrl_info.holding_time -
-			   seconds_delta,
-			   in_entry->packets_fwded);
-		if (in_entry->shortcut)
-			seq_printf(m, "   %-3d  %-3d",
-				   in_entry->shortcut->vpi,
-				   in_entry->shortcut->vci);
-		seq_printf(m, "\n");
-	}
-
-	seq_printf(m, "\n");
-	seq_printf(m, "Egress Entries:\nIngress MPC ATM addr\nCache-id        State      Holding time  Packets recvd  Latest IP addr   VPI VCI\n");
-	for (eg_entry = mpc->eg_cache; eg_entry; eg_entry = eg_entry->next) {
-		unsigned char *p = eg_entry->ctrl_info.in_MPC_data_ATM_addr;
-		unsigned long seconds_delta = now - eg_entry->time;
-
-		for (i = 0; i < ATM_ESA_LEN; i++)
-			seq_printf(m, "%02x", p[i]);
-		seq_printf(m, "\n%-16lu%s%-14lu%-15u",
-			   (unsigned long)ntohl(eg_entry->ctrl_info.cache_id),
-			   egress_state_string(eg_entry->entry_state),
-			   (eg_entry->ctrl_info.holding_time - seconds_delta),
-			   eg_entry->packets_rcvd);
-
-		/* latest IP address */
-		sprintf(ip_string, "%pI4", &eg_entry->latest_ip_addr);
-		seq_printf(m, "%-16s", ip_string);
-
-		if (eg_entry->shortcut)
-			seq_printf(m, " %-3d %-3d",
-				   eg_entry->shortcut->vpi,
-				   eg_entry->shortcut->vci);
-		seq_printf(m, "\n");
-	}
-	seq_printf(m, "\n");
-	return 0;
-}
-
-static const struct seq_operations mpc_op = {
-	.start =	mpc_start,
-	.next =		mpc_next,
-	.stop =		mpc_stop,
-	.show =		mpc_show
-};
-
-static int proc_mpc_open(struct inode *inode, struct file *file)
-{
-	return seq_open(file, &mpc_op);
-}
-
-static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
-			      size_t nbytes, loff_t *ppos)
-{
-	char *page, *p;
-	unsigned int len;
-
-	if (nbytes == 0)
-		return 0;
-
-	if (nbytes >= PAGE_SIZE)
-		nbytes = PAGE_SIZE-1;
-
-	page = (char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
-	for (p = page, len = 0; len < nbytes; p++) {
-		if (get_user(*p, buff++)) {
-			free_page((unsigned long)page);
-			return -EFAULT;
-		}
-		len += 1;
-		if (*p == '\0' || *p == '\n')
-			break;
-	}
-
-	*p = '\0';
-
-	if (!parse_qos(page))
-		printk("mpoa: proc_mpc_write: could not parse '%s'\n", page);
-
-	free_page((unsigned long)page);
-
-	return len;
-}
-
-static int parse_qos(const char *buff)
-{
-	/* possible lines look like this
-	 * add 130.230.54.142 tx=max_pcr,max_sdu rx=max_pcr,max_sdu
-	 */
-	unsigned char ip[4];
-	int tx_pcr, tx_sdu, rx_pcr, rx_sdu;
-	__be32 ipaddr;
-	struct atm_qos qos;
-
-	memset(&qos, 0, sizeof(struct atm_qos));
-
-	if (sscanf(buff, "del %hhu.%hhu.%hhu.%hhu",
-			ip, ip+1, ip+2, ip+3) == 4) {
-		ipaddr = *(__be32 *)ip;
-		return atm_mpoa_delete_qos(atm_mpoa_search_qos(ipaddr));
-	}
-
-	if (sscanf(buff, "add %hhu.%hhu.%hhu.%hhu tx=%d,%d rx=tx",
-			ip, ip+1, ip+2, ip+3, &tx_pcr, &tx_sdu) == 6) {
-		rx_pcr = tx_pcr;
-		rx_sdu = tx_sdu;
-	} else if (sscanf(buff, "add %hhu.%hhu.%hhu.%hhu tx=%d,%d rx=%d,%d",
-		ip, ip+1, ip+2, ip+3, &tx_pcr, &tx_sdu, &rx_pcr, &rx_sdu) != 8)
-		return 0;
-
-	ipaddr = *(__be32 *)ip;
-	qos.txtp.traffic_class = ATM_CBR;
-	qos.txtp.max_pcr = tx_pcr;
-	qos.txtp.max_sdu = tx_sdu;
-	qos.rxtp.traffic_class = ATM_CBR;
-	qos.rxtp.max_pcr = rx_pcr;
-	qos.rxtp.max_sdu = rx_sdu;
-	qos.aal = ATM_AAL5;
-	dprintk("parse_qos(): setting qos parameters to tx=%d,%d rx=%d,%d\n",
-		qos.txtp.max_pcr, qos.txtp.max_sdu,
-		qos.rxtp.max_pcr, qos.rxtp.max_sdu);
-
-	atm_mpoa_add_qos(ipaddr, &qos);
-	return 1;
-}
-
-/*
- * INITIALIZATION function - called when module is initialized/loaded.
- */
-int mpc_proc_init(void)
-{
-	struct proc_dir_entry *p;
-
-	p = proc_create(STAT_FILE_NAME, 0, atm_proc_root, &mpc_proc_ops);
-	if (!p) {
-		pr_err("Unable to initialize /proc/atm/%s\n", STAT_FILE_NAME);
-		return -ENOMEM;
-	}
-	return 0;
-}
-
-/*
- * DELETING function - called when module is removed.
- */
-void mpc_proc_clean(void)
-{
-	remove_proc_entry(STAT_FILE_NAME, atm_proc_root);
-}
-
-#endif /* CONFIG_PROC_FS */
diff --git a/net/bridge/br.c b/net/bridge/br.c
index c37e52e2f29a..a5e5b2db110e 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -464,10 +464,6 @@ static int __init br_init(void)
 
 	brioctl_set(br_ioctl_stub);
 
-#if IS_ENABLED(CONFIG_ATM_LANE)
-	br_fdb_test_addr_hook = br_fdb_test_addr;
-#endif
-
 #if IS_MODULE(CONFIG_BRIDGE_NETFILTER)
 	pr_info("bridge: filtering via arp/ip/ip6tables is no longer available "
 		"by default. Update your scripts to load br_netfilter if you "
@@ -506,9 +502,6 @@ static void __exit br_deinit(void)
 	rcu_barrier(); /* Wait for completion of call_rcu()'s */
 
 	br_nf_core_fini();
-#if IS_ENABLED(CONFIG_ATM_LANE)
-	br_fdb_test_addr_hook = NULL;
-#endif
 	br_fdb_fini();
 }
 
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index e2c17f620f00..9bcf6243914b 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -892,35 +892,6 @@ void br_fdb_delete_by_port(struct net_bridge *br,
 	spin_unlock_bh(&br->hash_lock);
 }
 
-#if IS_ENABLED(CONFIG_ATM_LANE)
-/* Interface used by ATM LANE hook to test
- * if an addr is on some other bridge port */
-int br_fdb_test_addr(struct net_device *dev, unsigned char *addr)
-{
-	struct net_bridge_fdb_entry *fdb;
-	struct net_bridge_port *port;
-	int ret;
-
-	rcu_read_lock();
-	port = br_port_get_rcu(dev);
-	if (!port)
-		ret = 0;
-	else {
-		const struct net_bridge_port *dst = NULL;
-
-		fdb = br_fdb_find_rcu(port->br, addr, 0);
-		if (fdb)
-			dst = READ_ONCE(fdb->dst);
-
-		ret = dst && dst->dev != dev &&
-		      dst->state == BR_STATE_FORWARDING;
-	}
-	rcu_read_unlock();
-
-	return ret;
-}
-#endif /* CONFIG_ATM_LANE */
-
 /*
  * Fill buffer with forwarding table records in
  * the API format.
diff --git a/net/core/dev.c b/net/core/dev.c
index e59f6025067c..1be81928d6c7 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5862,13 +5862,6 @@ static __latent_entropy void net_tx_action(void)
 	xfrm_dev_backlog(sd);
 }
 
-#if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_ATM_LANE)
-/* This hook is defined here for ATM LANE */
-int (*br_fdb_test_addr_hook)(struct net_device *dev,
-			     unsigned char *addr) __read_mostly;
-EXPORT_SYMBOL_GPL(br_fdb_test_addr_hook);
-#endif
-
 /**
  *	netdev_is_rx_handler_busy - check if receive handler is registered
  *	@dev: device to check
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index 81199dddcde7..950b48c3b111 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -52,10 +52,6 @@ CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_ATM=y
-CONFIG_ATM_CLIP=y
-CONFIG_ATM_LANE=m
-CONFIG_ATM_MPOA=m
-CONFIG_ATM_BR2684=m
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
 CONFIG_ATALK=m
@@ -108,7 +104,6 @@ CONFIG_ATA=y
 CONFIG_PATA_IXP4XX_CF=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
-CONFIG_ATM_TCP=m
 CONFIG_IXP4XX_ETH=y
 CONFIG_WAN=y
 CONFIG_HDLC=y
diff --git a/arch/mips/configs/gpr_defconfig b/arch/mips/configs/gpr_defconfig
index 261730af75c7..ad80ad2eae6b 100644
--- a/arch/mips/configs/gpr_defconfig
+++ b/arch/mips/configs/gpr_defconfig
@@ -87,10 +87,6 @@ CONFIG_BRIDGE_EBT_LOG=m
 CONFIG_IP_SCTP=m
 CONFIG_TIPC=m
 CONFIG_ATM=y
-CONFIG_ATM_CLIP=y
-CONFIG_ATM_LANE=m
-CONFIG_ATM_MPOA=m
-CONFIG_ATM_BR2684=m
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
 CONFIG_LLC2=m
@@ -156,15 +152,6 @@ CONFIG_SCSI_SAS_LIBSAS=m
 CONFIG_NETDEVICES=y
 CONFIG_NET_FC=y
 CONFIG_NETCONSOLE=m
-CONFIG_ATM_TCP=m
-CONFIG_ATM_LANAI=m
-CONFIG_ATM_ENI=m
-CONFIG_ATM_NICSTAR=m
-CONFIG_ATM_IDT77252=m
-CONFIG_ATM_IA=m
-CONFIG_ATM_FORE200E=m
-CONFIG_ATM_HE=m
-CONFIG_ATM_HE_USE_SUNI=y
 CONFIG_MIPS_AU1X00_ENET=y
 CONFIG_CICADA_PHY=m
 CONFIG_DAVICOM_PHY=m
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig
index 315650c6fe0b..1295164af08e 100644
--- a/arch/mips/configs/mtx1_defconfig
+++ b/arch/mips/configs/mtx1_defconfig
@@ -133,10 +133,6 @@ CONFIG_BRIDGE_EBT_LOG=m
 CONFIG_IP_SCTP=m
 CONFIG_TIPC=m
 CONFIG_ATM=y
-CONFIG_ATM_CLIP=y
-CONFIG_ATM_LANE=m
-CONFIG_ATM_MPOA=m
-CONFIG_ATM_BR2684=m
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
 CONFIG_LLC2=m
@@ -232,15 +228,6 @@ CONFIG_ARCNET_RIM_I=m
 CONFIG_ARCNET_COM20020=m
 CONFIG_ARCNET_COM20020_PCI=m
 CONFIG_ARCNET_COM20020_CS=m
-CONFIG_ATM_TCP=m
-CONFIG_ATM_LANAI=m
-CONFIG_ATM_ENI=m
-CONFIG_ATM_NICSTAR=m
-CONFIG_ATM_IDT77252=m
-CONFIG_ATM_IA=m
-CONFIG_ATM_FORE200E=m
-CONFIG_ATM_HE=m
-CONFIG_ATM_HE_USE_SUNI=y
 CONFIG_PCMCIA_3C574=m
 CONFIG_PCMCIA_3C589=m
 CONFIG_VORTEX=m
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig
index 6f40a275b7a9..02cc17e353a3 100644
--- a/arch/powerpc/configs/ppc6xx_defconfig
+++ b/arch/powerpc/configs/ppc6xx_defconfig
@@ -227,9 +227,6 @@ CONFIG_BRIDGE_EBT_LOG=m
 CONFIG_BRIDGE_EBT_NFLOG=m
 CONFIG_TIPC=m
 CONFIG_ATM=m
-CONFIG_ATM_CLIP=m
-CONFIG_ATM_LANE=m
-CONFIG_ATM_BR2684=m
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
 CONFIG_ATALK=m
@@ -398,12 +395,6 @@ CONFIG_NETCONSOLE=m
 CONFIG_TUN=m
 CONFIG_VETH=m
 CONFIG_VIRTIO_NET=m
-CONFIG_ATM_TCP=m
-CONFIG_ATM_LANAI=m
-CONFIG_ATM_ENI=m
-CONFIG_ATM_NICSTAR=m
-CONFIG_ATM_IDT77252=m
-CONFIG_ATM_HE=m
 CONFIG_EL3=m
 CONFIG_PCMCIA_3C574=m
 CONFIG_PCMCIA_3C589=m
diff --git a/drivers/atm/.gitignore b/drivers/atm/.gitignore
deleted file mode 100644
index ddd374e91965..000000000000
--- a/drivers/atm/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-fore200e_mkfirm
-fore200e_pca_fw.c
-pca200e.bin
-pca200e_ecd.bin2
diff --git a/drivers/atm/nicstarmac.copyright b/drivers/atm/nicstarmac.copyright
deleted file mode 100644
index 180531a83c62..000000000000
--- a/drivers/atm/nicstarmac.copyright
+++ /dev/null
@@ -1,61 +0,0 @@
-/* nicstar.c  v0.22  Jawaid Bazyar (bazyar@hypermall.com)
- * nicstar.c, M. Welsh (matt.welsh@cl.cam.ac.uk)
- *
- * Hacked October, 1997 by Jawaid Bazyar, Interlink Advertising Services Inc.
- * 	http://www.hypermall.com/
- * 10/1/97 - commented out CFG_PHYIE bit - we don't care when the PHY
- *	interrupts us (except possibly for removal/insertion of the cable?)
- * 10/4/97 - began heavy inline documentation of the code. Corrected typos
- *	and spelling mistakes.
- * 10/5/97 - added code to handle PHY interrupts, disable PHY on
- *	loss of link, and correctly re-enable PHY when link is
- *	re-established. (put back CFG_PHYIE)
- *
- *   Modified to work with the IDT7721 nicstar -- AAL5 (tested) only.
- *
- * R. D. Rechenmacher <ron@fnal.gov>, Aug. 6, 1997
- *
- * Linux driver for the IDT77201 NICStAR PCI ATM controller.
- * PHY component is expected to be 155 Mbps S/UNI-Lite or IDT 77155;
- * see init_nicstar() for PHY initialization to change this. This driver
- * expects the Linux ATM stack to support scatter-gather lists 
- * (skb->atm.iovcnt != 0) for Rx skb's passed to vcc->push.
- *
- * Implementing minimal-copy of received data:
- *   IDT always receives data into a small buffer, then large buffers
- *     as needed. This means that data must always be copied to create
- *     the linear buffer needed by most non-ATM protocol stacks (e.g. IP)
- *     Fix is simple: make large buffers large enough to hold entire
- *     SDU, and leave <small_buffer_data> bytes empty at the start. Then
- *     copy small buffer contents to head of large buffer.
- *   Trick is to avoid fragmenting Linux, due to need for a lot of large
- *     buffers. This is done by 2 things:
- *       1) skb->destructor / skb->atm.recycle_buffer
- *            combined, allow nicstar_free_rx_skb to be called to
- *            recycle large data buffers
- *       2) skb_clone of received buffers
- *   See nicstar_free_rx_skb and linearize_buffer for implementation
- *     details.
- *
- *
- *
- * Copyright (c) 1996 University of Cambridge Computer Laboratory
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- * 
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * M. Welsh, 6 July 1996
- *
- *
- */
-- 
2.53.0


^ permalink raw reply related

* [PATCH net-deletions] net: remove ISDN subsystem and Bluetooth CMTP
From: Jakub Kicinski @ 2026-04-21  2:21 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, Jakub Kicinski,
	corbet, skhan, marcel, luiz.dentz, mchehab+huawei, jani.nikula,
	gregkh, demarchi, rdunlap, justonli, ivecera, jonathan.cameron,
	kees, marco.crivellari, ferr.lambarginio, nihaal, mingo, tglx,
	linmq006, linux-doc, linux-bluetooth

Remove the ISDN (mISDN, CAPI) subsystem and Bluetooth CMTP protocol
from the kernel tree.

ISDN is a pretty old technology and it's unclear whether anyone still
uses it. I went over the last few years of git history and all the
commits are either tree-wide conversions or syzbot/static analyzer
fixes.

When we discussed removal in the past IIRC there were some concerns
about ISDN still being used in parts of Germany. Unfortunately, the
code base is quite old, none of the current maintainers are familiar
with it and AI tools will have a field day finding bugs here.

Delete this code and preserve it in an out-of-tree repository
for any remaining users:
https://github.com/linux-netdev/mod-orphan

UAPI constants AF_ISDN/PF_ISDN and the SELinux isdn_socket class
are preserved for ABI stability, but the rest of uAPI is removed.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
CC: corbet@lwn.net
CC: skhan@linuxfoundation.org
CC: marcel@holtmann.org
CC: luiz.dentz@gmail.com
CC: mchehab+huawei@kernel.org
CC: jani.nikula@intel.com
CC: gregkh@linuxfoundation.org
CC: demarchi@kernel.org
CC: rdunlap@infradead.org
CC: justonli@chromium.org
CC: ivecera@redhat.com
CC: jonathan.cameron@huawei.com
CC: kees@kernel.org
CC: marco.crivellari@suse.com
CC: ferr.lambarginio@gmail.com
CC: nihaal@cse.iitm.ac.in
CC: mingo@kernel.org
CC: tglx@kernel.org
CC: linmq006@gmail.com
CC: linux-doc@vger.kernel.org
CC: linux-bluetooth@vger.kernel.org
---
 MAINTAINERS                                 |   19 -
 Documentation/isdn/credits.rst              |   73 -
 Documentation/isdn/index.rst                |   14 -
 Documentation/isdn/interface_capi.rst       |  336 --
 Documentation/isdn/m_isdn.rst               |    9 -
 Documentation/subsystem-apis.rst            |    1 -
 drivers/Kconfig                             |    2 -
 drivers/isdn/Kconfig                        |   27 -
 drivers/isdn/capi/Kconfig                   |   32 -
 drivers/isdn/hardware/mISDN/Kconfig         |   98 -
 drivers/isdn/mISDN/Kconfig                  |   48 -
 net/bluetooth/Kconfig                       |    3 -
 net/bluetooth/cmtp/Kconfig                  |   12 -
 drivers/Makefile                            |    1 -
 drivers/isdn/Makefile                       |    8 -
 drivers/isdn/capi/Makefile                  |    6 -
 drivers/isdn/hardware/Makefile              |    6 -
 drivers/isdn/hardware/mISDN/Makefile        |   19 -
 drivers/isdn/mISDN/Makefile                 |   14 -
 net/bluetooth/Makefile                      |    1 -
 net/bluetooth/cmtp/Makefile                 |    8 -
 drivers/isdn/capi/kcapi.h                   |  182 -
 drivers/isdn/hardware/mISDN/hfc_multi.h     | 1236 -----
 drivers/isdn/hardware/mISDN/hfc_multi_8xx.h |  167 -
 drivers/isdn/hardware/mISDN/hfc_pci.h       |  214 -
 drivers/isdn/hardware/mISDN/hfcsusb.h       |  425 --
 drivers/isdn/hardware/mISDN/iohelper.h      |   96 -
 drivers/isdn/hardware/mISDN/ipac.h          |  393 --
 drivers/isdn/hardware/mISDN/isar.h          |  256 -
 drivers/isdn/hardware/mISDN/isdnhdlc.h      |   69 -
 drivers/isdn/hardware/mISDN/netjet.h        |   44 -
 drivers/isdn/hardware/mISDN/w6692.h         |  177 -
 drivers/isdn/mISDN/core.h                   |   69 -
 drivers/isdn/mISDN/dsp.h                    |  277 -
 drivers/isdn/mISDN/dsp_biquad.h             |   51 -
 drivers/isdn/mISDN/dsp_ecdis.h              |   96 -
 drivers/isdn/mISDN/dsp_hwec.h               |   10 -
 drivers/isdn/mISDN/fsm.h                    |   58 -
 drivers/isdn/mISDN/l1oip.h                  |   92 -
 drivers/isdn/mISDN/layer1.h                 |   16 -
 drivers/isdn/mISDN/layer2.h                 |  131 -
 include/linux/isdn/capilli.h                |   95 -
 include/linux/isdn/capiutil.h               |   60 -
 include/linux/kernelcapi.h                  |   45 -
 include/linux/mISDNdsp.h                    |   40 -
 include/linux/mISDNhw.h                     |  192 -
 include/linux/mISDNif.h                     |  603 --
 include/uapi/linux/capi.h                   |  134 -
 include/uapi/linux/isdn/capicmd.h           |  117 -
 include/uapi/linux/kernelcapi.h             |   48 -
 net/bluetooth/cmtp/cmtp.h                   |  129 -
 drivers/isdn/capi/capi.c                    | 1435 -----
 drivers/isdn/capi/capiutil.c                |  677 ---
 drivers/isdn/capi/kcapi.c                   |  933 ----
 drivers/isdn/capi/kcapi_proc.c              |  231 -
 drivers/isdn/hardware/mISDN/avmfritz.c      | 1164 ----
 drivers/isdn/hardware/mISDN/hfcmulti.c      | 5540 -------------------
 drivers/isdn/hardware/mISDN/hfcpci.c        | 2360 --------
 drivers/isdn/hardware/mISDN/hfcsusb.c       | 2157 --------
 drivers/isdn/hardware/mISDN/isdnhdlc.c      |  617 ---
 drivers/isdn/hardware/mISDN/mISDNinfineon.c | 1168 ----
 drivers/isdn/hardware/mISDN/mISDNipac.c     | 1636 ------
 drivers/isdn/hardware/mISDN/mISDNisar.c     | 1694 ------
 drivers/isdn/hardware/mISDN/netjet.c        | 1154 ----
 drivers/isdn/hardware/mISDN/speedfax.c      |  520 --
 drivers/isdn/hardware/mISDN/w6692.c         | 1417 -----
 drivers/isdn/mISDN/clock.c                  |  197 -
 drivers/isdn/mISDN/core.c                   |  400 --
 drivers/isdn/mISDN/dsp_audio.c              |  421 --
 drivers/isdn/mISDN/dsp_blowfish.c           |  667 ---
 drivers/isdn/mISDN/dsp_cmx.c                | 1949 -------
 drivers/isdn/mISDN/dsp_core.c               | 1227 ----
 drivers/isdn/mISDN/dsp_dtmf.c               |  313 --
 drivers/isdn/mISDN/dsp_hwec.c               |  122 -
 drivers/isdn/mISDN/dsp_pipeline.c           |  300 -
 drivers/isdn/mISDN/dsp_tones.c              |  550 --
 drivers/isdn/mISDN/fsm.c                    |  176 -
 drivers/isdn/mISDN/hwchannel.c              |  516 --
 drivers/isdn/mISDN/l1oip_codec.c            |  358 --
 drivers/isdn/mISDN/l1oip_core.c             | 1505 -----
 drivers/isdn/mISDN/layer1.c                 |  415 --
 drivers/isdn/mISDN/layer2.c                 | 2266 --------
 drivers/isdn/mISDN/socket.c                 |  825 ---
 drivers/isdn/mISDN/stack.c                  |  654 ---
 drivers/isdn/mISDN/tei.c                    | 1416 -----
 drivers/isdn/mISDN/timerdev.c               |  295 -
 net/bluetooth/cmtp/capi.c                   |  579 --
 net/bluetooth/cmtp/core.c                   |  519 --
 net/bluetooth/cmtp/sock.c                   |  271 -
 CREDITS                                     |    5 +
 90 files changed, 5 insertions(+), 44903 deletions(-)
 delete mode 100644 Documentation/isdn/credits.rst
 delete mode 100644 Documentation/isdn/index.rst
 delete mode 100644 Documentation/isdn/interface_capi.rst
 delete mode 100644 Documentation/isdn/m_isdn.rst
 delete mode 100644 drivers/isdn/Kconfig
 delete mode 100644 drivers/isdn/capi/Kconfig
 delete mode 100644 drivers/isdn/hardware/mISDN/Kconfig
 delete mode 100644 drivers/isdn/mISDN/Kconfig
 delete mode 100644 net/bluetooth/cmtp/Kconfig
 delete mode 100644 drivers/isdn/Makefile
 delete mode 100644 drivers/isdn/capi/Makefile
 delete mode 100644 drivers/isdn/hardware/Makefile
 delete mode 100644 drivers/isdn/hardware/mISDN/Makefile
 delete mode 100644 drivers/isdn/mISDN/Makefile
 delete mode 100644 net/bluetooth/cmtp/Makefile
 delete mode 100644 drivers/isdn/capi/kcapi.h
 delete mode 100644 drivers/isdn/hardware/mISDN/hfc_multi.h
 delete mode 100644 drivers/isdn/hardware/mISDN/hfc_multi_8xx.h
 delete mode 100644 drivers/isdn/hardware/mISDN/hfc_pci.h
 delete mode 100644 drivers/isdn/hardware/mISDN/hfcsusb.h
 delete mode 100644 drivers/isdn/hardware/mISDN/iohelper.h
 delete mode 100644 drivers/isdn/hardware/mISDN/ipac.h
 delete mode 100644 drivers/isdn/hardware/mISDN/isar.h
 delete mode 100644 drivers/isdn/hardware/mISDN/isdnhdlc.h
 delete mode 100644 drivers/isdn/hardware/mISDN/netjet.h
 delete mode 100644 drivers/isdn/hardware/mISDN/w6692.h
 delete mode 100644 drivers/isdn/mISDN/core.h
 delete mode 100644 drivers/isdn/mISDN/dsp.h
 delete mode 100644 drivers/isdn/mISDN/dsp_biquad.h
 delete mode 100644 drivers/isdn/mISDN/dsp_ecdis.h
 delete mode 100644 drivers/isdn/mISDN/dsp_hwec.h
 delete mode 100644 drivers/isdn/mISDN/fsm.h
 delete mode 100644 drivers/isdn/mISDN/l1oip.h
 delete mode 100644 drivers/isdn/mISDN/layer1.h
 delete mode 100644 drivers/isdn/mISDN/layer2.h
 delete mode 100644 include/linux/isdn/capilli.h
 delete mode 100644 include/linux/isdn/capiutil.h
 delete mode 100644 include/linux/kernelcapi.h
 delete mode 100644 include/linux/mISDNdsp.h
 delete mode 100644 include/linux/mISDNhw.h
 delete mode 100644 include/linux/mISDNif.h
 delete mode 100644 include/uapi/linux/capi.h
 delete mode 100644 include/uapi/linux/isdn/capicmd.h
 delete mode 100644 include/uapi/linux/kernelcapi.h
 delete mode 100644 net/bluetooth/cmtp/cmtp.h
 delete mode 100644 drivers/isdn/capi/capi.c
 delete mode 100644 drivers/isdn/capi/capiutil.c
 delete mode 100644 drivers/isdn/capi/kcapi.c
 delete mode 100644 drivers/isdn/capi/kcapi_proc.c
 delete mode 100644 drivers/isdn/hardware/mISDN/avmfritz.c
 delete mode 100644 drivers/isdn/hardware/mISDN/hfcmulti.c
 delete mode 100644 drivers/isdn/hardware/mISDN/hfcpci.c
 delete mode 100644 drivers/isdn/hardware/mISDN/hfcsusb.c
 delete mode 100644 drivers/isdn/hardware/mISDN/isdnhdlc.c
 delete mode 100644 drivers/isdn/hardware/mISDN/mISDNinfineon.c
 delete mode 100644 drivers/isdn/hardware/mISDN/mISDNipac.c
 delete mode 100644 drivers/isdn/hardware/mISDN/mISDNisar.c
 delete mode 100644 drivers/isdn/hardware/mISDN/netjet.c
 delete mode 100644 drivers/isdn/hardware/mISDN/speedfax.c
 delete mode 100644 drivers/isdn/hardware/mISDN/w6692.c
 delete mode 100644 drivers/isdn/mISDN/clock.c
 delete mode 100644 drivers/isdn/mISDN/core.c
 delete mode 100644 drivers/isdn/mISDN/dsp_audio.c
 delete mode 100644 drivers/isdn/mISDN/dsp_blowfish.c
 delete mode 100644 drivers/isdn/mISDN/dsp_cmx.c
 delete mode 100644 drivers/isdn/mISDN/dsp_core.c
 delete mode 100644 drivers/isdn/mISDN/dsp_dtmf.c
 delete mode 100644 drivers/isdn/mISDN/dsp_hwec.c
 delete mode 100644 drivers/isdn/mISDN/dsp_pipeline.c
 delete mode 100644 drivers/isdn/mISDN/dsp_tones.c
 delete mode 100644 drivers/isdn/mISDN/fsm.c
 delete mode 100644 drivers/isdn/mISDN/hwchannel.c
 delete mode 100644 drivers/isdn/mISDN/l1oip_codec.c
 delete mode 100644 drivers/isdn/mISDN/l1oip_core.c
 delete mode 100644 drivers/isdn/mISDN/layer1.c
 delete mode 100644 drivers/isdn/mISDN/layer2.c
 delete mode 100644 drivers/isdn/mISDN/socket.c
 delete mode 100644 drivers/isdn/mISDN/stack.c
 delete mode 100644 drivers/isdn/mISDN/tei.c
 delete mode 100644 drivers/isdn/mISDN/timerdev.c
 delete mode 100644 net/bluetooth/cmtp/capi.c
 delete mode 100644 net/bluetooth/cmtp/core.c
 delete mode 100644 net/bluetooth/cmtp/sock.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 6eb1a3ec60f1..cfcf422dd40a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13560,25 +13560,6 @@ S:	Supported
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master
 F:	drivers/infiniband/ulp/isert
 
-ISDN/CMTP OVER BLUETOOTH
-L:	netdev@vger.kernel.org
-S:	Orphan
-W:	http://www.isdn4linux.de
-F:	Documentation/isdn/
-F:	drivers/isdn/capi/
-F:	include/linux/isdn/
-F:	include/uapi/linux/isdn/
-F:	net/bluetooth/cmtp/
-
-ISDN/mISDN SUBSYSTEM
-L:	netdev@vger.kernel.org
-S:	Orphan
-W:	http://www.isdn4linux.de
-F:	drivers/isdn/Kconfig
-F:	drivers/isdn/Makefile
-F:	drivers/isdn/hardware/
-F:	drivers/isdn/mISDN/
-
 ISL28022 HARDWARE MONITORING DRIVER
 M:	Carsten Spieß <mail@carsten-spiess.de>
 L:	linux-hwmon@vger.kernel.org
diff --git a/Documentation/isdn/credits.rst b/Documentation/isdn/credits.rst
deleted file mode 100644
index 319323f2091f..000000000000
--- a/Documentation/isdn/credits.rst
+++ /dev/null
@@ -1,73 +0,0 @@
-=======
-Credits
-=======
-
-
-I want to thank all who contributed to this project and especially to:
-(in alphabetical order)
-
-Thomas Bogendörfer (tsbogend@bigbug.franken.de)
-  Tester, lots of bugfixes and hints.
-
-Alan Cox (alan@lxorguk.ukuu.org.uk)
-  For help getting into standard-kernel.
-
-Henner Eisen (eis@baty.hanse.de)
-  For X.25 implementation.
-
-Volker Götz (volker@oops.franken.de)
-  For contribution of man-pages, the imontty-tool and a perfect
-  maintaining of the mailing-list at hub-wue.
-
-Matthias Hessler (hessler@isdn4linux.de)
-  For creating and maintaining the FAQ.
-
-Bernhard Hailer (Bernhard.Hailer@lrz.uni-muenchen.de)
-  For creating the FAQ, and the leafsite HOWTO.
-
-Michael 'Ghandi' Herold (michael@abadonna.franken.de)
-  For contribution of the vbox answering machine.
-
-Michael Hipp (Michael.Hipp@student.uni-tuebingen.de)
-  For his Sync-PPP-code.
-
-Karsten Keil (keil@isdn4linux.de)
-  For adding 1TR6-support to the Teles-driver.
-  For the HiSax-driver.
-
-Michael Knigge (knick@cove.han.de)
-  For contributing the imon-tool
-
-Andreas Kool (akool@Kool.f.EUnet.de)
-  For contribution of the isdnlog/isdnrep-tool
-
-Pedro Roque Marques (roque@di.fc.ul.pt)
-  For lot of new ideas and the pcbit driver.
-
-Eberhard Mönkeberg (emoenke@gwdg.de)
-  For testing and help to get into kernel.
-
-Thomas Neumann (tn@ruhr.de)
-  For help with Cisco-SLARP and keepalive
-
-Jan den Ouden (denouden@groovin.xs4all.nl)
-  For contribution of the original teles-driver
-
-Carsten Paeth (calle@calle.in-berlin.de)
-  For the AVM-B1-CAPI2.0 driver
-
-Thomas Pfeiffer (pfeiffer@pds.de)
-  For V.110, extended T.70 and Hylafax extensions in isdn_tty.c
-
-Max Riegel (riegel@max.franken.de)
-  For making the ICN hardware-documentation and test-equipment available.
-
-Armin Schindler (mac@melware.de)
-  For the eicon active card driver.
-
-Gerhard 'Fido' Schneider (fido@wuff.mayn.de)
-  For heavy-duty-beta-testing with his BBS ;)
-
-Thomas Uhl (uhl@think.de)
-  For distributing the cards.
-  For pushing me to work ;-)
diff --git a/Documentation/isdn/index.rst b/Documentation/isdn/index.rst
deleted file mode 100644
index d1125a16a746..000000000000
--- a/Documentation/isdn/index.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-====
-ISDN
-====
-
-.. toctree::
-   :maxdepth: 2
-
-   interface_capi
-
-   m_isdn
-
-   credits
diff --git a/Documentation/isdn/interface_capi.rst b/Documentation/isdn/interface_capi.rst
deleted file mode 100644
index 4d63b34b35cf..000000000000
--- a/Documentation/isdn/interface_capi.rst
+++ /dev/null
@@ -1,336 +0,0 @@
-=========================================
-Kernel CAPI Interface to Hardware Drivers
-=========================================
-
-1. Overview
-===========
-
-From the CAPI 2.0 specification:
-COMMON-ISDN-API (CAPI) is an application programming interface standard used
-to access ISDN equipment connected to basic rate interfaces (BRI) and primary
-rate interfaces (PRI).
-
-Kernel CAPI operates as a dispatching layer between CAPI applications and CAPI
-hardware drivers. Hardware drivers register ISDN devices (controllers, in CAPI
-lingo) with Kernel CAPI to indicate their readiness to provide their service
-to CAPI applications. CAPI applications also register with Kernel CAPI,
-requesting association with a CAPI device. Kernel CAPI then dispatches the
-application registration to an available device, forwarding it to the
-corresponding hardware driver. Kernel CAPI then forwards CAPI messages in both
-directions between the application and the hardware driver.
-
-Format and semantics of CAPI messages are specified in the CAPI 2.0 standard.
-This standard is freely available from https://www.capi.org.
-
-
-2. Driver and Device Registration
-=================================
-
-CAPI drivers must register each of the ISDN devices they control with Kernel
-CAPI by calling the Kernel CAPI function attach_capi_ctr() with a pointer to a
-struct capi_ctr before they can be used. This structure must be filled with
-the names of the driver and controller, and a number of callback function
-pointers which are subsequently used by Kernel CAPI for communicating with the
-driver. The registration can be revoked by calling the function
-detach_capi_ctr() with a pointer to the same struct capi_ctr.
-
-Before the device can be actually used, the driver must fill in the device
-information fields 'manu', 'version', 'profile' and 'serial' in the capi_ctr
-structure of the device, and signal its readiness by calling capi_ctr_ready().
-From then on, Kernel CAPI may call the registered callback functions for the
-device.
-
-If the device becomes unusable for any reason (shutdown, disconnect ...), the
-driver has to call capi_ctr_down(). This will prevent further calls to the
-callback functions by Kernel CAPI.
-
-
-3. Application Registration and Communication
-=============================================
-
-Kernel CAPI forwards registration requests from applications (calls to CAPI
-operation CAPI_REGISTER) to an appropriate hardware driver by calling its
-register_appl() callback function. A unique Application ID (ApplID, u16) is
-allocated by Kernel CAPI and passed to register_appl() along with the
-parameter structure provided by the application. This is analogous to the
-open() operation on regular files or character devices.
-
-After a successful return from register_appl(), CAPI messages from the
-application may be passed to the driver for the device via calls to the
-send_message() callback function. Conversely, the driver may call Kernel
-CAPI's capi_ctr_handle_message() function to pass a received CAPI message to
-Kernel CAPI for forwarding to an application, specifying its ApplID.
-
-Deregistration requests (CAPI operation CAPI_RELEASE) from applications are
-forwarded as calls to the release_appl() callback function, passing the same
-ApplID as with register_appl(). After return from release_appl(), no CAPI
-messages for that application may be passed to or from the device anymore.
-
-
-4. Data Structures
-==================
-
-4.1 struct capi_driver
-----------------------
-
-This structure describes a Kernel CAPI driver itself. It is used in the
-register_capi_driver() and unregister_capi_driver() functions, and contains
-the following non-private fields, all to be set by the driver before calling
-register_capi_driver():
-
-``char name[32]``
-	the name of the driver, as a zero-terminated ASCII string
-``char revision[32]``
-	the revision number of the driver, as a zero-terminated ASCII string
-
-4.2 struct capi_ctr
--------------------
-
-This structure describes an ISDN device (controller) handled by a Kernel CAPI
-driver. After registration via the attach_capi_ctr() function it is passed to
-all controller specific lower layer interface and callback functions to
-identify the controller to operate on.
-
-It contains the following non-private fields:
-
-to be set by the driver before calling attach_capi_ctr():
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``struct module *owner``
-	pointer to the driver module owning the device
-
-``void *driverdata``
-	an opaque pointer to driver specific data, not touched by Kernel CAPI
-
-``char name[32]``
-	the name of the controller, as a zero-terminated ASCII string
-
-``char *driver_name``
-	the name of the driver, as a zero-terminated ASCII string
-
-``int (*load_firmware)(struct capi_ctr *ctrlr, capiloaddata *ldata)``
-	(optional) pointer to a callback function for sending firmware and
-	configuration data to the device
-
-	The function may return before the operation has completed.
-
-	Completion must be signalled by a call to capi_ctr_ready().
-
-	Return value: 0 on success, error code on error
-	Called in process context.
-
-``void (*reset_ctr)(struct capi_ctr *ctrlr)``
-	(optional) pointer to a callback function for stopping the device,
-	releasing all registered applications
-
-	The function may return before the operation has completed.
-
-	Completion must be signalled by a call to capi_ctr_down().
-
-	Called in process context.
-
-``void (*register_appl)(struct capi_ctr *ctrlr, u16 applid, capi_register_params *rparam)``
-	pointers to callback function for registration of
-	applications with the device
-
-	Calls to these functions are serialized by Kernel CAPI so that only
-	one call to any of them is active at any time.
-
-``void (*release_appl)(struct capi_ctr *ctrlr, u16 applid)``
-	pointers to callback functions deregistration of
-	applications with the device
-
-	Calls to these functions are serialized by Kernel CAPI so that only
-	one call to any of them is active at any time.
-
-``u16  (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb)``
-	pointer to a callback function for sending a CAPI message to the
-	device
-
-	Return value: CAPI error code
-
-	If the method returns 0 (CAPI_NOERROR) the driver has taken ownership
-	of the skb and the caller may no longer access it. If it returns a
-	non-zero (error) value then ownership of the skb returns to the caller
-	who may reuse or free it.
-
-	The return value should only be used to signal problems with respect
-	to accepting or queueing the message. Errors occurring during the
-	actual processing of the message should be signaled with an
-	appropriate reply message.
-
-	May be called in process or interrupt context.
-
-	Calls to this function are not serialized by Kernel CAPI, ie. it must
-	be prepared to be re-entered.
-
-``char *(*procinfo)(struct capi_ctr *ctrlr)``
-	pointer to a callback function returning the entry for the device in
-	the CAPI controller info table, /proc/capi/controller
-
-Note:
-  Callback functions except send_message() are never called in interrupt
-  context.
-
-to be filled in before calling capi_ctr_ready():
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``u8 manu[CAPI_MANUFACTURER_LEN]``
-	value to return for CAPI_GET_MANUFACTURER
-
-``capi_version version``
-	value to return for CAPI_GET_VERSION
-
-``capi_profile profile``
-	value to return for CAPI_GET_PROFILE
-
-``u8 serial[CAPI_SERIAL_LEN]``
-	value to return for CAPI_GET_SERIAL
-
-
-4.3 SKBs
---------
-
-CAPI messages are passed between Kernel CAPI and the driver via send_message()
-and capi_ctr_handle_message(), stored in the data portion of a socket buffer
-(skb).  Each skb contains a single CAPI message coded according to the CAPI 2.0
-standard.
-
-For the data transfer messages, DATA_B3_REQ and DATA_B3_IND, the actual
-payload data immediately follows the CAPI message itself within the same skb.
-The Data and Data64 parameters are not used for processing. The Data64
-parameter may be omitted by setting the length field of the CAPI message to 22
-instead of 30.
-
-
-4.4 The _cmsg Structure
------------------------
-
-(declared in <linux/isdn/capiutil.h>)
-
-The _cmsg structure stores the contents of a CAPI 2.0 message in an easily
-accessible form. It contains members for all possible CAPI 2.0 parameters,
-including subparameters of the Additional Info and B Protocol structured
-parameters, with the following exceptions:
-
-* second Calling party number (CONNECT_IND)
-
-* Data64 (DATA_B3_REQ and DATA_B3_IND)
-
-* Sending complete (subparameter of Additional Info, CONNECT_REQ and INFO_REQ)
-
-* Global Configuration (subparameter of B Protocol, CONNECT_REQ, CONNECT_RESP
-  and SELECT_B_PROTOCOL_REQ)
-
-Only those parameters appearing in the message type currently being processed
-are actually used. Unused members should be set to zero.
-
-Members are named after the CAPI 2.0 standard names of the parameters they
-represent. See <linux/isdn/capiutil.h> for the exact spelling. Member data
-types are:
-
-=========== =================================================================
-u8          for CAPI parameters of type 'byte'
-
-u16         for CAPI parameters of type 'word'
-
-u32         for CAPI parameters of type 'dword'
-
-_cstruct    for CAPI parameters of type 'struct'
-	    The member is a pointer to a buffer containing the parameter in
-	    CAPI encoding (length + content). It may also be NULL, which will
-	    be taken to represent an empty (zero length) parameter.
-	    Subparameters are stored in encoded form within the content part.
-
-_cmstruct   alternative representation for CAPI parameters of type 'struct'
-	    (used only for the 'Additional Info' and 'B Protocol' parameters)
-	    The representation is a single byte containing one of the values:
-	    CAPI_DEFAULT: The parameter is empty/absent.
-	    CAPI_COMPOSE: The parameter is present.
-	    Subparameter values are stored individually in the corresponding
-	    _cmsg structure members.
-=========== =================================================================
-
-
-5. Lower Layer Interface Functions
-==================================
-
-::
-
-  int attach_capi_ctr(struct capi_ctr *ctrlr)
-  int detach_capi_ctr(struct capi_ctr *ctrlr)
-
-register/unregister a device (controller) with Kernel CAPI
-
-::
-
-  void capi_ctr_ready(struct capi_ctr *ctrlr)
-  void capi_ctr_down(struct capi_ctr *ctrlr)
-
-signal controller ready/not ready
-
-::
-
-  void capi_ctr_handle_message(struct capi_ctr * ctrlr, u16 applid,
-			       struct sk_buff *skb)
-
-pass a received CAPI message to Kernel CAPI
-for forwarding to the specified application
-
-
-6. Helper Functions and Macros
-==============================
-
-Macros to extract/set element values from/in a CAPI message header
-(from <linux/isdn/capiutil.h>):
-
-======================  =============================   ====================
-Get Macro		Set Macro			Element (Type)
-======================  =============================   ====================
-CAPIMSG_LEN(m)		CAPIMSG_SETLEN(m, len)		Total Length (u16)
-CAPIMSG_APPID(m)	CAPIMSG_SETAPPID(m, applid)	ApplID (u16)
-CAPIMSG_COMMAND(m)	CAPIMSG_SETCOMMAND(m,cmd)	Command (u8)
-CAPIMSG_SUBCOMMAND(m)	CAPIMSG_SETSUBCOMMAND(m, cmd)	Subcommand (u8)
-CAPIMSG_CMD(m)		-				Command*256
-							+ Subcommand (u16)
-CAPIMSG_MSGID(m)	CAPIMSG_SETMSGID(m, msgid)	Message Number (u16)
-
-CAPIMSG_CONTROL(m)	CAPIMSG_SETCONTROL(m, contr)	Controller/PLCI/NCCI
-							(u32)
-CAPIMSG_DATALEN(m)	CAPIMSG_SETDATALEN(m, len)	Data Length (u16)
-======================  =============================   ====================
-
-
-Library functions for working with _cmsg structures
-(from <linux/isdn/capiutil.h>):
-
-``char *capi_cmd2str(u8 Command, u8 Subcommand)``
-	Returns the CAPI 2.0 message name corresponding to the given command
-	and subcommand values, as a static ASCII string. The return value may
-	be NULL if the command/subcommand is not one of those defined in the
-	CAPI 2.0 standard.
-
-
-7. Debugging
-============
-
-The module kernelcapi has a module parameter showcapimsgs controlling some
-debugging output produced by the module. It can only be set when the module is
-loaded, via a parameter "showcapimsgs=<n>" to the modprobe command, either on
-the command line or in the configuration file.
-
-If the lowest bit of showcapimsgs is set, kernelcapi logs controller and
-application up and down events.
-
-In addition, every registered CAPI controller has an associated traceflag
-parameter controlling how CAPI messages sent from and to the controller are
-logged. The traceflag parameter is initialized with the value of the
-showcapimsgs parameter when the controller is registered, but can later be
-changed via the MANUFACTURER_REQ command KCAPI_CMD_TRACE.
-
-If the value of traceflag is non-zero, CAPI messages are logged.
-DATA_B3 messages are only logged if the value of traceflag is > 2.
-
-If the lowest bit of traceflag is set, only the command/subcommand and message
-length are logged. Otherwise, kernelcapi logs a readable representation of
-the entire message.
diff --git a/Documentation/isdn/m_isdn.rst b/Documentation/isdn/m_isdn.rst
deleted file mode 100644
index 5847a164287e..000000000000
--- a/Documentation/isdn/m_isdn.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-============
-mISDN Driver
-============
-
-mISDN is a new modular ISDN driver, in the long term it should replace
-the old I4L driver architecture for passive ISDN cards.
-It was designed to allow a broad range of applications and interfaces
-but only have the basic function in kernel, the interface to the user
-space is based on sockets with a own address family AF_ISDN.
diff --git a/Documentation/subsystem-apis.rst b/Documentation/subsystem-apis.rst
index ff4fe8c936c8..b1ad48bb4001 100644
--- a/Documentation/subsystem-apis.rst
+++ b/Documentation/subsystem-apis.rst
@@ -46,7 +46,6 @@ Networking interfaces
    networking/index
    netlabel/index
    infiniband/index
-   isdn/index
    mhi/index
 
 Storage interfaces
diff --git a/drivers/Kconfig b/drivers/Kconfig
index c0f1fb893ec0..f2bed2ddeb66 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -61,8 +61,6 @@ source "drivers/macintosh/Kconfig"
 
 source "drivers/net/Kconfig"
 
-source "drivers/isdn/Kconfig"
-
 # input before char - char/joystick depends on it. As does USB.
 
 source "drivers/input/Kconfig"
diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig
deleted file mode 100644
index 6fd1b3f84a29..000000000000
--- a/drivers/isdn/Kconfig
+++ /dev/null
@@ -1,27 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# ISDN device configuration
-#
-
-menuconfig ISDN
-	bool "ISDN support"
-	depends on NET && NETDEVICES
-	help
-	  ISDN ("Integrated Services Digital Network", called RNIS in France)
-	  is a fully digital telephone service that can be used for voice and
-	  data connections.  If your computer is equipped with an ISDN
-	  adapter you can use it to connect to your Internet service provider
-	  (with SLIP or PPP) faster than via a conventional telephone modem
-	  (though still much slower than with DSL) or to make and accept
-	  voice calls (eg. turning your PC into a software answering machine
-	  or PABX).
-
-	  Select this option if you want your kernel to support ISDN.
-
-if ISDN
-
-source "drivers/isdn/capi/Kconfig"
-
-source "drivers/isdn/mISDN/Kconfig"
-
-endif # ISDN
diff --git a/drivers/isdn/capi/Kconfig b/drivers/isdn/capi/Kconfig
deleted file mode 100644
index fdb43a632215..000000000000
--- a/drivers/isdn/capi/Kconfig
+++ /dev/null
@@ -1,32 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-config ISDN_CAPI
-	def_bool ISDN && BT
-	help
-	  This provides CAPI (the Common ISDN Application Programming
-	  Interface) Version 2.0, a standard making it easy for programs to
-	  access ISDN hardware in a device independent way. (For details see
-	  <https://www.capi.org/>.)  CAPI supports making and accepting voice
-	  and data connections, controlling call options and protocols,
-	  as well as ISDN supplementary services like call forwarding or
-	  three-party conferences (if supported by the specific hardware
-	  driver).
-
-	  This subsystem requires a hardware specific driver.
-	  See CONFIG_BT_CMTP for the last remaining regular driver
-	  in the kernel that uses the CAPI subsystem.
-
-config CAPI_TRACE
-	def_bool BT_CMTP
-	help
-	  If you say Y here, the kernelcapi driver can make verbose traces
-	  of CAPI messages. This feature can be enabled/disabled via IOCTL for
-	  every controller (default disabled).
-
-config ISDN_CAPI_MIDDLEWARE
-	def_bool BT_CMTP && TTY
-	help
-	  This option will enhance the capabilities of the /dev/capi20
-	  interface.  It will provide a means of moving a data connection,
-	  established via the usual /dev/capi20 interface to a special tty
-	  device.  If you want to use pppd with pppdcapiplugin to dial up to
-	  your ISP, say Y here.
diff --git a/drivers/isdn/hardware/mISDN/Kconfig b/drivers/isdn/hardware/mISDN/Kconfig
deleted file mode 100644
index a35bff8a93f5..000000000000
--- a/drivers/isdn/hardware/mISDN/Kconfig
+++ /dev/null
@@ -1,98 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Hardware for mISDN
-#
-comment "mISDN hardware drivers"
-
-config MISDN_HFCPCI
-	tristate "Support for HFC PCI cards"
-	depends on MISDN
-	depends on PCI
-	help
-	  Enable support for cards with Cologne Chip AG's
-	  HFC PCI chip.
-
-config MISDN_HFCMULTI
-	tristate "Support for HFC multiport cards (HFC-4S/8S/E1)"
-	depends on (PCI || CPM1) && HAS_IOPORT
-	depends on MISDN
-	help
-	  Enable support for cards with Cologne Chip AG's HFC multiport
-	  chip. There are three types of chips that are quite similar,
-	  but the interface is different:
-	   * HFC-4S (4 S/T interfaces on one chip)
-	   * HFC-8S (8 S/T interfaces on one chip)
-	   * HFC-E1 (E1 interface for 2Mbit ISDN)
-
-config MISDN_HFCMULTI_8xx
-	bool "Support for XHFC embedded board in HFC multiport driver"
-	depends on MISDN
-	depends on MISDN_HFCMULTI
-	depends on CPM1
-	default CPM1
-	help
-	  Enable support for the XHFC embedded solution from Speech Design.
-
-config MISDN_HFCUSB
-	tristate "Support for HFC-S USB based TAs"
-	depends on USB
-	help
-	  Enable support for USB ISDN TAs with Cologne Chip AG's
-	  HFC-S USB ISDN Controller
-
-config MISDN_AVMFRITZ
-	tristate "Support for AVM FRITZ!CARD PCI"
-	depends on MISDN
-	depends on PCI && HAS_IOPORT
-	select MISDN_IPAC
-	help
-	  Enable support for AVMs FRITZ!CARD PCI cards
-
-config MISDN_SPEEDFAX
-	tristate "Support for Sedlbauer Speedfax+"
-	depends on MISDN
-	depends on PCI && HAS_IOPORT
-	select MISDN_IPAC
-	select MISDN_ISAR
-	help
-	  Enable support for Sedlbauer Speedfax+.
-
-config MISDN_INFINEON
-	tristate "Support for cards with Infineon chipset"
-	depends on MISDN
-	depends on PCI && HAS_IOPORT
-	select MISDN_IPAC
-	help
-	  Enable support for cards with ISAC + HSCX, IPAC or IPAC-SX
-	  chip from Infineon (former manufacturer Siemens).
-
-config MISDN_W6692
-	tristate "Support for cards with Winbond 6692"
-	depends on MISDN
-	depends on PCI && HAS_IOPORT
-	help
-	  Enable support for Winbond 6692 PCI chip based cards.
-
-config MISDN_NETJET
-	tristate "Support for NETJet cards"
-	depends on MISDN
-	depends on PCI && HAS_IOPORT
-	depends on TTY
-	select MISDN_IPAC
-	select MISDN_HDLC
-	help
-	  Enable support for Traverse Technologies NETJet PCI cards.
-
-config MISDN_HDLC
-	tristate
-	select CRC_CCITT
-	select BITREVERSE
-
-config MISDN_IPAC
-	tristate
-	depends on MISDN
-
-config MISDN_ISAR
-	tristate
-	depends on MISDN
-
diff --git a/drivers/isdn/mISDN/Kconfig b/drivers/isdn/mISDN/Kconfig
deleted file mode 100644
index c9a53c222472..000000000000
--- a/drivers/isdn/mISDN/Kconfig
+++ /dev/null
@@ -1,48 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# modularer ISDN driver
-#
-
-menuconfig MISDN
-	tristate "Modular ISDN driver"
-	help
-	  Enable support for the modular ISDN driver.
-
-if MISDN != n
-
-config MISDN_DSP
-	tristate "Digital Audio Processing of transparent data"
-	depends on MISDN
-	select BITREVERSE
-	help
-	  Enable support for digital audio processing capability.
-
-	  This module may be used for special applications that require
-	  cross connecting of bchannels, conferencing, dtmf decoding,
-	  echo cancellation, tone generation, and Blowfish encryption and
-	  decryption. It may use hardware features if available.
-
-	  E.g. it is required for PBX4Linux. Go to http://isdn.eversberg.eu
-	  and get more information about this module and its usage.
-
-	  If unsure, say 'N'.
-
-config MISDN_L1OIP
-	tristate "ISDN over IP tunnel"
-	depends on MISDN
-	help
-	  Enable support for ISDN over IP tunnel.
-
-	  It features:
-	    - dynamic IP exchange, if one or both peers have dynamic IPs
-	    - BRI (S0) and PRI (S2M) interface
-	    - layer 1 control via network keepalive frames
-	    - direct tunneling of physical interface via IP
-
-	  NOTE: This protocol is called 'Layer 1 over IP' and is not
-	  compatible with ISDNoIP (Agfeo) or TDMoIP. Protocol description is
-	  provided in the source code.
-
-source "drivers/isdn/hardware/mISDN/Kconfig"
-
-endif #MISDN
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 6b2b65a66700..ee6457d1a5ee 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -33,7 +33,6 @@ menuconfig BT
 	     HCI Device drivers (Interface to the hardware)
 	     RFCOMM Module (RFCOMM Protocol)  
 	     BNEP Module (Bluetooth Network Encapsulation Protocol)
-	     CMTP Module (CAPI Message Transport Protocol)
 	     HIDP Module (Human Interface Device Protocol)
 
 	  Say Y here to compile Bluetooth support into the kernel or say M to
@@ -58,8 +57,6 @@ source "net/bluetooth/rfcomm/Kconfig"
 
 source "net/bluetooth/bnep/Kconfig"
 
-source "net/bluetooth/cmtp/Kconfig"
-
 source "net/bluetooth/hidp/Kconfig"
 
 config BT_LE
diff --git a/net/bluetooth/cmtp/Kconfig b/net/bluetooth/cmtp/Kconfig
deleted file mode 100644
index 34e923466236..000000000000
--- a/net/bluetooth/cmtp/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-config BT_CMTP
-	tristate "CMTP protocol support (DEPRECATED)"
-	depends on BT_BREDR && ISDN_CAPI && DEPRECATED
-	help
-	  CMTP (CAPI Message Transport Protocol) is a transport layer
-	  for CAPI messages.  CMTP is required for the Bluetooth Common
-	  ISDN Access Profile.
-
-	  Say Y here to compile CMTP support into the kernel or say M to
-	  compile it as module (cmtp).
-
diff --git a/drivers/Makefile b/drivers/Makefile
index c902fe94f6e8..cc5fdb1ef79f 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -123,7 +123,6 @@ obj-$(CONFIG_WATCHDOG)		+= watchdog/
 obj-$(CONFIG_MD)		+= md/
 obj-$(CONFIG_BT)		+= bluetooth/
 obj-$(CONFIG_ACCESSIBILITY)	+= accessibility/
-obj-$(CONFIG_ISDN)		+= isdn/
 obj-$(CONFIG_EDAC)		+= edac/
 obj-$(CONFIG_EISA)		+= eisa/
 obj-$(CONFIG_PM_OPP)		+= opp/
diff --git a/drivers/isdn/Makefile b/drivers/isdn/Makefile
deleted file mode 100644
index d14334f4007e..000000000000
--- a/drivers/isdn/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# Makefile for the kernel ISDN subsystem and device drivers.
-
-# Object files in subdirectories
-
-obj-$(CONFIG_BT_CMTP)			+= capi/
-obj-$(CONFIG_MISDN)			+= mISDN/
-obj-$(CONFIG_ISDN)			+= hardware/
diff --git a/drivers/isdn/capi/Makefile b/drivers/isdn/capi/Makefile
deleted file mode 100644
index 4fd3a4d7133f..000000000000
--- a/drivers/isdn/capi/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# Makefile for the CAPI subsystem used by BT_CMTP
-
-obj-$(CONFIG_BT_CMTP)			+= kernelcapi.o
-kernelcapi-y				:= kcapi.o capiutil.o capi.o
-kernelcapi-$(CONFIG_PROC_FS)		+= kcapi_proc.o
diff --git a/drivers/isdn/hardware/Makefile b/drivers/isdn/hardware/Makefile
deleted file mode 100644
index 96f9eb2e46ba..000000000000
--- a/drivers/isdn/hardware/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-# Makefile for the CAPI hardware drivers
-
-# Object files in subdirectories
-
-obj-$(CONFIG_MISDN)		+= mISDN/
diff --git a/drivers/isdn/hardware/mISDN/Makefile b/drivers/isdn/hardware/mISDN/Makefile
deleted file mode 100644
index 3f50f8c4753f..000000000000
--- a/drivers/isdn/hardware/mISDN/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the modular ISDN hardware drivers
-#
-#
-
-obj-$(CONFIG_MISDN_HFCPCI) += hfcpci.o
-obj-$(CONFIG_MISDN_HFCMULTI) += hfcmulti.o
-obj-$(CONFIG_MISDN_HFCUSB) += hfcsusb.o
-obj-$(CONFIG_MISDN_AVMFRITZ) += avmfritz.o
-obj-$(CONFIG_MISDN_SPEEDFAX) += speedfax.o
-obj-$(CONFIG_MISDN_INFINEON) += mISDNinfineon.o
-obj-$(CONFIG_MISDN_W6692) += w6692.o
-obj-$(CONFIG_MISDN_NETJET) += netjet.o
-# chip modules
-obj-$(CONFIG_MISDN_IPAC) += mISDNipac.o
-obj-$(CONFIG_MISDN_ISAR) += mISDNisar.o
-
-obj-$(CONFIG_MISDN_HDLC) += isdnhdlc.o
diff --git a/drivers/isdn/mISDN/Makefile b/drivers/isdn/mISDN/Makefile
deleted file mode 100644
index f3b4b7fa85f8..000000000000
--- a/drivers/isdn/mISDN/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the modular ISDN driver
-#
-
-obj-$(CONFIG_MISDN) += mISDN_core.o
-obj-$(CONFIG_MISDN_DSP) += mISDN_dsp.o
-obj-$(CONFIG_MISDN_L1OIP) += l1oip.o
-
-# multi objects
-
-mISDN_core-objs := core.o fsm.o socket.o clock.o hwchannel.o stack.o layer1.o layer2.o tei.o timerdev.o
-mISDN_dsp-objs := dsp_core.o dsp_cmx.o dsp_tones.o dsp_dtmf.o dsp_audio.o dsp_blowfish.o dsp_pipeline.o dsp_hwec.o
-l1oip-objs := l1oip_core.o l1oip_codec.o
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index a7eede7616d8..41049b280887 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -6,7 +6,6 @@
 obj-$(CONFIG_BT)	+= bluetooth.o
 obj-$(CONFIG_BT_RFCOMM)	+= rfcomm/
 obj-$(CONFIG_BT_BNEP)	+= bnep/
-obj-$(CONFIG_BT_CMTP)	+= cmtp/
 obj-$(CONFIG_BT_HIDP)	+= hidp/
 obj-$(CONFIG_BT_6LOWPAN) += bluetooth_6lowpan.o
 
diff --git a/net/bluetooth/cmtp/Makefile b/net/bluetooth/cmtp/Makefile
deleted file mode 100644
index b2262ca97499..000000000000
--- a/net/bluetooth/cmtp/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for the Linux Bluetooth CMTP layer
-#
-
-obj-$(CONFIG_BT_CMTP) += cmtp.o
-
-cmtp-objs := core.o sock.o capi.o
diff --git a/drivers/isdn/capi/kcapi.h b/drivers/isdn/capi/kcapi.h
deleted file mode 100644
index 479623e1db2a..000000000000
--- a/drivers/isdn/capi/kcapi.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Kernel CAPI 2.0 Module
- *
- * Copyright 1999 by Carsten Paeth <calle@calle.de>
- * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <linux/isdn/capilli.h>
-
-#ifdef KCAPI_DEBUG
-#define DBG(format, arg...) do {					\
-		printk(KERN_DEBUG "%s: " format "\n" , __func__ , ## arg); \
-	} while (0)
-#else
-#define DBG(format, arg...) /* */
-#endif
-
-enum {
-	CAPI_CTR_DETACHED = 0,
-	CAPI_CTR_DETECTED = 1,
-	CAPI_CTR_LOADING  = 2,
-	CAPI_CTR_RUNNING  = 3,
-};
-
-extern struct capi_ctr *capi_controller[CAPI_MAXCONTR];
-extern struct mutex capi_controller_lock;
-
-extern struct capi20_appl *capi_applications[CAPI_MAXAPPL];
-
-void kcapi_proc_init(void);
-void kcapi_proc_exit(void);
-
-struct capi20_appl {
-	u16 applid;
-	capi_register_params rparam;
-	void (*recv_message)(struct capi20_appl *ap, struct sk_buff *skb);
-	void *private;
-
-	/* internal to kernelcapi.o */
-	unsigned long nrecvctlpkt;
-	unsigned long nrecvdatapkt;
-	unsigned long nsentctlpkt;
-	unsigned long nsentdatapkt;
-	struct mutex recv_mtx;
-	struct sk_buff_head recv_queue;
-	struct work_struct recv_work;
-	int release_in_progress;
-};
-
-u16 capi20_isinstalled(void);
-u16 capi20_register(struct capi20_appl *ap);
-u16 capi20_release(struct capi20_appl *ap);
-u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb);
-u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN]);
-u16 capi20_get_version(u32 contr, struct capi_version *verp);
-u16 capi20_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN]);
-u16 capi20_get_profile(u32 contr, struct capi_profile *profp);
-int capi20_manufacturer(unsigned long cmd, void __user *data);
-
-#define CAPICTR_UP			0
-#define CAPICTR_DOWN			1
-
-int kcapi_init(void);
-void kcapi_exit(void);
-
-/*----- basic-type definitions -----*/
-
-typedef __u8 *_cstruct;
-
-typedef enum {
-	CAPI_COMPOSE,
-	CAPI_DEFAULT
-} _cmstruct;
-
-/*
-   The _cmsg structure contains all possible CAPI 2.0 parameter.
-   All parameters are stored here first. The function CAPI_CMSG_2_MESSAGE
-   assembles the parameter and builds CAPI2.0 conform messages.
-   CAPI_MESSAGE_2_CMSG disassembles CAPI 2.0 messages and stores the
-   parameter in the _cmsg structure
- */
-
-typedef struct {
-	/* Header */
-	__u16 ApplId;
-	__u8 Command;
-	__u8 Subcommand;
-	__u16 Messagenumber;
-
-	/* Parameter */
-	union {
-		__u32 adrController;
-		__u32 adrPLCI;
-		__u32 adrNCCI;
-	} adr;
-
-	_cmstruct AdditionalInfo;
-	_cstruct B1configuration;
-	__u16 B1protocol;
-	_cstruct B2configuration;
-	__u16 B2protocol;
-	_cstruct B3configuration;
-	__u16 B3protocol;
-	_cstruct BC;
-	_cstruct BChannelinformation;
-	_cmstruct BProtocol;
-	_cstruct CalledPartyNumber;
-	_cstruct CalledPartySubaddress;
-	_cstruct CallingPartyNumber;
-	_cstruct CallingPartySubaddress;
-	__u32 CIPmask;
-	__u32 CIPmask2;
-	__u16 CIPValue;
-	__u32 Class;
-	_cstruct ConnectedNumber;
-	_cstruct ConnectedSubaddress;
-	__u32 Data;
-	__u16 DataHandle;
-	__u16 DataLength;
-	_cstruct FacilityConfirmationParameter;
-	_cstruct Facilitydataarray;
-	_cstruct FacilityIndicationParameter;
-	_cstruct FacilityRequestParameter;
-	__u16 FacilitySelector;
-	__u16 Flags;
-	__u32 Function;
-	_cstruct HLC;
-	__u16 Info;
-	_cstruct InfoElement;
-	__u32 InfoMask;
-	__u16 InfoNumber;
-	_cstruct Keypadfacility;
-	_cstruct LLC;
-	_cstruct ManuData;
-	__u32 ManuID;
-	_cstruct NCPI;
-	__u16 Reason;
-	__u16 Reason_B3;
-	__u16 Reject;
-	_cstruct Useruserdata;
-
-	/* intern */
-	unsigned l, p;
-	unsigned char *par;
-	__u8 *m;
-
-	/* buffer to construct message */
-	__u8 buf[180];
-
-} _cmsg;
-
-/*-----------------------------------------------------------------------*/
-
-/*
- * Debugging / Tracing functions
- */
-
-char *capi_cmd2str(__u8 cmd, __u8 subcmd);
-
-typedef struct {
-	u_char	*buf;
-	u_char	*p;
-	size_t	size;
-	size_t	pos;
-} _cdebbuf;
-
-#define	CDEBUG_SIZE	1024
-#define	CDEBUG_GSIZE	4096
-
-void cdebbuf_free(_cdebbuf *cdb);
-int cdebug_init(void);
-void cdebug_exit(void);
-
-_cdebbuf *capi_message2str(__u8 *msg);
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h
deleted file mode 100644
index 5acf826d913c..000000000000
--- a/drivers/isdn/hardware/mISDN/hfc_multi.h
+++ /dev/null
@@ -1,1236 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * see notice in hfc_multi.c
- */
-
-#define DEBUG_HFCMULTI_FIFO	0x00010000
-#define	DEBUG_HFCMULTI_CRC	0x00020000
-#define	DEBUG_HFCMULTI_INIT	0x00040000
-#define	DEBUG_HFCMULTI_PLXSD	0x00080000
-#define	DEBUG_HFCMULTI_MODE	0x00100000
-#define	DEBUG_HFCMULTI_MSG	0x00200000
-#define	DEBUG_HFCMULTI_STATE	0x00400000
-#define	DEBUG_HFCMULTI_FILL	0x00800000
-#define	DEBUG_HFCMULTI_SYNC	0x01000000
-#define	DEBUG_HFCMULTI_DTMF	0x02000000
-#define	DEBUG_HFCMULTI_LOCK	0x80000000
-
-#define	PCI_ENA_REGIO	0x01
-#define	PCI_ENA_MEMIO	0x02
-
-#define XHFC_IRQ	4		/* SIU_IRQ2 */
-#define XHFC_MEMBASE	0xFE000000
-#define XHFC_MEMSIZE    0x00001000
-#define XHFC_OFFSET	0x00001000
-#define PA_XHFC_A0	0x0020		/* PA10 */
-#define PB_XHFC_IRQ1	0x00000100	/* PB23 */
-#define PB_XHFC_IRQ2	0x00000200	/* PB22 */
-#define PB_XHFC_IRQ3	0x00000400	/* PB21 */
-#define PB_XHFC_IRQ4	0x00000800	/* PB20 */
-
-/*
- * NOTE: some registers are assigned multiple times due to different modes
- *       also registers are assigned differen for HFC-4s/8s and HFC-E1
- */
-
-/*
-  #define MAX_FRAME_SIZE	2048
-*/
-
-struct hfc_chan {
-	struct dchannel	*dch;	/* link if channel is a D-channel */
-	struct bchannel	*bch;	/* link if channel is a B-channel */
-	int		port;	/* the interface port this */
-				/* channel is associated with */
-	int		nt_timer; /* -1 if off, 0 if elapsed, >0 if running */
-	int		los, ais, slip_tx, slip_rx, rdi; /* current alarms */
-	int		jitter;
-	u_long		cfg;	/* port configuration */
-	int		sync;	/* sync state (used by E1) */
-	u_int		protocol; /* current protocol */
-	int		slot_tx; /* current pcm slot */
-	int		bank_tx; /* current pcm bank */
-	int		slot_rx;
-	int		bank_rx;
-	int		conf;	/* conference setting of TX slot */
-	int		txpending;	/* if there is currently data in */
-					/* the FIFO 0=no, 1=yes, 2=splloop */
-	int		Zfill;	/* rx-fifo level on last hfcmulti_tx */
-	int		rx_off; /* set to turn fifo receive off */
-	int		coeff_count; /* curren coeff block */
-	s32		*coeff; /* memory pointer to 8 coeff blocks */
-};
-
-
-struct hfcm_hw {
-	u_char	r_ctrl;
-	u_char	r_irq_ctrl;
-	u_char	r_cirm;
-	u_char	r_ram_sz;
-	u_char	r_pcm_md0;
-	u_char	r_irqmsk_misc;
-	u_char	r_dtmf;
-	u_char	r_st_sync;
-	u_char	r_sci_msk;
-	u_char	r_tx0, r_tx1;
-	u_char	a_st_ctrl0[8];
-	u_char	r_bert_wd_md;
-	timer_t	timer;
-};
-
-
-/* for each stack these flags are used (cfg) */
-#define	HFC_CFG_NONCAP_TX	1 /* S/T TX interface has less capacity */
-#define	HFC_CFG_DIS_ECHANNEL	2 /* disable E-channel processing */
-#define	HFC_CFG_REG_ECHANNEL	3 /* register E-channel */
-#define	HFC_CFG_OPTICAL		4 /* the E1 interface is optical */
-#define	HFC_CFG_REPORT_LOS	5 /* the card should report loss of signal */
-#define	HFC_CFG_REPORT_AIS	6 /* the card should report alarm ind. sign. */
-#define	HFC_CFG_REPORT_SLIP	7 /* the card should report bit slips */
-#define	HFC_CFG_REPORT_RDI	8 /* the card should report remote alarm */
-#define	HFC_CFG_DTMF		9 /* enable DTMF-detection */
-#define	HFC_CFG_CRC4		10 /* disable CRC-4 Multiframe mode, */
-/* use double frame instead. */
-
-#define HFC_TYPE_E1		1 /* controller is HFC-E1 */
-#define HFC_TYPE_4S		4 /* controller is HFC-4S */
-#define HFC_TYPE_8S		8 /* controller is HFC-8S */
-#define HFC_TYPE_XHFC		5 /* controller is XHFC */
-
-#define	HFC_CHIP_EXRAM_128	0 /* external ram 128k */
-#define	HFC_CHIP_EXRAM_512	1 /* external ram 256k */
-#define	HFC_CHIP_REVISION0	2 /* old fifo handling */
-#define	HFC_CHIP_PCM_SLAVE	3 /* PCM is slave */
-#define	HFC_CHIP_PCM_MASTER	4 /* PCM is master */
-#define	HFC_CHIP_RX_SYNC	5 /* disable pll sync for pcm */
-#define	HFC_CHIP_DTMF		6 /* DTMF decoding is enabled */
-#define	HFC_CHIP_CONF		7 /* conference handling is enabled */
-#define	HFC_CHIP_ULAW		8 /* ULAW mode */
-#define	HFC_CHIP_CLOCK2		9 /* double clock mode */
-#define	HFC_CHIP_E1CLOCK_GET	10 /* always get clock from E1 interface */
-#define	HFC_CHIP_E1CLOCK_PUT	11 /* always put clock from E1 interface */
-#define	HFC_CHIP_WATCHDOG	12 /* whether we should send signals */
-/* to the watchdog */
-#define	HFC_CHIP_B410P		13 /* whether we have a b410p with echocan in */
-/* hw */
-#define	HFC_CHIP_PLXSD		14 /* whether we have a Speech-Design PLX */
-#define	HFC_CHIP_EMBSD          15 /* whether we have a SD Embedded board */
-
-#define HFC_IO_MODE_PCIMEM	0x00 /* normal memory mapped IO */
-#define HFC_IO_MODE_REGIO	0x01 /* PCI io access */
-#define HFC_IO_MODE_PLXSD	0x02 /* access HFC via PLX9030 */
-#define HFC_IO_MODE_EMBSD	0x03 /* direct access */
-
-/* table entry in the PCI devices list */
-struct hm_map {
-	char *vendor_name;
-	char *card_name;
-	int type;
-	int ports;
-	int clock2;
-	int leds;
-	int opticalsupport;
-	int dip_type;
-	int io_mode;
-	int irq;
-};
-
-struct hfc_multi {
-	struct list_head	list;
-	struct hm_map	*mtyp;
-	int		id;
-	int		pcm;	/* id of pcm bus */
-	int		ctype;	/* controller type */
-	int		ports;
-
-	u_int		irq;	/* irq used by card */
-	u_int		irqcnt;
-	struct pci_dev	*pci_dev;
-	int		io_mode; /* selects mode */
-#ifdef HFC_REGISTER_DEBUG
-	void		(*HFC_outb)(struct hfc_multi *hc, u_char reg,
-				    u_char val, const char *function, int line);
-	void		(*HFC_outb_nodebug)(struct hfc_multi *hc, u_char reg,
-					    u_char val, const char *function, int line);
-	u_char		(*HFC_inb)(struct hfc_multi *hc, u_char reg,
-				   const char *function, int line);
-	u_char		(*HFC_inb_nodebug)(struct hfc_multi *hc, u_char reg,
-					   const char *function, int line);
-	u_short		(*HFC_inw)(struct hfc_multi *hc, u_char reg,
-				   const char *function, int line);
-	u_short		(*HFC_inw_nodebug)(struct hfc_multi *hc, u_char reg,
-					   const char *function, int line);
-	void		(*HFC_wait)(struct hfc_multi *hc,
-				    const char *function, int line);
-	void		(*HFC_wait_nodebug)(struct hfc_multi *hc,
-					    const char *function, int line);
-#else
-	void		(*HFC_outb)(struct hfc_multi *hc, u_char reg,
-				    u_char val);
-	void		(*HFC_outb_nodebug)(struct hfc_multi *hc, u_char reg,
-					    u_char val);
-	u_char		(*HFC_inb)(struct hfc_multi *hc, u_char reg);
-	u_char		(*HFC_inb_nodebug)(struct hfc_multi *hc, u_char reg);
-	u_short		(*HFC_inw)(struct hfc_multi *hc, u_char reg);
-	u_short		(*HFC_inw_nodebug)(struct hfc_multi *hc, u_char reg);
-	void		(*HFC_wait)(struct hfc_multi *hc);
-	void		(*HFC_wait_nodebug)(struct hfc_multi *hc);
-#endif
-	void		(*read_fifo)(struct hfc_multi *hc, u_char *data,
-				     int len);
-	void		(*write_fifo)(struct hfc_multi *hc, u_char *data,
-				      int len);
-	u_long		pci_origmembase, plx_origmembase;
-	void __iomem	*pci_membase; /* PCI memory */
-	void __iomem	*plx_membase; /* PLX memory */
-	u_long		xhfc_origmembase;
-	u_char		*xhfc_membase;
-	u_long		*xhfc_memaddr, *xhfc_memdata;
-#ifdef CONFIG_MISDN_HFCMULTI_8xx
-	struct immap	*immap;
-#endif
-	u_long		pb_irqmsk;	/* Portbit mask to check the IRQ line */
-	u_long		pci_iobase; /* PCI IO */
-	struct hfcm_hw	hw;	/* remember data of write-only-registers */
-
-	u_long		chip;	/* chip configuration */
-	int		masterclk; /* port that provides master clock -1=off */
-	unsigned char	silence;/* silence byte */
-	unsigned char	silence_data[128];/* silence block */
-	int		dtmf;	/* flag that dtmf is currently in process */
-	int		Flen;	/* F-buffer size */
-	int		Zlen;	/* Z-buffer size (must be int for calculation)*/
-	int		max_trans; /* maximum transparent fifo fill */
-	int		Zmin;	/* Z-buffer offset */
-	int		DTMFbase; /* base address of DTMF coefficients */
-
-	u_int		slots;	/* number of PCM slots */
-	u_int		leds;	/* type of leds */
-	u_long		ledstate; /* save last state of leds */
-	int		opticalsupport; /* has the e1 board */
-					/* an optical Interface */
-
-	u_int		bmask[32]; /* bitmask of bchannels for port */
-	u_char		dnum[32]; /* array of used dchannel numbers for port */
-	u_char		created[32]; /* what port is created */
-	u_int		activity_tx; /* if there is data TX / RX */
-	u_int		activity_rx; /* bitmask according to port number */
-				     /* (will be cleared after */
-				     /* showing led-states) */
-	u_int		flash[8]; /* counter for flashing 8 leds on activity */
-
-	u_long		wdcount;	/* every 500 ms we need to */
-					/* send the watchdog a signal */
-	u_char		wdbyte; /* watchdog toggle byte */
-	int		e1_state; /* keep track of last state */
-	int		e1_getclock; /* if sync is retrieved from interface */
-	int		syncronized; /* keep track of existing sync interface */
-	int		e1_resync; /* resync jobs */
-
-	spinlock_t	lock;	/* the lock */
-
-	struct mISDNclock *iclock; /* isdn clock support */
-	int		iclock_on;
-
-	/*
-	 * the channel index is counted from 0, regardless where the channel
-	 * is located on the hfc-channel.
-	 * the bch->channel is equvalent to the hfc-channel
-	 */
-	struct hfc_chan	chan[32];
-	signed char	slot_owner[256]; /* owner channel of slot */
-};
-
-/* PLX GPIOs */
-#define	PLX_GPIO4_DIR_BIT	13
-#define	PLX_GPIO4_BIT		14
-#define	PLX_GPIO5_DIR_BIT	16
-#define	PLX_GPIO5_BIT		17
-#define	PLX_GPIO6_DIR_BIT	19
-#define	PLX_GPIO6_BIT		20
-#define	PLX_GPIO7_DIR_BIT	22
-#define	PLX_GPIO7_BIT		23
-#define PLX_GPIO8_DIR_BIT	25
-#define PLX_GPIO8_BIT		26
-
-#define	PLX_GPIO4		(1 << PLX_GPIO4_BIT)
-#define	PLX_GPIO5		(1 << PLX_GPIO5_BIT)
-#define	PLX_GPIO6		(1 << PLX_GPIO6_BIT)
-#define	PLX_GPIO7		(1 << PLX_GPIO7_BIT)
-#define PLX_GPIO8		(1 << PLX_GPIO8_BIT)
-
-#define	PLX_GPIO4_DIR		(1 << PLX_GPIO4_DIR_BIT)
-#define	PLX_GPIO5_DIR		(1 << PLX_GPIO5_DIR_BIT)
-#define	PLX_GPIO6_DIR		(1 << PLX_GPIO6_DIR_BIT)
-#define	PLX_GPIO7_DIR		(1 << PLX_GPIO7_DIR_BIT)
-#define PLX_GPIO8_DIR		(1 << PLX_GPIO8_DIR_BIT)
-
-#define	PLX_TERM_ON			PLX_GPIO7
-#define	PLX_SLAVE_EN_N		PLX_GPIO5
-#define	PLX_MASTER_EN		PLX_GPIO6
-#define	PLX_SYNC_O_EN		PLX_GPIO4
-#define PLX_DSP_RES_N		PLX_GPIO8
-/* GPIO4..8 Enable & Set to OUT, SLAVE_EN_N = 1 */
-#define PLX_GPIOC_INIT		(PLX_GPIO4_DIR | PLX_GPIO5_DIR | PLX_GPIO6_DIR \
-				 | PLX_GPIO7_DIR | PLX_GPIO8_DIR | PLX_SLAVE_EN_N)
-
-/* PLX Interrupt Control/STATUS */
-#define PLX_INTCSR_LINTI1_ENABLE 0x01
-#define PLX_INTCSR_LINTI1_STATUS 0x04
-#define PLX_INTCSR_LINTI2_ENABLE 0x08
-#define PLX_INTCSR_LINTI2_STATUS 0x20
-#define PLX_INTCSR_PCIINT_ENABLE 0x40
-
-/* PLX Registers */
-#define PLX_INTCSR 0x4c
-#define PLX_CNTRL  0x50
-#define PLX_GPIOC  0x54
-
-
-/*
- * REGISTER SETTING FOR HFC-4S/8S AND HFC-E1
- */
-
-/* write only registers */
-#define R_CIRM			0x00
-#define R_CTRL			0x01
-#define R_BRG_PCM_CFG		0x02
-#define R_RAM_ADDR0		0x08
-#define R_RAM_ADDR1		0x09
-#define R_RAM_ADDR2		0x0A
-#define R_FIRST_FIFO		0x0B
-#define R_RAM_SZ		0x0C
-#define R_FIFO_MD		0x0D
-#define R_INC_RES_FIFO		0x0E
-#define R_FSM_IDX		0x0F
-#define R_FIFO			0x0F
-#define R_SLOT			0x10
-#define R_IRQMSK_MISC		0x11
-#define R_SCI_MSK		0x12
-#define R_IRQ_CTRL		0x13
-#define R_PCM_MD0		0x14
-#define R_PCM_MD1		0x15
-#define R_PCM_MD2		0x15
-#define R_SH0H			0x15
-#define R_SH1H			0x15
-#define R_SH0L			0x15
-#define R_SH1L			0x15
-#define R_SL_SEL0		0x15
-#define R_SL_SEL1		0x15
-#define R_SL_SEL2		0x15
-#define R_SL_SEL3		0x15
-#define R_SL_SEL4		0x15
-#define R_SL_SEL5		0x15
-#define R_SL_SEL6		0x15
-#define R_SL_SEL7		0x15
-#define R_ST_SEL		0x16
-#define R_ST_SYNC		0x17
-#define R_CONF_EN		0x18
-#define R_TI_WD			0x1A
-#define R_BERT_WD_MD		0x1B
-#define R_DTMF			0x1C
-#define R_DTMF_N		0x1D
-#define R_E1_WR_STA		0x20
-#define R_E1_RD_STA		0x20
-#define R_LOS0			0x22
-#define R_LOS1			0x23
-#define R_RX0			0x24
-#define R_RX_FR0		0x25
-#define R_RX_FR1		0x26
-#define R_TX0			0x28
-#define R_TX1			0x29
-#define R_TX_FR0		0x2C
-
-#define R_TX_FR1		0x2D
-#define R_TX_FR2		0x2E
-#define R_JATT_ATT		0x2F /* undocumented */
-#define A_ST_RD_STATE		0x30
-#define A_ST_WR_STATE		0x30
-#define R_RX_OFF		0x30
-#define A_ST_CTRL0		0x31
-#define R_SYNC_OUT		0x31
-#define A_ST_CTRL1		0x32
-#define A_ST_CTRL2		0x33
-#define A_ST_SQ_WR		0x34
-#define R_TX_OFF		0x34
-#define R_SYNC_CTRL		0x35
-#define A_ST_CLK_DLY		0x37
-#define R_PWM0			0x38
-#define R_PWM1			0x39
-#define A_ST_B1_TX		0x3C
-#define A_ST_B2_TX		0x3D
-#define A_ST_D_TX		0x3E
-#define R_GPIO_OUT0		0x40
-#define R_GPIO_OUT1		0x41
-#define R_GPIO_EN0		0x42
-#define R_GPIO_EN1		0x43
-#define R_GPIO_SEL		0x44
-#define R_BRG_CTRL		0x45
-#define R_PWM_MD		0x46
-#define R_BRG_MD		0x47
-#define R_BRG_TIM0		0x48
-#define R_BRG_TIM1		0x49
-#define R_BRG_TIM2		0x4A
-#define R_BRG_TIM3		0x4B
-#define R_BRG_TIM_SEL01		0x4C
-#define R_BRG_TIM_SEL23		0x4D
-#define R_BRG_TIM_SEL45		0x4E
-#define R_BRG_TIM_SEL67		0x4F
-#define A_SL_CFG		0xD0
-#define A_CONF			0xD1
-#define A_CH_MSK		0xF4
-#define A_CON_HDLC		0xFA
-#define A_SUBCH_CFG		0xFB
-#define A_CHANNEL		0xFC
-#define A_FIFO_SEQ		0xFD
-#define A_IRQ_MSK		0xFF
-
-/* read only registers */
-#define A_Z12			0x04
-#define A_Z1L			0x04
-#define A_Z1			0x04
-#define A_Z1H			0x05
-#define A_Z2L			0x06
-#define A_Z2			0x06
-#define A_Z2H			0x07
-#define A_F1			0x0C
-#define A_F12			0x0C
-#define A_F2			0x0D
-#define R_IRQ_OVIEW		0x10
-#define R_IRQ_MISC		0x11
-#define R_IRQ_STATECH		0x12
-#define R_CONF_OFLOW		0x14
-#define R_RAM_USE		0x15
-#define R_CHIP_ID		0x16
-#define R_BERT_STA		0x17
-#define R_F0_CNTL		0x18
-#define R_F0_CNTH		0x19
-#define R_BERT_EC		0x1A
-#define R_BERT_ECL		0x1A
-#define R_BERT_ECH		0x1B
-#define R_STATUS		0x1C
-#define R_CHIP_RV		0x1F
-#define R_STATE			0x20
-#define R_SYNC_STA		0x24
-#define R_RX_SL0_0		0x25
-#define R_RX_SL0_1		0x26
-#define R_RX_SL0_2		0x27
-#define R_JATT_DIR		0x2b /* undocumented */
-#define R_SLIP			0x2c
-#define A_ST_RD_STA		0x30
-#define R_FAS_EC		0x30
-#define R_FAS_ECL		0x30
-#define R_FAS_ECH		0x31
-#define R_VIO_EC		0x32
-#define R_VIO_ECL		0x32
-#define R_VIO_ECH		0x33
-#define A_ST_SQ_RD		0x34
-#define R_CRC_EC		0x34
-#define R_CRC_ECL		0x34
-#define R_CRC_ECH		0x35
-#define R_E_EC			0x36
-#define R_E_ECL			0x36
-#define R_E_ECH			0x37
-#define R_SA6_SA13_EC		0x38
-#define R_SA6_SA13_ECL		0x38
-#define R_SA6_SA13_ECH		0x39
-#define R_SA6_SA23_EC		0x3A
-#define R_SA6_SA23_ECL		0x3A
-#define R_SA6_SA23_ECH		0x3B
-#define A_ST_B1_RX		0x3C
-#define A_ST_B2_RX		0x3D
-#define A_ST_D_RX		0x3E
-#define A_ST_E_RX		0x3F
-#define R_GPIO_IN0		0x40
-#define R_GPIO_IN1		0x41
-#define R_GPI_IN0		0x44
-#define R_GPI_IN1		0x45
-#define R_GPI_IN2		0x46
-#define R_GPI_IN3		0x47
-#define R_INT_DATA		0x88
-#define R_IRQ_FIFO_BL0		0xC8
-#define R_IRQ_FIFO_BL1		0xC9
-#define R_IRQ_FIFO_BL2		0xCA
-#define R_IRQ_FIFO_BL3		0xCB
-#define R_IRQ_FIFO_BL4		0xCC
-#define R_IRQ_FIFO_BL5		0xCD
-#define R_IRQ_FIFO_BL6		0xCE
-#define R_IRQ_FIFO_BL7		0xCF
-
-/* read and write registers */
-#define A_FIFO_DATA0		0x80
-#define A_FIFO_DATA1		0x80
-#define A_FIFO_DATA2		0x80
-#define A_FIFO_DATA0_NOINC	0x84
-#define A_FIFO_DATA1_NOINC	0x84
-#define A_FIFO_DATA2_NOINC	0x84
-#define R_RAM_DATA		0xC0
-
-
-/*
- * BIT SETTING FOR HFC-4S/8S AND HFC-E1
- */
-
-/* chapter 2: universal bus interface */
-/* R_CIRM */
-#define V_IRQ_SEL		0x01
-#define V_SRES			0x08
-#define V_HFCRES		0x10
-#define V_PCMRES		0x20
-#define V_STRES			0x40
-#define V_ETRES			0x40
-#define V_RLD_EPR		0x80
-/* R_CTRL */
-#define V_FIFO_LPRIO		0x02
-#define V_SLOW_RD		0x04
-#define V_EXT_RAM		0x08
-#define V_CLK_OFF		0x20
-#define V_ST_CLK		0x40
-/* R_RAM_ADDR0 */
-#define V_RAM_ADDR2		0x01
-#define V_ADDR_RES		0x40
-#define V_ADDR_INC		0x80
-/* R_RAM_SZ */
-#define V_RAM_SZ		0x01
-#define V_PWM0_16KHZ		0x10
-#define V_PWM1_16KHZ		0x20
-#define V_FZ_MD			0x80
-/* R_CHIP_ID */
-#define V_PNP_IRQ		0x01
-#define V_CHIP_ID		0x10
-
-/* chapter 3: data flow */
-/* R_FIRST_FIFO */
-#define V_FIRST_FIRO_DIR	0x01
-#define V_FIRST_FIFO_NUM	0x02
-/* R_FIFO_MD */
-#define V_FIFO_MD		0x01
-#define V_CSM_MD		0x04
-#define V_FSM_MD		0x08
-#define V_FIFO_SZ		0x10
-/* R_FIFO */
-#define V_FIFO_DIR		0x01
-#define V_FIFO_NUM		0x02
-#define V_REV			0x80
-/* R_SLOT */
-#define V_SL_DIR		0x01
-#define V_SL_NUM		0x02
-/* A_SL_CFG */
-#define V_CH_DIR		0x01
-#define V_CH_SEL		0x02
-#define V_ROUTING		0x40
-/* A_CON_HDLC */
-#define V_IFF			0x01
-#define V_HDLC_TRP		0x02
-#define V_TRP_IRQ		0x04
-#define V_DATA_FLOW		0x20
-/* A_SUBCH_CFG */
-#define V_BIT_CNT		0x01
-#define V_START_BIT		0x08
-#define V_LOOP_FIFO		0x40
-#define V_INV_DATA		0x80
-/* A_CHANNEL */
-#define V_CH_DIR0		0x01
-#define V_CH_NUM0		0x02
-/* A_FIFO_SEQ */
-#define V_NEXT_FIFO_DIR		0x01
-#define V_NEXT_FIFO_NUM		0x02
-#define V_SEQ_END		0x40
-
-/* chapter 4: FIFO handling and HDLC controller */
-/* R_INC_RES_FIFO */
-#define V_INC_F			0x01
-#define V_RES_F			0x02
-#define V_RES_LOST		0x04
-
-/* chapter 5: S/T interface */
-/* R_SCI_MSK */
-#define V_SCI_MSK_ST0		0x01
-#define V_SCI_MSK_ST1		0x02
-#define V_SCI_MSK_ST2		0x04
-#define V_SCI_MSK_ST3		0x08
-#define V_SCI_MSK_ST4		0x10
-#define V_SCI_MSK_ST5		0x20
-#define V_SCI_MSK_ST6		0x40
-#define V_SCI_MSK_ST7		0x80
-/* R_ST_SEL */
-#define V_ST_SEL		0x01
-#define V_MULT_ST		0x08
-/* R_ST_SYNC */
-#define V_SYNC_SEL		0x01
-#define V_AUTO_SYNC		0x08
-/* A_ST_WR_STA */
-#define V_ST_SET_STA		0x01
-#define V_ST_LD_STA		0x10
-#define V_ST_ACT		0x20
-#define V_SET_G2_G3		0x80
-/* A_ST_CTRL0 */
-#define V_B1_EN			0x01
-#define V_B2_EN			0x02
-#define V_ST_MD			0x04
-#define V_D_PRIO		0x08
-#define V_SQ_EN			0x10
-#define V_96KHZ			0x20
-#define V_TX_LI			0x40
-#define V_ST_STOP		0x80
-/* A_ST_CTRL1 */
-#define V_G2_G3_EN		0x01
-#define V_D_HI			0x04
-#define V_E_IGNO		0x08
-#define V_E_LO			0x10
-#define V_B12_SWAP		0x80
-/* A_ST_CTRL2 */
-#define V_B1_RX_EN		0x01
-#define V_B2_RX_EN		0x02
-#define V_ST_TRIS		0x40
-/* A_ST_CLK_DLY */
-#define V_ST_CK_DLY		0x01
-#define V_ST_SMPL		0x10
-/* A_ST_D_TX */
-#define V_ST_D_TX		0x40
-/* R_IRQ_STATECH */
-#define V_SCI_ST0		0x01
-#define V_SCI_ST1		0x02
-#define V_SCI_ST2		0x04
-#define V_SCI_ST3		0x08
-#define V_SCI_ST4		0x10
-#define V_SCI_ST5		0x20
-#define V_SCI_ST6		0x40
-#define V_SCI_ST7		0x80
-/* A_ST_RD_STA */
-#define V_ST_STA		0x01
-#define V_FR_SYNC_ST		0x10
-#define V_TI2_EXP		0x20
-#define V_INFO0			0x40
-#define V_G2_G3			0x80
-/* A_ST_SQ_RD */
-#define V_ST_SQ			0x01
-#define V_MF_RX_RDY		0x10
-#define V_MF_TX_RDY		0x80
-/* A_ST_D_RX */
-#define V_ST_D_RX		0x40
-/* A_ST_E_RX */
-#define V_ST_E_RX		0x40
-
-/* chapter 5: E1 interface */
-/* R_E1_WR_STA */
-/* R_E1_RD_STA */
-#define V_E1_SET_STA		0x01
-#define V_E1_LD_STA		0x10
-/* R_RX0 */
-#define V_RX_CODE		0x01
-#define V_RX_FBAUD		0x04
-#define V_RX_CMI		0x08
-#define V_RX_INV_CMI		0x10
-#define V_RX_INV_CLK		0x20
-#define V_RX_INV_DATA		0x40
-#define V_AIS_ITU		0x80
-/* R_RX_FR0 */
-#define V_NO_INSYNC		0x01
-#define V_AUTO_RESYNC		0x02
-#define V_AUTO_RECO		0x04
-#define V_SWORD_COND		0x08
-#define V_SYNC_LOSS		0x10
-#define V_XCRC_SYNC		0x20
-#define V_MF_RESYNC		0x40
-#define V_RESYNC		0x80
-/* R_RX_FR1 */
-#define V_RX_MF			0x01
-#define V_RX_MF_SYNC		0x02
-#define V_RX_SL0_RAM		0x04
-#define V_ERR_SIM		0x20
-#define V_RES_NMF		0x40
-/* R_TX0 */
-#define V_TX_CODE		0x01
-#define V_TX_FBAUD		0x04
-#define V_TX_CMI_CODE		0x08
-#define V_TX_INV_CMI_CODE	0x10
-#define V_TX_INV_CLK		0x20
-#define V_TX_INV_DATA		0x40
-#define V_OUT_EN		0x80
-/* R_TX1 */
-#define V_INV_CLK		0x01
-#define V_EXCHG_DATA_LI		0x02
-#define V_AIS_OUT		0x04
-#define V_ATX			0x20
-#define V_NTRI			0x40
-#define V_AUTO_ERR_RES		0x80
-/* R_TX_FR0 */
-#define V_TRP_FAS		0x01
-#define V_TRP_NFAS		0x02
-#define V_TRP_RAL		0x04
-#define V_TRP_SA		0x08
-/* R_TX_FR1 */
-#define V_TX_FAS		0x01
-#define V_TX_NFAS		0x02
-#define V_TX_RAL		0x04
-#define V_TX_SA			0x08
-/* R_TX_FR2 */
-#define V_TX_MF			0x01
-#define V_TRP_SL0		0x02
-#define V_TX_SL0_RAM		0x04
-#define V_TX_E			0x10
-#define V_NEG_E			0x20
-#define V_XS12_ON		0x40
-#define V_XS15_ON		0x80
-/* R_RX_OFF */
-#define V_RX_SZ			0x01
-#define V_RX_INIT		0x04
-/* R_SYNC_OUT */
-#define V_SYNC_E1_RX		0x01
-#define V_IPATS0		0x20
-#define V_IPATS1		0x40
-#define V_IPATS2		0x80
-/* R_TX_OFF */
-#define V_TX_SZ			0x01
-#define V_TX_INIT		0x04
-/* R_SYNC_CTRL */
-#define V_EXT_CLK_SYNC		0x01
-#define V_SYNC_OFFS		0x02
-#define V_PCM_SYNC		0x04
-#define V_NEG_CLK		0x08
-#define V_HCLK			0x10
-/*
-  #define V_JATT_AUTO_DEL		0x20
-  #define V_JATT_AUTO		0x40
-*/
-#define V_JATT_OFF		0x80
-/* R_STATE */
-#define V_E1_STA		0x01
-#define V_ALT_FR_RX		0x40
-#define V_ALT_FR_TX		0x80
-/* R_SYNC_STA */
-#define V_RX_STA		0x01
-#define V_FR_SYNC_E1		0x04
-#define V_SIG_LOS		0x08
-#define V_MFA_STA		0x10
-#define V_AIS			0x40
-#define V_NO_MF_SYNC		0x80
-/* R_RX_SL0_0 */
-#define V_SI_FAS		0x01
-#define V_SI_NFAS		0x02
-#define V_A			0x04
-#define V_CRC_OK		0x08
-#define V_TX_E1			0x10
-#define V_TX_E2			0x20
-#define V_RX_E1			0x40
-#define V_RX_E2			0x80
-/* R_SLIP */
-#define V_SLIP_RX		0x01
-#define V_FOSLIP_RX		0x08
-#define V_SLIP_TX		0x10
-#define V_FOSLIP_TX		0x80
-
-/* chapter 6: PCM interface */
-/* R_PCM_MD0 */
-#define V_PCM_MD		0x01
-#define V_C4_POL		0x02
-#define V_F0_NEG		0x04
-#define V_F0_LEN		0x08
-#define V_PCM_ADDR		0x10
-/* R_SL_SEL0 */
-#define V_SL_SEL0		0x01
-#define V_SH_SEL0		0x80
-/* R_SL_SEL1 */
-#define V_SL_SEL1		0x01
-#define V_SH_SEL1		0x80
-/* R_SL_SEL2 */
-#define V_SL_SEL2		0x01
-#define V_SH_SEL2		0x80
-/* R_SL_SEL3 */
-#define V_SL_SEL3		0x01
-#define V_SH_SEL3		0x80
-/* R_SL_SEL4 */
-#define V_SL_SEL4		0x01
-#define V_SH_SEL4		0x80
-/* R_SL_SEL5 */
-#define V_SL_SEL5		0x01
-#define V_SH_SEL5		0x80
-/* R_SL_SEL6 */
-#define V_SL_SEL6		0x01
-#define V_SH_SEL6		0x80
-/* R_SL_SEL7 */
-#define V_SL_SEL7		0x01
-#define V_SH_SEL7		0x80
-/* R_PCM_MD1 */
-#define V_ODEC_CON		0x01
-#define V_PLL_ADJ		0x04
-#define V_PCM_DR		0x10
-#define V_PCM_LOOP		0x40
-/* R_PCM_MD2 */
-#define V_SYNC_PLL		0x02
-#define V_SYNC_SRC		0x04
-#define V_SYNC_OUT		0x08
-#define V_ICR_FR_TIME		0x40
-#define V_EN_PLL		0x80
-
-/* chapter 7: pulse width modulation */
-/* R_PWM_MD */
-#define V_EXT_IRQ_EN		0x08
-#define V_PWM0_MD		0x10
-#define V_PWM1_MD		0x40
-
-/* chapter 8: multiparty audio conferences */
-/* R_CONF_EN */
-#define V_CONF_EN		0x01
-#define V_ULAW			0x80
-/* A_CONF */
-#define V_CONF_NUM		0x01
-#define V_NOISE_SUPPR		0x08
-#define V_ATT_LEV		0x20
-#define V_CONF_SL		0x80
-/* R_CONF_OFLOW */
-#define V_CONF_OFLOW0		0x01
-#define V_CONF_OFLOW1		0x02
-#define V_CONF_OFLOW2		0x04
-#define V_CONF_OFLOW3		0x08
-#define V_CONF_OFLOW4		0x10
-#define V_CONF_OFLOW5		0x20
-#define V_CONF_OFLOW6		0x40
-#define V_CONF_OFLOW7		0x80
-
-/* chapter 9: DTMF contoller */
-/* R_DTMF0 */
-#define V_DTMF_EN		0x01
-#define V_HARM_SEL		0x02
-#define V_DTMF_RX_CH		0x04
-#define V_DTMF_STOP		0x08
-#define V_CHBL_SEL		0x10
-#define V_RST_DTMF		0x40
-#define V_ULAW_SEL		0x80
-
-/* chapter 10: BERT */
-/* R_BERT_WD_MD */
-#define V_PAT_SEQ		0x01
-#define V_BERT_ERR		0x08
-#define V_AUTO_WD_RES		0x20
-#define V_WD_RES		0x80
-/* R_BERT_STA */
-#define V_BERT_SYNC_SRC		0x01
-#define V_BERT_SYNC		0x10
-#define V_BERT_INV_DATA		0x20
-
-/* chapter 11: auxiliary interface */
-/* R_BRG_PCM_CFG */
-#define V_BRG_EN		0x01
-#define V_BRG_MD		0x02
-#define V_PCM_CLK		0x20
-#define V_ADDR_WRDLY		0x40
-/* R_BRG_CTRL */
-#define V_BRG_CS		0x01
-#define V_BRG_ADDR		0x08
-#define V_BRG_CS_SRC		0x80
-/* R_BRG_MD */
-#define V_BRG_MD0		0x01
-#define V_BRG_MD1		0x02
-#define V_BRG_MD2		0x04
-#define V_BRG_MD3		0x08
-#define V_BRG_MD4		0x10
-#define V_BRG_MD5		0x20
-#define V_BRG_MD6		0x40
-#define V_BRG_MD7		0x80
-/* R_BRG_TIM0 */
-#define V_BRG_TIM0_IDLE		0x01
-#define V_BRG_TIM0_CLK		0x10
-/* R_BRG_TIM1 */
-#define V_BRG_TIM1_IDLE		0x01
-#define V_BRG_TIM1_CLK		0x10
-/* R_BRG_TIM2 */
-#define V_BRG_TIM2_IDLE		0x01
-#define V_BRG_TIM2_CLK		0x10
-/* R_BRG_TIM3 */
-#define V_BRG_TIM3_IDLE		0x01
-#define V_BRG_TIM3_CLK		0x10
-/* R_BRG_TIM_SEL01 */
-#define V_BRG_WR_SEL0		0x01
-#define V_BRG_RD_SEL0		0x04
-#define V_BRG_WR_SEL1		0x10
-#define V_BRG_RD_SEL1		0x40
-/* R_BRG_TIM_SEL23 */
-#define V_BRG_WR_SEL2		0x01
-#define V_BRG_RD_SEL2		0x04
-#define V_BRG_WR_SEL3		0x10
-#define V_BRG_RD_SEL3		0x40
-/* R_BRG_TIM_SEL45 */
-#define V_BRG_WR_SEL4		0x01
-#define V_BRG_RD_SEL4		0x04
-#define V_BRG_WR_SEL5		0x10
-#define V_BRG_RD_SEL5		0x40
-/* R_BRG_TIM_SEL67 */
-#define V_BRG_WR_SEL6		0x01
-#define V_BRG_RD_SEL6		0x04
-#define V_BRG_WR_SEL7		0x10
-#define V_BRG_RD_SEL7		0x40
-
-/* chapter 12: clock, reset, interrupt, timer and watchdog */
-/* R_IRQMSK_MISC */
-#define V_STA_IRQMSK		0x01
-#define V_TI_IRQMSK		0x02
-#define V_PROC_IRQMSK		0x04
-#define V_DTMF_IRQMSK		0x08
-#define V_IRQ1S_MSK		0x10
-#define V_SA6_IRQMSK		0x20
-#define V_RX_EOMF_MSK		0x40
-#define V_TX_EOMF_MSK		0x80
-/* R_IRQ_CTRL */
-#define V_FIFO_IRQ		0x01
-#define V_GLOB_IRQ_EN		0x08
-#define V_IRQ_POL		0x10
-/* R_TI_WD */
-#define V_EV_TS			0x01
-#define V_WD_TS			0x10
-/* A_IRQ_MSK */
-#define V_IRQ			0x01
-#define V_BERT_EN		0x02
-#define V_MIX_IRQ		0x04
-/* R_IRQ_OVIEW */
-#define V_IRQ_FIFO_BL0		0x01
-#define V_IRQ_FIFO_BL1		0x02
-#define V_IRQ_FIFO_BL2		0x04
-#define V_IRQ_FIFO_BL3		0x08
-#define V_IRQ_FIFO_BL4		0x10
-#define V_IRQ_FIFO_BL5		0x20
-#define V_IRQ_FIFO_BL6		0x40
-#define V_IRQ_FIFO_BL7		0x80
-/* R_IRQ_MISC */
-#define V_STA_IRQ		0x01
-#define V_TI_IRQ		0x02
-#define V_IRQ_PROC		0x04
-#define V_DTMF_IRQ		0x08
-#define V_IRQ1S			0x10
-#define V_SA6_IRQ		0x20
-#define V_RX_EOMF		0x40
-#define V_TX_EOMF		0x80
-/* R_STATUS */
-#define V_BUSY			0x01
-#define V_PROC			0x02
-#define V_DTMF_STA		0x04
-#define V_LOST_STA		0x08
-#define V_SYNC_IN		0x10
-#define V_EXT_IRQSTA		0x20
-#define V_MISC_IRQSTA		0x40
-#define V_FR_IRQSTA		0x80
-/* R_IRQ_FIFO_BL0 */
-#define V_IRQ_FIFO0_TX		0x01
-#define V_IRQ_FIFO0_RX		0x02
-#define V_IRQ_FIFO1_TX		0x04
-#define V_IRQ_FIFO1_RX		0x08
-#define V_IRQ_FIFO2_TX		0x10
-#define V_IRQ_FIFO2_RX		0x20
-#define V_IRQ_FIFO3_TX		0x40
-#define V_IRQ_FIFO3_RX		0x80
-/* R_IRQ_FIFO_BL1 */
-#define V_IRQ_FIFO4_TX		0x01
-#define V_IRQ_FIFO4_RX		0x02
-#define V_IRQ_FIFO5_TX		0x04
-#define V_IRQ_FIFO5_RX		0x08
-#define V_IRQ_FIFO6_TX		0x10
-#define V_IRQ_FIFO6_RX		0x20
-#define V_IRQ_FIFO7_TX		0x40
-#define V_IRQ_FIFO7_RX		0x80
-/* R_IRQ_FIFO_BL2 */
-#define V_IRQ_FIFO8_TX		0x01
-#define V_IRQ_FIFO8_RX		0x02
-#define V_IRQ_FIFO9_TX		0x04
-#define V_IRQ_FIFO9_RX		0x08
-#define V_IRQ_FIFO10_TX		0x10
-#define V_IRQ_FIFO10_RX		0x20
-#define V_IRQ_FIFO11_TX		0x40
-#define V_IRQ_FIFO11_RX		0x80
-/* R_IRQ_FIFO_BL3 */
-#define V_IRQ_FIFO12_TX		0x01
-#define V_IRQ_FIFO12_RX		0x02
-#define V_IRQ_FIFO13_TX		0x04
-#define V_IRQ_FIFO13_RX		0x08
-#define V_IRQ_FIFO14_TX		0x10
-#define V_IRQ_FIFO14_RX		0x20
-#define V_IRQ_FIFO15_TX		0x40
-#define V_IRQ_FIFO15_RX		0x80
-/* R_IRQ_FIFO_BL4 */
-#define V_IRQ_FIFO16_TX		0x01
-#define V_IRQ_FIFO16_RX		0x02
-#define V_IRQ_FIFO17_TX		0x04
-#define V_IRQ_FIFO17_RX		0x08
-#define V_IRQ_FIFO18_TX		0x10
-#define V_IRQ_FIFO18_RX		0x20
-#define V_IRQ_FIFO19_TX		0x40
-#define V_IRQ_FIFO19_RX		0x80
-/* R_IRQ_FIFO_BL5 */
-#define V_IRQ_FIFO20_TX		0x01
-#define V_IRQ_FIFO20_RX		0x02
-#define V_IRQ_FIFO21_TX		0x04
-#define V_IRQ_FIFO21_RX		0x08
-#define V_IRQ_FIFO22_TX		0x10
-#define V_IRQ_FIFO22_RX		0x20
-#define V_IRQ_FIFO23_TX		0x40
-#define V_IRQ_FIFO23_RX		0x80
-/* R_IRQ_FIFO_BL6 */
-#define V_IRQ_FIFO24_TX		0x01
-#define V_IRQ_FIFO24_RX		0x02
-#define V_IRQ_FIFO25_TX		0x04
-#define V_IRQ_FIFO25_RX		0x08
-#define V_IRQ_FIFO26_TX		0x10
-#define V_IRQ_FIFO26_RX		0x20
-#define V_IRQ_FIFO27_TX		0x40
-#define V_IRQ_FIFO27_RX		0x80
-/* R_IRQ_FIFO_BL7 */
-#define V_IRQ_FIFO28_TX		0x01
-#define V_IRQ_FIFO28_RX		0x02
-#define V_IRQ_FIFO29_TX		0x04
-#define V_IRQ_FIFO29_RX		0x08
-#define V_IRQ_FIFO30_TX		0x10
-#define V_IRQ_FIFO30_RX		0x20
-#define V_IRQ_FIFO31_TX		0x40
-#define V_IRQ_FIFO31_RX		0x80
-
-/* chapter 13: general purpose I/O pins (GPIO) and input pins (GPI) */
-/* R_GPIO_OUT0 */
-#define V_GPIO_OUT0		0x01
-#define V_GPIO_OUT1		0x02
-#define V_GPIO_OUT2		0x04
-#define V_GPIO_OUT3		0x08
-#define V_GPIO_OUT4		0x10
-#define V_GPIO_OUT5		0x20
-#define V_GPIO_OUT6		0x40
-#define V_GPIO_OUT7		0x80
-/* R_GPIO_OUT1 */
-#define V_GPIO_OUT8		0x01
-#define V_GPIO_OUT9		0x02
-#define V_GPIO_OUT10		0x04
-#define V_GPIO_OUT11		0x08
-#define V_GPIO_OUT12		0x10
-#define V_GPIO_OUT13		0x20
-#define V_GPIO_OUT14		0x40
-#define V_GPIO_OUT15		0x80
-/* R_GPIO_EN0 */
-#define V_GPIO_EN0		0x01
-#define V_GPIO_EN1		0x02
-#define V_GPIO_EN2		0x04
-#define V_GPIO_EN3		0x08
-#define V_GPIO_EN4		0x10
-#define V_GPIO_EN5		0x20
-#define V_GPIO_EN6		0x40
-#define V_GPIO_EN7		0x80
-/* R_GPIO_EN1 */
-#define V_GPIO_EN8		0x01
-#define V_GPIO_EN9		0x02
-#define V_GPIO_EN10		0x04
-#define V_GPIO_EN11		0x08
-#define V_GPIO_EN12		0x10
-#define V_GPIO_EN13		0x20
-#define V_GPIO_EN14		0x40
-#define V_GPIO_EN15		0x80
-/* R_GPIO_SEL */
-#define V_GPIO_SEL0		0x01
-#define V_GPIO_SEL1		0x02
-#define V_GPIO_SEL2		0x04
-#define V_GPIO_SEL3		0x08
-#define V_GPIO_SEL4		0x10
-#define V_GPIO_SEL5		0x20
-#define V_GPIO_SEL6		0x40
-#define V_GPIO_SEL7		0x80
-/* R_GPIO_IN0 */
-#define V_GPIO_IN0		0x01
-#define V_GPIO_IN1		0x02
-#define V_GPIO_IN2		0x04
-#define V_GPIO_IN3		0x08
-#define V_GPIO_IN4		0x10
-#define V_GPIO_IN5		0x20
-#define V_GPIO_IN6		0x40
-#define V_GPIO_IN7		0x80
-/* R_GPIO_IN1 */
-#define V_GPIO_IN8		0x01
-#define V_GPIO_IN9		0x02
-#define V_GPIO_IN10		0x04
-#define V_GPIO_IN11		0x08
-#define V_GPIO_IN12		0x10
-#define V_GPIO_IN13		0x20
-#define V_GPIO_IN14		0x40
-#define V_GPIO_IN15		0x80
-/* R_GPI_IN0 */
-#define V_GPI_IN0		0x01
-#define V_GPI_IN1		0x02
-#define V_GPI_IN2		0x04
-#define V_GPI_IN3		0x08
-#define V_GPI_IN4		0x10
-#define V_GPI_IN5		0x20
-#define V_GPI_IN6		0x40
-#define V_GPI_IN7		0x80
-/* R_GPI_IN1 */
-#define V_GPI_IN8		0x01
-#define V_GPI_IN9		0x02
-#define V_GPI_IN10		0x04
-#define V_GPI_IN11		0x08
-#define V_GPI_IN12		0x10
-#define V_GPI_IN13		0x20
-#define V_GPI_IN14		0x40
-#define V_GPI_IN15		0x80
-/* R_GPI_IN2 */
-#define V_GPI_IN16		0x01
-#define V_GPI_IN17		0x02
-#define V_GPI_IN18		0x04
-#define V_GPI_IN19		0x08
-#define V_GPI_IN20		0x10
-#define V_GPI_IN21		0x20
-#define V_GPI_IN22		0x40
-#define V_GPI_IN23		0x80
-/* R_GPI_IN3 */
-#define V_GPI_IN24		0x01
-#define V_GPI_IN25		0x02
-#define V_GPI_IN26		0x04
-#define V_GPI_IN27		0x08
-#define V_GPI_IN28		0x10
-#define V_GPI_IN29		0x20
-#define V_GPI_IN30		0x40
-#define V_GPI_IN31		0x80
-
-/* map of all registers, used for debugging */
-
-#ifdef HFC_REGISTER_DEBUG
-struct hfc_register_names {
-	char *name;
-	u_char reg;
-} hfc_register_names[] = {
-	/* write registers */
-	{"R_CIRM",		0x00},
-	{"R_CTRL",		0x01},
-	{"R_BRG_PCM_CFG ",	0x02},
-	{"R_RAM_ADDR0",		0x08},
-	{"R_RAM_ADDR1",		0x09},
-	{"R_RAM_ADDR2",		0x0A},
-	{"R_FIRST_FIFO",	0x0B},
-	{"R_RAM_SZ",		0x0C},
-	{"R_FIFO_MD",		0x0D},
-	{"R_INC_RES_FIFO",	0x0E},
-	{"R_FIFO / R_FSM_IDX",	0x0F},
-	{"R_SLOT",		0x10},
-	{"R_IRQMSK_MISC",	0x11},
-	{"R_SCI_MSK",		0x12},
-	{"R_IRQ_CTRL",		0x13},
-	{"R_PCM_MD0",		0x14},
-	{"R_0x15",		0x15},
-	{"R_ST_SEL",		0x16},
-	{"R_ST_SYNC",		0x17},
-	{"R_CONF_EN",		0x18},
-	{"R_TI_WD",		0x1A},
-	{"R_BERT_WD_MD",	0x1B},
-	{"R_DTMF",		0x1C},
-	{"R_DTMF_N",		0x1D},
-	{"R_E1_XX_STA",		0x20},
-	{"R_LOS0",		0x22},
-	{"R_LOS1",		0x23},
-	{"R_RX0",		0x24},
-	{"R_RX_FR0",		0x25},
-	{"R_RX_FR1",		0x26},
-	{"R_TX0",		0x28},
-	{"R_TX1",		0x29},
-	{"R_TX_FR0",		0x2C},
-	{"R_TX_FR1",		0x2D},
-	{"R_TX_FR2",		0x2E},
-	{"R_JATT_ATT",		0x2F},
-	{"A_ST_xx_STA/R_RX_OFF", 0x30},
-	{"A_ST_CTRL0/R_SYNC_OUT", 0x31},
-	{"A_ST_CTRL1",		0x32},
-	{"A_ST_CTRL2",		0x33},
-	{"A_ST_SQ_WR",		0x34},
-	{"R_TX_OFF",		0x34},
-	{"R_SYNC_CTRL",		0x35},
-	{"A_ST_CLK_DLY",	0x37},
-	{"R_PWM0",		0x38},
-	{"R_PWM1",		0x39},
-	{"A_ST_B1_TX",		0x3C},
-	{"A_ST_B2_TX",		0x3D},
-	{"A_ST_D_TX",		0x3E},
-	{"R_GPIO_OUT0",		0x40},
-	{"R_GPIO_OUT1",		0x41},
-	{"R_GPIO_EN0",		0x42},
-	{"R_GPIO_EN1",		0x43},
-	{"R_GPIO_SEL",		0x44},
-	{"R_BRG_CTRL",		0x45},
-	{"R_PWM_MD",		0x46},
-	{"R_BRG_MD",		0x47},
-	{"R_BRG_TIM0",		0x48},
-	{"R_BRG_TIM1",		0x49},
-	{"R_BRG_TIM2",		0x4A},
-	{"R_BRG_TIM3",		0x4B},
-	{"R_BRG_TIM_SEL01",	0x4C},
-	{"R_BRG_TIM_SEL23",	0x4D},
-	{"R_BRG_TIM_SEL45",	0x4E},
-	{"R_BRG_TIM_SEL67",	0x4F},
-	{"A_FIFO_DATA0-2",	0x80},
-	{"A_FIFO_DATA0-2_NOINC", 0x84},
-	{"R_RAM_DATA",		0xC0},
-	{"A_SL_CFG",		0xD0},
-	{"A_CONF",		0xD1},
-	{"A_CH_MSK",		0xF4},
-	{"A_CON_HDLC",		0xFA},
-	{"A_SUBCH_CFG",		0xFB},
-	{"A_CHANNEL",		0xFC},
-	{"A_FIFO_SEQ",		0xFD},
-	{"A_IRQ_MSK",		0xFF},
-	{NULL, 0},
-
-	/* read registers */
-	{"A_Z1",		0x04},
-	{"A_Z1H",		0x05},
-	{"A_Z2",		0x06},
-	{"A_Z2H",		0x07},
-	{"A_F1",		0x0C},
-	{"A_F2",		0x0D},
-	{"R_IRQ_OVIEW",		0x10},
-	{"R_IRQ_MISC",		0x11},
-	{"R_IRQ_STATECH",	0x12},
-	{"R_CONF_OFLOW",	0x14},
-	{"R_RAM_USE",		0x15},
-	{"R_CHIP_ID",		0x16},
-	{"R_BERT_STA",		0x17},
-	{"R_F0_CNTL",		0x18},
-	{"R_F0_CNTH",		0x19},
-	{"R_BERT_ECL",		0x1A},
-	{"R_BERT_ECH",		0x1B},
-	{"R_STATUS",		0x1C},
-	{"R_CHIP_RV",		0x1F},
-	{"R_STATE",		0x20},
-	{"R_SYNC_STA",		0x24},
-	{"R_RX_SL0_0",		0x25},
-	{"R_RX_SL0_1",		0x26},
-	{"R_RX_SL0_2",		0x27},
-	{"R_JATT_DIR",		0x2b},
-	{"R_SLIP",		0x2c},
-	{"A_ST_RD_STA",		0x30},
-	{"R_FAS_ECL",		0x30},
-	{"R_FAS_ECH",		0x31},
-	{"R_VIO_ECL",		0x32},
-	{"R_VIO_ECH",		0x33},
-	{"R_CRC_ECL / A_ST_SQ_RD", 0x34},
-	{"R_CRC_ECH",		0x35},
-	{"R_E_ECL",		0x36},
-	{"R_E_ECH",		0x37},
-	{"R_SA6_SA13_ECL",	0x38},
-	{"R_SA6_SA13_ECH",	0x39},
-	{"R_SA6_SA23_ECL",	0x3A},
-	{"R_SA6_SA23_ECH",	0x3B},
-	{"A_ST_B1_RX",		0x3C},
-	{"A_ST_B2_RX",		0x3D},
-	{"A_ST_D_RX",		0x3E},
-	{"A_ST_E_RX",		0x3F},
-	{"R_GPIO_IN0",		0x40},
-	{"R_GPIO_IN1",		0x41},
-	{"R_GPI_IN0",		0x44},
-	{"R_GPI_IN1",		0x45},
-	{"R_GPI_IN2",		0x46},
-	{"R_GPI_IN3",		0x47},
-	{"A_FIFO_DATA0-2",	0x80},
-	{"A_FIFO_DATA0-2_NOINC", 0x84},
-	{"R_INT_DATA",		0x88},
-	{"R_RAM_DATA",		0xC0},
-	{"R_IRQ_FIFO_BL0",	0xC8},
-	{"R_IRQ_FIFO_BL1",	0xC9},
-	{"R_IRQ_FIFO_BL2",	0xCA},
-	{"R_IRQ_FIFO_BL3",	0xCB},
-	{"R_IRQ_FIFO_BL4",	0xCC},
-	{"R_IRQ_FIFO_BL5",	0xCD},
-	{"R_IRQ_FIFO_BL6",	0xCE},
-	{"R_IRQ_FIFO_BL7",	0xCF},
-};
-#endif /* HFC_REGISTER_DEBUG */
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h b/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h
deleted file mode 100644
index 448ded8f9d24..000000000000
--- a/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * For License see notice in hfc_multi.c
- *
- * special IO and init functions for the embedded XHFC board
- * from Speech Design
- *
- */
-
-#include <asm/cpm1.h>
-
-/* Change this to the value used by your board */
-#ifndef IMAP_ADDR
-#define IMAP_ADDR	0xFFF00000
-#endif
-
-static void
-#ifdef HFC_REGISTER_DEBUG
-HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val,
-	       const char *function, int line)
-#else
-	HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val)
-#endif
-{
-	hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
-	writeb(reg, hc->xhfc_memaddr);
-	hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
-	writeb(val, hc->xhfc_memdata);
-}
-static u_char
-#ifdef HFC_REGISTER_DEBUG
-HFC_inb_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line)
-#else
-	HFC_inb_embsd(struct hfc_multi *hc, u_char reg)
-#endif
-{
-	hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
-	writeb(reg, hc->xhfc_memaddr);
-	hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
-	return readb(hc->xhfc_memdata);
-}
-static u_short
-#ifdef HFC_REGISTER_DEBUG
-HFC_inw_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line)
-#else
-	HFC_inw_embsd(struct hfc_multi *hc, u_char reg)
-#endif
-{
-	hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
-	writeb(reg, hc->xhfc_memaddr);
-	hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
-	return readb(hc->xhfc_memdata);
-}
-static void
-#ifdef HFC_REGISTER_DEBUG
-HFC_wait_embsd(struct hfc_multi *hc, const char *function, int line)
-#else
-	HFC_wait_embsd(struct hfc_multi *hc)
-#endif
-{
-	hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
-	writeb(R_STATUS, hc->xhfc_memaddr);
-	hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
-	while (readb(hc->xhfc_memdata) & V_BUSY)
-		cpu_relax();
-}
-
-/* write fifo data (EMBSD) */
-void
-write_fifo_embsd(struct hfc_multi *hc, u_char *data, int len)
-{
-	hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
-	*hc->xhfc_memaddr = A_FIFO_DATA0;
-	hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
-	while (len) {
-		*hc->xhfc_memdata = *data;
-		data++;
-		len--;
-	}
-}
-
-/* read fifo data (EMBSD) */
-void
-read_fifo_embsd(struct hfc_multi *hc, u_char *data, int len)
-{
-	hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
-	*hc->xhfc_memaddr = A_FIFO_DATA0;
-	hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
-	while (len) {
-		*data = (u_char)(*hc->xhfc_memdata);
-		data++;
-		len--;
-	}
-}
-
-static int
-setup_embedded(struct hfc_multi *hc, struct hm_map *m)
-{
-	printk(KERN_INFO
-	       "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",
-	       m->vendor_name, m->card_name, m->clock2 ? "double" : "normal");
-
-	hc->pci_dev = NULL;
-	if (m->clock2)
-		test_and_set_bit(HFC_CHIP_CLOCK2, &hc->chip);
-
-	hc->leds = m->leds;
-	hc->ledstate = 0xAFFEAFFE;
-	hc->opticalsupport = m->opticalsupport;
-
-	hc->pci_iobase = 0;
-	hc->pci_membase = 0;
-	hc->xhfc_membase = NULL;
-	hc->xhfc_memaddr = NULL;
-	hc->xhfc_memdata = NULL;
-
-	/* set memory access methods */
-	if (m->io_mode) /* use mode from card config */
-		hc->io_mode = m->io_mode;
-	switch (hc->io_mode) {
-	case HFC_IO_MODE_EMBSD:
-		test_and_set_bit(HFC_CHIP_EMBSD, &hc->chip);
-		hc->slots = 128; /* required */
-		hc->HFC_outb = HFC_outb_embsd;
-		hc->HFC_inb = HFC_inb_embsd;
-		hc->HFC_inw = HFC_inw_embsd;
-		hc->HFC_wait = HFC_wait_embsd;
-		hc->read_fifo = read_fifo_embsd;
-		hc->write_fifo = write_fifo_embsd;
-		hc->xhfc_origmembase = XHFC_MEMBASE + XHFC_OFFSET * hc->id;
-		hc->xhfc_membase = (u_char *)ioremap(hc->xhfc_origmembase,
-						     XHFC_MEMSIZE);
-		if (!hc->xhfc_membase) {
-			printk(KERN_WARNING
-			       "HFC-multi: failed to remap xhfc address space. "
-			       "(internal error)\n");
-			return -EIO;
-		}
-		hc->xhfc_memaddr = (u_long *)(hc->xhfc_membase + 4);
-		hc->xhfc_memdata = (u_long *)(hc->xhfc_membase);
-		printk(KERN_INFO
-		       "HFC-multi: xhfc_membase:%#lx xhfc_origmembase:%#lx "
-		       "xhfc_memaddr:%#lx xhfc_memdata:%#lx\n",
-		       (u_long)hc->xhfc_membase, hc->xhfc_origmembase,
-		       (u_long)hc->xhfc_memaddr, (u_long)hc->xhfc_memdata);
-		break;
-	default:
-		printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n");
-		return -EIO;
-	}
-
-	/* Prepare the MPC8XX PortA 10 as output (address/data selector) */
-	hc->immap = (struct immap *)(IMAP_ADDR);
-	hc->immap->im_ioport.iop_papar &= ~(PA_XHFC_A0);
-	hc->immap->im_ioport.iop_paodr &= ~(PA_XHFC_A0);
-	hc->immap->im_ioport.iop_padir |=   PA_XHFC_A0;
-
-	/* Prepare the MPC8xx PortB __X__ as input (ISDN__X__IRQ) */
-	hc->pb_irqmsk = (PB_XHFC_IRQ1 << hc->id);
-	hc->immap->im_cpm.cp_pbpar &= ~(hc->pb_irqmsk);
-	hc->immap->im_cpm.cp_pbodr &= ~(hc->pb_irqmsk);
-	hc->immap->im_cpm.cp_pbdir &= ~(hc->pb_irqmsk);
-
-	/* At this point the needed config is done */
-	/* fifos are still not enabled */
-	return 0;
-}
diff --git a/drivers/isdn/hardware/mISDN/hfc_pci.h b/drivers/isdn/hardware/mISDN/hfc_pci.h
deleted file mode 100644
index a0e4806c11fa..000000000000
--- a/drivers/isdn/hardware/mISDN/hfc_pci.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- *  specific defines for CCD's HFC 2BDS0 PCI chips
- *
- * Author     Werner Cornelius (werner@isdn4linux.de)
- *
- * Copyright 1999  by Werner Cornelius (werner@isdn4linux.de)
- */
-
-/*
- * thresholds for transparent B-channel mode
- * change mask and threshold simultaneously
- */
-#define HFCPCI_BTRANS_THRESHOLD 128
-#define HFCPCI_FILLEMPTY	64
-#define HFCPCI_BTRANS_THRESMASK 0x00
-
-/* defines for PCI config */
-#define PCI_ENA_MEMIO		0x02
-#define PCI_ENA_MASTER		0x04
-
-/* GCI/IOM bus monitor registers */
-#define HCFPCI_C_I		0x08
-#define HFCPCI_TRxR		0x0C
-#define HFCPCI_MON1_D		0x28
-#define HFCPCI_MON2_D		0x2C
-
-/* GCI/IOM bus timeslot registers */
-#define HFCPCI_B1_SSL		0x80
-#define HFCPCI_B2_SSL		0x84
-#define HFCPCI_AUX1_SSL		0x88
-#define HFCPCI_AUX2_SSL		0x8C
-#define HFCPCI_B1_RSL		0x90
-#define HFCPCI_B2_RSL		0x94
-#define HFCPCI_AUX1_RSL		0x98
-#define HFCPCI_AUX2_RSL		0x9C
-
-/* GCI/IOM bus data registers */
-#define HFCPCI_B1_D		0xA0
-#define HFCPCI_B2_D		0xA4
-#define HFCPCI_AUX1_D		0xA8
-#define HFCPCI_AUX2_D		0xAC
-
-/* GCI/IOM bus configuration registers */
-#define HFCPCI_MST_EMOD		0xB4
-#define HFCPCI_MST_MODE		0xB8
-#define HFCPCI_CONNECT		0xBC
-
-
-/* Interrupt and status registers */
-#define HFCPCI_FIFO_EN		0x44
-#define HFCPCI_TRM		0x48
-#define HFCPCI_B_MODE		0x4C
-#define HFCPCI_CHIP_ID		0x58
-#define HFCPCI_CIRM		0x60
-#define HFCPCI_CTMT		0x64
-#define HFCPCI_INT_M1		0x68
-#define HFCPCI_INT_M2		0x6C
-#define HFCPCI_INT_S1		0x78
-#define HFCPCI_INT_S2		0x7C
-#define HFCPCI_STATUS		0x70
-
-/* S/T section registers */
-#define HFCPCI_STATES		0xC0
-#define HFCPCI_SCTRL		0xC4
-#define HFCPCI_SCTRL_E		0xC8
-#define HFCPCI_SCTRL_R		0xCC
-#define HFCPCI_SQ		0xD0
-#define HFCPCI_CLKDEL		0xDC
-#define HFCPCI_B1_REC		0xF0
-#define HFCPCI_B1_SEND		0xF0
-#define HFCPCI_B2_REC		0xF4
-#define HFCPCI_B2_SEND		0xF4
-#define HFCPCI_D_REC		0xF8
-#define HFCPCI_D_SEND		0xF8
-#define HFCPCI_E_REC		0xFC
-
-
-/* bits in status register (READ) */
-#define HFCPCI_PCI_PROC		0x02
-#define HFCPCI_NBUSY		0x04
-#define HFCPCI_TIMER_ELAP	0x10
-#define HFCPCI_STATINT		0x20
-#define HFCPCI_FRAMEINT		0x40
-#define HFCPCI_ANYINT		0x80
-
-/* bits in CTMT (Write) */
-#define HFCPCI_CLTIMER		0x80
-#define HFCPCI_TIM3_125		0x04
-#define HFCPCI_TIM25		0x10
-#define HFCPCI_TIM50		0x14
-#define HFCPCI_TIM400		0x18
-#define HFCPCI_TIM800		0x1C
-#define HFCPCI_AUTO_TIMER	0x20
-#define HFCPCI_TRANSB2		0x02
-#define HFCPCI_TRANSB1		0x01
-
-/* bits in CIRM (Write) */
-#define HFCPCI_AUX_MSK		0x07
-#define HFCPCI_RESET		0x08
-#define HFCPCI_B1_REV		0x40
-#define HFCPCI_B2_REV		0x80
-
-/* bits in INT_M1 and INT_S1 */
-#define HFCPCI_INTS_B1TRANS	0x01
-#define HFCPCI_INTS_B2TRANS	0x02
-#define HFCPCI_INTS_DTRANS	0x04
-#define HFCPCI_INTS_B1REC	0x08
-#define HFCPCI_INTS_B2REC	0x10
-#define HFCPCI_INTS_DREC	0x20
-#define HFCPCI_INTS_L1STATE	0x40
-#define HFCPCI_INTS_TIMER	0x80
-
-/* bits in INT_M2 */
-#define HFCPCI_PROC_TRANS	0x01
-#define HFCPCI_GCI_I_CHG	0x02
-#define HFCPCI_GCI_MON_REC	0x04
-#define HFCPCI_IRQ_ENABLE	0x08
-#define HFCPCI_PMESEL		0x80
-
-/* bits in STATES */
-#define HFCPCI_STATE_MSK	0x0F
-#define HFCPCI_LOAD_STATE	0x10
-#define HFCPCI_ACTIVATE		0x20
-#define HFCPCI_DO_ACTION	0x40
-#define HFCPCI_NT_G2_G3		0x80
-
-/* bits in HFCD_MST_MODE */
-#define HFCPCI_MASTER		0x01
-#define HFCPCI_SLAVE		0x00
-#define HFCPCI_F0IO_POSITIV	0x02
-#define HFCPCI_F0_NEGATIV	0x04
-#define HFCPCI_F0_2C4		0x08
-/* remaining bits are for codecs control */
-
-/* bits in HFCD_SCTRL */
-#define SCTRL_B1_ENA		0x01
-#define SCTRL_B2_ENA		0x02
-#define SCTRL_MODE_TE		0x00
-#define SCTRL_MODE_NT		0x04
-#define SCTRL_LOW_PRIO		0x08
-#define SCTRL_SQ_ENA		0x10
-#define SCTRL_TEST		0x20
-#define SCTRL_NONE_CAP		0x40
-#define SCTRL_PWR_DOWN		0x80
-
-/* bits in SCTRL_E  */
-#define HFCPCI_AUTO_AWAKE	0x01
-#define HFCPCI_DBIT_1		0x04
-#define HFCPCI_IGNORE_COL	0x08
-#define HFCPCI_CHG_B1_B2	0x80
-
-/* bits in FIFO_EN register */
-#define HFCPCI_FIFOEN_B1	0x03
-#define HFCPCI_FIFOEN_B2	0x0C
-#define HFCPCI_FIFOEN_DTX	0x10
-#define HFCPCI_FIFOEN_B1TX	0x01
-#define HFCPCI_FIFOEN_B1RX	0x02
-#define HFCPCI_FIFOEN_B2TX	0x04
-#define HFCPCI_FIFOEN_B2RX	0x08
-
-
-/* definitions of fifo memory area */
-#define MAX_D_FRAMES 15
-#define MAX_B_FRAMES 31
-#define B_SUB_VAL    0x200
-#define B_FIFO_SIZE  (0x2000 - B_SUB_VAL)
-#define D_FIFO_SIZE  512
-#define D_FREG_MASK  0xF
-
-struct zt {
-	__le16 z1;  /* Z1 pointer 16 Bit */
-	__le16 z2;  /* Z2 pointer 16 Bit */
-};
-
-struct dfifo {
-	u_char data[D_FIFO_SIZE]; /* FIFO data space */
-	u_char fill1[0x20A0 - D_FIFO_SIZE]; /* reserved, do not use */
-	u_char f1, f2; /* f pointers */
-	u_char fill2[0x20C0 - 0x20A2]; /* reserved, do not use */
-	/* mask index with D_FREG_MASK for access */
-	struct zt za[MAX_D_FRAMES + 1];
-	u_char fill3[0x4000 - 0x2100]; /* align 16K */
-};
-
-struct bzfifo {
-	struct zt	za[MAX_B_FRAMES + 1]; /* only range 0x0..0x1F allowed */
-	u_char		f1, f2; /* f pointers */
-	u_char		fill[0x2100 - 0x2082]; /* alignment */
-};
-
-
-union fifo_area {
-	struct {
-		struct dfifo d_tx; /* D-send channel */
-		struct dfifo d_rx; /* D-receive channel */
-	} d_chan;
-	struct {
-		u_char		fill1[0x200];
-		u_char		txdat_b1[B_FIFO_SIZE];
-		struct bzfifo	txbz_b1;
-		struct bzfifo	txbz_b2;
-		u_char		txdat_b2[B_FIFO_SIZE];
-		u_char		fill2[D_FIFO_SIZE];
-		u_char		rxdat_b1[B_FIFO_SIZE];
-		struct bzfifo	rxbz_b1;
-		struct bzfifo	rxbz_b2;
-		u_char rxdat_b2[B_FIFO_SIZE];
-	} b_chans;
-	u_char fill[32768];
-};
-
-#define Write_hfc(a, b, c) (writeb(c, (a->hw.pci_io) + b))
-#define Read_hfc(a, b) (readb((a->hw.pci_io) + b))
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.h b/drivers/isdn/hardware/mISDN/hfcsusb.h
deleted file mode 100644
index 7e2bc5068019..000000000000
--- a/drivers/isdn/hardware/mISDN/hfcsusb.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * hfcsusb.h, HFC-S USB mISDN driver
- */
-
-#ifndef __HFCSUSB_H__
-#define __HFCSUSB_H__
-
-
-#define DRIVER_NAME "HFC-S_USB"
-
-#define DBG_HFC_CALL_TRACE	0x00010000
-#define DBG_HFC_FIFO_VERBOSE	0x00020000
-#define DBG_HFC_USB_VERBOSE	0x00100000
-#define DBG_HFC_URB_INFO	0x00200000
-#define DBG_HFC_URB_ERROR	0x00400000
-
-#define DEFAULT_TRANSP_BURST_SZ 128
-
-#define HFC_CTRL_TIMEOUT	20	/* 5ms timeout writing/reading regs */
-#define CLKDEL_TE		0x0f	/* CLKDEL in TE mode */
-#define CLKDEL_NT		0x6c	/* CLKDEL in NT mode */
-
-/* hfcsusb Layer1 commands */
-#define HFC_L1_ACTIVATE_TE		1
-#define HFC_L1_ACTIVATE_NT		2
-#define HFC_L1_DEACTIVATE_NT		3
-#define HFC_L1_FORCE_DEACTIVATE_TE	4
-
-/* cmd FLAGS in HFCUSB_STATES register */
-#define HFCUSB_LOAD_STATE	0x10
-#define HFCUSB_ACTIVATE		0x20
-#define HFCUSB_DO_ACTION	0x40
-#define HFCUSB_NT_G2_G3		0x80
-
-/* timers */
-#define NT_ACTIVATION_TIMER	0x01	/* enables NT mode activation Timer */
-#define NT_T1_COUNT		10
-
-#define MAX_BCH_SIZE		2048	/* allowed B-channel packet size */
-
-#define HFCUSB_RX_THRESHOLD	64	/* threshold for fifo report bit rx */
-#define HFCUSB_TX_THRESHOLD	96	/* threshold for fifo report bit tx */
-
-#define HFCUSB_CHIP_ID		0x16	/* Chip ID register index */
-#define HFCUSB_CIRM		0x00	/* cirm register index */
-#define HFCUSB_USB_SIZE		0x07	/* int length register */
-#define HFCUSB_USB_SIZE_I	0x06	/* iso length register */
-#define HFCUSB_F_CROSS		0x0b	/* bit order register */
-#define HFCUSB_CLKDEL		0x37	/* bit delay register */
-#define HFCUSB_CON_HDLC		0xfa	/* channel connect register */
-#define HFCUSB_HDLC_PAR		0xfb
-#define HFCUSB_SCTRL		0x31	/* S-bus control register (tx) */
-#define HFCUSB_SCTRL_E		0x32	/* same for E and special funcs */
-#define HFCUSB_SCTRL_R		0x33	/* S-bus control register (rx) */
-#define HFCUSB_F_THRES		0x0c	/* threshold register */
-#define HFCUSB_FIFO		0x0f	/* fifo select register */
-#define HFCUSB_F_USAGE		0x1a	/* fifo usage register */
-#define HFCUSB_MST_MODE0	0x14
-#define HFCUSB_MST_MODE1	0x15
-#define HFCUSB_P_DATA		0x1f
-#define HFCUSB_INC_RES_F	0x0e
-#define HFCUSB_B1_SSL		0x20
-#define HFCUSB_B2_SSL		0x21
-#define HFCUSB_B1_RSL		0x24
-#define HFCUSB_B2_RSL		0x25
-#define HFCUSB_STATES		0x30
-
-
-#define HFCUSB_CHIPID		0x40	/* ID value of HFC-S USB */
-
-/* fifo registers */
-#define HFCUSB_NUM_FIFOS	8	/* maximum number of fifos */
-#define HFCUSB_B1_TX		0	/* index for B1 transmit bulk/int */
-#define HFCUSB_B1_RX		1	/* index for B1 receive bulk/int */
-#define HFCUSB_B2_TX		2
-#define HFCUSB_B2_RX		3
-#define HFCUSB_D_TX		4
-#define HFCUSB_D_RX		5
-#define HFCUSB_PCM_TX		6
-#define HFCUSB_PCM_RX		7
-
-
-#define USB_INT		0
-#define USB_BULK	1
-#define USB_ISOC	2
-
-#define ISOC_PACKETS_D	8
-#define ISOC_PACKETS_B	8
-#define ISO_BUFFER_SIZE	128
-
-/* defines how much ISO packets are handled in one URB */
-static int iso_packets[8] =
-{ ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B,
-  ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D
-};
-
-
-/* Fifo flow Control for TX ISO */
-#define SINK_MAX	68
-#define SINK_MIN	48
-#define SINK_DMIN	12
-#define SINK_DMAX	18
-#define BITLINE_INF	(-96 * 8)
-
-/* HFC-S USB register access by Control-URSs */
-#define write_reg_atomic(a, b, c)					\
-	usb_control_msg((a)->dev, (a)->ctrl_out_pipe, 0, 0x40, (c), (b), \
-			0, 0, HFC_CTRL_TIMEOUT)
-#define read_reg_atomic(a, b, c)					\
-	usb_control_msg((a)->dev, (a)->ctrl_in_pipe, 1, 0xC0, 0, (b), (c), \
-			1, HFC_CTRL_TIMEOUT)
-#define HFC_CTRL_BUFSIZE 64
-
-struct ctrl_buf {
-	__u8 hfcs_reg;		/* register number */
-	__u8 reg_val;		/* value to be written (or read) */
-};
-
-/*
- * URB error codes
- * Used to represent a list of values and their respective symbolic names
- */
-struct hfcusb_symbolic_list {
-	const int num;
-	const char *name;
-};
-
-static struct hfcusb_symbolic_list urb_errlist[] = {
-	{-ENOMEM, "No memory for allocation of internal structures"},
-	{-ENOSPC, "The host controller's bandwidth is already consumed"},
-	{-ENOENT, "URB was canceled by unlink_urb"},
-	{-EXDEV, "ISO transfer only partially completed"},
-	{-EAGAIN, "Too match scheduled for the future"},
-	{-ENXIO, "URB already queued"},
-	{-EFBIG, "Too much ISO frames requested"},
-	{-ENOSR, "Buffer error (overrun)"},
-	{-EPIPE, "Specified endpoint is stalled (device not responding)"},
-	{-EOVERFLOW, "Babble (bad cable?)"},
-	{-EPROTO, "Bit-stuff error (bad cable?)"},
-	{-EILSEQ, "CRC/Timeout"},
-	{-ETIMEDOUT, "NAK (device does not respond)"},
-	{-ESHUTDOWN, "Device unplugged"},
-	{-1, NULL}
-};
-
-static inline const char *
-symbolic(struct hfcusb_symbolic_list list[], const int num)
-{
-	int i;
-	for (i = 0; list[i].name != NULL; i++)
-		if (list[i].num == num)
-			return list[i].name;
-	return "<unknown USB Error>";
-}
-
-/* USB descriptor need to contain one of the following EndPoint combination: */
-#define CNF_4INT3ISO	1	/* 4 INT IN, 3 ISO OUT */
-#define CNF_3INT3ISO	2	/* 3 INT IN, 3 ISO OUT */
-#define CNF_4ISO3ISO	3	/* 4 ISO IN, 3 ISO OUT */
-#define CNF_3ISO3ISO	4	/* 3 ISO IN, 3 ISO OUT */
-
-#define EP_NUL 1	/* Endpoint at this position not allowed */
-#define EP_NOP 2	/* all type of endpoints allowed at this position */
-#define EP_ISO 3	/* Isochron endpoint mandatory at this position */
-#define EP_BLK 4	/* Bulk endpoint mandatory at this position */
-#define EP_INT 5	/* Interrupt endpoint mandatory at this position */
-
-#define HFC_CHAN_B1	0
-#define HFC_CHAN_B2	1
-#define HFC_CHAN_D	2
-#define HFC_CHAN_E	3
-
-
-/*
- * List of all supported endpoint configuration sets, used to find the
- * best matching endpoint configuration within a device's USB descriptor.
- * We need at least 3 RX endpoints, and 3 TX endpoints, either
- * INT-in and ISO-out, or ISO-in and ISO-out)
- * with 4 RX endpoints even E-Channel logging is possible
- */
-static int
-validconf[][19] = {
-	/* INT in, ISO out config */
-	{EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT,
-	 EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_NUL, EP_NUL,
-	 CNF_4INT3ISO, 2, 1},
-	{EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_NUL,
-	 EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_NUL, EP_NUL,
-	 CNF_3INT3ISO, 2, 0},
-	/* ISO in, ISO out config */
-	{EP_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP,
-	 EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_NOP, EP_ISO,
-	 CNF_4ISO3ISO, 2, 1},
-	{EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL,
-	 EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_NUL, EP_NUL,
-	 CNF_3ISO3ISO, 2, 0},
-	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* EOL element */
-};
-
-/* string description of chosen config */
-static char *conf_str[] = {
-	"4 Interrupt IN + 3 Isochron OUT",
-	"3 Interrupt IN + 3 Isochron OUT",
-	"4 Isochron IN + 3 Isochron OUT",
-	"3 Isochron IN + 3 Isochron OUT"
-};
-
-
-#define LED_OFF		0	/* no LED support */
-#define LED_SCHEME1	1	/* LED standard scheme */
-#define LED_SCHEME2	2	/* not used yet... */
-
-#define LED_POWER_ON	1
-#define LED_POWER_OFF	2
-#define LED_S0_ON	3
-#define LED_S0_OFF	4
-#define LED_B1_ON	5
-#define LED_B1_OFF	6
-#define LED_B1_DATA	7
-#define LED_B2_ON	8
-#define LED_B2_OFF	9
-#define LED_B2_DATA	10
-
-#define LED_NORMAL	0	/* LEDs are normal */
-#define LED_INVERTED	1	/* LEDs are inverted */
-
-/* time in ms to perform a Flashing LED when B-Channel has traffic */
-#define LED_TIME      250
-
-
-
-struct hfcsusb;
-struct usb_fifo;
-
-/* structure defining input+output fifos (interrupt/bulk mode) */
-struct iso_urb {
-	struct urb *urb;
-	__u8 buffer[ISO_BUFFER_SIZE];	/* buffer rx/tx USB URB data */
-	struct usb_fifo *owner_fifo;	/* pointer to owner fifo */
-	__u8 indx; /* Fifos's ISO double buffer 0 or 1 ? */
-#ifdef ISO_FRAME_START_DEBUG
-	int start_frames[ISO_FRAME_START_RING_COUNT];
-	__u8 iso_frm_strt_pos; /* index in start_frame[] */
-#endif
-};
-
-struct usb_fifo {
-	int fifonum;		/* fifo index attached to this structure */
-	int active;		/* fifo is currently active */
-	struct hfcsusb *hw;	/* pointer to main structure */
-	int pipe;		/* address of endpoint */
-	__u8 usb_packet_maxlen;	/* maximum length for usb transfer */
-	unsigned int max_size;	/* maximum size of receive/send packet */
-	__u8 intervall;		/* interrupt interval */
-	struct urb *urb;	/* transfer structure for usb routines */
-	__u8 buffer[128];	/* buffer USB INT OUT URB data */
-	int bit_line;		/* how much bits are in the fifo? */
-
-	__u8 usb_transfer_mode; /* switched between ISO and INT */
-	struct iso_urb	iso[2]; /* two urbs to have one always
-				   one pending */
-
-	struct dchannel *dch;	/* link to hfcsusb_t->dch */
-	struct bchannel *bch;	/* link to hfcsusb_t->bch */
-	struct dchannel *ech;	/* link to hfcsusb_t->ech, TODO: E-CHANNEL */
-	int last_urblen;	/* remember length of last packet */
-	__u8 stop_gracefull;	/* stops URB retransmission */
-};
-
-struct hfcsusb {
-	struct list_head	list;
-	struct dchannel		dch;
-	struct bchannel		bch[2];
-	struct dchannel		ech; /* TODO : wait for struct echannel ;) */
-
-	struct usb_device	*dev;		/* our device */
-	struct usb_interface	*intf;		/* used interface */
-	int			if_used;	/* used interface number */
-	int			alt_used;	/* used alternate config */
-	int			cfg_used;	/* configuration index used */
-	int			vend_idx;	/* index in hfcsusb_idtab */
-	int			packet_size;
-	int			iso_packet_size;
-	struct usb_fifo		fifos[HFCUSB_NUM_FIFOS];
-
-	/* control pipe background handling */
-	struct ctrl_buf		ctrl_buff[HFC_CTRL_BUFSIZE];
-	int			ctrl_in_idx, ctrl_out_idx, ctrl_cnt;
-	struct urb		*ctrl_urb;
-	struct usb_ctrlrequest	ctrl_write;
-	struct usb_ctrlrequest	ctrl_read;
-	int			ctrl_paksize;
-	int			ctrl_in_pipe, ctrl_out_pipe;
-	spinlock_t		ctrl_lock; /* lock for ctrl */
-	spinlock_t              lock;
-
-	__u8			threshold_mask;
-	__u8			led_state;
-
-	__u8			protocol;
-	int			nt_timer;
-	int			open;
-	__u8			timers;
-	__u8			initdone;
-	char			name[MISDN_MAX_IDLEN];
-};
-
-/* private vendor specific data */
-struct hfcsusb_vdata {
-	__u8		led_scheme;  /* led display scheme */
-	signed short	led_bits[8]; /* array of 8 possible LED bitmask */
-	char		*vend_name;  /* device name */
-};
-
-
-#define HFC_MAX_TE_LAYER1_STATE 8
-#define HFC_MAX_NT_LAYER1_STATE 4
-
-static const char *HFC_TE_LAYER1_STATES[HFC_MAX_TE_LAYER1_STATE + 1] = {
-	"TE F0 - Reset",
-	"TE F1 - Reset",
-	"TE F2 - Sensing",
-	"TE F3 - Deactivated",
-	"TE F4 - Awaiting signal",
-	"TE F5 - Identifying input",
-	"TE F6 - Synchronized",
-	"TE F7 - Activated",
-	"TE F8 - Lost framing",
-};
-
-static const char *HFC_NT_LAYER1_STATES[HFC_MAX_NT_LAYER1_STATE + 1] = {
-	"NT G0 - Reset",
-	"NT G1 - Deactive",
-	"NT G2 - Pending activation",
-	"NT G3 - Active",
-	"NT G4 - Pending deactivation",
-};
-
-/* supported devices */
-static const struct usb_device_id hfcsusb_idtab[] = {
-	{
-		USB_DEVICE(0x0959, 0x2bd0),
-		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			{LED_OFF, {4, 0, 2, 1},
-					"ISDN USB TA (Cologne Chip HFC-S USB based)"}),
-	},
-	{
-		USB_DEVICE(0x0675, 0x1688),
-		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			{LED_SCHEME1, {1, 2, 0, 0},
-					"DrayTek miniVigor 128 USB ISDN TA"}),
-	},
-	{
-		USB_DEVICE(0x07b0, 0x0007),
-		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			{LED_SCHEME1, {0x80, -64, -32, -16},
-					"Billion tiny USB ISDN TA 128"}),
-	},
-	{
-		USB_DEVICE(0x0742, 0x2008),
-		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			{LED_SCHEME1, {4, 0, 2, 1},
-					"Stollmann USB TA"}),
-	},
-	{
-		USB_DEVICE(0x0742, 0x2009),
-		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			{LED_SCHEME1, {4, 0, 2, 1},
-					"Aceex USB ISDN TA"}),
-	},
-	{
-		USB_DEVICE(0x0742, 0x200A),
-		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			{LED_SCHEME1, {4, 0, 2, 1},
-					"OEM USB ISDN TA"}),
-	},
-	{
-		USB_DEVICE(0x08e3, 0x0301),
-		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			{LED_SCHEME1, {2, 0, 1, 4},
-					"Olitec USB RNIS"}),
-	},
-	{
-		USB_DEVICE(0x07fa, 0x0846),
-		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			{LED_SCHEME1, {0x80, -64, -32, -16},
-					"Bewan Modem RNIS USB"}),
-	},
-	{
-		USB_DEVICE(0x07fa, 0x0847),
-		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			{LED_SCHEME1, {0x80, -64, -32, -16},
-					"Djinn Numeris USB"}),
-	},
-	{
-		USB_DEVICE(0x07b0, 0x0006),
-		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			{LED_SCHEME1, {0x80, -64, -32, -16},
-					"Twister ISDN TA"}),
-	},
-	{
-		USB_DEVICE(0x071d, 0x1005),
-		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			{LED_SCHEME1, {0x02, 0, 0x01, 0x04},
-					"Eicon DIVA USB 4.0"}),
-	},
-	{
-		USB_DEVICE(0x0586, 0x0102),
-		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			{LED_SCHEME1, {0x88, -64, -32, -16},
-					"ZyXEL OMNI.NET USB II"}),
-	},
-	{
-		USB_DEVICE(0x1ae7, 0x0525),
-		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			{LED_SCHEME1, {0x88, -64, -32, -16},
-					"X-Tensions USB ISDN TA XC-525"}),
-	},
-	{ }
-};
-
-MODULE_DEVICE_TABLE(usb, hfcsusb_idtab);
-
-#endif	/* __HFCSUSB_H__ */
diff --git a/drivers/isdn/hardware/mISDN/iohelper.h b/drivers/isdn/hardware/mISDN/iohelper.h
deleted file mode 100644
index c81f7aba4b57..000000000000
--- a/drivers/isdn/hardware/mISDN/iohelper.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * iohelper.h
- *		helper for define functions to access ISDN hardware
- *              supported are memory mapped IO
- *		indirect port IO (one port for address, one for data)
- *
- * Author       Karsten Keil <keil@isdn4linux.de>
- *
- * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
- */
-
-#ifndef _IOHELPER_H
-#define _IOHELPER_H
-
-typedef u8 (read_reg_func)(void *hwp, u8 offset);
-typedef void (write_reg_func)(void *hwp, u8 offset, u8 value);
-typedef void (fifo_func)(void *hwp, u8 offset, u8 *datap, int size);
-
-struct _ioport {
-	u32 port;
-	u32 ale;
-};
-
-#define IOFUNC_IO(name, hws, ap)					\
-	static u8 Read##name##_IO(void *p, u8 off) {			\
-		struct hws *hw = p;					\
-		return inb(hw->ap.port + off);				\
-	}								\
-	static void Write##name##_IO(void *p, u8 off, u8 val) {		\
-		struct hws *hw = p;					\
-		outb(val, hw->ap.port + off);				\
-	}								\
-	static void ReadFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) { \
-		struct hws *hw = p;					\
-		insb(hw->ap.port + off, dp, size);			\
-	}								\
-	static void WriteFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) { \
-		struct hws *hw = p;					\
-		outsb(hw->ap.port + off, dp, size);			\
-	}
-
-#define IOFUNC_IND(name, hws, ap)					\
-	static u8 Read##name##_IND(void *p, u8 off) {			\
-		struct hws *hw = p;					\
-		outb(off, hw->ap.ale);					\
-		return inb(hw->ap.port);				\
-	}								\
-	static void Write##name##_IND(void *p, u8 off, u8 val) {	\
-		struct hws *hw = p;					\
-		outb(off, hw->ap.ale);					\
-		outb(val, hw->ap.port);					\
-	}								\
-	static void ReadFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) { \
-		struct hws *hw = p;					\
-		outb(off, hw->ap.ale);					\
-		insb(hw->ap.port, dp, size);				\
-	}								\
-	static void WriteFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) { \
-		struct hws *hw = p;					\
-		outb(off, hw->ap.ale);					\
-		outsb(hw->ap.port, dp, size);				\
-	}
-
-#define IOFUNC_MEMIO(name, hws, typ, adr)				\
-	static u8 Read##name##_MIO(void *p, u8 off) {			\
-		struct hws *hw = p;					\
-		return readb(((typ *)hw->adr) + off);			\
-	}								\
-	static void Write##name##_MIO(void *p, u8 off, u8 val) {	\
-		struct hws *hw = p;					\
-		writeb(val, ((typ *)hw->adr) + off);			\
-	}								\
-	static void ReadFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) { \
-		struct hws *hw = p;					\
-		while (size--)						\
-			*dp++ = readb(((typ *)hw->adr) + off);		\
-	}								\
-	static void WriteFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) { \
-		struct hws *hw = p;					\
-		while (size--)						\
-			writeb(*dp++, ((typ *)hw->adr) + off);		\
-	}
-
-#define ASSIGN_FUNC(typ, name, dest)	do {			\
-		dest.read_reg = &Read##name##_##typ;		\
-		dest.write_reg = &Write##name##_##typ;		\
-		dest.read_fifo = &ReadFiFo##name##_##typ;	\
-		dest.write_fifo = &WriteFiFo##name##_##typ;	\
-	} while (0)
-#define ASSIGN_FUNC_IPAC(typ, target)	do {		\
-		ASSIGN_FUNC(typ, ISAC, target.isac);	\
-		ASSIGN_FUNC(typ, IPAC, target);		\
-	} while (0)
-
-#endif
diff --git a/drivers/isdn/hardware/mISDN/ipac.h b/drivers/isdn/hardware/mISDN/ipac.h
deleted file mode 100644
index 2f0c4978a7a5..000000000000
--- a/drivers/isdn/hardware/mISDN/ipac.h
+++ /dev/null
@@ -1,393 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- *
- * ipac.h	Defines for the Infineon (former Siemens) ISDN
- *		chip series
- *
- * Author       Karsten Keil <keil@isdn4linux.de>
- *
- * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
- */
-
-#include "iohelper.h"
-
-struct isac_hw {
-	struct dchannel		dch;
-	u32			type;
-	u32			off;		/* offset to isac regs */
-	char			*name;
-	spinlock_t		*hwlock;	/* lock HW access */
-	read_reg_func		*read_reg;
-	write_reg_func		*write_reg;
-	fifo_func		*read_fifo;
-	fifo_func		*write_fifo;
-	int			(*monitor)(void *, u32, u8 *, int);
-	void			(*release)(struct isac_hw *);
-	int			(*init)(struct isac_hw *);
-	int			(*ctrl)(struct isac_hw *, u32, u_long);
-	int			(*open)(struct isac_hw *, struct channel_req *);
-	u8			*mon_tx;
-	u8			*mon_rx;
-	int			mon_txp;
-	int			mon_txc;
-	int			mon_rxp;
-	struct arcofi_msg	*arcofi_list;
-	struct timer_list	arcofitimer;
-	wait_queue_head_t	arcofi_wait;
-	u8			arcofi_bc;
-	u8			arcofi_state;
-	u8			mocr;
-	u8			adf2;
-	u8			state;
-};
-
-struct ipac_hw;
-
-struct hscx_hw {
-	struct bchannel		bch;
-	struct ipac_hw		*ip;
-	u8			fifo_size;
-	u8			off;	/* offset to ICA or ICB */
-	u8			slot;
-	char			log[64];
-};
-
-struct ipac_hw {
-	struct isac_hw		isac;
-	struct hscx_hw		hscx[2];
-	char			*name;
-	void			*hw;
-	spinlock_t		*hwlock;	/* lock HW access */
-	struct module		*owner;
-	u32			type;
-	read_reg_func		*read_reg;
-	write_reg_func		*write_reg;
-	fifo_func		*read_fifo;
-	fifo_func		*write_fifo;
-	void			(*release)(struct ipac_hw *);
-	int			(*init)(struct ipac_hw *);
-	int			(*ctrl)(struct ipac_hw *, u32, u_long);
-	u8			conf;
-};
-
-#define IPAC_TYPE_ISAC		0x0010
-#define IPAC_TYPE_IPAC		0x0020
-#define IPAC_TYPE_ISACX		0x0040
-#define IPAC_TYPE_IPACX		0x0080
-#define IPAC_TYPE_HSCX		0x0100
-
-#define ISAC_USE_ARCOFI		0x1000
-
-/* Monitor functions */
-#define MONITOR_RX_0		0x1000
-#define MONITOR_RX_1		0x1001
-#define MONITOR_TX_0		0x2000
-#define MONITOR_TX_1		0x2001
-
-/* All registers original Siemens Spec  */
-/* IPAC/ISAC registers */
-#define ISAC_ISTA		0x20
-#define ISAC_MASK		0x20
-#define ISAC_CMDR		0x21
-#define ISAC_STAR		0x21
-#define ISAC_MODE		0x22
-#define ISAC_TIMR		0x23
-#define ISAC_EXIR		0x24
-#define ISAC_RBCL		0x25
-#define ISAC_RSTA		0x27
-#define ISAC_RBCH		0x2A
-#define ISAC_SPCR		0x30
-#define ISAC_CIR0		0x31
-#define ISAC_CIX0		0x31
-#define ISAC_MOR0		0x32
-#define ISAC_MOX0		0x32
-#define ISAC_CIR1		0x33
-#define ISAC_CIX1		0x33
-#define ISAC_MOR1		0x34
-#define ISAC_MOX1		0x34
-#define ISAC_STCR		0x37
-#define ISAC_ADF1		0x38
-#define ISAC_ADF2		0x39
-#define ISAC_MOCR		0x3a
-#define ISAC_MOSR		0x3a
-#define ISAC_SQRR		0x3b
-#define ISAC_SQXR		0x3b
-
-#define ISAC_RBCH_XAC		0x80
-
-#define IPAC_D_TIN2		0x01
-
-/* IPAC/HSCX */
-#define IPAC_ISTAB		0x20	/* RD	*/
-#define IPAC_MASKB		0x20	/* WR	*/
-#define IPAC_STARB		0x21	/* RD	*/
-#define IPAC_CMDRB		0x21	/* WR	*/
-#define IPAC_MODEB		0x22	/* R/W	*/
-#define IPAC_EXIRB		0x24	/* RD	*/
-#define IPAC_RBCLB		0x25	/* RD	*/
-#define IPAC_RAH1		0x26	/* WR	*/
-#define IPAC_RAH2		0x27	/* WR	*/
-#define IPAC_RSTAB		0x27	/* RD	*/
-#define IPAC_RAL1		0x28	/* R/W	*/
-#define IPAC_RAL2		0x29	/* WR	*/
-#define IPAC_RHCRB		0x29	/* RD	*/
-#define IPAC_XBCL		0x2A	/* WR	*/
-#define IPAC_CCR2		0x2C	/* R/W	*/
-#define IPAC_RBCHB		0x2D	/* RD	*/
-#define IPAC_XBCH		0x2D	/* WR	*/
-#define HSCX_VSTR		0x2E	/* RD	*/
-#define IPAC_RLCR		0x2E	/* WR	*/
-#define IPAC_CCR1		0x2F	/* R/W	*/
-#define IPAC_TSAX		0x30	/* WR	*/
-#define IPAC_TSAR		0x31	/* WR	*/
-#define IPAC_XCCR		0x32	/* WR	*/
-#define IPAC_RCCR		0x33	/* WR	*/
-
-/* IPAC_ISTAB/IPAC_MASKB bits */
-#define IPAC_B_XPR		0x10
-#define IPAC_B_RPF		0x40
-#define IPAC_B_RME		0x80
-#define IPAC_B_ON		0x2F
-
-/* IPAC_EXIRB bits */
-#define IPAC_B_RFS		0x04
-#define IPAC_B_RFO		0x10
-#define IPAC_B_XDU		0x40
-#define IPAC_B_XMR		0x80
-
-/* IPAC special registers */
-#define IPAC_CONF		0xC0	/* R/W	*/
-#define IPAC_ISTA		0xC1	/* RD	*/
-#define IPAC_MASK		0xC1	/* WR	*/
-#define IPAC_ID			0xC2	/* RD	*/
-#define IPAC_ACFG		0xC3	/* R/W	*/
-#define IPAC_AOE		0xC4	/* R/W	*/
-#define IPAC_ARX		0xC5	/* RD	*/
-#define IPAC_ATX		0xC5	/* WR	*/
-#define IPAC_PITA1		0xC6	/* R/W	*/
-#define IPAC_PITA2		0xC7	/* R/W	*/
-#define IPAC_POTA1		0xC8	/* R/W	*/
-#define IPAC_POTA2		0xC9	/* R/W	*/
-#define IPAC_PCFG		0xCA	/* R/W	*/
-#define IPAC_SCFG		0xCB	/* R/W	*/
-#define IPAC_TIMR2		0xCC	/* R/W	*/
-
-/* IPAC_ISTA/_MASK bits */
-#define IPAC__EXB		0x01
-#define IPAC__ICB		0x02
-#define IPAC__EXA		0x04
-#define IPAC__ICA		0x08
-#define IPAC__EXD		0x10
-#define IPAC__ICD		0x20
-#define IPAC__INT0		0x40
-#define IPAC__INT1		0x80
-#define IPAC__ON		0xC0
-
-/* HSCX ISTA/MASK bits */
-#define HSCX__EXB		0x01
-#define HSCX__EXA		0x02
-#define HSCX__ICA		0x04
-
-/* ISAC/ISACX/IPAC/IPACX L1 commands */
-#define ISAC_CMD_TIM		0x0
-#define ISAC_CMD_RS		0x1
-#define ISAC_CMD_SCZ		0x4
-#define ISAC_CMD_SSZ		0x2
-#define ISAC_CMD_AR8		0x8
-#define ISAC_CMD_AR10		0x9
-#define ISAC_CMD_ARL		0xA
-#define ISAC_CMD_DUI		0xF
-
-/* ISAC/ISACX/IPAC/IPACX L1 indications */
-#define ISAC_IND_DR		0x0
-#define ISAC_IND_RS		0x1
-#define ISAC_IND_SD		0x2
-#define ISAC_IND_DIS		0x3
-#define ISAC_IND_RSY		0x4
-#define ISAC_IND_DR6		0x5
-#define ISAC_IND_EI		0x6
-#define ISAC_IND_PU		0x7
-#define ISAC_IND_ARD		0x8
-#define ISAC_IND_TI		0xA
-#define ISAC_IND_ATI		0xB
-#define ISAC_IND_AI8		0xC
-#define ISAC_IND_AI10		0xD
-#define ISAC_IND_DID		0xF
-
-/* the new ISACX / IPACX */
-/* D-channel registers   */
-#define ISACX_RFIFOD		0x00	/* RD	*/
-#define ISACX_XFIFOD		0x00	/* WR	*/
-#define ISACX_ISTAD		0x20	/* RD	*/
-#define ISACX_MASKD		0x20	/* WR	*/
-#define ISACX_STARD		0x21	/* RD	*/
-#define ISACX_CMDRD		0x21	/* WR	*/
-#define ISACX_MODED		0x22	/* R/W	*/
-#define ISACX_EXMD1		0x23	/* R/W	*/
-#define ISACX_TIMR1		0x24	/* R/W	*/
-#define ISACX_SAP1		0x25	/* WR	*/
-#define ISACX_SAP2		0x26	/* WR	*/
-#define ISACX_RBCLD		0x26	/* RD	*/
-#define ISACX_RBCHD		0x27	/* RD	*/
-#define ISACX_TEI1		0x27	/* WR	*/
-#define ISACX_TEI2		0x28	/* WR	*/
-#define ISACX_RSTAD		0x28	/* RD	*/
-#define ISACX_TMD		0x29	/* R/W	*/
-#define ISACX_CIR0		0x2E	/* RD	*/
-#define ISACX_CIX0		0x2E	/* WR	*/
-#define ISACX_CIR1		0x2F	/* RD	*/
-#define ISACX_CIX1		0x2F	/* WR	*/
-
-/* Transceiver registers  */
-#define ISACX_TR_CONF0		0x30	/* R/W	*/
-#define ISACX_TR_CONF1		0x31	/* R/W	*/
-#define ISACX_TR_CONF2		0x32	/* R/W	*/
-#define ISACX_TR_STA		0x33	/* RD	*/
-#define ISACX_TR_CMD		0x34	/* R/W	*/
-#define ISACX_SQRR1		0x35	/* RD	*/
-#define ISACX_SQXR1		0x35	/* WR	*/
-#define ISACX_SQRR2		0x36	/* RD	*/
-#define ISACX_SQXR2		0x36	/* WR	*/
-#define ISACX_SQRR3		0x37	/* RD	*/
-#define ISACX_SQXR3		0x37	/* WR	*/
-#define ISACX_ISTATR		0x38	/* RD	*/
-#define ISACX_MASKTR		0x39	/* R/W	*/
-#define ISACX_TR_MODE		0x3A	/* R/W	*/
-#define ISACX_ACFG1		0x3C	/* R/W	*/
-#define ISACX_ACFG2		0x3D	/* R/W	*/
-#define ISACX_AOE		0x3E	/* R/W	*/
-#define ISACX_ARX		0x3F	/* RD	*/
-#define ISACX_ATX		0x3F	/* WR	*/
-
-/* IOM: Timeslot, DPS, CDA  */
-#define ISACX_CDA10		0x40	/* R/W	*/
-#define ISACX_CDA11		0x41	/* R/W	*/
-#define ISACX_CDA20		0x42	/* R/W	*/
-#define ISACX_CDA21		0x43	/* R/W	*/
-#define ISACX_CDA_TSDP10	0x44	/* R/W	*/
-#define ISACX_CDA_TSDP11	0x45	/* R/W	*/
-#define ISACX_CDA_TSDP20	0x46	/* R/W	*/
-#define ISACX_CDA_TSDP21	0x47	/* R/W	*/
-#define ISACX_BCHA_TSDP_BC1	0x48	/* R/W	*/
-#define ISACX_BCHA_TSDP_BC2	0x49	/* R/W	*/
-#define ISACX_BCHB_TSDP_BC1	0x4A	/* R/W	*/
-#define ISACX_BCHB_TSDP_BC2	0x4B	/* R/W	*/
-#define ISACX_TR_TSDP_BC1	0x4C	/* R/W	*/
-#define ISACX_TR_TSDP_BC2	0x4D	/* R/W	*/
-#define ISACX_CDA1_CR		0x4E	/* R/W	*/
-#define ISACX_CDA2_CR		0x4F	/* R/W	*/
-
-/* IOM: Contol, Sync transfer, Monitor    */
-#define ISACX_TR_CR		0x50	/* R/W	*/
-#define ISACX_TRC_CR		0x50	/* R/W	*/
-#define ISACX_BCHA_CR		0x51	/* R/W	*/
-#define ISACX_BCHB_CR		0x52	/* R/W	*/
-#define ISACX_DCI_CR		0x53	/* R/W	*/
-#define ISACX_DCIC_CR		0x53	/* R/W	*/
-#define ISACX_MON_CR		0x54	/* R/W	*/
-#define ISACX_SDS1_CR		0x55	/* R/W	*/
-#define ISACX_SDS2_CR		0x56	/* R/W	*/
-#define ISACX_IOM_CR		0x57	/* R/W	*/
-#define ISACX_STI		0x58	/* RD	*/
-#define ISACX_ASTI		0x58	/* WR	*/
-#define ISACX_MSTI		0x59	/* R/W	*/
-#define ISACX_SDS_CONF		0x5A	/* R/W	*/
-#define ISACX_MCDA		0x5B	/* RD	*/
-#define ISACX_MOR		0x5C	/* RD	*/
-#define ISACX_MOX		0x5C	/* WR	*/
-#define ISACX_MOSR		0x5D	/* RD	*/
-#define ISACX_MOCR		0x5E	/* R/W	*/
-#define ISACX_MSTA		0x5F	/* RD	*/
-#define ISACX_MCONF		0x5F	/* WR	*/
-
-/* Interrupt and general registers */
-#define ISACX_ISTA		0x60	/* RD	*/
-#define ISACX_MASK		0x60	/* WR	*/
-#define ISACX_AUXI		0x61	/* RD	*/
-#define ISACX_AUXM		0x61	/* WR	*/
-#define ISACX_MODE1		0x62	/* R/W	*/
-#define ISACX_MODE2		0x63	/* R/W	*/
-#define ISACX_ID		0x64	/* RD	*/
-#define ISACX_SRES		0x64	/* WR	*/
-#define ISACX_TIMR2		0x65	/* R/W	*/
-
-/* Register Bits */
-/* ISACX/IPACX _ISTAD (R) and _MASKD (W) */
-#define ISACX_D_XDU		0x04
-#define ISACX_D_XMR		0x08
-#define ISACX_D_XPR		0x10
-#define ISACX_D_RFO		0x20
-#define ISACX_D_RPF		0x40
-#define ISACX_D_RME		0x80
-
-/* ISACX/IPACX _ISTA (R) and _MASK (W) */
-#define ISACX__ICD		0x01
-#define ISACX__MOS		0x02
-#define ISACX__TRAN		0x04
-#define ISACX__AUX		0x08
-#define ISACX__CIC		0x10
-#define ISACX__ST		0x20
-#define IPACX__ON		0x2C
-#define IPACX__ICB		0x40
-#define IPACX__ICA		0x80
-
-/* ISACX/IPACX _CMDRD (W) */
-#define ISACX_CMDRD_XRES	0x01
-#define ISACX_CMDRD_XME		0x02
-#define ISACX_CMDRD_XTF		0x08
-#define ISACX_CMDRD_STI		0x10
-#define ISACX_CMDRD_RRES	0x40
-#define ISACX_CMDRD_RMC		0x80
-
-/* ISACX/IPACX _RSTAD (R) */
-#define ISACX_RSTAD_TA		0x01
-#define ISACX_RSTAD_CR		0x02
-#define ISACX_RSTAD_SA0		0x04
-#define ISACX_RSTAD_SA1		0x08
-#define ISACX_RSTAD_RAB		0x10
-#define ISACX_RSTAD_CRC		0x20
-#define ISACX_RSTAD_RDO		0x40
-#define ISACX_RSTAD_VFR		0x80
-
-/* ISACX/IPACX _CIR0 (R) */
-#define ISACX_CIR0_BAS		0x01
-#define ISACX_CIR0_SG		0x08
-#define ISACX_CIR0_CIC1		0x08
-#define ISACX_CIR0_CIC0		0x08
-
-/* B-channel registers */
-#define IPACX_OFF_ICA		0x70
-#define IPACX_OFF_ICB		0x80
-
-/* ICA: IPACX_OFF_ICA + Reg ICB: IPACX_OFF_ICB + Reg */
-
-#define IPACX_ISTAB		0x00    /* RD	*/
-#define IPACX_MASKB		0x00	/* WR	*/
-#define IPACX_STARB		0x01	/* RD	*/
-#define IPACX_CMDRB		0x01	/* WR	*/
-#define IPACX_MODEB		0x02	/* R/W	*/
-#define IPACX_EXMB		0x03	/* R/W	*/
-#define IPACX_RAH1		0x05	/* WR	*/
-#define IPACX_RAH2		0x06	/* WR	*/
-#define IPACX_RBCLB		0x06	/* RD	*/
-#define IPACX_RBCHB		0x07	/* RD	*/
-#define IPACX_RAL1		0x07	/* WR	*/
-#define IPACX_RAL2		0x08	/* WR	*/
-#define IPACX_RSTAB		0x08	/* RD	*/
-#define IPACX_TMB		0x09	/* R/W	*/
-#define IPACX_RFIFOB		0x0A	/* RD	*/
-#define IPACX_XFIFOB		0x0A	/* WR	*/
-
-/* IPACX_ISTAB / IPACX_MASKB bits */
-#define IPACX_B_XDU		0x04
-#define IPACX_B_XPR		0x10
-#define IPACX_B_RFO		0x20
-#define IPACX_B_RPF		0x40
-#define IPACX_B_RME		0x80
-
-#define IPACX_B_ON		0x0B
-
-extern int mISDNisac_init(struct isac_hw *, void *);
-extern irqreturn_t mISDNisac_irq(struct isac_hw *, u8);
-extern u32 mISDNipac_init(struct ipac_hw *, void *);
-extern irqreturn_t mISDNipac_irq(struct ipac_hw *, int);
diff --git a/drivers/isdn/hardware/mISDN/isar.h b/drivers/isdn/hardware/mISDN/isar.h
deleted file mode 100644
index 36a9fa564b17..000000000000
--- a/drivers/isdn/hardware/mISDN/isar.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- *
- * isar.h   ISAR (Siemens PSB 7110) specific defines
- *
- * Author Karsten Keil (keil@isdn4linux.de)
- *
- * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
- */
-
-#include "iohelper.h"
-
-struct isar_hw;
-
-struct isar_ch {
-	struct bchannel		bch;
-	struct isar_hw		*is;
-	struct timer_list	ftimer;
-	u8			nr;
-	u8			dpath;
-	u8			mml;
-	u8			state;
-	u8			cmd;
-	u8			mod;
-	u8			newcmd;
-	u8			newmod;
-	u8			try_mod;
-	u8			conmsg[16];
-};
-
-struct isar_hw {
-	struct	isar_ch	ch[2];
-	void		*hw;
-	spinlock_t	*hwlock;	/* lock HW access */
-	char		*name;
-	struct module	*owner;
-	read_reg_func	*read_reg;
-	write_reg_func	*write_reg;
-	fifo_func	*read_fifo;
-	fifo_func	*write_fifo;
-	int		(*ctrl)(void *, u32, u_long);
-	void		(*release)(struct isar_hw *);
-	int		(*init)(struct isar_hw *);
-	int		(*open)(struct isar_hw *, struct channel_req *);
-	int		(*firmware)(struct isar_hw *, const u8 *, int);
-	unsigned long	Flags;
-	int		version;
-	u8		bstat;
-	u8		iis;
-	u8		cmsb;
-	u8		clsb;
-	u8		buf[256];
-	u8		log[256];
-};
-
-#define ISAR_IRQMSK	0x04
-#define ISAR_IRQSTA	0x04
-#define ISAR_IRQBIT	0x75
-#define ISAR_CTRL_H	0x61
-#define ISAR_CTRL_L	0x60
-#define ISAR_IIS	0x58
-#define ISAR_IIA	0x58
-#define ISAR_HIS	0x50
-#define ISAR_HIA	0x50
-#define ISAR_MBOX	0x4c
-#define ISAR_WADR	0x4a
-#define ISAR_RADR	0x48
-
-#define ISAR_HIS_VNR		0x14
-#define ISAR_HIS_DKEY		0x02
-#define ISAR_HIS_FIRM		0x1e
-#define ISAR_HIS_STDSP		0x08
-#define ISAR_HIS_DIAG		0x05
-#define ISAR_HIS_P0CFG		0x3c
-#define ISAR_HIS_P12CFG		0x24
-#define ISAR_HIS_SARTCFG	0x25
-#define ISAR_HIS_PUMPCFG	0x26
-#define ISAR_HIS_PUMPCTRL	0x2a
-#define ISAR_HIS_IOM2CFG	0x27
-#define ISAR_HIS_IOM2REQ	0x07
-#define ISAR_HIS_IOM2CTRL	0x2b
-#define ISAR_HIS_BSTREQ		0x0c
-#define ISAR_HIS_PSTREQ		0x0e
-#define ISAR_HIS_SDATA		0x20
-#define ISAR_HIS_DPS1		0x40
-#define ISAR_HIS_DPS2		0x80
-#define SET_DPS(x)		((x << 6) & 0xc0)
-
-#define ISAR_IIS_MSCMSD		0x3f
-#define ISAR_IIS_VNR		0x15
-#define ISAR_IIS_DKEY		0x03
-#define ISAR_IIS_FIRM		0x1f
-#define ISAR_IIS_STDSP		0x09
-#define ISAR_IIS_DIAG		0x25
-#define ISAR_IIS_GSTEV		0x00
-#define ISAR_IIS_BSTEV		0x28
-#define ISAR_IIS_BSTRSP		0x2c
-#define ISAR_IIS_PSTRSP		0x2e
-#define ISAR_IIS_PSTEV		0x2a
-#define ISAR_IIS_IOM2RSP	0x27
-#define ISAR_IIS_RDATA		0x20
-#define ISAR_IIS_INVMSG		0x3f
-
-#define ISAR_CTRL_SWVER	0x10
-#define ISAR_CTRL_STST	0x40
-
-#define ISAR_MSG_HWVER	0x20
-
-#define ISAR_DP1_USE	1
-#define ISAR_DP2_USE	2
-#define ISAR_RATE_REQ	3
-
-#define PMOD_DISABLE	0
-#define PMOD_FAX	1
-#define PMOD_DATAMODEM	2
-#define PMOD_HALFDUPLEX	3
-#define PMOD_V110	4
-#define PMOD_DTMF	5
-#define PMOD_DTMF_TRANS	6
-#define PMOD_BYPASS	7
-
-#define PCTRL_ORIG	0x80
-#define PV32P2_V23R	0x40
-#define PV32P2_V22A	0x20
-#define PV32P2_V22B	0x10
-#define PV32P2_V22C	0x08
-#define PV32P2_V21	0x02
-#define PV32P2_BEL	0x01
-
-/* LSB MSB in ISAR doc wrong !!! Arghhh */
-#define PV32P3_AMOD	0x80
-#define PV32P3_V32B	0x02
-#define PV32P3_V23B	0x01
-#define PV32P4_48	0x11
-#define PV32P5_48	0x05
-#define PV32P4_UT48	0x11
-#define PV32P5_UT48	0x0d
-#define PV32P4_96	0x11
-#define PV32P5_96	0x03
-#define PV32P4_UT96	0x11
-#define PV32P5_UT96	0x0f
-#define PV32P4_B96	0x91
-#define PV32P5_B96	0x0b
-#define PV32P4_UTB96	0xd1
-#define PV32P5_UTB96	0x0f
-#define PV32P4_120	0xb1
-#define PV32P5_120	0x09
-#define PV32P4_UT120	0xf1
-#define PV32P5_UT120	0x0f
-#define PV32P4_144	0x99
-#define PV32P5_144	0x09
-#define PV32P4_UT144	0xf9
-#define PV32P5_UT144	0x0f
-#define PV32P6_CTN	0x01
-#define PV32P6_ATN	0x02
-
-#define PFAXP2_CTN	0x01
-#define PFAXP2_ATN	0x04
-
-#define PSEV_10MS_TIMER	0x02
-#define PSEV_CON_ON	0x18
-#define PSEV_CON_OFF	0x19
-#define PSEV_V24_OFF	0x20
-#define PSEV_CTS_ON	0x21
-#define PSEV_CTS_OFF	0x22
-#define PSEV_DCD_ON	0x23
-#define PSEV_DCD_OFF	0x24
-#define PSEV_DSR_ON	0x25
-#define PSEV_DSR_OFF	0x26
-#define PSEV_REM_RET	0xcc
-#define PSEV_REM_REN	0xcd
-#define PSEV_GSTN_CLR	0xd4
-
-#define PSEV_RSP_READY	0xbc
-#define PSEV_LINE_TX_H	0xb3
-#define PSEV_LINE_TX_B	0xb2
-#define PSEV_LINE_RX_H	0xb1
-#define PSEV_LINE_RX_B	0xb0
-#define PSEV_RSP_CONN	0xb5
-#define PSEV_RSP_DISC	0xb7
-#define PSEV_RSP_FCERR	0xb9
-#define PSEV_RSP_SILDET	0xbe
-#define PSEV_RSP_SILOFF	0xab
-#define PSEV_FLAGS_DET	0xba
-
-#define PCTRL_CMD_TDTMF	0x5a
-
-#define PCTRL_CMD_FTH	0xa7
-#define PCTRL_CMD_FRH	0xa5
-#define PCTRL_CMD_FTM	0xa8
-#define PCTRL_CMD_FRM	0xa6
-#define PCTRL_CMD_SILON	0xac
-#define PCTRL_CMD_CONT	0xa2
-#define PCTRL_CMD_ESC	0xa4
-#define PCTRL_CMD_SILOFF 0xab
-#define PCTRL_CMD_HALT	0xa9
-
-#define PCTRL_LOC_RET	0xcf
-#define PCTRL_LOC_REN	0xce
-
-#define SMODE_DISABLE	0
-#define SMODE_V14	2
-#define SMODE_HDLC	3
-#define SMODE_BINARY	4
-#define SMODE_FSK_V14	5
-
-#define SCTRL_HDMC_BOTH	0x00
-#define SCTRL_HDMC_DTX	0x80
-#define SCTRL_HDMC_DRX	0x40
-#define S_P1_OVSP	0x40
-#define S_P1_SNP	0x20
-#define S_P1_EOP	0x10
-#define S_P1_EDP	0x08
-#define S_P1_NSB	0x04
-#define S_P1_CHS_8	0x03
-#define S_P1_CHS_7	0x02
-#define S_P1_CHS_6	0x01
-#define S_P1_CHS_5	0x00
-
-#define S_P2_BFT_DEF	0x10
-
-#define IOM_CTRL_ENA	0x80
-#define IOM_CTRL_NOPCM	0x00
-#define IOM_CTRL_ALAW	0x02
-#define IOM_CTRL_ULAW	0x04
-#define IOM_CTRL_RCV	0x01
-
-#define IOM_P1_TXD	0x10
-
-#define HDLC_FED	0x40
-#define HDLC_FSD	0x20
-#define HDLC_FST	0x20
-#define HDLC_ERROR	0x1c
-#define HDLC_ERR_FAD	0x10
-#define HDLC_ERR_RER	0x08
-#define HDLC_ERR_CER	0x04
-#define SART_NMD	0x01
-
-#define BSTAT_RDM0	0x1
-#define BSTAT_RDM1	0x2
-#define BSTAT_RDM2	0x4
-#define BSTAT_RDM3	0x8
-#define BSTEV_TBO	0x1f
-#define BSTEV_RBO	0x2f
-
-/* FAX State Machine */
-#define STFAX_NULL	0
-#define STFAX_READY	1
-#define STFAX_LINE	2
-#define STFAX_CONT	3
-#define STFAX_ACTIV	4
-#define STFAX_ESCAPE	5
-#define STFAX_SILDET	6
-
-extern u32 mISDNisar_init(struct isar_hw *, void *);
-extern void mISDNisar_irq(struct isar_hw *);
diff --git a/drivers/isdn/hardware/mISDN/isdnhdlc.h b/drivers/isdn/hardware/mISDN/isdnhdlc.h
deleted file mode 100644
index fe2c1279c139..000000000000
--- a/drivers/isdn/hardware/mISDN/isdnhdlc.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * hdlc.h  --  General purpose ISDN HDLC decoder.
- *
- * Implementation of a HDLC decoder/encoder in software.
- * Necessary because some ISDN devices don't have HDLC
- * controllers.
- *
- * Copyright (C)
- *	2009	Karsten Keil		<keil@b1-systems.de>
- *	2002	Wolfgang Mües		<wolfgang@iksw-muees.de>
- *	2001	Frode Isaksen		<fisaksen@bewan.com>
- *	2001	Kai Germaschewski	<kai.germaschewski@gmx.de>
- */
-
-#ifndef __ISDNHDLC_H__
-#define __ISDNHDLC_H__
-
-struct isdnhdlc_vars {
-	int bit_shift;
-	int hdlc_bits1;
-	int data_bits;
-	int ffbit_shift;	/* encoding only */
-	int state;
-	int dstpos;
-
-	u16 crc;
-
-	u8 cbin;
-	u8 shift_reg;
-	u8 ffvalue;
-
-	/* set if transferring data */
-	u32 data_received:1;
-	/* set if D channel (send idle instead of flags) */
-	u32 dchannel:1;
-	/* set if 56K adaptation */
-	u32 do_adapt56:1;
-	/* set if in closing phase (need to send CRC + flag) */
-	u32 do_closing:1;
-	/* set if data is bitreverse */
-	u32 do_bitreverse:1;
-};
-
-/* Feature Flags */
-#define HDLC_56KBIT	0x01
-#define HDLC_DCHANNEL	0x02
-#define HDLC_BITREVERSE	0x04
-
-/*
-  The return value from isdnhdlc_decode is
-  the frame length, 0 if no complete frame was decoded,
-  or a negative error number
-*/
-#define HDLC_FRAMING_ERROR     1
-#define HDLC_CRC_ERROR         2
-#define HDLC_LENGTH_ERROR      3
-
-extern void	isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features);
-
-extern int	isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src,
-			int slen, int *count, u8 *dst, int dsize);
-
-extern void	isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features);
-
-extern int	isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src,
-			u16 slen, int *count, u8 *dst, int dsize);
-
-#endif /* __ISDNHDLC_H__ */
diff --git a/drivers/isdn/hardware/mISDN/netjet.h b/drivers/isdn/hardware/mISDN/netjet.h
deleted file mode 100644
index b23ad9f6d4d0..000000000000
--- a/drivers/isdn/hardware/mISDN/netjet.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * NETjet common header file
- *
- * Author	Karsten Keil
- *              based on work of Matt Henderson and Daniel Potts,
- *              Traverse Technologies P/L www.traverse.com.au
- *
- * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
- */
-
-#define NJ_CTRL			0x00
-#define NJ_DMACTRL		0x01
-#define NJ_AUXCTRL		0x02
-#define NJ_AUXDATA		0x03
-#define NJ_IRQMASK0		0x04
-#define NJ_IRQMASK1		0x05
-#define NJ_IRQSTAT0		0x06
-#define NJ_IRQSTAT1		0x07
-#define NJ_DMA_READ_START	0x08
-#define NJ_DMA_READ_IRQ		0x0c
-#define NJ_DMA_READ_END		0x10
-#define NJ_DMA_READ_ADR		0x14
-#define NJ_DMA_WRITE_START	0x18
-#define NJ_DMA_WRITE_IRQ	0x1c
-#define NJ_DMA_WRITE_END	0x20
-#define NJ_DMA_WRITE_ADR	0x24
-#define NJ_PULSE_CNT		0x28
-
-#define NJ_ISAC_OFF		0xc0
-#define NJ_ISACIRQ		0x10
-
-#define NJ_IRQM0_RD_MASK	0x03
-#define NJ_IRQM0_RD_IRQ		0x01
-#define NJ_IRQM0_RD_END		0x02
-#define NJ_IRQM0_WR_MASK	0x0c
-#define NJ_IRQM0_WR_IRQ		0x04
-#define NJ_IRQM0_WR_END		0x08
-
-/* one page here is no need to be smaller */
-#define NJ_DMA_SIZE		4096
-/* 2 * 64 byte is a compromise between IRQ count and latency */
-#define NJ_DMA_RXSIZE		128  /* 2 * 64 */
-#define NJ_DMA_TXSIZE		128  /* 2 * 64 */
diff --git a/drivers/isdn/hardware/mISDN/w6692.h b/drivers/isdn/hardware/mISDN/w6692.h
deleted file mode 100644
index 45e1dc5d6c2d..000000000000
--- a/drivers/isdn/hardware/mISDN/w6692.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Winbond W6692 specific defines
- *
- * Author       Karsten Keil <keil@isdn4linux.de>
- *		based on the w6692 I4L driver from Petr Novak <petr.novak@i.cz>
- *
- * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
- */
-
-/* Specifications of W6692 registers */
-
-#define W_D_RFIFO	0x00	/* R */
-#define W_D_XFIFO	0x04	/* W */
-#define W_D_CMDR	0x08	/* W */
-#define W_D_MODE	0x0c	/* R/W */
-#define W_D_TIMR	0x10	/* R/W */
-#define W_ISTA		0x14	/* R_clr */
-#define W_IMASK		0x18	/* R/W */
-#define W_D_EXIR	0x1c	/* R_clr */
-#define W_D_EXIM	0x20	/* R/W */
-#define W_D_STAR	0x24	/* R */
-#define W_D_RSTA	0x28	/* R */
-#define W_D_SAM		0x2c	/* R/W */
-#define W_D_SAP1	0x30	/* R/W */
-#define W_D_SAP2	0x34	/* R/W */
-#define W_D_TAM		0x38	/* R/W */
-#define W_D_TEI1	0x3c	/* R/W */
-#define W_D_TEI2	0x40	/* R/W */
-#define W_D_RBCH	0x44	/* R */
-#define W_D_RBCL	0x48	/* R */
-#define W_TIMR2		0x4c	/* W */
-#define W_L1_RC		0x50	/* R/W */
-#define W_D_CTL		0x54	/* R/W */
-#define W_CIR		0x58	/* R */
-#define W_CIX		0x5c	/* W */
-#define W_SQR		0x60	/* R */
-#define W_SQX		0x64	/* W */
-#define W_PCTL		0x68	/* R/W */
-#define W_MOR		0x6c	/* R */
-#define W_MOX		0x70	/* R/W */
-#define W_MOSR		0x74	/* R_clr */
-#define W_MOCR		0x78	/* R/W */
-#define W_GCR		0x7c	/* R/W */
-
-#define	W_B_RFIFO	0x80	/* R */
-#define	W_B_XFIFO	0x84	/* W */
-#define	W_B_CMDR	0x88	/* W */
-#define	W_B_MODE	0x8c	/* R/W */
-#define	W_B_EXIR	0x90	/* R_clr */
-#define	W_B_EXIM	0x94	/* R/W */
-#define	W_B_STAR	0x98	/* R */
-#define	W_B_ADM1	0x9c	/* R/W */
-#define	W_B_ADM2	0xa0	/* R/W */
-#define	W_B_ADR1	0xa4	/* R/W */
-#define	W_B_ADR2	0xa8	/* R/W */
-#define	W_B_RBCL	0xac	/* R */
-#define	W_B_RBCH	0xb0	/* R */
-
-#define W_XADDR		0xf4	/* R/W */
-#define W_XDATA		0xf8	/* R/W */
-#define W_EPCTL		0xfc	/* W */
-
-/* W6692 register bits */
-
-#define	W_D_CMDR_XRST	0x01
-#define	W_D_CMDR_XME	0x02
-#define	W_D_CMDR_XMS	0x08
-#define	W_D_CMDR_STT	0x10
-#define	W_D_CMDR_RRST	0x40
-#define	W_D_CMDR_RACK	0x80
-
-#define	W_D_MODE_RLP	0x01
-#define	W_D_MODE_DLP	0x02
-#define	W_D_MODE_MFD	0x04
-#define	W_D_MODE_TEE	0x08
-#define	W_D_MODE_TMS	0x10
-#define	W_D_MODE_RACT	0x40
-#define	W_D_MODE_MMS	0x80
-
-#define W_INT_B2_EXI	0x01
-#define W_INT_B1_EXI	0x02
-#define W_INT_D_EXI	0x04
-#define W_INT_XINT0	0x08
-#define W_INT_XINT1	0x10
-#define W_INT_D_XFR	0x20
-#define W_INT_D_RME	0x40
-#define W_INT_D_RMR	0x80
-
-#define W_D_EXI_WEXP	0x01
-#define W_D_EXI_TEXP	0x02
-#define W_D_EXI_ISC	0x04
-#define W_D_EXI_MOC	0x08
-#define W_D_EXI_TIN2	0x10
-#define W_D_EXI_XCOL	0x20
-#define W_D_EXI_XDUN	0x40
-#define W_D_EXI_RDOV	0x80
-
-#define	W_D_STAR_DRDY	0x10
-#define	W_D_STAR_XBZ	0x20
-#define	W_D_STAR_XDOW	0x80
-
-#define W_D_RSTA_RMB	0x10
-#define W_D_RSTA_CRCE	0x20
-#define W_D_RSTA_RDOV	0x40
-
-#define W_D_CTL_SRST	0x20
-
-#define W_CIR_SCC	0x80
-#define W_CIR_ICC	0x40
-#define W_CIR_COD_MASK	0x0f
-
-#define W_PCTL_PCX	0x01
-#define W_PCTL_XMODE	0x02
-#define W_PCTL_OE0	0x04
-#define W_PCTL_OE1	0x08
-#define W_PCTL_OE2	0x10
-#define W_PCTL_OE3	0x20
-#define W_PCTL_OE4	0x40
-#define W_PCTL_OE5	0x80
-
-#define	W_B_CMDR_XRST	0x01
-#define	W_B_CMDR_XME	0x02
-#define	W_B_CMDR_XMS	0x04
-#define	W_B_CMDR_RACT	0x20
-#define	W_B_CMDR_RRST	0x40
-#define	W_B_CMDR_RACK	0x80
-
-#define	W_B_MODE_FTS0	0x01
-#define	W_B_MODE_FTS1	0x02
-#define	W_B_MODE_SW56	0x04
-#define	W_B_MODE_BSW0	0x08
-#define	W_B_MODE_BSW1	0x10
-#define	W_B_MODE_EPCM	0x20
-#define	W_B_MODE_ITF	0x40
-#define	W_B_MODE_MMS	0x80
-
-#define	W_B_EXI_XDUN	0x01
-#define	W_B_EXI_XFR	0x02
-#define	W_B_EXI_RDOV	0x10
-#define	W_B_EXI_RME	0x20
-#define	W_B_EXI_RMR	0x40
-
-#define	W_B_STAR_XBZ	0x01
-#define	W_B_STAR_XDOW	0x04
-#define	W_B_STAR_RMB	0x10
-#define	W_B_STAR_CRCE	0x20
-#define	W_B_STAR_RDOV	0x40
-
-#define	W_B_RBCH_LOV	0x20
-
-/* W6692 Layer1 commands */
-
-#define	W_L1CMD_ECK	0x00
-#define W_L1CMD_RST	0x01
-#define W_L1CMD_SCP	0x04
-#define W_L1CMD_SSP	0x02
-#define W_L1CMD_AR8	0x08
-#define W_L1CMD_AR10	0x09
-#define W_L1CMD_EAL	0x0a
-#define W_L1CMD_DRC	0x0f
-
-/* W6692 Layer1 indications */
-
-#define W_L1IND_CE	0x07
-#define W_L1IND_DRD	0x00
-#define W_L1IND_LD	0x04
-#define W_L1IND_ARD	0x08
-#define W_L1IND_TI	0x0a
-#define W_L1IND_ATI	0x0b
-#define W_L1IND_AI8	0x0c
-#define W_L1IND_AI10	0x0d
-#define W_L1IND_CD	0x0f
-
-/* FIFO thresholds */
-#define W_D_FIFO_THRESH	64
-#define W_B_FIFO_THRESH	64
diff --git a/drivers/isdn/mISDN/core.h b/drivers/isdn/mISDN/core.h
deleted file mode 100644
index 5617c06de8e4..000000000000
--- a/drivers/isdn/mISDN/core.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- */
-
-#ifndef mISDN_CORE_H
-#define mISDN_CORE_H
-
-extern struct mISDNdevice	*get_mdevice(u_int);
-extern int			get_mdevice_count(void);
-
-/* stack status flag */
-#define mISDN_STACK_ACTION_MASK		0x0000ffff
-#define mISDN_STACK_COMMAND_MASK	0x000f0000
-#define mISDN_STACK_STATUS_MASK		0xfff00000
-/* action bits 0-15 */
-#define mISDN_STACK_WORK	0
-#define mISDN_STACK_SETUP	1
-#define mISDN_STACK_CLEARING	2
-#define mISDN_STACK_RESTART	3
-#define mISDN_STACK_WAKEUP	4
-#define mISDN_STACK_ABORT	15
-/* command bits 16-19 */
-#define mISDN_STACK_STOPPED	16
-#define mISDN_STACK_INIT	17
-#define mISDN_STACK_THREADSTART	18
-/* status bits 20-31 */
-#define mISDN_STACK_BCHANNEL	20
-#define mISDN_STACK_ACTIVE      29
-#define mISDN_STACK_RUNNING     30
-#define mISDN_STACK_KILLED      31
-
-
-/* manager options */
-#define MGR_OPT_USER		24
-#define MGR_OPT_NETWORK		25
-
-extern int	connect_Bstack(struct mISDNdevice *, struct mISDNchannel *,
-			       u_int, struct sockaddr_mISDN *);
-extern int	connect_layer1(struct mISDNdevice *, struct mISDNchannel *,
-			       u_int, struct sockaddr_mISDN *);
-extern int	create_l2entity(struct mISDNdevice *, struct mISDNchannel *,
-				u_int, struct sockaddr_mISDN *);
-
-extern int	create_stack(struct mISDNdevice *);
-extern int	create_teimanager(struct mISDNdevice *);
-extern void	delete_teimanager(struct mISDNchannel *);
-extern void	delete_channel(struct mISDNchannel *);
-extern void	delete_stack(struct mISDNdevice *);
-extern void	mISDN_initstack(u_int *);
-extern int      misdn_sock_init(u_int *);
-extern void     misdn_sock_cleanup(void);
-extern void	add_layer2(struct mISDNchannel *, struct mISDNstack *);
-extern void	__add_layer2(struct mISDNchannel *, struct mISDNstack *);
-
-extern u_int		get_all_Bprotocols(void);
-struct Bprotocol	*get_Bprotocol4mask(u_int);
-
-extern int	mISDN_inittimer(u_int *);
-extern void	mISDN_timer_cleanup(void);
-
-extern int	Isdnl1_Init(u_int *);
-extern void	Isdnl1_cleanup(void);
-extern int	Isdnl2_Init(u_int *);
-extern void	Isdnl2_cleanup(void);
-
-extern void	mISDN_init_clock(u_int *);
-
-#endif
diff --git a/drivers/isdn/mISDN/dsp.h b/drivers/isdn/mISDN/dsp.h
deleted file mode 100644
index baf31258f5c9..000000000000
--- a/drivers/isdn/mISDN/dsp.h
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Audio support data for ISDN4Linux.
- *
- * Copyright 2002/2003 by Andreas Eversberg (jolly@eversberg.eu)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#define DEBUG_DSP_CTRL		0x0001
-#define DEBUG_DSP_CORE		0x0002
-#define DEBUG_DSP_DTMF		0x0004
-#define DEBUG_DSP_CMX		0x0010
-#define DEBUG_DSP_TONE		0x0020
-#define DEBUG_DSP_BLOWFISH	0x0040
-#define DEBUG_DSP_DELAY		0x0100
-#define DEBUG_DSP_CLOCK		0x0200
-#define DEBUG_DSP_DTMFCOEFF	0x8000 /* heavy output */
-
-/* options may be:
- *
- * bit 0 = use ulaw instead of alaw
- * bit 1 = enable hfc hardware acceleration for all channels
- *
- */
-#define DSP_OPT_ULAW		(1 << 0)
-#define DSP_OPT_NOHARDWARE	(1 << 1)
-
-#include <linux/timer.h>
-#include <linux/workqueue.h>
-
-#include "dsp_ecdis.h"
-
-extern int dsp_options;
-extern int dsp_debug;
-extern int dsp_poll;
-extern int dsp_tics;
-extern spinlock_t dsp_lock;
-extern struct work_struct dsp_workq;
-extern u32 dsp_poll_diff; /* calculated fix-comma corrected poll value */
-
-/***************
- * audio stuff *
- ***************/
-
-extern s32 dsp_audio_alaw_to_s32[256];
-extern s32 dsp_audio_ulaw_to_s32[256];
-extern s32 *dsp_audio_law_to_s32;
-extern u8 dsp_audio_s16_to_law[65536];
-extern u8 dsp_audio_alaw_to_ulaw[256];
-extern u8 dsp_audio_mix_law[65536];
-extern u8 dsp_audio_seven2law[128];
-extern u8 dsp_audio_law2seven[256];
-extern void dsp_audio_generate_law_tables(void);
-extern void dsp_audio_generate_s2law_table(void);
-extern void dsp_audio_generate_seven(void);
-extern void dsp_audio_generate_mix_table(void);
-extern void dsp_audio_generate_ulaw_samples(void);
-extern void dsp_audio_generate_volume_changes(void);
-extern u8 dsp_silence;
-
-
-/*************
- * cmx stuff *
- *************/
-
-#define MAX_POLL	256	/* maximum number of send-chunks */
-
-#define CMX_BUFF_SIZE	0x8000	/* must be 2**n (0x1000 about 1/2 second) */
-#define CMX_BUFF_HALF	0x4000	/* CMX_BUFF_SIZE / 2 */
-#define CMX_BUFF_MASK	0x7fff	/* CMX_BUFF_SIZE - 1 */
-
-/* how many seconds will we check the lowest delay until the jitter buffer
-   is reduced by that delay */
-#define MAX_SECONDS_JITTER_CHECK 5
-
-extern struct timer_list dsp_spl_tl;
-
-/* the datatype need to match jiffies datatype */
-extern unsigned long dsp_spl_jiffies;
-
-/* the structure of conferences:
- *
- * each conference has a unique number, given by user space.
- * the conferences are linked in a chain.
- * each conference has members linked in a chain.
- * each dsplayer points to a member, each member points to a dsplayer.
- */
-
-/* all members within a conference (this is linked 1:1 with the dsp) */
-struct dsp;
-struct dsp_conf_member {
-	struct list_head	list;
-	struct dsp		*dsp;
-};
-
-/* the list of all conferences */
-struct dsp_conf {
-	struct list_head	list;
-	u32			id;
-	/* all cmx stacks with the same ID are
-	   connected */
-	struct list_head	mlist;
-	int			software; /* conf is processed by software */
-	int			hardware; /* conf is processed by hardware */
-	/* note: if both unset, has only one member */
-};
-
-
-/**************
- * DTMF stuff *
- **************/
-
-#define DSP_DTMF_NPOINTS 102
-
-#define ECHOCAN_BUFF_SIZE 0x400 /* must be 2**n */
-#define ECHOCAN_BUFF_MASK 0x3ff /* -1 */
-
-struct dsp_dtmf {
-	int		enable; /* dtmf is enabled */
-	int		treshold; /* above this is dtmf (square of) */
-	int		software; /* dtmf uses software decoding */
-	int		hardware; /* dtmf uses hardware decoding */
-	int		size; /* number of bytes in buffer */
-	signed short	buffer[DSP_DTMF_NPOINTS];
-	/* buffers one full dtmf frame */
-	u8		lastwhat, lastdigit;
-	int		count;
-	u8		digits[16]; /* dtmf result */
-};
-
-
-/******************
- * pipeline stuff *
- ******************/
-struct dsp_pipeline {
-	rwlock_t  lock;
-	struct list_head list;
-	int inuse;
-};
-
-/***************
- * tones stuff *
- ***************/
-
-struct dsp_tone {
-	int		software; /* tones are generated by software */
-	int		hardware; /* tones are generated by hardware */
-	int		tone;
-	void		*pattern;
-	int		count;
-	int		index;
-	struct timer_list tl;
-};
-
-/***************
- * echo stuff *
- ***************/
-
-struct dsp_echo {
-	int		software; /* echo is generated by software */
-	int		hardware; /* echo is generated by hardware */
-};
-
-/*****************
- * general stuff *
- *****************/
-
-struct dsp {
-	struct list_head list;
-	struct mISDNchannel	ch;
-	struct mISDNchannel	*up;
-	unsigned char	name[64];
-	int		b_active;
-	struct dsp_echo	echo;
-	int		rx_disabled; /* what the user wants */
-	int		rx_is_off; /* what the card is */
-	int		tx_mix;
-	struct dsp_tone	tone;
-	struct dsp_dtmf	dtmf;
-	int		tx_volume, rx_volume;
-
-	/* queue for sending frames */
-	struct work_struct	workq;
-	struct sk_buff_head	sendq;
-	int		hdlc;	/* if mode is hdlc */
-	int		data_pending;	/* currently an unconfirmed frame */
-
-	/* conference stuff */
-	u32		conf_id;
-	struct dsp_conf	*conf;
-	struct dsp_conf_member
-	*member;
-
-	/* buffer stuff */
-	int		rx_W; /* current write pos for data without timestamp */
-	int		rx_R; /* current read pos for transmit clock */
-	int		rx_init; /* if set, pointers will be adjusted first */
-	int		tx_W; /* current write pos for transmit data */
-	int		tx_R; /* current read pos for transmit clock */
-	int		rx_delay[MAX_SECONDS_JITTER_CHECK];
-	int		tx_delay[MAX_SECONDS_JITTER_CHECK];
-	u8		tx_buff[CMX_BUFF_SIZE];
-	u8		rx_buff[CMX_BUFF_SIZE];
-	int		last_tx; /* if set, we transmitted last poll interval */
-	int		cmx_delay; /* initial delay of buffers,
-				      or 0 for dynamic jitter buffer */
-	int		tx_dejitter; /* if set, dejitter tx buffer */
-	int		tx_data; /* enables tx-data of CMX to upper layer */
-
-	/* hardware stuff */
-	struct dsp_features features;
-	int		features_rx_off; /* set if rx_off is featured */
-	int		features_fill_empty; /* set if fill_empty is featured */
-	int		pcm_slot_rx; /* current PCM slot (or -1) */
-	int		pcm_bank_rx;
-	int		pcm_slot_tx;
-	int		pcm_bank_tx;
-	int		hfc_conf; /* unique id of current conference (or -1) */
-
-	/* encryption stuff */
-	int		bf_enable;
-	u32		bf_p[18];
-	u32		bf_s[1024];
-	int		bf_crypt_pos;
-	u8		bf_data_in[9];
-	u8		bf_crypt_out[9];
-	int		bf_decrypt_in_pos;
-	int		bf_decrypt_out_pos;
-	u8		bf_crypt_inring[16];
-	u8		bf_data_out[9];
-	int		bf_sync;
-
-	struct dsp_pipeline
-	pipeline;
-};
-
-/* functions */
-
-extern void dsp_change_volume(struct sk_buff *skb, int volume);
-
-extern struct list_head dsp_ilist;
-extern struct list_head conf_ilist;
-extern void dsp_cmx_debug(struct dsp *dsp);
-extern void dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp);
-extern int dsp_cmx_conf(struct dsp *dsp, u32 conf_id);
-extern void dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb);
-extern void dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb);
-extern void dsp_cmx_send(struct timer_list *arg);
-extern void dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb);
-extern int dsp_cmx_del_conf_member(struct dsp *dsp);
-extern int dsp_cmx_del_conf(struct dsp_conf *conf);
-
-extern void dsp_dtmf_goertzel_init(struct dsp *dsp);
-extern void dsp_dtmf_hardware(struct dsp *dsp);
-extern u8 *dsp_dtmf_goertzel_decode(struct dsp *dsp, u8 *data, int len,
-				    int fmt);
-
-extern int dsp_tone(struct dsp *dsp, int tone);
-extern void dsp_tone_copy(struct dsp *dsp, u8 *data, int len);
-extern void dsp_tone_timeout(struct timer_list *t);
-
-extern void dsp_bf_encrypt(struct dsp *dsp, u8 *data, int len);
-extern void dsp_bf_decrypt(struct dsp *dsp, u8 *data, int len);
-extern int dsp_bf_init(struct dsp *dsp, const u8 *key, unsigned int keylen);
-extern void dsp_bf_cleanup(struct dsp *dsp);
-
-extern int  dsp_pipeline_module_init(void);
-extern void dsp_pipeline_module_exit(void);
-extern int  dsp_pipeline_init(struct dsp_pipeline *pipeline);
-extern void dsp_pipeline_destroy(struct dsp_pipeline *pipeline);
-extern int  dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg);
-extern void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data,
-				    int len);
-extern void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data,
-				    int len, unsigned int txlen);
diff --git a/drivers/isdn/mISDN/dsp_biquad.h b/drivers/isdn/mISDN/dsp_biquad.h
deleted file mode 100644
index f40d52a4c4ee..000000000000
--- a/drivers/isdn/mISDN/dsp_biquad.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * SpanDSP - a series of DSP components for telephony
- *
- * biquad.h - General telephony bi-quad section routines (currently this just
- *            handles canonic/type 2 form)
- *
- * Written by Steve Underwood <steveu@coppice.org>
- *
- * Copyright (C) 2001 Steve Underwood
- *
- * All rights reserved.
- */
-
-struct biquad2_state {
-	int32_t gain;
-	int32_t a1;
-	int32_t a2;
-	int32_t b1;
-	int32_t b2;
-
-	int32_t z1;
-	int32_t z2;
-};
-
-static inline void biquad2_init(struct biquad2_state *bq,
-				int32_t gain, int32_t a1, int32_t a2, int32_t b1, int32_t b2)
-{
-	bq->gain = gain;
-	bq->a1 = a1;
-	bq->a2 = a2;
-	bq->b1 = b1;
-	bq->b2 = b2;
-
-	bq->z1 = 0;
-	bq->z2 = 0;
-}
-
-static inline int16_t biquad2(struct biquad2_state *bq, int16_t sample)
-{
-	int32_t y;
-	int32_t z0;
-
-	z0 = sample * bq->gain + bq->z1 * bq->a1 + bq->z2 * bq->a2;
-	y = z0 + bq->z1 * bq->b1 + bq->z2 * bq->b2;
-
-	bq->z2 = bq->z1;
-	bq->z1 = z0 >> 15;
-	y >>= 15;
-	return  y;
-}
diff --git a/drivers/isdn/mISDN/dsp_ecdis.h b/drivers/isdn/mISDN/dsp_ecdis.h
deleted file mode 100644
index 4bcdf321875d..000000000000
--- a/drivers/isdn/mISDN/dsp_ecdis.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * SpanDSP - a series of DSP components for telephony
- *
- * ec_disable_detector.h - A detector which should eventually meet the
- *                         G.164/G.165 requirements for detecting the
- *                         2100Hz echo cancellor disable tone.
- *
- * Written by Steve Underwood <steveu@coppice.org>
- *
- * Copyright (C) 2001 Steve Underwood
- *
- * All rights reserved.
- */
-
-#include "dsp_biquad.h"
-
-struct ec_disable_detector_state {
-	struct biquad2_state notch;
-	int notch_level;
-	int channel_level;
-	int tone_present;
-	int tone_cycle_duration;
-	int good_cycles;
-	int hit;
-};
-
-
-#define FALSE 0
-#define TRUE (!FALSE)
-
-static inline void
-echo_can_disable_detector_init(struct ec_disable_detector_state *det)
-{
-	/* Elliptic notch */
-	/* This is actually centred at 2095Hz, but gets the balance we want, due
-	   to the asymmetric walls of the notch */
-	biquad2_init(&det->notch,
-		     (int32_t)(-0.7600000 * 32768.0),
-		     (int32_t)(-0.1183852 * 32768.0),
-		     (int32_t)(-0.5104039 * 32768.0),
-		     (int32_t)(0.1567596 * 32768.0),
-		     (int32_t)(1.0000000 * 32768.0));
-
-	det->channel_level = 0;
-	det->notch_level = 0;
-	det->tone_present = FALSE;
-	det->tone_cycle_duration = 0;
-	det->good_cycles = 0;
-	det->hit = 0;
-}
-/*- End of function --------------------------------------------------------*/
-
-static inline int
-echo_can_disable_detector_update(struct ec_disable_detector_state *det,
-				 int16_t amp)
-{
-	int16_t notched;
-
-	notched = biquad2(&det->notch, amp);
-	/* Estimate the overall energy in the channel, and the energy in
-	   the notch (i.e. overall channel energy - tone energy => noise).
-	   Use abs instead of multiply for speed (is it really faster?).
-	   Damp the overall energy a little more for a stable result.
-	   Damp the notch energy a little less, so we don't damp out the
-	   blip every time the phase reverses */
-	det->channel_level += ((abs(amp) - det->channel_level) >> 5);
-	det->notch_level += ((abs(notched) - det->notch_level) >> 4);
-	if (det->channel_level > 280) {
-		/* There is adequate energy in the channel.
-		   Is it mostly at 2100Hz? */
-		if (det->notch_level * 6 < det->channel_level) {
-			/* The notch says yes, so we have the tone. */
-			if (!det->tone_present) {
-				/* Do we get a kick every 450+-25ms? */
-				if (det->tone_cycle_duration >= 425 * 8
-				    && det->tone_cycle_duration <= 475 * 8) {
-					det->good_cycles++;
-					if (det->good_cycles > 2)
-						det->hit = TRUE;
-				}
-				det->tone_cycle_duration = 0;
-			}
-			det->tone_present = TRUE;
-		} else
-			det->tone_present = FALSE;
-		det->tone_cycle_duration++;
-	} else {
-		det->tone_present = FALSE;
-		det->tone_cycle_duration = 0;
-		det->good_cycles = 0;
-	}
-	return det->hit;
-}
-/*- End of function --------------------------------------------------------*/
-/*- End of file ------------------------------------------------------------*/
diff --git a/drivers/isdn/mISDN/dsp_hwec.h b/drivers/isdn/mISDN/dsp_hwec.h
deleted file mode 100644
index c9cb0ea249da..000000000000
--- a/drivers/isdn/mISDN/dsp_hwec.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * dsp_hwec.h
- */
-
-extern struct mISDN_dsp_element *dsp_hwec;
-extern void dsp_hwec_enable(struct dsp *dsp, const char *arg);
-extern void dsp_hwec_disable(struct dsp *dsp);
-extern int  dsp_hwec_init(void);
-extern void dsp_hwec_exit(void);
diff --git a/drivers/isdn/mISDN/fsm.h b/drivers/isdn/mISDN/fsm.h
deleted file mode 100644
index 211554b997f8..000000000000
--- a/drivers/isdn/mISDN/fsm.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- *
- * Author       Karsten Keil <kkeil@novell.com>
- *
- * Thanks to    Jan den Ouden
- *              Fritz Elfert
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- */
-
-#ifndef _MISDN_FSM_H
-#define _MISDN_FSM_H
-
-#include <linux/timer.h>
-
-/* Statemachine */
-
-struct FsmInst;
-
-typedef void (*FSMFNPTR)(struct FsmInst *, int, void *);
-
-struct Fsm {
-	FSMFNPTR *jumpmatrix;
-	int state_count, event_count;
-	char **strEvent, **strState;
-};
-
-struct FsmInst {
-	struct Fsm *fsm;
-	int state;
-	int debug;
-	void *userdata;
-	int userint;
-	void (*printdebug) (struct FsmInst *, char *, ...);
-};
-
-struct FsmNode {
-	int state, event;
-	void (*routine) (struct FsmInst *, int, void *);
-};
-
-struct FsmTimer {
-	struct FsmInst *fi;
-	struct timer_list tl;
-	int event;
-	void *arg;
-};
-
-extern int mISDN_FsmNew(struct Fsm *, struct FsmNode *, int);
-extern void mISDN_FsmFree(struct Fsm *);
-extern int mISDN_FsmEvent(struct FsmInst *, int , void *);
-extern void mISDN_FsmChangeState(struct FsmInst *, int);
-extern void mISDN_FsmInitTimer(struct FsmInst *, struct FsmTimer *);
-extern int mISDN_FsmAddTimer(struct FsmTimer *, int, int, void *, int);
-extern void mISDN_FsmRestartTimer(struct FsmTimer *, int, int, void *, int);
-extern void mISDN_FsmDelTimer(struct FsmTimer *, int);
-
-#endif
diff --git a/drivers/isdn/mISDN/l1oip.h b/drivers/isdn/mISDN/l1oip.h
deleted file mode 100644
index 48133d022812..000000000000
--- a/drivers/isdn/mISDN/l1oip.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * see notice in l1oip.c
- */
-
-/* debugging */
-#define DEBUG_L1OIP_INIT	0x00010000
-#define DEBUG_L1OIP_SOCKET	0x00020000
-#define DEBUG_L1OIP_MGR		0x00040000
-#define DEBUG_L1OIP_MSG		0x00080000
-
-/* enable to disorder received bchannels by sequence 2143658798... */
-/*
-  #define REORDER_DEBUG
-*/
-
-/* frames */
-#define L1OIP_MAX_LEN		2048		/* max packet size form l2 */
-#define L1OIP_MAX_PERFRAME	1400		/* max data size in one frame */
-
-
-/* timers */
-#define L1OIP_KEEPALIVE		15
-#define L1OIP_TIMEOUT		65
-
-
-/* socket */
-#define L1OIP_DEFAULTPORT	931
-
-
-/* channel structure */
-struct l1oip_chan {
-	struct dchannel		*dch;
-	struct bchannel		*bch;
-	u32			tx_counter;	/* counts xmit bytes/packets */
-	u32			rx_counter;	/* counts recv bytes/packets */
-	u32			codecstate;	/* used by codec to save data */
-#ifdef REORDER_DEBUG
-	int			disorder_flag;
-	struct sk_buff		*disorder_skb;
-	u32			disorder_cnt;
-#endif
-};
-
-
-/* card structure */
-struct l1oip {
-	struct list_head        list;
-
-	/* card */
-	int			registered;	/* if registered with mISDN */
-	char			name[MISDN_MAX_IDLEN];
-	int			idx;		/* card index */
-	int			pri;		/* 1=pri, 0=bri */
-	int			d_idx;		/* current dchannel number */
-	int			b_num;		/* number of bchannels */
-	u32			id;		/* id of connection */
-	int			ondemand;	/* if transmis. is on demand */
-	int			bundle;		/* bundle channels in one frm */
-	int			codec;		/* codec to use for transmis. */
-	int			limit;		/* limit number of bchannels */
-	bool			shutdown;	/* if card is released */
-
-	/* timer */
-	struct timer_list	keep_tl;
-	struct timer_list	timeout_tl;
-	int			timeout_on;
-	struct work_struct	workq;
-
-	/* socket */
-	struct socket		*socket;	/* if set, socket is created */
-	struct completion	socket_complete;/* completion of sock thread */
-	struct task_struct	*socket_thread;
-	spinlock_t		socket_lock;	/* access sock outside thread */
-	u32			remoteip;	/* if all set, ip is assigned */
-	u16			localport;	/* must always be set */
-	u16			remoteport;	/* must always be set */
-	struct sockaddr_in	sin_local;	/* local socket name */
-	struct sockaddr_in	sin_remote;	/* remote socket name */
-	struct msghdr		sendmsg;	/* ip message to send */
-	struct kvec		sendiov;	/* iov for message */
-
-	/* frame */
-	struct l1oip_chan	chan[128];	/* channel instances */
-};
-
-extern int l1oip_law_to_4bit(u8 *data, int len, u8 *result, u32 *state);
-extern int l1oip_4bit_to_law(u8 *data, int len, u8 *result);
-extern int l1oip_alaw_to_ulaw(u8 *data, int len, u8 *result);
-extern int l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result);
-extern void l1oip_4bit_free(void);
-extern int l1oip_4bit_alloc(int ulaw);
diff --git a/drivers/isdn/mISDN/layer1.h b/drivers/isdn/mISDN/layer1.h
deleted file mode 100644
index f03e86450daf..000000000000
--- a/drivers/isdn/mISDN/layer1.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- *
- * Layer 1 defines
- *
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- */
-
-#define FLG_L1_ACTIVATING	1
-#define FLG_L1_ACTIVATED	2
-#define FLG_L1_DEACTTIMER	3
-#define FLG_L1_ACTTIMER		4
-#define FLG_L1_T3RUN		5
-#define FLG_L1_PULL_REQ		6
-#define FLG_L1_UINT		7
-#define FLG_L1_DBLOCKED		8
diff --git a/drivers/isdn/mISDN/layer2.h b/drivers/isdn/mISDN/layer2.h
deleted file mode 100644
index c466fd94aa02..000000000000
--- a/drivers/isdn/mISDN/layer2.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Layer 2 defines
- *
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- */
-
-#include <linux/mISDNif.h>
-#include <linux/skbuff.h>
-#include "fsm.h"
-
-#define MAX_WINDOW	8
-
-struct manager {
-	struct mISDNchannel	ch;
-	struct mISDNchannel	bcast;
-	u_long			options;
-	struct list_head	layer2;
-	rwlock_t		lock;
-	struct FsmInst		deact;
-	struct FsmTimer		datimer;
-	struct sk_buff_head	sendq;
-	struct mISDNchannel	*up;
-	u_int			nextid;
-	u_int			lastid;
-};
-
-struct teimgr {
-	int			ri;
-	int			rcnt;
-	struct FsmInst		tei_m;
-	struct FsmTimer		timer;
-	int			tval, nval;
-	struct layer2		*l2;
-	struct manager		*mgr;
-};
-
-struct laddr {
-	u_char	A;
-	u_char	B;
-};
-
-struct layer2 {
-	struct list_head	list;
-	struct mISDNchannel	ch;
-	u_long			flag;
-	int			id;
-	struct mISDNchannel	*up;
-	signed char		sapi;
-	signed char		tei;
-	struct laddr		addr;
-	u_int			maxlen;
-	struct teimgr		*tm;
-	u_int			vs, va, vr;
-	int			rc;
-	u_int			window;
-	u_int			sow;
-	struct FsmInst		l2m;
-	struct FsmTimer		t200, t203;
-	int			T200, N200, T203;
-	u_int			next_id;
-	u_int			down_id;
-	struct sk_buff		*windowar[MAX_WINDOW];
-	struct sk_buff_head	i_queue;
-	struct sk_buff_head	ui_queue;
-	struct sk_buff_head	down_queue;
-	struct sk_buff_head	tmp_queue;
-};
-
-enum {
-	ST_L2_1,
-	ST_L2_2,
-	ST_L2_3,
-	ST_L2_4,
-	ST_L2_5,
-	ST_L2_6,
-	ST_L2_7,
-	ST_L2_8,
-};
-
-#define L2_STATE_COUNT (ST_L2_8 + 1)
-
-extern struct layer2	*create_l2(struct mISDNchannel *, u_int,
-				   u_long, int, int);
-extern int		tei_l2(struct layer2 *, u_int, u_long arg);
-
-
-/* from tei.c */
-extern int		l2_tei(struct layer2 *, u_int, u_long arg);
-extern void		TEIrelease(struct layer2 *);
-extern int		TEIInit(u_int *);
-extern void		TEIFree(void);
-
-#define MAX_L2HEADER_LEN 4
-
-#define RR	0x01
-#define RNR	0x05
-#define REJ	0x09
-#define SABME	0x6f
-#define SABM	0x2f
-#define DM	0x0f
-#define UI	0x03
-#define DISC	0x43
-#define UA	0x63
-#define FRMR	0x87
-#define XID	0xaf
-
-#define CMD	0
-#define RSP	1
-
-#define LC_FLUSH_WAIT 1
-
-#define FLG_LAPB	0
-#define FLG_LAPD	1
-#define FLG_ORIG	2
-#define FLG_MOD128	3
-#define FLG_PEND_REL	4
-#define FLG_L3_INIT	5
-#define FLG_T200_RUN	6
-#define FLG_ACK_PEND	7
-#define FLG_REJEXC	8
-#define FLG_OWN_BUSY	9
-#define FLG_PEER_BUSY	10
-#define FLG_DCHAN_BUSY	11
-#define FLG_L1_ACTIV	12
-#define FLG_ESTAB_PEND	13
-#define FLG_PTP		14
-#define FLG_FIXED_TEI	15
-#define FLG_L2BLOCK	16
-#define FLG_L1_NOTREADY	17
-#define FLG_LAPD_NET	18
diff --git a/include/linux/isdn/capilli.h b/include/linux/isdn/capilli.h
deleted file mode 100644
index 12be09b6883b..000000000000
--- a/include/linux/isdn/capilli.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* $Id: capilli.h,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
- * 
- * Kernel CAPI 2.0 Driver Interface for Linux
- * 
- * Copyright 1999 by Carsten Paeth <calle@calle.de>
- * 
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef __CAPILLI_H__
-#define __CAPILLI_H__
-
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/capi.h>
-#include <linux/kernelcapi.h>
-
-typedef struct capiloaddatapart {
-	int user;		/* data in userspace ? */
-	int len;
-	unsigned char *data;
-} capiloaddatapart;
-
-typedef struct capiloaddata {
-	capiloaddatapart firmware;
-	capiloaddatapart configuration;
-} capiloaddata;
-
-typedef struct capicardparams {
-	unsigned int port;
-	unsigned irq;
-	int cardtype;
-	int cardnr;
-	unsigned int membase;
-} capicardparams;
-
-struct capi_ctr {
-	/* filled in before calling attach_capi_ctr */
-	struct module *owner;
-	void *driverdata;			/* driver specific */
-	char name[32];				/* name of controller */
-	char *driver_name;			/* name of driver */
-	int (*load_firmware)(struct capi_ctr *, capiloaddata *);
-	void (*reset_ctr)(struct capi_ctr *);
-	void (*register_appl)(struct capi_ctr *, u16 appl,
-			      capi_register_params *);
-	void (*release_appl)(struct capi_ctr *, u16 appl);
-	u16  (*send_message)(struct capi_ctr *, struct sk_buff *skb);
-	
-	char *(*procinfo)(struct capi_ctr *);
-	int (*proc_show)(struct seq_file *, void *);
-
-	/* filled in before calling ready callback */
-	u8 manu[CAPI_MANUFACTURER_LEN];		/* CAPI_GET_MANUFACTURER */
-	capi_version version;			/* CAPI_GET_VERSION */
-	capi_profile profile;			/* CAPI_GET_PROFILE */
-	u8 serial[CAPI_SERIAL_LEN];		/* CAPI_GET_SERIAL */
-
-	/* management information for kcapi */
-
-	unsigned long nrecvctlpkt;
-	unsigned long nrecvdatapkt;
-	unsigned long nsentctlpkt;
-	unsigned long nsentdatapkt;
-
-	int cnr;				/* controller number */
-	unsigned short state;			/* controller state */
-	int blocked;				/* output blocked */
-	int traceflag;				/* capi trace */
-
-	struct proc_dir_entry *procent;
-        char procfn[128];
-};
-
-int attach_capi_ctr(struct capi_ctr *);
-int detach_capi_ctr(struct capi_ctr *);
-
-void capi_ctr_ready(struct capi_ctr * card);
-void capi_ctr_down(struct capi_ctr * card);
-void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *skb);
-
-// ---------------------------------------------------------------------------
-// needed for AVM capi drivers
-
-struct capi_driver {
-	char name[32];				/* driver name */
-	char revision[32];
-
-	/* management information for kcapi */
-	struct list_head list; 
-};
-
-#endif				/* __CAPILLI_H__ */
diff --git a/include/linux/isdn/capiutil.h b/include/linux/isdn/capiutil.h
deleted file mode 100644
index 953fd500dff7..000000000000
--- a/include/linux/isdn/capiutil.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* $Id: capiutil.h,v 1.5.6.2 2001/09/23 22:24:33 kai Exp $
- *
- * CAPI 2.0 defines & types
- *
- * From CAPI 2.0 Development Kit AVM 1995 (msg.c)
- * Rewritten for Linux 1996 by Carsten Paeth <calle@calle.de>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef __CAPIUTIL_H__
-#define __CAPIUTIL_H__
-
-#include <asm/types.h>
-
-#define CAPIMSG_BASELEN		8
-#define CAPIMSG_U8(m, off)	(m[off])
-#define CAPIMSG_U16(m, off)	(m[off]|(m[(off)+1]<<8))
-#define CAPIMSG_U32(m, off)	(m[off]|(m[(off)+1]<<8)|(m[(off)+2]<<16)|(m[(off)+3]<<24))
-#define	CAPIMSG_LEN(m)		CAPIMSG_U16(m,0)
-#define	CAPIMSG_APPID(m)	CAPIMSG_U16(m,2)
-#define	CAPIMSG_COMMAND(m)	CAPIMSG_U8(m,4)
-#define	CAPIMSG_SUBCOMMAND(m)	CAPIMSG_U8(m,5)
-#define CAPIMSG_CMD(m)		(((m[4])<<8)|(m[5]))
-#define	CAPIMSG_MSGID(m)	CAPIMSG_U16(m,6)
-#define CAPIMSG_CONTROLLER(m)	(m[8] & 0x7f)
-#define CAPIMSG_CONTROL(m)	CAPIMSG_U32(m, 8)
-#define CAPIMSG_NCCI(m)		CAPIMSG_CONTROL(m)
-#define CAPIMSG_DATALEN(m)	CAPIMSG_U16(m,16) /* DATA_B3_REQ */
-
-static inline void capimsg_setu8(void *m, int off, __u8 val)
-{
-	((__u8 *)m)[off] = val;
-}
-
-static inline void capimsg_setu16(void *m, int off, __u16 val)
-{
-	((__u8 *)m)[off] = val & 0xff;
-	((__u8 *)m)[off+1] = (val >> 8) & 0xff;
-}
-
-static inline void capimsg_setu32(void *m, int off, __u32 val)
-{
-	((__u8 *)m)[off] = val & 0xff;
-	((__u8 *)m)[off+1] = (val >> 8) & 0xff;
-	((__u8 *)m)[off+2] = (val >> 16) & 0xff;
-	((__u8 *)m)[off+3] = (val >> 24) & 0xff;
-}
-
-#define	CAPIMSG_SETLEN(m, len)		capimsg_setu16(m, 0, len)
-#define	CAPIMSG_SETAPPID(m, applid)	capimsg_setu16(m, 2, applid)
-#define	CAPIMSG_SETCOMMAND(m,cmd)	capimsg_setu8(m, 4, cmd)
-#define	CAPIMSG_SETSUBCOMMAND(m, cmd)	capimsg_setu8(m, 5, cmd)
-#define	CAPIMSG_SETMSGID(m, msgid)	capimsg_setu16(m, 6, msgid)
-#define	CAPIMSG_SETCONTROL(m, contr)	capimsg_setu32(m, 8, contr)
-#define	CAPIMSG_SETDATALEN(m, len)	capimsg_setu16(m, 16, len)
-
-#endif				/* __CAPIUTIL_H__ */
diff --git a/include/linux/kernelcapi.h b/include/linux/kernelcapi.h
deleted file mode 100644
index 94ba42bf9da1..000000000000
--- a/include/linux/kernelcapi.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * $Id: kernelcapi.h,v 1.8.6.2 2001/02/07 11:31:31 kai Exp $
- * 
- * Kernel CAPI 2.0 Interface for Linux
- * 
- * (c) Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
- * 
- */
-#ifndef __KERNELCAPI_H__
-#define __KERNELCAPI_H__
-
-#include <linux/list.h>
-#include <linux/skbuff.h>
-#include <linux/workqueue.h>
-#include <linux/notifier.h>
-#include <uapi/linux/kernelcapi.h>
-
-#define CAPI_NOERROR                      0x0000
-
-#define CAPI_TOOMANYAPPLS		  0x1001
-#define CAPI_LOGBLKSIZETOSMALL	          0x1002
-#define CAPI_BUFFEXECEEDS64K 	          0x1003
-#define CAPI_MSGBUFSIZETOOSMALL	          0x1004
-#define CAPI_ANZLOGCONNNOTSUPPORTED	  0x1005
-#define CAPI_REGRESERVED		  0x1006
-#define CAPI_REGBUSY 		          0x1007
-#define CAPI_REGOSRESOURCEERR	          0x1008
-#define CAPI_REGNOTINSTALLED 	          0x1009
-#define CAPI_REGCTRLERNOTSUPPORTEXTEQUIP  0x100a
-#define CAPI_REGCTRLERONLYSUPPORTEXTEQUIP 0x100b
-
-#define CAPI_ILLAPPNR		          0x1101
-#define CAPI_ILLCMDORSUBCMDORMSGTOSMALL   0x1102
-#define CAPI_SENDQUEUEFULL		  0x1103
-#define CAPI_RECEIVEQUEUEEMPTY	          0x1104
-#define CAPI_RECEIVEOVERFLOW 	          0x1105
-#define CAPI_UNKNOWNNOTPAR		  0x1106
-#define CAPI_MSGBUSY 		          0x1107
-#define CAPI_MSGOSRESOURCEERR	          0x1108
-#define CAPI_MSGNOTINSTALLED 	          0x1109
-#define CAPI_MSGCTRLERNOTSUPPORTEXTEQUIP  0x110a
-#define CAPI_MSGCTRLERONLYSUPPORTEXTEQUIP 0x110b
-
-#endif				/* __KERNELCAPI_H__ */
diff --git a/include/linux/mISDNdsp.h b/include/linux/mISDNdsp.h
deleted file mode 100644
index 00758f45fddc..000000000000
--- a/include/linux/mISDNdsp.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __mISDNdsp_H__
-#define __mISDNdsp_H__
-
-struct mISDN_dsp_element_arg {
-	char	*name;
-	char	*def;
-	char	*desc;
-};
-
-struct mISDN_dsp_element {
-	char	*name;
-	void	*(*new)(const char *arg);
-	void	(*free)(void *p);
-	void	(*process_tx)(void *p, unsigned char *data, int len);
-	void	(*process_rx)(void *p, unsigned char *data, int len,
-			unsigned int txlen);
-	int	num_args;
-	struct mISDN_dsp_element_arg
-		*args;
-};
-
-extern int  mISDN_dsp_element_register(struct mISDN_dsp_element *elem);
-extern void mISDN_dsp_element_unregister(struct mISDN_dsp_element *elem);
-
-struct dsp_features {
-	int	hfc_id; /* unique id to identify the chip (or -1) */
-	int	hfc_dtmf; /* set if HFCmulti card supports dtmf */
-	int	hfc_conf; /* set if HFCmulti card supports conferences */
-	int	hfc_loops; /* set if card supports tone loops */
-	int	hfc_echocanhw; /* set if card supports echocancelation*/
-	int	pcm_id; /* unique id to identify the pcm bus (or -1) */
-	int	pcm_slots; /* number of slots on the pcm bus */
-	int	pcm_banks; /* number of IO banks of pcm bus */
-	int	unclocked; /* data is not clocked (has jitter/loss) */
-	int	unordered; /* data is unordered (packets have index) */
-};
-
-#endif
-
diff --git a/include/linux/mISDNhw.h b/include/linux/mISDNhw.h
deleted file mode 100644
index ef4f8eb02eac..000000000000
--- a/include/linux/mISDNhw.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- *
- * Author	Karsten Keil <kkeil@novell.com>
- *
- *   Basic declarations for the mISDN HW channels
- *
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- */
-
-#ifndef MISDNHW_H
-#define MISDNHW_H
-#include <linux/mISDNif.h>
-#include <linux/timer.h>
-
-/*
- * HW DEBUG 0xHHHHGGGG
- * H - hardware driver specific bits
- * G - for all drivers
- */
-
-#define DEBUG_HW		0x00000001
-#define DEBUG_HW_OPEN		0x00000002
-#define DEBUG_HW_DCHANNEL	0x00000100
-#define DEBUG_HW_DFIFO		0x00000200
-#define DEBUG_HW_BCHANNEL	0x00001000
-#define DEBUG_HW_BFIFO		0x00002000
-
-#define MAX_DFRAME_LEN_L1	300
-#define MAX_MON_FRAME		32
-#define MAX_LOG_SPACE		2048
-#define MISDN_COPY_SIZE		32
-
-/* channel->Flags bit field */
-#define FLG_TX_BUSY		0	/* tx_buf in use */
-#define FLG_TX_NEXT		1	/* next_skb in use */
-#define FLG_L1_BUSY		2	/* L1 is permanent busy */
-#define FLG_L2_ACTIVATED	3	/* activated from L2 */
-#define FLG_OPEN		5	/* channel is in use */
-#define FLG_ACTIVE		6	/* channel is activated */
-#define FLG_BUSY_TIMER		7
-/* channel type */
-#define FLG_DCHANNEL		8	/* channel is D-channel */
-#define FLG_BCHANNEL		9	/* channel is B-channel */
-#define FLG_ECHANNEL		10	/* channel is E-channel */
-#define FLG_TRANSPARENT		12	/* channel use transparent data */
-#define FLG_HDLC		13	/* channel use hdlc data */
-#define FLG_L2DATA		14	/* channel use L2 DATA primitivs */
-#define FLG_ORIGIN		15	/* channel is on origin site */
-/* channel specific stuff */
-#define FLG_FILLEMPTY		16	/* fill fifo on first frame (empty) */
-/* arcofi specific */
-#define FLG_ARCOFI_TIMER	17
-#define FLG_ARCOFI_ERROR	18
-/* isar specific */
-#define FLG_INITIALIZED		17
-#define FLG_DLEETX		18
-#define FLG_LASTDLE		19
-#define FLG_FIRST		20
-#define FLG_LASTDATA		21
-#define FLG_NMD_DATA		22
-#define FLG_FTI_RUN		23
-#define FLG_LL_OK		24
-#define FLG_LL_CONN		25
-#define FLG_DTMFSEND		26
-#define FLG_TX_EMPTY		27
-/* stop sending received data upstream */
-#define FLG_RX_OFF		28
-/* workq events */
-#define FLG_RECVQUEUE		30
-#define	FLG_PHCHANGE		31
-
-#define schedule_event(s, ev)	do { \
-					test_and_set_bit(ev, &((s)->Flags)); \
-					schedule_work(&((s)->workq)); \
-				} while (0)
-
-struct dchannel {
-	struct mISDNdevice	dev;
-	u_long			Flags;
-	struct work_struct	workq;
-	void			(*phfunc) (struct dchannel *);
-	u_int			state;
-	void			*l1;
-	void			*hw;
-	int			slot;	/* multiport card channel slot */
-	struct timer_list	timer;
-	/* receive data */
-	struct sk_buff		*rx_skb;
-	int			maxlen;
-	/* send data */
-	struct sk_buff_head	squeue;
-	struct sk_buff_head	rqueue;
-	struct sk_buff		*tx_skb;
-	int			tx_idx;
-	int			debug;
-	/* statistics */
-	int			err_crc;
-	int			err_tx;
-	int			err_rx;
-};
-
-typedef int	(dchannel_l1callback)(struct dchannel *, u_int);
-extern int	create_l1(struct dchannel *, dchannel_l1callback *);
-
-/* private L1 commands */
-#define INFO0		0x8002
-#define INFO1		0x8102
-#define INFO2		0x8202
-#define INFO3_P8	0x8302
-#define INFO3_P10	0x8402
-#define INFO4_P8	0x8502
-#define INFO4_P10	0x8602
-#define LOSTFRAMING	0x8702
-#define ANYSIGNAL	0x8802
-#define HW_POWERDOWN	0x8902
-#define HW_RESET_REQ	0x8a02
-#define HW_POWERUP_REQ	0x8b02
-#define HW_DEACT_REQ	0x8c02
-#define HW_ACTIVATE_REQ	0x8e02
-#define HW_D_NOBLOCKED  0x8f02
-#define HW_RESET_IND	0x9002
-#define HW_POWERUP_IND	0x9102
-#define HW_DEACT_IND	0x9202
-#define HW_ACTIVATE_IND	0x9302
-#define HW_DEACT_CNF	0x9402
-#define HW_TESTLOOP	0x9502
-#define HW_TESTRX_RAW	0x9602
-#define HW_TESTRX_HDLC	0x9702
-#define HW_TESTRX_OFF	0x9802
-#define HW_TIMER3_IND	0x9902
-#define HW_TIMER3_VALUE	0x9a00
-#define HW_TIMER3_VMASK	0x00FF
-
-struct layer1;
-extern int	l1_event(struct layer1 *, u_int);
-
-#define MISDN_BCH_FILL_SIZE	4
-
-struct bchannel {
-	struct mISDNchannel	ch;
-	int			nr;
-	u_long			Flags;
-	struct work_struct	workq;
-	u_int			state;
-	void			*hw;
-	int			slot;	/* multiport card channel slot */
-	struct timer_list	timer;
-	/* receive data */
-	u8			fill[MISDN_BCH_FILL_SIZE];
-	struct sk_buff		*rx_skb;
-	unsigned short		maxlen;
-	unsigned short		init_maxlen; /* initial value */
-	unsigned short		next_maxlen; /* pending value */
-	unsigned short		minlen; /* for transparent data */
-	unsigned short		init_minlen; /* initial value */
-	unsigned short		next_minlen; /* pending value */
-	/* send data */
-	struct sk_buff		*next_skb;
-	struct sk_buff		*tx_skb;
-	struct sk_buff_head	rqueue;
-	int			rcount;
-	int			tx_idx;
-	int			debug;
-	/* statistics */
-	int			err_crc;
-	int			err_tx;
-	int			err_rx;
-	int			dropcnt;
-};
-
-extern int	mISDN_initdchannel(struct dchannel *, int, void *);
-extern int	mISDN_initbchannel(struct bchannel *, unsigned short,
-				   unsigned short);
-extern int	mISDN_freedchannel(struct dchannel *);
-extern void	mISDN_clear_bchannel(struct bchannel *);
-extern void	mISDN_freebchannel(struct bchannel *);
-extern int	mISDN_ctrl_bchannel(struct bchannel *, struct mISDN_ctrl_req *);
-extern void	queue_ch_frame(struct mISDNchannel *, u_int,
-			int, struct sk_buff *);
-extern int	dchannel_senddata(struct dchannel *, struct sk_buff *);
-extern int	bchannel_senddata(struct bchannel *, struct sk_buff *);
-extern int      bchannel_get_rxbuf(struct bchannel *, int);
-extern void	recv_Dchannel(struct dchannel *);
-extern void	recv_Echannel(struct dchannel *, struct dchannel *);
-extern void	recv_Bchannel(struct bchannel *, unsigned int, bool);
-extern void	recv_Dchannel_skb(struct dchannel *, struct sk_buff *);
-extern void	recv_Bchannel_skb(struct bchannel *, struct sk_buff *);
-extern int	get_next_bframe(struct bchannel *);
-extern int	get_next_dframe(struct dchannel *);
-
-#endif
diff --git a/include/linux/mISDNif.h b/include/linux/mISDNif.h
deleted file mode 100644
index 7aab4a769736..000000000000
--- a/include/linux/mISDNif.h
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- *
- * Author	Karsten Keil <kkeil@novell.com>
- *
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- *
- * This code is free software; you can redistribute it and/or modify
- * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
- * version 2.1 as published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU LESSER GENERAL PUBLIC LICENSE for more details.
- *
- */
-
-#ifndef mISDNIF_H
-#define mISDNIF_H
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/socket.h>
-
-/*
- * ABI Version 32 bit
- *
- * <8 bit> Major version
- *		- changed if any interface become backwards incompatible
- *
- * <8 bit> Minor version
- *              - changed if any interface is extended but backwards compatible
- *
- * <16 bit> Release number
- *              - should be incremented on every checkin
- */
-#define	MISDN_MAJOR_VERSION	1
-#define	MISDN_MINOR_VERSION	1
-#define MISDN_RELEASE		29
-
-/* primitives for information exchange
- * generell format
- * <16  bit  0 >
- * <8  bit command>
- *    BIT 8 = 1 LAYER private
- *    BIT 7 = 1 answer
- *    BIT 6 = 1 DATA
- * <8  bit target layer mask>
- *
- * Layer = 00 is reserved for general commands
-   Layer = 01  L2 -> HW
-   Layer = 02  HW -> L2
-   Layer = 04  L3 -> L2
-   Layer = 08  L2 -> L3
- * Layer = FF is reserved for broadcast commands
- */
-
-#define MISDN_CMDMASK		0xff00
-#define MISDN_LAYERMASK		0x00ff
-
-/* generell commands */
-#define OPEN_CHANNEL		0x0100
-#define CLOSE_CHANNEL		0x0200
-#define CONTROL_CHANNEL		0x0300
-#define CHECK_DATA		0x0400
-
-/* layer 2 -> layer 1 */
-#define PH_ACTIVATE_REQ		0x0101
-#define PH_DEACTIVATE_REQ	0x0201
-#define PH_DATA_REQ		0x2001
-#define MPH_ACTIVATE_REQ	0x0501
-#define MPH_DEACTIVATE_REQ	0x0601
-#define MPH_INFORMATION_REQ	0x0701
-#define PH_CONTROL_REQ		0x0801
-
-/* layer 1 -> layer 2 */
-#define PH_ACTIVATE_IND		0x0102
-#define PH_ACTIVATE_CNF		0x4102
-#define PH_DEACTIVATE_IND	0x0202
-#define PH_DEACTIVATE_CNF	0x4202
-#define PH_DATA_IND		0x2002
-#define PH_DATA_E_IND		0x3002
-#define MPH_ACTIVATE_IND	0x0502
-#define MPH_DEACTIVATE_IND	0x0602
-#define MPH_INFORMATION_IND	0x0702
-#define PH_DATA_CNF		0x6002
-#define PH_CONTROL_IND		0x0802
-#define PH_CONTROL_CNF		0x4802
-
-/* layer 3 -> layer 2 */
-#define DL_ESTABLISH_REQ	0x1004
-#define DL_RELEASE_REQ		0x1104
-#define DL_DATA_REQ		0x3004
-#define DL_UNITDATA_REQ		0x3104
-#define DL_INFORMATION_REQ	0x0004
-
-/* layer 2 -> layer 3 */
-#define DL_ESTABLISH_IND	0x1008
-#define DL_ESTABLISH_CNF	0x5008
-#define DL_RELEASE_IND		0x1108
-#define DL_RELEASE_CNF		0x5108
-#define DL_DATA_IND		0x3008
-#define DL_UNITDATA_IND		0x3108
-#define DL_INFORMATION_IND	0x0008
-
-/* intern layer 2 management */
-#define MDL_ASSIGN_REQ		0x1804
-#define MDL_ASSIGN_IND		0x1904
-#define MDL_REMOVE_REQ		0x1A04
-#define MDL_REMOVE_IND		0x1B04
-#define MDL_STATUS_UP_IND	0x1C04
-#define MDL_STATUS_DOWN_IND	0x1D04
-#define MDL_STATUS_UI_IND	0x1E04
-#define MDL_ERROR_IND		0x1F04
-#define MDL_ERROR_RSP		0x5F04
-
-/* intern layer 2 */
-#define DL_TIMER200_IND		0x7004
-#define DL_TIMER203_IND		0x7304
-#define DL_INTERN_MSG		0x7804
-
-/* DL_INFORMATION_IND types */
-#define DL_INFO_L2_CONNECT	0x0001
-#define DL_INFO_L2_REMOVED	0x0002
-
-/* PH_CONTROL types */
-/* TOUCH TONE IS 0x20XX  XX "0"..."9", "A","B","C","D","*","#" */
-#define DTMF_TONE_VAL		0x2000
-#define DTMF_TONE_MASK		0x007F
-#define DTMF_TONE_START		0x2100
-#define DTMF_TONE_STOP		0x2200
-#define DTMF_HFC_COEF		0x4000
-#define DSP_CONF_JOIN		0x2403
-#define DSP_CONF_SPLIT		0x2404
-#define DSP_RECEIVE_OFF		0x2405
-#define DSP_RECEIVE_ON		0x2406
-#define DSP_ECHO_ON		0x2407
-#define DSP_ECHO_OFF		0x2408
-#define DSP_MIX_ON		0x2409
-#define DSP_MIX_OFF		0x240a
-#define DSP_DELAY		0x240b
-#define DSP_JITTER		0x240c
-#define DSP_TXDATA_ON		0x240d
-#define DSP_TXDATA_OFF		0x240e
-#define DSP_TX_DEJITTER		0x240f
-#define DSP_TX_DEJ_OFF		0x2410
-#define DSP_TONE_PATT_ON	0x2411
-#define DSP_TONE_PATT_OFF	0x2412
-#define DSP_VOL_CHANGE_TX	0x2413
-#define DSP_VOL_CHANGE_RX	0x2414
-#define DSP_BF_ENABLE_KEY	0x2415
-#define DSP_BF_DISABLE		0x2416
-#define DSP_BF_ACCEPT		0x2416
-#define DSP_BF_REJECT		0x2417
-#define DSP_PIPELINE_CFG	0x2418
-#define HFC_VOL_CHANGE_TX	0x2601
-#define HFC_VOL_CHANGE_RX	0x2602
-#define HFC_SPL_LOOP_ON		0x2603
-#define HFC_SPL_LOOP_OFF	0x2604
-/* for T30 FAX and analog modem */
-#define HW_MOD_FRM		0x4000
-#define HW_MOD_FRH		0x4001
-#define HW_MOD_FTM		0x4002
-#define HW_MOD_FTH		0x4003
-#define HW_MOD_FTS		0x4004
-#define HW_MOD_CONNECT		0x4010
-#define HW_MOD_OK		0x4011
-#define HW_MOD_NOCARR		0x4012
-#define HW_MOD_FCERROR		0x4013
-#define HW_MOD_READY		0x4014
-#define HW_MOD_LASTDATA		0x4015
-
-/* DSP_TONE_PATT_ON parameter */
-#define TONE_OFF			0x0000
-#define TONE_GERMAN_DIALTONE		0x0001
-#define TONE_GERMAN_OLDDIALTONE		0x0002
-#define TONE_AMERICAN_DIALTONE		0x0003
-#define TONE_GERMAN_DIALPBX		0x0004
-#define TONE_GERMAN_OLDDIALPBX		0x0005
-#define TONE_AMERICAN_DIALPBX		0x0006
-#define TONE_GERMAN_RINGING		0x0007
-#define TONE_GERMAN_OLDRINGING		0x0008
-#define TONE_AMERICAN_RINGPBX		0x000b
-#define TONE_GERMAN_RINGPBX		0x000c
-#define TONE_GERMAN_OLDRINGPBX		0x000d
-#define TONE_AMERICAN_RINGING		0x000e
-#define TONE_GERMAN_BUSY		0x000f
-#define TONE_GERMAN_OLDBUSY		0x0010
-#define TONE_AMERICAN_BUSY		0x0011
-#define TONE_GERMAN_HANGUP		0x0012
-#define TONE_GERMAN_OLDHANGUP		0x0013
-#define TONE_AMERICAN_HANGUP		0x0014
-#define TONE_SPECIAL_INFO		0x0015
-#define TONE_GERMAN_GASSENBESETZT	0x0016
-#define TONE_GERMAN_AUFSCHALTTON	0x0016
-
-/* MPH_INFORMATION_IND */
-#define L1_SIGNAL_LOS_OFF	0x0010
-#define L1_SIGNAL_LOS_ON	0x0011
-#define L1_SIGNAL_AIS_OFF	0x0012
-#define L1_SIGNAL_AIS_ON	0x0013
-#define L1_SIGNAL_RDI_OFF	0x0014
-#define L1_SIGNAL_RDI_ON	0x0015
-#define L1_SIGNAL_SLIP_RX	0x0020
-#define L1_SIGNAL_SLIP_TX	0x0021
-
-/*
- * protocol ids
- * D channel 1-31
- * B channel 33 - 63
- */
-
-#define ISDN_P_NONE		0
-#define ISDN_P_BASE		0
-#define ISDN_P_TE_S0		0x01
-#define ISDN_P_NT_S0  		0x02
-#define ISDN_P_TE_E1		0x03
-#define ISDN_P_NT_E1  		0x04
-#define ISDN_P_TE_UP0		0x05
-#define ISDN_P_NT_UP0		0x06
-
-#define IS_ISDN_P_TE(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_TE_E1) || \
-				(p == ISDN_P_TE_UP0) || (p == ISDN_P_LAPD_TE))
-#define IS_ISDN_P_NT(p) ((p == ISDN_P_NT_S0) || (p == ISDN_P_NT_E1) || \
-				(p == ISDN_P_NT_UP0) || (p == ISDN_P_LAPD_NT))
-#define IS_ISDN_P_S0(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_NT_S0))
-#define IS_ISDN_P_E1(p) ((p == ISDN_P_TE_E1) || (p == ISDN_P_NT_E1))
-#define IS_ISDN_P_UP0(p) ((p == ISDN_P_TE_UP0) || (p == ISDN_P_NT_UP0))
-
-
-#define ISDN_P_LAPD_TE		0x10
-#define	ISDN_P_LAPD_NT		0x11
-
-#define ISDN_P_B_MASK		0x1f
-#define ISDN_P_B_START		0x20
-
-#define ISDN_P_B_RAW		0x21
-#define ISDN_P_B_HDLC		0x22
-#define ISDN_P_B_X75SLP		0x23
-#define ISDN_P_B_L2DTMF		0x24
-#define ISDN_P_B_L2DSP		0x25
-#define ISDN_P_B_L2DSPHDLC	0x26
-#define ISDN_P_B_T30_FAX	0x27
-#define ISDN_P_B_MODEM_ASYNC	0x28
-
-#define OPTION_L2_PMX		1
-#define OPTION_L2_PTP		2
-#define OPTION_L2_FIXEDTEI	3
-#define OPTION_L2_CLEANUP	4
-#define OPTION_L1_HOLD		5
-
-/* should be in sync with linux/kobject.h:KOBJ_NAME_LEN */
-#define MISDN_MAX_IDLEN		20
-
-struct mISDNhead {
-	unsigned int	prim;
-	unsigned int	id;
-}  __packed;
-
-#define MISDN_HEADER_LEN	sizeof(struct mISDNhead)
-#define MAX_DATA_SIZE		2048
-#define MAX_DATA_MEM		(MAX_DATA_SIZE + MISDN_HEADER_LEN)
-#define MAX_DFRAME_LEN		260
-
-#define MISDN_ID_ADDR_MASK	0xFFFF
-#define MISDN_ID_TEI_MASK	0xFF00
-#define MISDN_ID_SAPI_MASK	0x00FF
-#define MISDN_ID_TEI_ANY	0x7F00
-
-#define MISDN_ID_ANY		0xFFFF
-#define MISDN_ID_NONE		0xFFFE
-
-#define GROUP_TEI		127
-#define TEI_SAPI		63
-#define CTRL_SAPI		0
-
-#define MISDN_MAX_CHANNEL	127
-#define MISDN_CHMAP_SIZE	((MISDN_MAX_CHANNEL + 1) >> 3)
-
-#define SOL_MISDN	0
-
-struct sockaddr_mISDN {
-	sa_family_t    family;
-	unsigned char	dev;
-	unsigned char	channel;
-	unsigned char	sapi;
-	unsigned char	tei;
-};
-
-struct mISDNversion {
-	unsigned char	major;
-	unsigned char	minor;
-	unsigned short	release;
-};
-
-struct mISDN_devinfo {
-	u_int			id;
-	u_int			Dprotocols;
-	u_int			Bprotocols;
-	u_int			protocol;
-	u_char			channelmap[MISDN_CHMAP_SIZE];
-	u_int			nrbchan;
-	char			name[MISDN_MAX_IDLEN];
-};
-
-struct mISDN_devrename {
-	u_int			id;
-	char			name[MISDN_MAX_IDLEN]; /* new name */
-};
-
-/* MPH_INFORMATION_REQ payload */
-struct ph_info_ch {
-	__u32 protocol;
-	__u64 Flags;
-};
-
-struct ph_info_dch {
-	struct ph_info_ch ch;
-	__u16 state;
-	__u16 num_bch;
-};
-
-struct ph_info {
-	struct ph_info_dch dch;
-	struct ph_info_ch  bch[];
-};
-
-/* timer device ioctl */
-#define IMADDTIMER	_IOR('I', 64, int)
-#define IMDELTIMER	_IOR('I', 65, int)
-
-/* socket ioctls */
-#define	IMGETVERSION	_IOR('I', 66, int)
-#define	IMGETCOUNT	_IOR('I', 67, int)
-#define IMGETDEVINFO	_IOR('I', 68, int)
-#define IMCTRLREQ	_IOR('I', 69, int)
-#define IMCLEAR_L2	_IOR('I', 70, int)
-#define IMSETDEVNAME	_IOR('I', 71, struct mISDN_devrename)
-#define IMHOLD_L1	_IOR('I', 72, int)
-
-static inline int
-test_channelmap(u_int nr, u_char *map)
-{
-	if (nr <= MISDN_MAX_CHANNEL)
-		return map[nr >> 3] & (1 << (nr & 7));
-	else
-		return 0;
-}
-
-static inline void
-set_channelmap(u_int nr, u_char *map)
-{
-	map[nr >> 3] |= (1 << (nr & 7));
-}
-
-static inline void
-clear_channelmap(u_int nr, u_char *map)
-{
-	map[nr >> 3] &= ~(1 << (nr & 7));
-}
-
-/* CONTROL_CHANNEL parameters */
-#define MISDN_CTRL_GETOP		0x0000
-#define MISDN_CTRL_LOOP			0x0001
-#define MISDN_CTRL_CONNECT		0x0002
-#define MISDN_CTRL_DISCONNECT		0x0004
-#define MISDN_CTRL_RX_BUFFER		0x0008
-#define MISDN_CTRL_PCMCONNECT		0x0010
-#define MISDN_CTRL_PCMDISCONNECT	0x0020
-#define MISDN_CTRL_SETPEER		0x0040
-#define MISDN_CTRL_UNSETPEER		0x0080
-#define MISDN_CTRL_RX_OFF		0x0100
-#define MISDN_CTRL_FILL_EMPTY		0x0200
-#define MISDN_CTRL_GETPEER		0x0400
-#define MISDN_CTRL_L1_TIMER3		0x0800
-#define MISDN_CTRL_HW_FEATURES_OP	0x2000
-#define MISDN_CTRL_HW_FEATURES		0x2001
-#define MISDN_CTRL_HFC_OP		0x4000
-#define MISDN_CTRL_HFC_PCM_CONN		0x4001
-#define MISDN_CTRL_HFC_PCM_DISC		0x4002
-#define MISDN_CTRL_HFC_CONF_JOIN	0x4003
-#define MISDN_CTRL_HFC_CONF_SPLIT	0x4004
-#define MISDN_CTRL_HFC_RECEIVE_OFF	0x4005
-#define MISDN_CTRL_HFC_RECEIVE_ON	0x4006
-#define MISDN_CTRL_HFC_ECHOCAN_ON 	0x4007
-#define MISDN_CTRL_HFC_ECHOCAN_OFF 	0x4008
-#define MISDN_CTRL_HFC_WD_INIT		0x4009
-#define MISDN_CTRL_HFC_WD_RESET		0x400A
-
-/* special RX buffer value for MISDN_CTRL_RX_BUFFER request.p1 is the minimum
- * buffer size request.p2 the maximum. Using  MISDN_CTRL_RX_SIZE_IGNORE will
- * not change the value, but still read back the actual stetting.
- */
-#define MISDN_CTRL_RX_SIZE_IGNORE	-1
-
-/* socket options */
-#define MISDN_TIME_STAMP		0x0001
-
-struct mISDN_ctrl_req {
-	int		op;
-	int		channel;
-	int		p1;
-	int		p2;
-};
-
-/* muxer options */
-#define MISDN_OPT_ALL		1
-#define MISDN_OPT_TEIMGR	2
-
-#ifdef __KERNEL__
-#include <linux/list.h>
-#include <linux/skbuff.h>
-#include <linux/net.h>
-#include <net/sock.h>
-#include <linux/completion.h>
-
-#define DEBUG_CORE		0x000000ff
-#define DEBUG_CORE_FUNC		0x00000002
-#define DEBUG_SOCKET		0x00000004
-#define DEBUG_MANAGER		0x00000008
-#define DEBUG_SEND_ERR		0x00000010
-#define DEBUG_MSG_THREAD	0x00000020
-#define DEBUG_QUEUE_FUNC	0x00000040
-#define DEBUG_L1		0x0000ff00
-#define DEBUG_L1_FSM		0x00000200
-#define DEBUG_L2		0x00ff0000
-#define DEBUG_L2_FSM		0x00020000
-#define DEBUG_L2_CTRL		0x00040000
-#define DEBUG_L2_RECV		0x00080000
-#define DEBUG_L2_TEI		0x00100000
-#define DEBUG_L2_TEIFSM		0x00200000
-#define DEBUG_TIMER		0x01000000
-#define DEBUG_CLOCK		0x02000000
-
-#define mISDN_HEAD_P(s)		((struct mISDNhead *)&s->cb[0])
-#define mISDN_HEAD_PRIM(s)	(((struct mISDNhead *)&s->cb[0])->prim)
-#define mISDN_HEAD_ID(s)	(((struct mISDNhead *)&s->cb[0])->id)
-
-/* socket states */
-#define MISDN_OPEN	1
-#define MISDN_BOUND	2
-#define MISDN_CLOSED	3
-
-struct mISDNchannel;
-struct mISDNdevice;
-struct mISDNstack;
-struct mISDNclock;
-
-struct channel_req {
-	u_int			protocol;
-	struct sockaddr_mISDN	adr;
-	struct mISDNchannel	*ch;
-};
-
-typedef	int	(ctrl_func_t)(struct mISDNchannel *, u_int, void *);
-typedef	int	(send_func_t)(struct mISDNchannel *, struct sk_buff *);
-typedef int	(create_func_t)(struct channel_req *);
-
-struct Bprotocol {
-	struct list_head	list;
-	char			*name;
-	u_int			Bprotocols;
-	create_func_t		*create;
-};
-
-struct mISDNchannel {
-	struct list_head	list;
-	u_int			protocol;
-	u_int			nr;
-	u_long			opt;
-	u_int			addr;
-	struct mISDNstack	*st;
-	struct mISDNchannel	*peer;
-	send_func_t		*send;
-	send_func_t		*recv;
-	ctrl_func_t		*ctrl;
-};
-
-struct mISDN_sock_list {
-	struct hlist_head	head;
-	rwlock_t		lock;
-};
-
-struct mISDN_sock {
-	struct sock		sk;
-	struct mISDNchannel	ch;
-	u_int			cmask;
-	struct mISDNdevice	*dev;
-};
-
-
-
-struct mISDNdevice {
-	struct mISDNchannel	D;
-	u_int			id;
-	u_int			Dprotocols;
-	u_int			Bprotocols;
-	u_int			nrbchan;
-	u_char			channelmap[MISDN_CHMAP_SIZE];
-	struct list_head	bchannels;
-	struct mISDNchannel	*teimgr;
-	struct device		dev;
-};
-
-struct mISDNstack {
-	u_long			status;
-	struct mISDNdevice	*dev;
-	struct task_struct	*thread;
-	struct completion	*notify;
-	wait_queue_head_t	workq;
-	struct sk_buff_head	msgq;
-	struct list_head	layer2;
-	struct mISDNchannel	*layer1;
-	struct mISDNchannel	own;
-	struct mutex		lmutex; /* protect lists */
-	struct mISDN_sock_list	l1sock;
-#ifdef MISDN_MSG_STATS
-	u_int			msg_cnt;
-	u_int			sleep_cnt;
-	u_int			stopped_cnt;
-#endif
-};
-
-typedef	int	(clockctl_func_t)(void *, int);
-
-struct	mISDNclock {
-	struct list_head	list;
-	char			name[64];
-	int			pri;
-	clockctl_func_t		*ctl;
-	void			*priv;
-};
-
-/* global alloc/queue functions */
-
-static inline struct sk_buff *
-mI_alloc_skb(unsigned int len, gfp_t gfp_mask)
-{
-	struct sk_buff	*skb;
-
-	skb = alloc_skb(len + MISDN_HEADER_LEN, gfp_mask);
-	if (likely(skb))
-		skb_reserve(skb, MISDN_HEADER_LEN);
-	return skb;
-}
-
-static inline struct sk_buff *
-_alloc_mISDN_skb(u_int prim, u_int id, u_int len, void *dp, gfp_t gfp_mask)
-{
-	struct sk_buff	*skb = mI_alloc_skb(len, gfp_mask);
-	struct mISDNhead *hh;
-
-	if (!skb)
-		return NULL;
-	if (len)
-		skb_put_data(skb, dp, len);
-	hh = mISDN_HEAD_P(skb);
-	hh->prim = prim;
-	hh->id = id;
-	return skb;
-}
-
-static inline void
-_queue_data(struct mISDNchannel *ch, u_int prim,
-    u_int id, u_int len, void *dp, gfp_t gfp_mask)
-{
-	struct sk_buff		*skb;
-
-	if (!ch->peer)
-		return;
-	skb = _alloc_mISDN_skb(prim, id, len, dp, gfp_mask);
-	if (!skb)
-		return;
-	if (ch->recv(ch->peer, skb))
-		dev_kfree_skb(skb);
-}
-
-/* global register/unregister functions */
-
-extern int	mISDN_register_device(struct mISDNdevice *,
-					struct device *parent, char *name);
-extern void	mISDN_unregister_device(struct mISDNdevice *);
-extern int	mISDN_register_Bprotocol(struct Bprotocol *);
-extern void	mISDN_unregister_Bprotocol(struct Bprotocol *);
-extern struct mISDNclock *mISDN_register_clock(char *, int, clockctl_func_t *,
-						void *);
-extern void	mISDN_unregister_clock(struct mISDNclock *);
-
-static inline struct mISDNdevice *dev_to_mISDN(const struct device *dev)
-{
-	if (dev)
-		return dev_get_drvdata(dev);
-	else
-		return NULL;
-}
-
-extern void	set_channel_address(struct mISDNchannel *, u_int, u_int);
-extern void	mISDN_clock_update(struct mISDNclock *, int, ktime_t *);
-extern unsigned short mISDN_clock_get(void);
-extern const char *mISDNDevName4ch(struct mISDNchannel *);
-
-#endif /* __KERNEL__ */
-#endif /* mISDNIF_H */
diff --git a/include/uapi/linux/capi.h b/include/uapi/linux/capi.h
deleted file mode 100644
index 31f946f8a88d..000000000000
--- a/include/uapi/linux/capi.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/* $Id: capi.h,v 1.4.6.1 2001/09/23 22:25:05 kai Exp $
- * 
- * CAPI 2.0 Interface for Linux
- * 
- * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
- * 
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef __LINUX_CAPI_H__
-#define __LINUX_CAPI_H__
-
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#ifndef __KERNEL__
-#include <linux/kernelcapi.h>
-#endif
-
-/*
- * CAPI_REGISTER
- */
-
-typedef struct capi_register_params {	/* CAPI_REGISTER */
-	__u32 level3cnt;	/* No. of simulatneous user data connections */
-	__u32 datablkcnt;	/* No. of buffered data messages */
-	__u32 datablklen;	/* Size of buffered data messages */
-} capi_register_params;
-
-#define	CAPI_REGISTER	_IOW('C',0x01,struct capi_register_params)
-
-/*
- * CAPI_GET_MANUFACTURER
- */
-
-#define CAPI_MANUFACTURER_LEN		64
-
-#define	CAPI_GET_MANUFACTURER	_IOWR('C',0x06,int)	/* broken: wanted size 64 (CAPI_MANUFACTURER_LEN) */
-
-/*
- * CAPI_GET_VERSION
- */
-
-typedef struct capi_version {
-	__u32 majorversion;
-	__u32 minorversion;
-	__u32 majormanuversion;
-	__u32 minormanuversion;
-} capi_version;
-
-#define CAPI_GET_VERSION	_IOWR('C',0x07,struct capi_version)
-
-/*
- * CAPI_GET_SERIAL
- */
-
-#define CAPI_SERIAL_LEN		8
-#define CAPI_GET_SERIAL		_IOWR('C',0x08,int)	/* broken: wanted size 8 (CAPI_SERIAL_LEN) */
-
-/*
- * CAPI_GET_PROFILE
- */
-
-typedef struct capi_profile {
-	__u16 ncontroller;	/* number of installed controller */
-	__u16 nbchannel;	/* number of B-Channels */
-	__u32 goptions;		/* global options */
-	__u32 support1;		/* B1 protocols support */
-	__u32 support2;		/* B2 protocols support */
-	__u32 support3;		/* B3 protocols support */
-	__u32 reserved[6];	/* reserved */
-	__u32 manu[5];		/* manufacturer specific information */
-} capi_profile;
-
-#define CAPI_GET_PROFILE	_IOWR('C',0x09,struct capi_profile)
-
-typedef struct capi_manufacturer_cmd {
-	unsigned long cmd;
-	void __user *data;
-} capi_manufacturer_cmd;
-
-/*
- * CAPI_MANUFACTURER_CMD
- */
-
-#define CAPI_MANUFACTURER_CMD	_IOWR('C',0x20, struct capi_manufacturer_cmd)
-
-/*
- * CAPI_GET_ERRCODE
- * capi errcode is set, * if read, write, or ioctl returns EIO,
- * ioctl returns errcode directly, and in arg, if != 0
- */
-
-#define CAPI_GET_ERRCODE	_IOR('C',0x21, __u16)
-
-/*
- * CAPI_INSTALLED
- */
-#define CAPI_INSTALLED		_IOR('C',0x22, __u16)
-
-
-/*
- * member contr is input for
- * CAPI_GET_MANUFACTURER, CAPI_GET_VERSION, CAPI_GET_SERIAL
- * and CAPI_GET_PROFILE
- */
-typedef union capi_ioctl_struct {
-	__u32 contr;
-	capi_register_params rparams;
-	__u8 manufacturer[CAPI_MANUFACTURER_LEN];
-	capi_version version;
-	__u8 serial[CAPI_SERIAL_LEN];
-	capi_profile profile;
-	capi_manufacturer_cmd cmd;
-	__u16 errcode;
-} capi_ioctl_struct;
-
-/*
- * Middleware extension
- */
-
-#define CAPIFLAG_HIGHJACKING	0x0001
-
-#define CAPI_GET_FLAGS		_IOR('C',0x23, unsigned)
-#define CAPI_SET_FLAGS		_IOR('C',0x24, unsigned)
-#define CAPI_CLR_FLAGS		_IOR('C',0x25, unsigned)
-
-#define CAPI_NCCI_OPENCOUNT	_IOR('C',0x26, unsigned)
-
-#define CAPI_NCCI_GETUNIT	_IOR('C',0x27, unsigned)
-
-#endif				/* __LINUX_CAPI_H__ */
diff --git a/include/uapi/linux/isdn/capicmd.h b/include/uapi/linux/isdn/capicmd.h
deleted file mode 100644
index 5ec88e7548a9..000000000000
--- a/include/uapi/linux/isdn/capicmd.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/* $Id: capicmd.h,v 1.2.6.2 2001/09/23 22:24:33 kai Exp $
- * 
- * CAPI 2.0 Interface for Linux
- * 
- * Copyright 1997 by Carsten Paeth <calle@calle.de>
- * 
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef __CAPICMD_H__
-#define __CAPICMD_H__
-
-#define CAPI_MSG_BASELEN		8
-#define CAPI_DATA_B3_REQ_LEN		(CAPI_MSG_BASELEN+4+4+2+2+2)
-#define CAPI_DATA_B3_RESP_LEN		(CAPI_MSG_BASELEN+4+2)
-#define CAPI_DISCONNECT_B3_RESP_LEN	(CAPI_MSG_BASELEN+4)
-
-/*----- CAPI commands -----*/
-#define CAPI_ALERT		    0x01
-#define CAPI_CONNECT		    0x02
-#define CAPI_CONNECT_ACTIVE	    0x03
-#define CAPI_CONNECT_B3_ACTIVE	    0x83
-#define CAPI_CONNECT_B3 	    0x82
-#define CAPI_CONNECT_B3_T90_ACTIVE  0x88
-#define CAPI_DATA_B3		    0x86
-#define CAPI_DISCONNECT_B3	    0x84
-#define CAPI_DISCONNECT 	    0x04
-#define CAPI_FACILITY		    0x80
-#define CAPI_INFO		    0x08
-#define CAPI_LISTEN		    0x05
-#define CAPI_MANUFACTURER	    0xff
-#define CAPI_RESET_B3		    0x87
-#define CAPI_SELECT_B_PROTOCOL	    0x41
-
-/*----- CAPI subcommands -----*/
-
-#define CAPI_REQ    0x80
-#define CAPI_CONF   0x81
-#define CAPI_IND    0x82
-#define CAPI_RESP   0x83
-
-/*----- CAPI combined commands -----*/
-
-#define CAPICMD(cmd,subcmd)	(((cmd)<<8)|(subcmd))
-
-#define CAPI_DISCONNECT_REQ		CAPICMD(CAPI_DISCONNECT,CAPI_REQ)
-#define CAPI_DISCONNECT_CONF		CAPICMD(CAPI_DISCONNECT,CAPI_CONF)
-#define CAPI_DISCONNECT_IND		CAPICMD(CAPI_DISCONNECT,CAPI_IND)
-#define CAPI_DISCONNECT_RESP		CAPICMD(CAPI_DISCONNECT,CAPI_RESP)
-
-#define CAPI_ALERT_REQ			CAPICMD(CAPI_ALERT,CAPI_REQ)
-#define CAPI_ALERT_CONF			CAPICMD(CAPI_ALERT,CAPI_CONF)
-
-#define CAPI_CONNECT_REQ		CAPICMD(CAPI_CONNECT,CAPI_REQ)
-#define CAPI_CONNECT_CONF		CAPICMD(CAPI_CONNECT,CAPI_CONF)
-#define CAPI_CONNECT_IND		CAPICMD(CAPI_CONNECT,CAPI_IND)
-#define CAPI_CONNECT_RESP		CAPICMD(CAPI_CONNECT,CAPI_RESP)
-
-#define CAPI_CONNECT_ACTIVE_REQ		CAPICMD(CAPI_CONNECT_ACTIVE,CAPI_REQ)
-#define CAPI_CONNECT_ACTIVE_CONF	CAPICMD(CAPI_CONNECT_ACTIVE,CAPI_CONF)
-#define CAPI_CONNECT_ACTIVE_IND		CAPICMD(CAPI_CONNECT_ACTIVE,CAPI_IND)
-#define CAPI_CONNECT_ACTIVE_RESP	CAPICMD(CAPI_CONNECT_ACTIVE,CAPI_RESP)
-
-#define CAPI_SELECT_B_PROTOCOL_REQ	CAPICMD(CAPI_SELECT_B_PROTOCOL,CAPI_REQ)
-#define CAPI_SELECT_B_PROTOCOL_CONF	CAPICMD(CAPI_SELECT_B_PROTOCOL,CAPI_CONF)
-
-#define CAPI_CONNECT_B3_ACTIVE_REQ	CAPICMD(CAPI_CONNECT_B3_ACTIVE,CAPI_REQ)
-#define CAPI_CONNECT_B3_ACTIVE_CONF	CAPICMD(CAPI_CONNECT_B3_ACTIVE,CAPI_CONF)
-#define CAPI_CONNECT_B3_ACTIVE_IND	CAPICMD(CAPI_CONNECT_B3_ACTIVE,CAPI_IND)
-#define CAPI_CONNECT_B3_ACTIVE_RESP	CAPICMD(CAPI_CONNECT_B3_ACTIVE,CAPI_RESP)
-
-#define CAPI_CONNECT_B3_REQ		CAPICMD(CAPI_CONNECT_B3,CAPI_REQ)
-#define CAPI_CONNECT_B3_CONF		CAPICMD(CAPI_CONNECT_B3,CAPI_CONF)
-#define CAPI_CONNECT_B3_IND		CAPICMD(CAPI_CONNECT_B3,CAPI_IND)
-#define CAPI_CONNECT_B3_RESP		CAPICMD(CAPI_CONNECT_B3,CAPI_RESP)
-
-
-#define CAPI_CONNECT_B3_T90_ACTIVE_IND	CAPICMD(CAPI_CONNECT_B3_T90_ACTIVE,CAPI_IND)
-#define CAPI_CONNECT_B3_T90_ACTIVE_RESP	CAPICMD(CAPI_CONNECT_B3_T90_ACTIVE,CAPI_RESP)
-
-#define CAPI_DATA_B3_REQ		CAPICMD(CAPI_DATA_B3,CAPI_REQ)
-#define CAPI_DATA_B3_CONF		CAPICMD(CAPI_DATA_B3,CAPI_CONF)
-#define CAPI_DATA_B3_IND		CAPICMD(CAPI_DATA_B3,CAPI_IND)
-#define CAPI_DATA_B3_RESP		CAPICMD(CAPI_DATA_B3,CAPI_RESP)
-
-#define CAPI_DISCONNECT_B3_REQ		CAPICMD(CAPI_DISCONNECT_B3,CAPI_REQ)
-#define CAPI_DISCONNECT_B3_CONF		CAPICMD(CAPI_DISCONNECT_B3,CAPI_CONF)
-#define CAPI_DISCONNECT_B3_IND		CAPICMD(CAPI_DISCONNECT_B3,CAPI_IND)
-#define CAPI_DISCONNECT_B3_RESP		CAPICMD(CAPI_DISCONNECT_B3,CAPI_RESP)
-
-#define CAPI_RESET_B3_REQ		CAPICMD(CAPI_RESET_B3,CAPI_REQ)
-#define CAPI_RESET_B3_CONF		CAPICMD(CAPI_RESET_B3,CAPI_CONF)
-#define CAPI_RESET_B3_IND		CAPICMD(CAPI_RESET_B3,CAPI_IND)
-#define CAPI_RESET_B3_RESP		CAPICMD(CAPI_RESET_B3,CAPI_RESP)
-
-#define CAPI_LISTEN_REQ			CAPICMD(CAPI_LISTEN,CAPI_REQ)
-#define CAPI_LISTEN_CONF		CAPICMD(CAPI_LISTEN,CAPI_CONF)
-
-#define CAPI_MANUFACTURER_REQ		CAPICMD(CAPI_MANUFACTURER,CAPI_REQ)
-#define CAPI_MANUFACTURER_CONF		CAPICMD(CAPI_MANUFACTURER,CAPI_CONF)
-#define CAPI_MANUFACTURER_IND		CAPICMD(CAPI_MANUFACTURER,CAPI_IND)
-#define CAPI_MANUFACTURER_RESP		CAPICMD(CAPI_MANUFACTURER,CAPI_RESP)
-
-#define CAPI_FACILITY_REQ		CAPICMD(CAPI_FACILITY,CAPI_REQ)
-#define CAPI_FACILITY_CONF		CAPICMD(CAPI_FACILITY,CAPI_CONF)
-#define CAPI_FACILITY_IND		CAPICMD(CAPI_FACILITY,CAPI_IND)
-#define CAPI_FACILITY_RESP		CAPICMD(CAPI_FACILITY,CAPI_RESP)
-
-#define CAPI_INFO_REQ			CAPICMD(CAPI_INFO,CAPI_REQ)
-#define CAPI_INFO_CONF			CAPICMD(CAPI_INFO,CAPI_CONF)
-#define CAPI_INFO_IND			CAPICMD(CAPI_INFO,CAPI_IND)
-#define CAPI_INFO_RESP			CAPICMD(CAPI_INFO,CAPI_RESP)
-
-#endif				/* __CAPICMD_H__ */
diff --git a/include/uapi/linux/kernelcapi.h b/include/uapi/linux/kernelcapi.h
deleted file mode 100644
index 325a856e0e20..000000000000
--- a/include/uapi/linux/kernelcapi.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * $Id: kernelcapi.h,v 1.8.6.2 2001/02/07 11:31:31 kai Exp $
- * 
- * Kernel CAPI 2.0 Interface for Linux
- * 
- * (c) Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
- * 
- */
-
-#ifndef _UAPI__KERNELCAPI_H__
-#define _UAPI__KERNELCAPI_H__
-
-#define CAPI_MAXAPPL	240	/* maximum number of applications  */
-#define CAPI_MAXCONTR	32	/* maximum number of controller    */
-#define CAPI_MAXDATAWINDOW	8
-
-
-typedef struct kcapi_flagdef {
-	int contr;
-	int flag;
-} kcapi_flagdef;
-
-typedef struct kcapi_carddef {
-	char		driver[32];
-	unsigned int	port;
-	unsigned	irq;
-	unsigned int	membase;
-	int		cardnr;
-} kcapi_carddef;
-
-/* new ioctls >= 10 */
-#define KCAPI_CMD_TRACE		10
-#define KCAPI_CMD_ADDCARD	11	/* OBSOLETE */
-
-/* 
- * flag > 2 => trace also data
- * flag & 1 => show trace
- */
-#define KCAPI_TRACE_OFF			0
-#define KCAPI_TRACE_SHORT_NO_DATA	1
-#define KCAPI_TRACE_FULL_NO_DATA	2
-#define KCAPI_TRACE_SHORT		3
-#define KCAPI_TRACE_FULL		4
-
-
-
-#endif /* _UAPI__KERNELCAPI_H__ */
diff --git a/net/bluetooth/cmtp/cmtp.h b/net/bluetooth/cmtp/cmtp.h
deleted file mode 100644
index f6b9dc4e408f..000000000000
--- a/net/bluetooth/cmtp/cmtp.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-   CMTP implementation for Linux Bluetooth stack (BlueZ).
-   Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-   SOFTWARE IS DISCLAIMED.
-*/
-
-#ifndef __CMTP_H
-#define __CMTP_H
-
-#include <linux/types.h>
-#include <net/bluetooth/bluetooth.h>
-
-#define BTNAMSIZ 21
-
-/* CMTP ioctl defines */
-#define CMTPCONNADD	_IOW('C', 200, int)
-#define CMTPCONNDEL	_IOW('C', 201, int)
-#define CMTPGETCONNLIST	_IOR('C', 210, int)
-#define CMTPGETCONNINFO	_IOR('C', 211, int)
-
-#define CMTP_LOOPBACK	0
-
-struct cmtp_connadd_req {
-	int   sock;	/* Connected socket */
-	__u32 flags;
-};
-
-struct cmtp_conndel_req {
-	bdaddr_t bdaddr;
-	__u32    flags;
-};
-
-struct cmtp_conninfo {
-	bdaddr_t bdaddr;
-	__u32    flags;
-	__u16    state;
-	int      num;
-};
-
-struct cmtp_connlist_req {
-	__u32  cnum;
-	struct cmtp_conninfo __user *ci;
-};
-
-int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock);
-int cmtp_del_connection(struct cmtp_conndel_req *req);
-int cmtp_get_connlist(struct cmtp_connlist_req *req);
-int cmtp_get_conninfo(struct cmtp_conninfo *ci);
-
-/* CMTP session defines */
-#define CMTP_INTEROP_TIMEOUT	(HZ * 5)
-#define CMTP_INITIAL_MSGNUM	0xff00
-
-struct cmtp_session {
-	struct list_head list;
-
-	struct socket *sock;
-
-	bdaddr_t bdaddr;
-
-	unsigned long state;
-	unsigned long flags;
-
-	uint mtu;
-
-	char name[BTNAMSIZ];
-
-	atomic_t terminate;
-	struct task_struct *task;
-
-	wait_queue_head_t wait;
-
-	int ncontroller;
-	int num;
-	struct capi_ctr ctrl;
-
-	struct list_head applications;
-
-	unsigned long blockids;
-	int msgnum;
-
-	struct sk_buff_head transmit;
-
-	struct sk_buff *reassembly[16];
-};
-
-struct cmtp_application {
-	struct list_head list;
-
-	unsigned long state;
-	int err;
-
-	__u16 appl;
-	__u16 mapping;
-
-	__u16 msgnum;
-};
-
-struct cmtp_scb {
-	int id;
-	int data;
-};
-
-int  cmtp_attach_device(struct cmtp_session *session);
-void cmtp_detach_device(struct cmtp_session *session);
-
-void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb);
-
-/* CMTP init defines */
-int cmtp_init_sockets(void);
-void cmtp_cleanup_sockets(void);
-
-#endif /* __CMTP_H */
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
deleted file mode 100644
index aa28b1d32c4e..000000000000
--- a/drivers/isdn/capi/capi.c
+++ /dev/null
@@ -1,1435 +0,0 @@
-/* $Id: capi.c,v 1.1.2.7 2004/04/28 09:48:59 armin Exp $
- *
- * CAPI 2.0 Interface for Linux
- *
- * Copyright 1996 by Carsten Paeth <calle@calle.de>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/compiler.h>
-#include <linux/module.h>
-#include <linux/ethtool.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/fcntl.h>
-#include <linux/fs.h>
-#include <linux/signal.h>
-#include <linux/mutex.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/wait.h>
-#include <linux/tty.h>
-#include <linux/netdevice.h>
-#include <linux/ppp_defs.h>
-#include <linux/ppp-ioctl.h>
-#include <linux/skbuff.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/poll.h>
-#include <linux/capi.h>
-#include <linux/kernelcapi.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/moduleparam.h>
-#include <linux/isdn/capiutil.h>
-#include <linux/isdn/capicmd.h>
-
-#include "kcapi.h"
-
-MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer and /dev/capi20 interface");
-MODULE_AUTHOR("Carsten Paeth");
-MODULE_LICENSE("GPL");
-
-/* -------- driver information -------------------------------------- */
-
-static DEFINE_MUTEX(capi_mutex);
-static const struct class capi_class = {
-	.name = "capi",
-};
-static int capi_major = 68;		/* allocated */
-
-module_param_named(major, capi_major, uint, 0);
-
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-#define CAPINC_NR_PORTS		32
-#define CAPINC_MAX_PORTS	256
-
-static int capi_ttyminors = CAPINC_NR_PORTS;
-
-module_param_named(ttyminors, capi_ttyminors, uint, 0);
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
-
-/* -------- defines ------------------------------------------------- */
-
-#define CAPINC_MAX_RECVQUEUE	10
-#define CAPINC_MAX_SENDQUEUE	10
-#define CAPI_MAX_BLKSIZE	2048
-
-/* -------- data structures ----------------------------------------- */
-
-struct capidev;
-struct capincci;
-struct capiminor;
-
-struct ackqueue_entry {
-	struct list_head	list;
-	u16			datahandle;
-};
-
-struct capiminor {
-	unsigned int      minor;
-
-	struct capi20_appl	*ap;
-	u32			ncci;
-	atomic_t		datahandle;
-	atomic_t		msgid;
-
-	struct tty_port port;
-	int                ttyinstop;
-	int                ttyoutstop;
-
-	struct sk_buff_head	inqueue;
-
-	struct sk_buff_head	outqueue;
-	int			outbytes;
-	struct sk_buff		*outskb;
-	spinlock_t		outlock;
-
-	/* transmit path */
-	struct list_head ackqueue;
-	int nack;
-	spinlock_t ackqlock;
-};
-
-struct capincci {
-	struct list_head list;
-	u32		 ncci;
-	struct capidev	*cdev;
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-	struct capiminor *minorp;
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
-};
-
-struct capidev {
-	struct list_head list;
-	struct capi20_appl ap;
-	u16		errcode;
-	unsigned        userflags;
-
-	struct sk_buff_head recvqueue;
-	wait_queue_head_t recvwait;
-
-	struct list_head nccis;
-
-	struct mutex lock;
-};
-
-/* -------- global variables ---------------------------------------- */
-
-static DEFINE_MUTEX(capidev_list_lock);
-static LIST_HEAD(capidev_list);
-
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-
-static DEFINE_SPINLOCK(capiminors_lock);
-static struct capiminor **capiminors;
-
-static struct tty_driver *capinc_tty_driver;
-
-/* -------- datahandles --------------------------------------------- */
-
-static int capiminor_add_ack(struct capiminor *mp, u16 datahandle)
-{
-	struct ackqueue_entry *n;
-
-	n = kmalloc_obj(*n, GFP_ATOMIC);
-	if (unlikely(!n)) {
-		printk(KERN_ERR "capi: alloc datahandle failed\n");
-		return -1;
-	}
-	n->datahandle = datahandle;
-	INIT_LIST_HEAD(&n->list);
-	spin_lock_bh(&mp->ackqlock);
-	list_add_tail(&n->list, &mp->ackqueue);
-	mp->nack++;
-	spin_unlock_bh(&mp->ackqlock);
-	return 0;
-}
-
-static int capiminor_del_ack(struct capiminor *mp, u16 datahandle)
-{
-	struct ackqueue_entry *p, *tmp;
-
-	spin_lock_bh(&mp->ackqlock);
-	list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
-		if (p->datahandle == datahandle) {
-			list_del(&p->list);
-			mp->nack--;
-			spin_unlock_bh(&mp->ackqlock);
-			kfree(p);
-			return 0;
-		}
-	}
-	spin_unlock_bh(&mp->ackqlock);
-	return -1;
-}
-
-static void capiminor_del_all_ack(struct capiminor *mp)
-{
-	struct ackqueue_entry *p, *tmp;
-
-	list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
-		list_del(&p->list);
-		kfree(p);
-		mp->nack--;
-	}
-}
-
-
-/* -------- struct capiminor ---------------------------------------- */
-
-static void capiminor_destroy(struct tty_port *port)
-{
-	struct capiminor *mp = container_of(port, struct capiminor, port);
-
-	kfree_skb(mp->outskb);
-	skb_queue_purge(&mp->inqueue);
-	skb_queue_purge(&mp->outqueue);
-	capiminor_del_all_ack(mp);
-	kfree(mp);
-}
-
-static const struct tty_port_operations capiminor_port_ops = {
-	.destruct = capiminor_destroy,
-};
-
-static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
-{
-	struct capiminor *mp;
-	struct device *dev;
-	unsigned int minor;
-
-	mp = kzalloc_obj(*mp);
-	if (!mp) {
-		printk(KERN_ERR "capi: can't alloc capiminor\n");
-		return NULL;
-	}
-
-	mp->ap = ap;
-	mp->ncci = ncci;
-	INIT_LIST_HEAD(&mp->ackqueue);
-	spin_lock_init(&mp->ackqlock);
-
-	skb_queue_head_init(&mp->inqueue);
-	skb_queue_head_init(&mp->outqueue);
-	spin_lock_init(&mp->outlock);
-
-	tty_port_init(&mp->port);
-	mp->port.ops = &capiminor_port_ops;
-
-	/* Allocate the least unused minor number. */
-	spin_lock(&capiminors_lock);
-	for (minor = 0; minor < capi_ttyminors; minor++)
-		if (!capiminors[minor]) {
-			capiminors[minor] = mp;
-			break;
-		}
-	spin_unlock(&capiminors_lock);
-
-	if (minor == capi_ttyminors) {
-		printk(KERN_NOTICE "capi: out of minors\n");
-		goto err_out1;
-	}
-
-	mp->minor = minor;
-
-	dev = tty_port_register_device(&mp->port, capinc_tty_driver, minor,
-			NULL);
-	if (IS_ERR(dev))
-		goto err_out2;
-
-	return mp;
-
-err_out2:
-	spin_lock(&capiminors_lock);
-	capiminors[minor] = NULL;
-	spin_unlock(&capiminors_lock);
-
-err_out1:
-	tty_port_put(&mp->port);
-	return NULL;
-}
-
-static struct capiminor *capiminor_get(unsigned int minor)
-{
-	struct capiminor *mp;
-
-	spin_lock(&capiminors_lock);
-	mp = capiminors[minor];
-	if (mp)
-		tty_port_get(&mp->port);
-	spin_unlock(&capiminors_lock);
-
-	return mp;
-}
-
-static inline void capiminor_put(struct capiminor *mp)
-{
-	tty_port_put(&mp->port);
-}
-
-static void capiminor_free(struct capiminor *mp)
-{
-	tty_unregister_device(capinc_tty_driver, mp->minor);
-
-	spin_lock(&capiminors_lock);
-	capiminors[mp->minor] = NULL;
-	spin_unlock(&capiminors_lock);
-
-	capiminor_put(mp);
-}
-
-/* -------- struct capincci ----------------------------------------- */
-
-static void capincci_alloc_minor(struct capidev *cdev, struct capincci *np)
-{
-	if (cdev->userflags & CAPIFLAG_HIGHJACKING)
-		np->minorp = capiminor_alloc(&cdev->ap, np->ncci);
-}
-
-static void capincci_free_minor(struct capincci *np)
-{
-	struct capiminor *mp = np->minorp;
-
-	if (mp) {
-		tty_port_tty_vhangup(&mp->port);
-		capiminor_free(mp);
-	}
-}
-
-static inline unsigned int capincci_minor_opencount(struct capincci *np)
-{
-	struct capiminor *mp = np->minorp;
-	unsigned int count = 0;
-	struct tty_struct *tty;
-
-	if (mp) {
-		tty = tty_port_tty_get(&mp->port);
-		if (tty) {
-			count = tty->count;
-			tty_kref_put(tty);
-		}
-	}
-	return count;
-}
-
-#else /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
-
-static inline void
-capincci_alloc_minor(struct capidev *cdev, struct capincci *np) { }
-static inline void capincci_free_minor(struct capincci *np) { }
-
-#endif /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
-
-static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci)
-{
-	struct capincci *np;
-
-	np = kzalloc_obj(*np);
-	if (!np)
-		return NULL;
-	np->ncci = ncci;
-	np->cdev = cdev;
-
-	capincci_alloc_minor(cdev, np);
-
-	list_add_tail(&np->list, &cdev->nccis);
-
-	return np;
-}
-
-static void capincci_free(struct capidev *cdev, u32 ncci)
-{
-	struct capincci *np, *tmp;
-
-	list_for_each_entry_safe(np, tmp, &cdev->nccis, list)
-		if (ncci == 0xffffffff || np->ncci == ncci) {
-			capincci_free_minor(np);
-			list_del(&np->list);
-			kfree(np);
-		}
-}
-
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-static struct capincci *capincci_find(struct capidev *cdev, u32 ncci)
-{
-	struct capincci *np;
-
-	list_for_each_entry(np, &cdev->nccis, list)
-		if (np->ncci == ncci)
-			return np;
-	return NULL;
-}
-
-/* -------- handle data queue --------------------------------------- */
-
-static struct sk_buff *
-gen_data_b3_resp_for(struct capiminor *mp, struct sk_buff *skb)
-{
-	struct sk_buff *nskb;
-	nskb = alloc_skb(CAPI_DATA_B3_RESP_LEN, GFP_KERNEL);
-	if (nskb) {
-		u16 datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4 + 4 + 2);
-		unsigned char *s = skb_put(nskb, CAPI_DATA_B3_RESP_LEN);
-		capimsg_setu16(s, 0, CAPI_DATA_B3_RESP_LEN);
-		capimsg_setu16(s, 2, mp->ap->applid);
-		capimsg_setu8 (s, 4, CAPI_DATA_B3);
-		capimsg_setu8 (s, 5, CAPI_RESP);
-		capimsg_setu16(s, 6, atomic_inc_return(&mp->msgid));
-		capimsg_setu32(s, 8, mp->ncci);
-		capimsg_setu16(s, 12, datahandle);
-	}
-	return nskb;
-}
-
-static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
-{
-	unsigned int datalen = skb->len - CAPIMSG_LEN(skb->data);
-	struct tty_struct *tty;
-	struct sk_buff *nskb;
-	u16 errcode, datahandle;
-	struct tty_ldisc *ld;
-	int ret = -1;
-
-	tty = tty_port_tty_get(&mp->port);
-	if (!tty) {
-		pr_debug("capi: currently no receiver\n");
-		return -1;
-	}
-
-	ld = tty_ldisc_ref(tty);
-	if (!ld) {
-		/* fatal error, do not requeue */
-		ret = 0;
-		kfree_skb(skb);
-		goto deref_tty;
-	}
-
-	if (ld->ops->receive_buf == NULL) {
-		pr_debug("capi: ldisc has no receive_buf function\n");
-		/* fatal error, do not requeue */
-		goto free_skb;
-	}
-	if (mp->ttyinstop) {
-		pr_debug("capi: recv tty throttled\n");
-		goto deref_ldisc;
-	}
-
-	if (tty->receive_room < datalen) {
-		pr_debug("capi: no room in tty\n");
-		goto deref_ldisc;
-	}
-
-	nskb = gen_data_b3_resp_for(mp, skb);
-	if (!nskb) {
-		printk(KERN_ERR "capi: gen_data_b3_resp failed\n");
-		goto deref_ldisc;
-	}
-
-	datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4);
-
-	errcode = capi20_put_message(mp->ap, nskb);
-
-	if (errcode == CAPI_NOERROR) {
-		skb_pull(skb, CAPIMSG_LEN(skb->data));
-		pr_debug("capi: DATA_B3_RESP %u len=%d => ldisc\n",
-			 datahandle, skb->len);
-		ld->ops->receive_buf(tty, skb->data, NULL, skb->len);
-	} else {
-		printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
-		       errcode);
-		kfree_skb(nskb);
-
-		if (errcode == CAPI_SENDQUEUEFULL)
-			goto deref_ldisc;
-	}
-
-free_skb:
-	ret = 0;
-	kfree_skb(skb);
-
-deref_ldisc:
-	tty_ldisc_deref(ld);
-
-deref_tty:
-	tty_kref_put(tty);
-	return ret;
-}
-
-static void handle_minor_recv(struct capiminor *mp)
-{
-	struct sk_buff *skb;
-
-	while ((skb = skb_dequeue(&mp->inqueue)) != NULL)
-		if (handle_recv_skb(mp, skb) < 0) {
-			skb_queue_head(&mp->inqueue, skb);
-			return;
-		}
-}
-
-static void handle_minor_send(struct capiminor *mp)
-{
-	struct tty_struct *tty;
-	struct sk_buff *skb;
-	u16 len;
-	u16 errcode;
-	u16 datahandle;
-
-	tty = tty_port_tty_get(&mp->port);
-	if (!tty)
-		return;
-
-	if (mp->ttyoutstop) {
-		pr_debug("capi: send: tty stopped\n");
-		tty_kref_put(tty);
-		return;
-	}
-
-	while (1) {
-		spin_lock_bh(&mp->outlock);
-		skb = __skb_dequeue(&mp->outqueue);
-		if (!skb) {
-			spin_unlock_bh(&mp->outlock);
-			break;
-		}
-		len = (u16)skb->len;
-		mp->outbytes -= len;
-		spin_unlock_bh(&mp->outlock);
-
-		datahandle = atomic_inc_return(&mp->datahandle);
-		skb_push(skb, CAPI_DATA_B3_REQ_LEN);
-		memset(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
-		capimsg_setu16(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
-		capimsg_setu16(skb->data, 2, mp->ap->applid);
-		capimsg_setu8 (skb->data, 4, CAPI_DATA_B3);
-		capimsg_setu8 (skb->data, 5, CAPI_REQ);
-		capimsg_setu16(skb->data, 6, atomic_inc_return(&mp->msgid));
-		capimsg_setu32(skb->data, 8, mp->ncci);	/* NCCI */
-		capimsg_setu32(skb->data, 12, (u32)(long)skb->data);/* Data32 */
-		capimsg_setu16(skb->data, 16, len);	/* Data length */
-		capimsg_setu16(skb->data, 18, datahandle);
-		capimsg_setu16(skb->data, 20, 0);	/* Flags */
-
-		if (capiminor_add_ack(mp, datahandle) < 0) {
-			skb_pull(skb, CAPI_DATA_B3_REQ_LEN);
-
-			spin_lock_bh(&mp->outlock);
-			__skb_queue_head(&mp->outqueue, skb);
-			mp->outbytes += len;
-			spin_unlock_bh(&mp->outlock);
-
-			break;
-		}
-		errcode = capi20_put_message(mp->ap, skb);
-		if (errcode == CAPI_NOERROR) {
-			pr_debug("capi: DATA_B3_REQ %u len=%u\n",
-				 datahandle, len);
-			continue;
-		}
-		capiminor_del_ack(mp, datahandle);
-
-		if (errcode == CAPI_SENDQUEUEFULL) {
-			skb_pull(skb, CAPI_DATA_B3_REQ_LEN);
-
-			spin_lock_bh(&mp->outlock);
-			__skb_queue_head(&mp->outqueue, skb);
-			mp->outbytes += len;
-			spin_unlock_bh(&mp->outlock);
-
-			break;
-		}
-
-		/* ups, drop packet */
-		printk(KERN_ERR "capi: put_message = %x\n", errcode);
-		kfree_skb(skb);
-	}
-	tty_kref_put(tty);
-}
-
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
-/* -------- function called by lower level -------------------------- */
-
-static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
-{
-	struct capidev *cdev = ap->private;
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-	struct capiminor *mp;
-	u16 datahandle;
-	struct capincci *np;
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
-
-	mutex_lock(&cdev->lock);
-
-	if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) {
-		u16 info = CAPIMSG_U16(skb->data, 12); // Info field
-		if ((info & 0xff00) == 0)
-			capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
-	}
-	if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND)
-		capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
-
-	if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) {
-		skb_queue_tail(&cdev->recvqueue, skb);
-		wake_up_interruptible(&cdev->recvwait);
-		goto unlock_out;
-	}
-
-#ifndef CONFIG_ISDN_CAPI_MIDDLEWARE
-	skb_queue_tail(&cdev->recvqueue, skb);
-	wake_up_interruptible(&cdev->recvwait);
-
-#else /* CONFIG_ISDN_CAPI_MIDDLEWARE */
-
-	np = capincci_find(cdev, CAPIMSG_CONTROL(skb->data));
-	if (!np) {
-		printk(KERN_ERR "BUG: capi_signal: ncci not found\n");
-		skb_queue_tail(&cdev->recvqueue, skb);
-		wake_up_interruptible(&cdev->recvwait);
-		goto unlock_out;
-	}
-
-	mp = np->minorp;
-	if (!mp) {
-		skb_queue_tail(&cdev->recvqueue, skb);
-		wake_up_interruptible(&cdev->recvwait);
-		goto unlock_out;
-	}
-	if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
-		datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4 + 4 + 2);
-		pr_debug("capi_signal: DATA_B3_IND %u len=%d\n",
-			 datahandle, skb->len-CAPIMSG_LEN(skb->data));
-		skb_queue_tail(&mp->inqueue, skb);
-
-		handle_minor_recv(mp);
-
-	} else if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF) {
-
-		datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4);
-		pr_debug("capi_signal: DATA_B3_CONF %u 0x%x\n",
-			 datahandle,
-			 CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4 + 2));
-		kfree_skb(skb);
-		capiminor_del_ack(mp, datahandle);
-		tty_port_tty_wakeup(&mp->port);
-		handle_minor_send(mp);
-
-	} else {
-		/* ups, let capi application handle it :-) */
-		skb_queue_tail(&cdev->recvqueue, skb);
-		wake_up_interruptible(&cdev->recvwait);
-	}
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
-
-unlock_out:
-	mutex_unlock(&cdev->lock);
-}
-
-/* -------- file_operations for capidev ----------------------------- */
-
-static ssize_t
-capi_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
-{
-	struct capidev *cdev = file->private_data;
-	struct sk_buff *skb;
-	size_t copied;
-	int err;
-
-	if (!cdev->ap.applid)
-		return -ENODEV;
-
-	skb = skb_dequeue(&cdev->recvqueue);
-	if (!skb) {
-		if (file->f_flags & O_NONBLOCK)
-			return -EAGAIN;
-		err = wait_event_interruptible(cdev->recvwait,
-					       (skb = skb_dequeue(&cdev->recvqueue)));
-		if (err)
-			return err;
-	}
-	if (skb->len > count) {
-		skb_queue_head(&cdev->recvqueue, skb);
-		return -EMSGSIZE;
-	}
-	if (copy_to_user(buf, skb->data, skb->len)) {
-		skb_queue_head(&cdev->recvqueue, skb);
-		return -EFAULT;
-	}
-	copied = skb->len;
-
-	kfree_skb(skb);
-
-	return copied;
-}
-
-static ssize_t
-capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
-{
-	struct capidev *cdev = file->private_data;
-	struct sk_buff *skb;
-	u16 mlen;
-
-	if (!cdev->ap.applid)
-		return -ENODEV;
-
-	if (count < CAPIMSG_BASELEN)
-		return -EINVAL;
-
-	skb = alloc_skb(count, GFP_USER);
-	if (!skb)
-		return -ENOMEM;
-
-	if (copy_from_user(skb_put(skb, count), buf, count)) {
-		kfree_skb(skb);
-		return -EFAULT;
-	}
-	mlen = CAPIMSG_LEN(skb->data);
-	if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
-		if (count < CAPI_DATA_B3_REQ_LEN ||
-		    (size_t)(mlen + CAPIMSG_DATALEN(skb->data)) != count) {
-			kfree_skb(skb);
-			return -EINVAL;
-		}
-	} else {
-		if (mlen != count) {
-			kfree_skb(skb);
-			return -EINVAL;
-		}
-	}
-	CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);
-
-	if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) {
-		if (count < CAPI_DISCONNECT_B3_RESP_LEN) {
-			kfree_skb(skb);
-			return -EINVAL;
-		}
-		mutex_lock(&cdev->lock);
-		capincci_free(cdev, CAPIMSG_NCCI(skb->data));
-		mutex_unlock(&cdev->lock);
-	}
-
-	cdev->errcode = capi20_put_message(&cdev->ap, skb);
-
-	if (cdev->errcode) {
-		kfree_skb(skb);
-		return -EIO;
-	}
-	return count;
-}
-
-static __poll_t
-capi_poll(struct file *file, poll_table *wait)
-{
-	struct capidev *cdev = file->private_data;
-	__poll_t mask = 0;
-
-	if (!cdev->ap.applid)
-		return EPOLLERR;
-
-	poll_wait(file, &(cdev->recvwait), wait);
-	mask = EPOLLOUT | EPOLLWRNORM;
-	if (!skb_queue_empty_lockless(&cdev->recvqueue))
-		mask |= EPOLLIN | EPOLLRDNORM;
-	return mask;
-}
-
-static int
-capi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct capidev *cdev = file->private_data;
-	capi_ioctl_struct data;
-	int retval = -EINVAL;
-	void __user *argp = (void __user *)arg;
-
-	switch (cmd) {
-	case CAPI_REGISTER:
-		mutex_lock(&cdev->lock);
-
-		if (cdev->ap.applid) {
-			retval = -EEXIST;
-			goto register_out;
-		}
-		if (copy_from_user(&cdev->ap.rparam, argp,
-				   sizeof(struct capi_register_params))) {
-			retval = -EFAULT;
-			goto register_out;
-		}
-		cdev->ap.private = cdev;
-		cdev->ap.recv_message = capi_recv_message;
-		cdev->errcode = capi20_register(&cdev->ap);
-		retval = (int)cdev->ap.applid;
-		if (cdev->errcode) {
-			cdev->ap.applid = 0;
-			retval = -EIO;
-		}
-
-register_out:
-		mutex_unlock(&cdev->lock);
-		return retval;
-
-	case CAPI_GET_VERSION:
-		if (copy_from_user(&data.contr, argp,
-				   sizeof(data.contr)))
-			return -EFAULT;
-		cdev->errcode = capi20_get_version(data.contr, &data.version);
-		if (cdev->errcode)
-			return -EIO;
-		if (copy_to_user(argp, &data.version,
-				 sizeof(data.version)))
-			return -EFAULT;
-		return 0;
-
-	case CAPI_GET_SERIAL:
-		if (copy_from_user(&data.contr, argp,
-				   sizeof(data.contr)))
-			return -EFAULT;
-		cdev->errcode = capi20_get_serial(data.contr, data.serial);
-		if (cdev->errcode)
-			return -EIO;
-		if (copy_to_user(argp, data.serial,
-				 sizeof(data.serial)))
-			return -EFAULT;
-		return 0;
-
-	case CAPI_GET_PROFILE:
-		if (copy_from_user(&data.contr, argp,
-				   sizeof(data.contr)))
-			return -EFAULT;
-
-		if (data.contr == 0) {
-			cdev->errcode = capi20_get_profile(data.contr, &data.profile);
-			if (cdev->errcode)
-				return -EIO;
-
-			retval = copy_to_user(argp,
-					      &data.profile.ncontroller,
-					      sizeof(data.profile.ncontroller));
-
-		} else {
-			cdev->errcode = capi20_get_profile(data.contr, &data.profile);
-			if (cdev->errcode)
-				return -EIO;
-
-			retval = copy_to_user(argp, &data.profile,
-					      sizeof(data.profile));
-		}
-		if (retval)
-			return -EFAULT;
-		return 0;
-
-	case CAPI_GET_MANUFACTURER:
-		if (copy_from_user(&data.contr, argp,
-				   sizeof(data.contr)))
-			return -EFAULT;
-		cdev->errcode = capi20_get_manufacturer(data.contr, data.manufacturer);
-		if (cdev->errcode)
-			return -EIO;
-
-		if (copy_to_user(argp, data.manufacturer,
-				 sizeof(data.manufacturer)))
-			return -EFAULT;
-
-		return 0;
-
-	case CAPI_GET_ERRCODE:
-		data.errcode = cdev->errcode;
-		cdev->errcode = CAPI_NOERROR;
-		if (arg) {
-			if (copy_to_user(argp, &data.errcode,
-					 sizeof(data.errcode)))
-				return -EFAULT;
-		}
-		return data.errcode;
-
-	case CAPI_INSTALLED:
-		if (capi20_isinstalled() == CAPI_NOERROR)
-			return 0;
-		return -ENXIO;
-
-	case CAPI_MANUFACTURER_CMD: {
-		struct capi_manufacturer_cmd mcmd;
-		if (!capable(CAP_SYS_ADMIN))
-			return -EPERM;
-		if (copy_from_user(&mcmd, argp, sizeof(mcmd)))
-			return -EFAULT;
-		return capi20_manufacturer(mcmd.cmd, mcmd.data);
-	}
-	case CAPI_SET_FLAGS:
-	case CAPI_CLR_FLAGS: {
-		unsigned userflags;
-
-		if (copy_from_user(&userflags, argp, sizeof(userflags)))
-			return -EFAULT;
-
-		mutex_lock(&cdev->lock);
-		if (cmd == CAPI_SET_FLAGS)
-			cdev->userflags |= userflags;
-		else
-			cdev->userflags &= ~userflags;
-		mutex_unlock(&cdev->lock);
-		return 0;
-	}
-	case CAPI_GET_FLAGS:
-		if (copy_to_user(argp, &cdev->userflags,
-				 sizeof(cdev->userflags)))
-			return -EFAULT;
-		return 0;
-
-#ifndef CONFIG_ISDN_CAPI_MIDDLEWARE
-	case CAPI_NCCI_OPENCOUNT:
-		return 0;
-
-#else /* CONFIG_ISDN_CAPI_MIDDLEWARE */
-	case CAPI_NCCI_OPENCOUNT: {
-		struct capincci *nccip;
-		unsigned ncci;
-		int count = 0;
-
-		if (copy_from_user(&ncci, argp, sizeof(ncci)))
-			return -EFAULT;
-
-		mutex_lock(&cdev->lock);
-		nccip = capincci_find(cdev, (u32)ncci);
-		if (nccip)
-			count = capincci_minor_opencount(nccip);
-		mutex_unlock(&cdev->lock);
-		return count;
-	}
-
-	case CAPI_NCCI_GETUNIT: {
-		struct capincci *nccip;
-		struct capiminor *mp;
-		unsigned ncci;
-		int unit = -ESRCH;
-
-		if (copy_from_user(&ncci, argp, sizeof(ncci)))
-			return -EFAULT;
-
-		mutex_lock(&cdev->lock);
-		nccip = capincci_find(cdev, (u32)ncci);
-		if (nccip) {
-			mp = nccip->minorp;
-			if (mp)
-				unit = mp->minor;
-		}
-		mutex_unlock(&cdev->lock);
-		return unit;
-	}
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
-
-	default:
-		return -EINVAL;
-	}
-}
-
-static long
-capi_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	int ret;
-
-	mutex_lock(&capi_mutex);
-	ret = capi_ioctl(file, cmd, arg);
-	mutex_unlock(&capi_mutex);
-
-	return ret;
-}
-
-#ifdef CONFIG_COMPAT
-static long
-capi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	int ret;
-
-	if (cmd == CAPI_MANUFACTURER_CMD) {
-		struct {
-			compat_ulong_t cmd;
-			compat_uptr_t data;
-		} mcmd32;
-
-		if (!capable(CAP_SYS_ADMIN))
-			return -EPERM;
-		if (copy_from_user(&mcmd32, compat_ptr(arg), sizeof(mcmd32)))
-			return -EFAULT;
-
-		mutex_lock(&capi_mutex);
-		ret = capi20_manufacturer(mcmd32.cmd, compat_ptr(mcmd32.data));
-		mutex_unlock(&capi_mutex);
-
-		return ret;
-	}
-
-	return capi_unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
-}
-#endif
-
-static int capi_open(struct inode *inode, struct file *file)
-{
-	struct capidev *cdev;
-
-	cdev = kzalloc_obj(*cdev);
-	if (!cdev)
-		return -ENOMEM;
-
-	mutex_init(&cdev->lock);
-	skb_queue_head_init(&cdev->recvqueue);
-	init_waitqueue_head(&cdev->recvwait);
-	INIT_LIST_HEAD(&cdev->nccis);
-	file->private_data = cdev;
-
-	mutex_lock(&capidev_list_lock);
-	list_add_tail(&cdev->list, &capidev_list);
-	mutex_unlock(&capidev_list_lock);
-
-	return stream_open(inode, file);
-}
-
-static int capi_release(struct inode *inode, struct file *file)
-{
-	struct capidev *cdev = file->private_data;
-
-	mutex_lock(&capidev_list_lock);
-	list_del(&cdev->list);
-	mutex_unlock(&capidev_list_lock);
-
-	if (cdev->ap.applid)
-		capi20_release(&cdev->ap);
-	skb_queue_purge(&cdev->recvqueue);
-	capincci_free(cdev, 0xffffffff);
-
-	kfree(cdev);
-	return 0;
-}
-
-static const struct file_operations capi_fops =
-{
-	.owner		= THIS_MODULE,
-	.read		= capi_read,
-	.write		= capi_write,
-	.poll		= capi_poll,
-	.unlocked_ioctl	= capi_unlocked_ioctl,
-#ifdef CONFIG_COMPAT
-	.compat_ioctl	= capi_compat_ioctl,
-#endif
-	.open		= capi_open,
-	.release	= capi_release,
-};
-
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-/* -------- tty_operations for capincci ----------------------------- */
-
-static int
-capinc_tty_install(struct tty_driver *driver, struct tty_struct *tty)
-{
-	struct capiminor *mp = capiminor_get(tty->index);
-	int ret = tty_standard_install(driver, tty);
-
-	if (ret == 0)
-		tty->driver_data = mp;
-	else
-		capiminor_put(mp);
-	return ret;
-}
-
-static void capinc_tty_cleanup(struct tty_struct *tty)
-{
-	struct capiminor *mp = tty->driver_data;
-	tty->driver_data = NULL;
-	capiminor_put(mp);
-}
-
-static int capinc_tty_open(struct tty_struct *tty, struct file *filp)
-{
-	struct capiminor *mp = tty->driver_data;
-	int err;
-
-	err = tty_port_open(&mp->port, tty, filp);
-	if (err)
-		return err;
-
-	handle_minor_recv(mp);
-	return 0;
-}
-
-static void capinc_tty_close(struct tty_struct *tty, struct file *filp)
-{
-	struct capiminor *mp = tty->driver_data;
-
-	tty_port_close(&mp->port, tty, filp);
-}
-
-static ssize_t capinc_tty_write(struct tty_struct *tty, const u8 *buf,
-				size_t count)
-{
-	struct capiminor *mp = tty->driver_data;
-	struct sk_buff *skb;
-
-	pr_debug("capinc_tty_write(count=%zu)\n", count);
-
-	spin_lock_bh(&mp->outlock);
-	skb = mp->outskb;
-	if (skb) {
-		mp->outskb = NULL;
-		__skb_queue_tail(&mp->outqueue, skb);
-		mp->outbytes += skb->len;
-	}
-
-	skb = alloc_skb(CAPI_DATA_B3_REQ_LEN + count, GFP_ATOMIC);
-	if (!skb) {
-		printk(KERN_ERR "capinc_tty_write: alloc_skb failed\n");
-		spin_unlock_bh(&mp->outlock);
-		return -ENOMEM;
-	}
-
-	skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
-	skb_put_data(skb, buf, count);
-
-	__skb_queue_tail(&mp->outqueue, skb);
-	mp->outbytes += skb->len;
-	spin_unlock_bh(&mp->outlock);
-
-	handle_minor_send(mp);
-
-	return count;
-}
-
-static int capinc_tty_put_char(struct tty_struct *tty, u8 ch)
-{
-	struct capiminor *mp = tty->driver_data;
-	bool invoke_send = false;
-	struct sk_buff *skb;
-	int ret = 1;
-
-	pr_debug("capinc_put_char(%u)\n", ch);
-
-	spin_lock_bh(&mp->outlock);
-	skb = mp->outskb;
-	if (skb) {
-		if (skb_tailroom(skb) > 0) {
-			skb_put_u8(skb, ch);
-			goto unlock_out;
-		}
-		mp->outskb = NULL;
-		__skb_queue_tail(&mp->outqueue, skb);
-		mp->outbytes += skb->len;
-		invoke_send = true;
-	}
-
-	skb = alloc_skb(CAPI_DATA_B3_REQ_LEN + CAPI_MAX_BLKSIZE, GFP_ATOMIC);
-	if (skb) {
-		skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
-		skb_put_u8(skb, ch);
-		mp->outskb = skb;
-	} else {
-		printk(KERN_ERR "capinc_put_char: char %u lost\n", ch);
-		ret = 0;
-	}
-
-unlock_out:
-	spin_unlock_bh(&mp->outlock);
-
-	if (invoke_send)
-		handle_minor_send(mp);
-
-	return ret;
-}
-
-static void capinc_tty_flush_chars(struct tty_struct *tty)
-{
-	struct capiminor *mp = tty->driver_data;
-	struct sk_buff *skb;
-
-	spin_lock_bh(&mp->outlock);
-	skb = mp->outskb;
-	if (skb) {
-		mp->outskb = NULL;
-		__skb_queue_tail(&mp->outqueue, skb);
-		mp->outbytes += skb->len;
-		spin_unlock_bh(&mp->outlock);
-
-		handle_minor_send(mp);
-	} else
-		spin_unlock_bh(&mp->outlock);
-
-	handle_minor_recv(mp);
-}
-
-static unsigned int capinc_tty_write_room(struct tty_struct *tty)
-{
-	struct capiminor *mp = tty->driver_data;
-	unsigned int room;
-
-	room = CAPINC_MAX_SENDQUEUE-skb_queue_len(&mp->outqueue);
-	room *= CAPI_MAX_BLKSIZE;
-	pr_debug("capinc_tty_write_room = %u\n", room);
-	return room;
-}
-
-static unsigned int capinc_tty_chars_in_buffer(struct tty_struct *tty)
-{
-	struct capiminor *mp = tty->driver_data;
-
-	pr_debug("capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%d\n",
-		 mp->outbytes, mp->nack,
-		 skb_queue_len(&mp->outqueue),
-		 skb_queue_len(&mp->inqueue));
-	return mp->outbytes;
-}
-
-static void capinc_tty_throttle(struct tty_struct *tty)
-{
-	struct capiminor *mp = tty->driver_data;
-	mp->ttyinstop = 1;
-}
-
-static void capinc_tty_unthrottle(struct tty_struct *tty)
-{
-	struct capiminor *mp = tty->driver_data;
-
-	mp->ttyinstop = 0;
-	handle_minor_recv(mp);
-}
-
-static void capinc_tty_stop(struct tty_struct *tty)
-{
-	struct capiminor *mp = tty->driver_data;
-
-	mp->ttyoutstop = 1;
-}
-
-static void capinc_tty_start(struct tty_struct *tty)
-{
-	struct capiminor *mp = tty->driver_data;
-
-	mp->ttyoutstop = 0;
-	handle_minor_send(mp);
-}
-
-static void capinc_tty_hangup(struct tty_struct *tty)
-{
-	struct capiminor *mp = tty->driver_data;
-
-	tty_port_hangup(&mp->port);
-}
-
-static void capinc_tty_send_xchar(struct tty_struct *tty, u8 ch)
-{
-	pr_debug("capinc_tty_send_xchar(%u)\n", ch);
-}
-
-static const struct tty_operations capinc_ops = {
-	.open = capinc_tty_open,
-	.close = capinc_tty_close,
-	.write = capinc_tty_write,
-	.put_char = capinc_tty_put_char,
-	.flush_chars = capinc_tty_flush_chars,
-	.write_room = capinc_tty_write_room,
-	.chars_in_buffer = capinc_tty_chars_in_buffer,
-	.throttle = capinc_tty_throttle,
-	.unthrottle = capinc_tty_unthrottle,
-	.stop = capinc_tty_stop,
-	.start = capinc_tty_start,
-	.hangup = capinc_tty_hangup,
-	.send_xchar = capinc_tty_send_xchar,
-	.install = capinc_tty_install,
-	.cleanup = capinc_tty_cleanup,
-};
-
-static int __init capinc_tty_init(void)
-{
-	struct tty_driver *drv;
-	int err;
-
-	if (capi_ttyminors > CAPINC_MAX_PORTS)
-		capi_ttyminors = CAPINC_MAX_PORTS;
-	if (capi_ttyminors <= 0)
-		capi_ttyminors = CAPINC_NR_PORTS;
-
-	capiminors = kzalloc_objs(struct capiminor *, capi_ttyminors);
-	if (!capiminors)
-		return -ENOMEM;
-
-	drv = tty_alloc_driver(capi_ttyminors, TTY_DRIVER_REAL_RAW |
-			TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_DYNAMIC_DEV);
-	if (IS_ERR(drv)) {
-		kfree(capiminors);
-		return PTR_ERR(drv);
-	}
-	drv->driver_name = "capi_nc";
-	drv->name = "capi!";
-	drv->major = 0;
-	drv->minor_start = 0;
-	drv->type = TTY_DRIVER_TYPE_SERIAL;
-	drv->subtype = SERIAL_TYPE_NORMAL;
-	drv->init_termios = tty_std_termios;
-	drv->init_termios.c_iflag = ICRNL;
-	drv->init_termios.c_oflag = OPOST | ONLCR;
-	drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-	drv->init_termios.c_lflag = 0;
-	tty_set_operations(drv, &capinc_ops);
-
-	err = tty_register_driver(drv);
-	if (err) {
-		tty_driver_kref_put(drv);
-		kfree(capiminors);
-		printk(KERN_ERR "Couldn't register capi_nc driver\n");
-		return err;
-	}
-	capinc_tty_driver = drv;
-	return 0;
-}
-
-static void __exit capinc_tty_exit(void)
-{
-	tty_unregister_driver(capinc_tty_driver);
-	tty_driver_kref_put(capinc_tty_driver);
-	kfree(capiminors);
-}
-
-#else /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
-
-static inline int capinc_tty_init(void)
-{
-	return 0;
-}
-
-static inline void capinc_tty_exit(void) { }
-
-#endif /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
-
-/* -------- /proc functions ----------------------------------------- */
-
-/*
- * /proc/capi/capi20:
- *  minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
- */
-static int __maybe_unused capi20_proc_show(struct seq_file *m, void *v)
-{
-	struct capidev *cdev;
-	struct list_head *l;
-
-	mutex_lock(&capidev_list_lock);
-	list_for_each(l, &capidev_list) {
-		cdev = list_entry(l, struct capidev, list);
-		seq_printf(m, "0 %d %lu %lu %lu %lu\n",
-			   cdev->ap.applid,
-			   cdev->ap.nrecvctlpkt,
-			   cdev->ap.nrecvdatapkt,
-			   cdev->ap.nsentctlpkt,
-			   cdev->ap.nsentdatapkt);
-	}
-	mutex_unlock(&capidev_list_lock);
-	return 0;
-}
-
-/*
- * /proc/capi/capi20ncci:
- *  applid ncci
- */
-static int __maybe_unused capi20ncci_proc_show(struct seq_file *m, void *v)
-{
-	struct capidev *cdev;
-	struct capincci *np;
-
-	mutex_lock(&capidev_list_lock);
-	list_for_each_entry(cdev, &capidev_list, list) {
-		mutex_lock(&cdev->lock);
-		list_for_each_entry(np, &cdev->nccis, list)
-			seq_printf(m, "%d 0x%x\n", cdev->ap.applid, np->ncci);
-		mutex_unlock(&cdev->lock);
-	}
-	mutex_unlock(&capidev_list_lock);
-	return 0;
-}
-
-static void __init proc_init(void)
-{
-	proc_create_single("capi/capi20", 0, NULL, capi20_proc_show);
-	proc_create_single("capi/capi20ncci", 0, NULL, capi20ncci_proc_show);
-}
-
-static void __exit proc_exit(void)
-{
-	remove_proc_entry("capi/capi20", NULL);
-	remove_proc_entry("capi/capi20ncci", NULL);
-}
-
-/* -------- init function and module interface ---------------------- */
-
-
-static int __init capi_init(void)
-{
-	const char *compileinfo;
-	int major_ret;
-	int ret;
-
-	ret = kcapi_init();
-	if (ret)
-		return ret;
-
-	major_ret = register_chrdev(capi_major, "capi20", &capi_fops);
-	if (major_ret < 0) {
-		printk(KERN_ERR "capi20: unable to get major %d\n", capi_major);
-		kcapi_exit();
-		return major_ret;
-	}
-
-	ret = class_register(&capi_class);
-	if (ret) {
-		unregister_chrdev(capi_major, "capi20");
-		kcapi_exit();
-		return ret;
-	}
-
-	device_create(&capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi20");
-
-	if (capinc_tty_init() < 0) {
-		device_destroy(&capi_class, MKDEV(capi_major, 0));
-		class_unregister(&capi_class);
-		unregister_chrdev(capi_major, "capi20");
-		kcapi_exit();
-		return -ENOMEM;
-	}
-
-	proc_init();
-
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-	compileinfo = " (middleware)";
-#else
-	compileinfo = " (no middleware)";
-#endif
-	printk(KERN_NOTICE "CAPI 2.0 started up with major %d%s\n",
-	       capi_major, compileinfo);
-
-	return 0;
-}
-
-static void __exit capi_exit(void)
-{
-	proc_exit();
-
-	device_destroy(&capi_class, MKDEV(capi_major, 0));
-	class_unregister(&capi_class);
-	unregister_chrdev(capi_major, "capi20");
-
-	capinc_tty_exit();
-
-	kcapi_exit();
-}
-
-module_init(capi_init);
-module_exit(capi_exit);
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c
deleted file mode 100644
index eec9b36343b7..000000000000
--- a/drivers/isdn/capi/capiutil.c
+++ /dev/null
@@ -1,677 +0,0 @@
-/* $Id: capiutil.c,v 1.13.6.4 2001/09/23 22:24:33 kai Exp $
- *
- * CAPI 2.0 convert capi message to capi message struct
- *
- * From CAPI 2.0 Development Kit AVM 1995 (msg.c)
- * Rewritten for Linux 1996 by Carsten Paeth <calle@calle.de>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/isdn/capiutil.h>
-#include <linux/slab.h>
-
-#include "kcapi.h"
-
-/* from CAPI2.0 DDK AVM Berlin GmbH */
-
-typedef struct {
-	int typ;
-	size_t off;
-} _cdef;
-
-#define _CBYTE	       1
-#define _CWORD	       2
-#define _CDWORD        3
-#define _CSTRUCT       4
-#define _CMSTRUCT      5
-#define _CEND	       6
-
-static _cdef cdef[] =
-{
-	/*00 */
-	{_CEND},
-	/*01 */
-	{_CEND},
-	/*02 */
-	{_CEND},
-	/*03 */
-	{_CDWORD, offsetof(_cmsg, adr.adrController)},
-	/*04 */
-	{_CMSTRUCT, offsetof(_cmsg, AdditionalInfo)},
-	/*05 */
-	{_CSTRUCT, offsetof(_cmsg, B1configuration)},
-	/*06 */
-	{_CWORD, offsetof(_cmsg, B1protocol)},
-	/*07 */
-	{_CSTRUCT, offsetof(_cmsg, B2configuration)},
-	/*08 */
-	{_CWORD, offsetof(_cmsg, B2protocol)},
-	/*09 */
-	{_CSTRUCT, offsetof(_cmsg, B3configuration)},
-	/*0a */
-	{_CWORD, offsetof(_cmsg, B3protocol)},
-	/*0b */
-	{_CSTRUCT, offsetof(_cmsg, BC)},
-	/*0c */
-	{_CSTRUCT, offsetof(_cmsg, BChannelinformation)},
-	/*0d */
-	{_CMSTRUCT, offsetof(_cmsg, BProtocol)},
-	/*0e */
-	{_CSTRUCT, offsetof(_cmsg, CalledPartyNumber)},
-	/*0f */
-	{_CSTRUCT, offsetof(_cmsg, CalledPartySubaddress)},
-	/*10 */
-	{_CSTRUCT, offsetof(_cmsg, CallingPartyNumber)},
-	/*11 */
-	{_CSTRUCT, offsetof(_cmsg, CallingPartySubaddress)},
-	/*12 */
-	{_CDWORD, offsetof(_cmsg, CIPmask)},
-	/*13 */
-	{_CDWORD, offsetof(_cmsg, CIPmask2)},
-	/*14 */
-	{_CWORD, offsetof(_cmsg, CIPValue)},
-	/*15 */
-	{_CDWORD, offsetof(_cmsg, Class)},
-	/*16 */
-	{_CSTRUCT, offsetof(_cmsg, ConnectedNumber)},
-	/*17 */
-	{_CSTRUCT, offsetof(_cmsg, ConnectedSubaddress)},
-	/*18 */
-	{_CDWORD, offsetof(_cmsg, Data)},
-	/*19 */
-	{_CWORD, offsetof(_cmsg, DataHandle)},
-	/*1a */
-	{_CWORD, offsetof(_cmsg, DataLength)},
-	/*1b */
-	{_CSTRUCT, offsetof(_cmsg, FacilityConfirmationParameter)},
-	/*1c */
-	{_CSTRUCT, offsetof(_cmsg, Facilitydataarray)},
-	/*1d */
-	{_CSTRUCT, offsetof(_cmsg, FacilityIndicationParameter)},
-	/*1e */
-	{_CSTRUCT, offsetof(_cmsg, FacilityRequestParameter)},
-	/*1f */
-	{_CWORD, offsetof(_cmsg, FacilitySelector)},
-	/*20 */
-	{_CWORD, offsetof(_cmsg, Flags)},
-	/*21 */
-	{_CDWORD, offsetof(_cmsg, Function)},
-	/*22 */
-	{_CSTRUCT, offsetof(_cmsg, HLC)},
-	/*23 */
-	{_CWORD, offsetof(_cmsg, Info)},
-	/*24 */
-	{_CSTRUCT, offsetof(_cmsg, InfoElement)},
-	/*25 */
-	{_CDWORD, offsetof(_cmsg, InfoMask)},
-	/*26 */
-	{_CWORD, offsetof(_cmsg, InfoNumber)},
-	/*27 */
-	{_CSTRUCT, offsetof(_cmsg, Keypadfacility)},
-	/*28 */
-	{_CSTRUCT, offsetof(_cmsg, LLC)},
-	/*29 */
-	{_CSTRUCT, offsetof(_cmsg, ManuData)},
-	/*2a */
-	{_CDWORD, offsetof(_cmsg, ManuID)},
-	/*2b */
-	{_CSTRUCT, offsetof(_cmsg, NCPI)},
-	/*2c */
-	{_CWORD, offsetof(_cmsg, Reason)},
-	/*2d */
-	{_CWORD, offsetof(_cmsg, Reason_B3)},
-	/*2e */
-	{_CWORD, offsetof(_cmsg, Reject)},
-	/*2f */
-	{_CSTRUCT, offsetof(_cmsg, Useruserdata)}
-};
-
-static unsigned char *cpars[] =
-{
-	/* ALERT_REQ */ [0x01] = "\x03\x04\x0c\x27\x2f\x1c\x01\x01",
-	/* CONNECT_REQ */ [0x02] = "\x03\x14\x0e\x10\x0f\x11\x0d\x06\x08\x0a\x05\x07\x09\x01\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01",
-	/* DISCONNECT_REQ */ [0x04] = "\x03\x04\x0c\x27\x2f\x1c\x01\x01",
-	/* LISTEN_REQ */ [0x05] = "\x03\x25\x12\x13\x10\x11\x01",
-	/* INFO_REQ */ [0x08] = "\x03\x0e\x04\x0c\x27\x2f\x1c\x01\x01",
-	/* FACILITY_REQ */ [0x09] = "\x03\x1f\x1e\x01",
-	/* SELECT_B_PROTOCOL_REQ */ [0x0a] = "\x03\x0d\x06\x08\x0a\x05\x07\x09\x01\x01",
-	/* CONNECT_B3_REQ */ [0x0b] = "\x03\x2b\x01",
-	/* DISCONNECT_B3_REQ */ [0x0d] = "\x03\x2b\x01",
-	/* DATA_B3_REQ */ [0x0f] = "\x03\x18\x1a\x19\x20\x01",
-	/* RESET_B3_REQ */ [0x10] = "\x03\x2b\x01",
-	/* ALERT_CONF */ [0x13] = "\x03\x23\x01",
-	/* CONNECT_CONF */ [0x14] = "\x03\x23\x01",
-	/* DISCONNECT_CONF */ [0x16] = "\x03\x23\x01",
-	/* LISTEN_CONF */ [0x17] = "\x03\x23\x01",
-	/* MANUFACTURER_REQ */ [0x18] = "\x03\x2a\x15\x21\x29\x01",
-	/* INFO_CONF */ [0x1a] = "\x03\x23\x01",
-	/* FACILITY_CONF */ [0x1b] = "\x03\x23\x1f\x1b\x01",
-	/* SELECT_B_PROTOCOL_CONF */ [0x1c] = "\x03\x23\x01",
-	/* CONNECT_B3_CONF */ [0x1d] = "\x03\x23\x01",
-	/* DISCONNECT_B3_CONF */ [0x1f] = "\x03\x23\x01",
-	/* DATA_B3_CONF */ [0x21] = "\x03\x19\x23\x01",
-	/* RESET_B3_CONF */ [0x22] = "\x03\x23\x01",
-	/* CONNECT_IND */ [0x26] = "\x03\x14\x0e\x10\x0f\x11\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01",
-	/* CONNECT_ACTIVE_IND */ [0x27] = "\x03\x16\x17\x28\x01",
-	/* DISCONNECT_IND */ [0x28] = "\x03\x2c\x01",
-	/* MANUFACTURER_CONF */ [0x2a] = "\x03\x2a\x15\x21\x29\x01",
-	/* INFO_IND */ [0x2c] = "\x03\x26\x24\x01",
-	/* FACILITY_IND */ [0x2d] = "\x03\x1f\x1d\x01",
-	/* CONNECT_B3_IND */ [0x2f] = "\x03\x2b\x01",
-	/* CONNECT_B3_ACTIVE_IND */ [0x30] = "\x03\x2b\x01",
-	/* DISCONNECT_B3_IND */ [0x31] = "\x03\x2d\x2b\x01",
-	/* DATA_B3_IND */ [0x33] = "\x03\x18\x1a\x19\x20\x01",
-	/* RESET_B3_IND */ [0x34] = "\x03\x2b\x01",
-	/* CONNECT_B3_T90_ACTIVE_IND */ [0x35] = "\x03\x2b\x01",
-	/* CONNECT_RESP */ [0x38] = "\x03\x2e\x0d\x06\x08\x0a\x05\x07\x09\x01\x16\x17\x28\x04\x0c\x27\x2f\x1c\x01\x01",
-	/* CONNECT_ACTIVE_RESP */ [0x39] = "\x03\x01",
-	/* DISCONNECT_RESP */ [0x3a] = "\x03\x01",
-	/* MANUFACTURER_IND */ [0x3c] = "\x03\x2a\x15\x21\x29\x01",
-	/* INFO_RESP */ [0x3e] = "\x03\x01",
-	/* FACILITY_RESP */ [0x3f] = "\x03\x1f\x01",
-	/* CONNECT_B3_RESP */ [0x41] = "\x03\x2e\x2b\x01",
-	/* CONNECT_B3_ACTIVE_RESP */ [0x42] = "\x03\x01",
-	/* DISCONNECT_B3_RESP */ [0x43] = "\x03\x01",
-	/* DATA_B3_RESP */ [0x45] = "\x03\x19\x01",
-	/* RESET_B3_RESP */ [0x46] = "\x03\x01",
-	/* CONNECT_B3_T90_ACTIVE_RESP */ [0x47] = "\x03\x01",
-	/* MANUFACTURER_RESP */ [0x4e] = "\x03\x2a\x15\x21\x29\x01",
-};
-
-/*-------------------------------------------------------*/
-
-#define byteTLcpy(x, y)         *(u8 *)(x) = *(u8 *)(y);
-#define wordTLcpy(x, y)         *(u16 *)(x) = *(u16 *)(y);
-#define dwordTLcpy(x, y)        memcpy(x, y, 4);
-#define structTLcpy(x, y, l)    memcpy(x, y, l)
-#define structTLcpyovl(x, y, l) memmove(x, y, l)
-
-#define byteTRcpy(x, y)         *(u8 *)(y) = *(u8 *)(x);
-#define wordTRcpy(x, y)         *(u16 *)(y) = *(u16 *)(x);
-#define dwordTRcpy(x, y)        memcpy(y, x, 4);
-#define structTRcpy(x, y, l)    memcpy(y, x, l)
-#define structTRcpyovl(x, y, l) memmove(y, x, l)
-
-/*-------------------------------------------------------*/
-static unsigned command_2_index(u8 c, u8 sc)
-{
-	if (c & 0x80)
-		c = 0x9 + (c & 0x0f);
-	else if (c == 0x41)
-		c = 0x9 + 0x1;
-	if (c > 0x18)
-		c = 0x00;
-	return (sc & 3) * (0x9 + 0x9) + c;
-}
-
-/**
- * capi_cmd2par() - find parameter string for CAPI 2.0 command/subcommand
- * @cmd:	command number
- * @subcmd:	subcommand number
- *
- * Return value: static string, NULL if command/subcommand unknown
- */
-
-static unsigned char *capi_cmd2par(u8 cmd, u8 subcmd)
-{
-	return cpars[command_2_index(cmd, subcmd)];
-}
-
-/*-------------------------------------------------------*/
-#define TYP (cdef[cmsg->par[cmsg->p]].typ)
-#define OFF (((u8 *)cmsg) + cdef[cmsg->par[cmsg->p]].off)
-
-static void jumpcstruct(_cmsg *cmsg)
-{
-	unsigned layer;
-	for (cmsg->p++, layer = 1; layer;) {
-		/* $$$$$ assert (cmsg->p); */
-		cmsg->p++;
-		switch (TYP) {
-		case _CMSTRUCT:
-			layer++;
-			break;
-		case _CEND:
-			layer--;
-			break;
-		}
-	}
-}
-
-/*-------------------------------------------------------*/
-
-static char *mnames[] =
-{
-	[0x01] = "ALERT_REQ",
-	[0x02] = "CONNECT_REQ",
-	[0x04] = "DISCONNECT_REQ",
-	[0x05] = "LISTEN_REQ",
-	[0x08] = "INFO_REQ",
-	[0x09] = "FACILITY_REQ",
-	[0x0a] = "SELECT_B_PROTOCOL_REQ",
-	[0x0b] = "CONNECT_B3_REQ",
-	[0x0d] = "DISCONNECT_B3_REQ",
-	[0x0f] = "DATA_B3_REQ",
-	[0x10] = "RESET_B3_REQ",
-	[0x13] = "ALERT_CONF",
-	[0x14] = "CONNECT_CONF",
-	[0x16] = "DISCONNECT_CONF",
-	[0x17] = "LISTEN_CONF",
-	[0x18] = "MANUFACTURER_REQ",
-	[0x1a] = "INFO_CONF",
-	[0x1b] = "FACILITY_CONF",
-	[0x1c] = "SELECT_B_PROTOCOL_CONF",
-	[0x1d] = "CONNECT_B3_CONF",
-	[0x1f] = "DISCONNECT_B3_CONF",
-	[0x21] = "DATA_B3_CONF",
-	[0x22] = "RESET_B3_CONF",
-	[0x26] = "CONNECT_IND",
-	[0x27] = "CONNECT_ACTIVE_IND",
-	[0x28] = "DISCONNECT_IND",
-	[0x2a] = "MANUFACTURER_CONF",
-	[0x2c] = "INFO_IND",
-	[0x2d] = "FACILITY_IND",
-	[0x2f] = "CONNECT_B3_IND",
-	[0x30] = "CONNECT_B3_ACTIVE_IND",
-	[0x31] = "DISCONNECT_B3_IND",
-	[0x33] = "DATA_B3_IND",
-	[0x34] = "RESET_B3_IND",
-	[0x35] = "CONNECT_B3_T90_ACTIVE_IND",
-	[0x38] = "CONNECT_RESP",
-	[0x39] = "CONNECT_ACTIVE_RESP",
-	[0x3a] = "DISCONNECT_RESP",
-	[0x3c] = "MANUFACTURER_IND",
-	[0x3e] = "INFO_RESP",
-	[0x3f] = "FACILITY_RESP",
-	[0x41] = "CONNECT_B3_RESP",
-	[0x42] = "CONNECT_B3_ACTIVE_RESP",
-	[0x43] = "DISCONNECT_B3_RESP",
-	[0x45] = "DATA_B3_RESP",
-	[0x46] = "RESET_B3_RESP",
-	[0x47] = "CONNECT_B3_T90_ACTIVE_RESP",
-	[0x4e] = "MANUFACTURER_RESP"
-};
-
-/**
- * capi_cmd2str() - convert CAPI 2.0 command/subcommand number to name
- * @cmd:	command number
- * @subcmd:	subcommand number
- *
- * Return value: static string
- */
-
-char *capi_cmd2str(u8 cmd, u8 subcmd)
-{
-	char *result;
-
-	result = mnames[command_2_index(cmd, subcmd)];
-	if (result == NULL)
-		result = "INVALID_COMMAND";
-	return result;
-}
-
-
-/*-------------------------------------------------------*/
-
-#ifdef CONFIG_CAPI_TRACE
-
-/*-------------------------------------------------------*/
-
-static char *pnames[] =
-{
-	/*00 */ NULL,
-	/*01 */ NULL,
-	/*02 */ NULL,
-	/*03 */ "Controller/PLCI/NCCI",
-	/*04 */ "AdditionalInfo",
-	/*05 */ "B1configuration",
-	/*06 */ "B1protocol",
-	/*07 */ "B2configuration",
-	/*08 */ "B2protocol",
-	/*09 */ "B3configuration",
-	/*0a */ "B3protocol",
-	/*0b */ "BC",
-	/*0c */ "BChannelinformation",
-	/*0d */ "BProtocol",
-	/*0e */ "CalledPartyNumber",
-	/*0f */ "CalledPartySubaddress",
-	/*10 */ "CallingPartyNumber",
-	/*11 */ "CallingPartySubaddress",
-	/*12 */ "CIPmask",
-	/*13 */ "CIPmask2",
-	/*14 */ "CIPValue",
-	/*15 */ "Class",
-	/*16 */ "ConnectedNumber",
-	/*17 */ "ConnectedSubaddress",
-	/*18 */ "Data32",
-	/*19 */ "DataHandle",
-	/*1a */ "DataLength",
-	/*1b */ "FacilityConfirmationParameter",
-	/*1c */ "Facilitydataarray",
-	/*1d */ "FacilityIndicationParameter",
-	/*1e */ "FacilityRequestParameter",
-	/*1f */ "FacilitySelector",
-	/*20 */ "Flags",
-	/*21 */ "Function",
-	/*22 */ "HLC",
-	/*23 */ "Info",
-	/*24 */ "InfoElement",
-	/*25 */ "InfoMask",
-	/*26 */ "InfoNumber",
-	/*27 */ "Keypadfacility",
-	/*28 */ "LLC",
-	/*29 */ "ManuData",
-	/*2a */ "ManuID",
-	/*2b */ "NCPI",
-	/*2c */ "Reason",
-	/*2d */ "Reason_B3",
-	/*2e */ "Reject",
-	/*2f */ "Useruserdata"
-};
-
-#include <linux/stdarg.h>
-
-/*-------------------------------------------------------*/
-static _cdebbuf *bufprint(_cdebbuf *cdb, char *fmt, ...)
-{
-	va_list f;
-	size_t n, r;
-
-	if (!cdb)
-		return NULL;
-	va_start(f, fmt);
-	r = cdb->size - cdb->pos;
-	n = vsnprintf(cdb->p, r, fmt, f);
-	va_end(f);
-	if (n >= r) {
-		/* truncated, need bigger buffer */
-		size_t ns = 2 * cdb->size;
-		u_char *nb;
-
-		while ((ns - cdb->pos) <= n)
-			ns *= 2;
-		nb = kmalloc(ns, GFP_ATOMIC);
-		if (!nb) {
-			cdebbuf_free(cdb);
-			return NULL;
-		}
-		memcpy(nb, cdb->buf, cdb->pos);
-		kfree(cdb->buf);
-		nb[cdb->pos] = 0;
-		cdb->buf = nb;
-		cdb->p = cdb->buf + cdb->pos;
-		cdb->size = ns;
-		va_start(f, fmt);
-		r = cdb->size - cdb->pos;
-		n = vsnprintf(cdb->p, r, fmt, f);
-		va_end(f);
-	}
-	cdb->p += n;
-	cdb->pos += n;
-	return cdb;
-}
-
-static _cdebbuf *printstructlen(_cdebbuf *cdb, u8 *m, unsigned len)
-{
-	unsigned hex = 0;
-
-	if (!cdb)
-		return NULL;
-	for (; len; len--, m++)
-		if (isalnum(*m) || *m == ' ') {
-			if (hex)
-				cdb = bufprint(cdb, ">");
-			cdb = bufprint(cdb, "%c", *m);
-			hex = 0;
-		} else {
-			if (!hex)
-				cdb = bufprint(cdb, "<%02x", *m);
-			else
-				cdb = bufprint(cdb, " %02x", *m);
-			hex = 1;
-		}
-	if (hex)
-		cdb = bufprint(cdb, ">");
-	return cdb;
-}
-
-static _cdebbuf *printstruct(_cdebbuf *cdb, u8 *m)
-{
-	unsigned len;
-
-	if (m[0] != 0xff) {
-		len = m[0];
-		m += 1;
-	} else {
-		len = ((u16 *) (m + 1))[0];
-		m += 3;
-	}
-	cdb = printstructlen(cdb, m, len);
-	return cdb;
-}
-
-/*-------------------------------------------------------*/
-#define NAME (pnames[cmsg->par[cmsg->p]])
-
-static _cdebbuf *protocol_message_2_pars(_cdebbuf *cdb, _cmsg *cmsg, int level)
-{
-	if (!cmsg->par)
-		return NULL;	/* invalid command/subcommand */
-
-	for (; TYP != _CEND; cmsg->p++) {
-		int slen = 29 + 3 - level;
-		int i;
-
-		if (!cdb)
-			return NULL;
-		cdb = bufprint(cdb, "  ");
-		for (i = 0; i < level - 1; i++)
-			cdb = bufprint(cdb, " ");
-
-		switch (TYP) {
-		case _CBYTE:
-			cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u8 *) (cmsg->m + cmsg->l));
-			cmsg->l++;
-			break;
-		case _CWORD:
-			cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u16 *) (cmsg->m + cmsg->l));
-			cmsg->l += 2;
-			break;
-		case _CDWORD:
-			cdb = bufprint(cdb, "%-*s = 0x%lx\n", slen, NAME, *(u32 *) (cmsg->m + cmsg->l));
-			cmsg->l += 4;
-			break;
-		case _CSTRUCT:
-			cdb = bufprint(cdb, "%-*s = ", slen, NAME);
-			if (cmsg->m[cmsg->l] == '\0')
-				cdb = bufprint(cdb, "default");
-			else
-				cdb = printstruct(cdb, cmsg->m + cmsg->l);
-			cdb = bufprint(cdb, "\n");
-			if (cmsg->m[cmsg->l] != 0xff)
-				cmsg->l += 1 + cmsg->m[cmsg->l];
-			else
-				cmsg->l += 3 + *(u16 *) (cmsg->m + cmsg->l + 1);
-
-			break;
-
-		case _CMSTRUCT:
-/*----- Metastruktur 0 -----*/
-			if (cmsg->m[cmsg->l] == '\0') {
-				cdb = bufprint(cdb, "%-*s = default\n", slen, NAME);
-				cmsg->l++;
-				jumpcstruct(cmsg);
-			} else {
-				char *name = NAME;
-				unsigned _l = cmsg->l;
-				cdb = bufprint(cdb, "%-*s\n", slen, name);
-				cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1;
-				cmsg->p++;
-				cdb = protocol_message_2_pars(cdb, cmsg, level + 1);
-			}
-			break;
-		}
-	}
-	return cdb;
-}
-/*-------------------------------------------------------*/
-
-static _cdebbuf *g_debbuf;
-static u_long g_debbuf_lock;
-static _cmsg *g_cmsg;
-
-static _cdebbuf *cdebbuf_alloc(void)
-{
-	_cdebbuf *cdb;
-
-	if (likely(!test_and_set_bit(1, &g_debbuf_lock))) {
-		cdb = g_debbuf;
-		goto init;
-	} else
-		cdb = kmalloc_obj(_cdebbuf, GFP_ATOMIC);
-	if (!cdb)
-		return NULL;
-	cdb->buf = kmalloc(CDEBUG_SIZE, GFP_ATOMIC);
-	if (!cdb->buf) {
-		kfree(cdb);
-		return NULL;
-	}
-	cdb->size = CDEBUG_SIZE;
-init:
-	cdb->buf[0] = 0;
-	cdb->p = cdb->buf;
-	cdb->pos = 0;
-	return cdb;
-}
-
-/**
- * cdebbuf_free() - free CAPI debug buffer
- * @cdb:	buffer to free
- */
-
-void cdebbuf_free(_cdebbuf *cdb)
-{
-	if (likely(cdb == g_debbuf)) {
-		test_and_clear_bit(1, &g_debbuf_lock);
-		return;
-	}
-	if (likely(cdb))
-		kfree(cdb->buf);
-	kfree(cdb);
-}
-
-
-/**
- * capi_message2str() - format CAPI 2.0 message for printing
- * @msg:	CAPI 2.0 message
- *
- * Allocates a CAPI debug buffer and fills it with a printable representation
- * of the CAPI 2.0 message in @msg.
- * Return value: allocated debug buffer, NULL on error
- * The returned buffer should be freed by a call to cdebbuf_free() after use.
- */
-
-_cdebbuf *capi_message2str(u8 *msg)
-{
-	_cdebbuf *cdb;
-	_cmsg	*cmsg;
-
-	cdb = cdebbuf_alloc();
-	if (unlikely(!cdb))
-		return NULL;
-	if (likely(cdb == g_debbuf))
-		cmsg = g_cmsg;
-	else
-		cmsg = kmalloc_obj(_cmsg, GFP_ATOMIC);
-	if (unlikely(!cmsg)) {
-		cdebbuf_free(cdb);
-		return NULL;
-	}
-	cmsg->m = msg;
-	cmsg->l = 8;
-	cmsg->p = 0;
-	byteTRcpy(cmsg->m + 4, &cmsg->Command);
-	byteTRcpy(cmsg->m + 5, &cmsg->Subcommand);
-	cmsg->par = capi_cmd2par(cmsg->Command, cmsg->Subcommand);
-
-	cdb = bufprint(cdb, "%-26s ID=%03d #0x%04x LEN=%04d\n",
-		       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
-		       ((unsigned short *) msg)[1],
-		       ((unsigned short *) msg)[3],
-		       ((unsigned short *) msg)[0]);
-
-	cdb = protocol_message_2_pars(cdb, cmsg, 1);
-	if (unlikely(cmsg != g_cmsg))
-		kfree(cmsg);
-	return cdb;
-}
-
-int __init cdebug_init(void)
-{
-	g_cmsg = kmalloc_obj(_cmsg);
-	if (!g_cmsg)
-		return -ENOMEM;
-	g_debbuf = kmalloc_obj(_cdebbuf);
-	if (!g_debbuf) {
-		kfree(g_cmsg);
-		return -ENOMEM;
-	}
-	g_debbuf->buf = kmalloc(CDEBUG_GSIZE, GFP_KERNEL);
-	if (!g_debbuf->buf) {
-		kfree(g_cmsg);
-		kfree(g_debbuf);
-		return -ENOMEM;
-	}
-	g_debbuf->size = CDEBUG_GSIZE;
-	g_debbuf->buf[0] = 0;
-	g_debbuf->p = g_debbuf->buf;
-	g_debbuf->pos = 0;
-	return 0;
-}
-
-void cdebug_exit(void)
-{
-	if (g_debbuf)
-		kfree(g_debbuf->buf);
-	kfree(g_debbuf);
-	kfree(g_cmsg);
-}
-
-#else /* !CONFIG_CAPI_TRACE */
-
-static _cdebbuf g_debbuf = {"CONFIG_CAPI_TRACE not enabled", NULL, 0, 0};
-
-_cdebbuf *capi_message2str(u8 *msg)
-{
-	return &g_debbuf;
-}
-
-_cdebbuf *capi_cmsg2str(_cmsg *cmsg)
-{
-	return &g_debbuf;
-}
-
-void cdebbuf_free(_cdebbuf *cdb)
-{
-}
-
-int __init cdebug_init(void)
-{
-	return 0;
-}
-
-void cdebug_exit(void)
-{
-}
-
-#endif
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
deleted file mode 100644
index f9fa17d68095..000000000000
--- a/drivers/isdn/capi/kcapi.c
+++ /dev/null
@@ -1,933 +0,0 @@
-/* $Id: kcapi.c,v 1.1.2.8 2004/03/26 19:57:20 armin Exp $
- *
- * Kernel CAPI 2.0 Module
- *
- * Copyright 1999 by Carsten Paeth <calle@calle.de>
- * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include "kcapi.h"
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/proc_fs.h>
-#include <linux/sched/signal.h>
-#include <linux/seq_file.h>
-#include <linux/skbuff.h>
-#include <linux/workqueue.h>
-#include <linux/capi.h>
-#include <linux/kernelcapi.h>
-#include <linux/init.h>
-#include <linux/moduleparam.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/isdn/capicmd.h>
-#include <linux/isdn/capiutil.h>
-#include <linux/mutex.h>
-#include <linux/rcupdate.h>
-
-static int showcapimsgs;
-static struct workqueue_struct *kcapi_wq;
-
-module_param(showcapimsgs, uint, 0);
-
-/* ------------------------------------------------------------- */
-
-struct capictr_event {
-	struct work_struct work;
-	unsigned int type;
-	u32 controller;
-};
-
-/* ------------------------------------------------------------- */
-
-static const struct capi_version driver_version = {2, 0, 1, 1 << 4};
-static char driver_serial[CAPI_SERIAL_LEN] = "0004711";
-static char capi_manufakturer[64] = "AVM Berlin";
-
-#define NCCI2CTRL(ncci)    (((ncci) >> 24) & 0x7f)
-
-struct capi_ctr *capi_controller[CAPI_MAXCONTR];
-DEFINE_MUTEX(capi_controller_lock);
-
-struct capi20_appl *capi_applications[CAPI_MAXAPPL];
-
-static int ncontrollers;
-
-/* -------- controller ref counting -------------------------------------- */
-
-static inline struct capi_ctr *
-capi_ctr_get(struct capi_ctr *ctr)
-{
-	if (!try_module_get(ctr->owner))
-		return NULL;
-	return ctr;
-}
-
-static inline void
-capi_ctr_put(struct capi_ctr *ctr)
-{
-	module_put(ctr->owner);
-}
-
-/* ------------------------------------------------------------- */
-
-static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
-{
-	if (contr < 1 || contr - 1 >= CAPI_MAXCONTR)
-		return NULL;
-
-	return capi_controller[contr - 1];
-}
-
-static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid)
-{
-	lockdep_assert_held(&capi_controller_lock);
-
-	if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
-		return NULL;
-
-	return capi_applications[applid - 1];
-}
-
-static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
-{
-	if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
-		return NULL;
-
-	return rcu_dereference(capi_applications[applid - 1]);
-}
-
-/* -------- util functions ------------------------------------ */
-
-static inline int capi_cmd_valid(u8 cmd)
-{
-	switch (cmd) {
-	case CAPI_ALERT:
-	case CAPI_CONNECT:
-	case CAPI_CONNECT_ACTIVE:
-	case CAPI_CONNECT_B3_ACTIVE:
-	case CAPI_CONNECT_B3:
-	case CAPI_CONNECT_B3_T90_ACTIVE:
-	case CAPI_DATA_B3:
-	case CAPI_DISCONNECT_B3:
-	case CAPI_DISCONNECT:
-	case CAPI_FACILITY:
-	case CAPI_INFO:
-	case CAPI_LISTEN:
-	case CAPI_MANUFACTURER:
-	case CAPI_RESET_B3:
-	case CAPI_SELECT_B_PROTOCOL:
-		return 1;
-	}
-	return 0;
-}
-
-static inline int capi_subcmd_valid(u8 subcmd)
-{
-	switch (subcmd) {
-	case CAPI_REQ:
-	case CAPI_CONF:
-	case CAPI_IND:
-	case CAPI_RESP:
-		return 1;
-	}
-	return 0;
-}
-
-/* ------------------------------------------------------------ */
-
-static void
-register_appl(struct capi_ctr *ctr, u16 applid, capi_register_params *rparam)
-{
-	ctr = capi_ctr_get(ctr);
-
-	if (ctr)
-		ctr->register_appl(ctr, applid, rparam);
-	else
-		printk(KERN_WARNING "%s: cannot get controller resources\n",
-		       __func__);
-}
-
-
-static void release_appl(struct capi_ctr *ctr, u16 applid)
-{
-	DBG("applid %#x", applid);
-
-	ctr->release_appl(ctr, applid);
-	capi_ctr_put(ctr);
-}
-
-static void notify_up(u32 contr)
-{
-	struct capi20_appl *ap;
-	struct capi_ctr *ctr;
-	u16 applid;
-
-	mutex_lock(&capi_controller_lock);
-
-	if (showcapimsgs & 1)
-		printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr);
-
-	ctr = get_capi_ctr_by_nr(contr);
-	if (ctr) {
-		if (ctr->state == CAPI_CTR_RUNNING)
-			goto unlock_out;
-
-		ctr->state = CAPI_CTR_RUNNING;
-
-		for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
-			ap = __get_capi_appl_by_nr(applid);
-			if (ap)
-				register_appl(ctr, applid, &ap->rparam);
-		}
-	} else
-		printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
-
-unlock_out:
-	mutex_unlock(&capi_controller_lock);
-}
-
-static void ctr_down(struct capi_ctr *ctr, int new_state)
-{
-	struct capi20_appl *ap;
-	u16 applid;
-
-	if (ctr->state == CAPI_CTR_DETECTED || ctr->state == CAPI_CTR_DETACHED)
-		return;
-
-	ctr->state = new_state;
-
-	memset(ctr->manu, 0, sizeof(ctr->manu));
-	memset(&ctr->version, 0, sizeof(ctr->version));
-	memset(&ctr->profile, 0, sizeof(ctr->profile));
-	memset(ctr->serial, 0, sizeof(ctr->serial));
-
-	for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
-		ap = __get_capi_appl_by_nr(applid);
-		if (ap)
-			capi_ctr_put(ctr);
-	}
-}
-
-static void notify_down(u32 contr)
-{
-	struct capi_ctr *ctr;
-
-	mutex_lock(&capi_controller_lock);
-
-	if (showcapimsgs & 1)
-		printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr);
-
-	ctr = get_capi_ctr_by_nr(contr);
-	if (ctr)
-		ctr_down(ctr, CAPI_CTR_DETECTED);
-	else
-		printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
-
-	mutex_unlock(&capi_controller_lock);
-}
-
-static void do_notify_work(struct work_struct *work)
-{
-	struct capictr_event *event =
-		container_of(work, struct capictr_event, work);
-
-	switch (event->type) {
-	case CAPICTR_UP:
-		notify_up(event->controller);
-		break;
-	case CAPICTR_DOWN:
-		notify_down(event->controller);
-		break;
-	}
-
-	kfree(event);
-}
-
-static int notify_push(unsigned int event_type, u32 controller)
-{
-	struct capictr_event *event = kmalloc_obj(*event, GFP_ATOMIC);
-
-	if (!event)
-		return -ENOMEM;
-
-	INIT_WORK(&event->work, do_notify_work);
-	event->type = event_type;
-	event->controller = controller;
-
-	queue_work(kcapi_wq, &event->work);
-	return 0;
-}
-
-/* -------- Receiver ------------------------------------------ */
-
-static void recv_handler(struct work_struct *work)
-{
-	struct sk_buff *skb;
-	struct capi20_appl *ap =
-		container_of(work, struct capi20_appl, recv_work);
-
-	if ((!ap) || (ap->release_in_progress))
-		return;
-
-	mutex_lock(&ap->recv_mtx);
-	while ((skb = skb_dequeue(&ap->recv_queue))) {
-		if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_IND)
-			ap->nrecvdatapkt++;
-		else
-			ap->nrecvctlpkt++;
-
-		ap->recv_message(ap, skb);
-	}
-	mutex_unlock(&ap->recv_mtx);
-}
-
-/**
- * capi_ctr_handle_message() - handle incoming CAPI message
- * @ctr:	controller descriptor structure.
- * @appl:	application ID.
- * @skb:	message.
- *
- * Called by hardware driver to pass a CAPI message to the application.
- */
-
-void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl,
-			     struct sk_buff *skb)
-{
-	struct capi20_appl *ap;
-	int showctl = 0;
-	u8 cmd, subcmd;
-	_cdebbuf *cdb;
-
-	if (ctr->state != CAPI_CTR_RUNNING) {
-		cdb = capi_message2str(skb->data);
-		if (cdb) {
-			printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s",
-			       ctr->cnr, cdb->buf);
-			cdebbuf_free(cdb);
-		} else
-			printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n",
-			       ctr->cnr);
-		goto error;
-	}
-
-	cmd = CAPIMSG_COMMAND(skb->data);
-	subcmd = CAPIMSG_SUBCOMMAND(skb->data);
-	if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) {
-		ctr->nrecvdatapkt++;
-		if (ctr->traceflag > 2)
-			showctl |= 2;
-	} else {
-		ctr->nrecvctlpkt++;
-		if (ctr->traceflag)
-			showctl |= 2;
-	}
-	showctl |= (ctr->traceflag & 1);
-	if (showctl & 2) {
-		if (showctl & 1) {
-			printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n",
-			       ctr->cnr, CAPIMSG_APPID(skb->data),
-			       capi_cmd2str(cmd, subcmd),
-			       CAPIMSG_LEN(skb->data));
-		} else {
-			cdb = capi_message2str(skb->data);
-			if (cdb) {
-				printk(KERN_DEBUG "kcapi: got [%03d] %s\n",
-				       ctr->cnr, cdb->buf);
-				cdebbuf_free(cdb);
-			} else
-				printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n",
-				       ctr->cnr, CAPIMSG_APPID(skb->data),
-				       capi_cmd2str(cmd, subcmd),
-				       CAPIMSG_LEN(skb->data));
-		}
-
-	}
-
-	rcu_read_lock();
-	ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data));
-	if (!ap) {
-		rcu_read_unlock();
-		cdb = capi_message2str(skb->data);
-		if (cdb) {
-			printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n",
-			       CAPIMSG_APPID(skb->data), cdb->buf);
-			cdebbuf_free(cdb);
-		} else
-			printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s) cannot trace\n",
-			       CAPIMSG_APPID(skb->data),
-			       capi_cmd2str(cmd, subcmd));
-		goto error;
-	}
-	skb_queue_tail(&ap->recv_queue, skb);
-	queue_work(kcapi_wq, &ap->recv_work);
-	rcu_read_unlock();
-
-	return;
-
-error:
-	kfree_skb(skb);
-}
-
-EXPORT_SYMBOL(capi_ctr_handle_message);
-
-/**
- * capi_ctr_ready() - signal CAPI controller ready
- * @ctr:	controller descriptor structure.
- *
- * Called by hardware driver to signal that the controller is up and running.
- */
-
-void capi_ctr_ready(struct capi_ctr *ctr)
-{
-	printk(KERN_NOTICE "kcapi: controller [%03d] \"%s\" ready.\n",
-	       ctr->cnr, ctr->name);
-
-	notify_push(CAPICTR_UP, ctr->cnr);
-}
-
-EXPORT_SYMBOL(capi_ctr_ready);
-
-/**
- * capi_ctr_down() - signal CAPI controller not ready
- * @ctr:	controller descriptor structure.
- *
- * Called by hardware driver to signal that the controller is down and
- * unavailable for use.
- */
-
-void capi_ctr_down(struct capi_ctr *ctr)
-{
-	printk(KERN_NOTICE "kcapi: controller [%03d] down.\n", ctr->cnr);
-
-	notify_push(CAPICTR_DOWN, ctr->cnr);
-}
-
-EXPORT_SYMBOL(capi_ctr_down);
-
-/* ------------------------------------------------------------- */
-
-/**
- * attach_capi_ctr() - register CAPI controller
- * @ctr:	controller descriptor structure.
- *
- * Called by hardware driver to register a controller with the CAPI subsystem.
- * Return value: 0 on success, error code < 0 on error
- */
-
-int attach_capi_ctr(struct capi_ctr *ctr)
-{
-	int i;
-
-	mutex_lock(&capi_controller_lock);
-
-	for (i = 0; i < CAPI_MAXCONTR; i++) {
-		if (!capi_controller[i])
-			break;
-	}
-	if (i == CAPI_MAXCONTR) {
-		mutex_unlock(&capi_controller_lock);
-		printk(KERN_ERR "kcapi: out of controller slots\n");
-		return -EBUSY;
-	}
-	capi_controller[i] = ctr;
-
-	ctr->nrecvctlpkt = 0;
-	ctr->nrecvdatapkt = 0;
-	ctr->nsentctlpkt = 0;
-	ctr->nsentdatapkt = 0;
-	ctr->cnr = i + 1;
-	ctr->state = CAPI_CTR_DETECTED;
-	ctr->blocked = 0;
-	ctr->traceflag = showcapimsgs;
-
-	sprintf(ctr->procfn, "capi/controllers/%d", ctr->cnr);
-	ctr->procent = proc_create_single_data(ctr->procfn, 0, NULL,
-			ctr->proc_show, ctr);
-
-	ncontrollers++;
-
-	mutex_unlock(&capi_controller_lock);
-
-	printk(KERN_NOTICE "kcapi: controller [%03d]: %s attached\n",
-	       ctr->cnr, ctr->name);
-	return 0;
-}
-
-EXPORT_SYMBOL(attach_capi_ctr);
-
-/**
- * detach_capi_ctr() - unregister CAPI controller
- * @ctr:	controller descriptor structure.
- *
- * Called by hardware driver to remove the registration of a controller
- * with the CAPI subsystem.
- * Return value: 0 on success, error code < 0 on error
- */
-
-int detach_capi_ctr(struct capi_ctr *ctr)
-{
-	int err = 0;
-
-	mutex_lock(&capi_controller_lock);
-
-	ctr_down(ctr, CAPI_CTR_DETACHED);
-
-	if (ctr->cnr < 1 || ctr->cnr - 1 >= CAPI_MAXCONTR) {
-		err = -EINVAL;
-		goto unlock_out;
-	}
-
-	if (capi_controller[ctr->cnr - 1] != ctr) {
-		err = -EINVAL;
-		goto unlock_out;
-	}
-	capi_controller[ctr->cnr - 1] = NULL;
-	ncontrollers--;
-
-	if (ctr->procent)
-		remove_proc_entry(ctr->procfn, NULL);
-
-	printk(KERN_NOTICE "kcapi: controller [%03d]: %s unregistered\n",
-	       ctr->cnr, ctr->name);
-
-unlock_out:
-	mutex_unlock(&capi_controller_lock);
-
-	return err;
-}
-
-EXPORT_SYMBOL(detach_capi_ctr);
-
-/* ------------------------------------------------------------- */
-/* -------- CAPI2.0 Interface ---------------------------------- */
-/* ------------------------------------------------------------- */
-
-/**
- * capi20_isinstalled() - CAPI 2.0 operation CAPI_INSTALLED
- *
- * Return value: CAPI result code (CAPI_NOERROR if at least one ISDN controller
- *	is ready for use, CAPI_REGNOTINSTALLED otherwise)
- */
-
-u16 capi20_isinstalled(void)
-{
-	u16 ret = CAPI_REGNOTINSTALLED;
-	int i;
-
-	mutex_lock(&capi_controller_lock);
-
-	for (i = 0; i < CAPI_MAXCONTR; i++)
-		if (capi_controller[i] &&
-		    capi_controller[i]->state == CAPI_CTR_RUNNING) {
-			ret = CAPI_NOERROR;
-			break;
-		}
-
-	mutex_unlock(&capi_controller_lock);
-
-	return ret;
-}
-
-/**
- * capi20_register() - CAPI 2.0 operation CAPI_REGISTER
- * @ap:		CAPI application descriptor structure.
- *
- * Register an application's presence with CAPI.
- * A unique application ID is assigned and stored in @ap->applid.
- * After this function returns successfully, the message receive
- * callback function @ap->recv_message() may be called at any time
- * until capi20_release() has been called for the same @ap.
- * Return value: CAPI result code
- */
-
-u16 capi20_register(struct capi20_appl *ap)
-{
-	int i;
-	u16 applid;
-
-	DBG("");
-
-	if (ap->rparam.datablklen < 128)
-		return CAPI_LOGBLKSIZETOSMALL;
-
-	ap->nrecvctlpkt = 0;
-	ap->nrecvdatapkt = 0;
-	ap->nsentctlpkt = 0;
-	ap->nsentdatapkt = 0;
-	mutex_init(&ap->recv_mtx);
-	skb_queue_head_init(&ap->recv_queue);
-	INIT_WORK(&ap->recv_work, recv_handler);
-	ap->release_in_progress = 0;
-
-	mutex_lock(&capi_controller_lock);
-
-	for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
-		if (capi_applications[applid - 1] == NULL)
-			break;
-	}
-	if (applid > CAPI_MAXAPPL) {
-		mutex_unlock(&capi_controller_lock);
-		return CAPI_TOOMANYAPPLS;
-	}
-
-	ap->applid = applid;
-	capi_applications[applid - 1] = ap;
-
-	for (i = 0; i < CAPI_MAXCONTR; i++) {
-		if (!capi_controller[i] ||
-		    capi_controller[i]->state != CAPI_CTR_RUNNING)
-			continue;
-		register_appl(capi_controller[i], applid, &ap->rparam);
-	}
-
-	mutex_unlock(&capi_controller_lock);
-
-	if (showcapimsgs & 1) {
-		printk(KERN_DEBUG "kcapi: appl %d up\n", applid);
-	}
-
-	return CAPI_NOERROR;
-}
-
-/**
- * capi20_release() - CAPI 2.0 operation CAPI_RELEASE
- * @ap:		CAPI application descriptor structure.
- *
- * Terminate an application's registration with CAPI.
- * After this function returns successfully, the message receive
- * callback function @ap->recv_message() will no longer be called.
- * Return value: CAPI result code
- */
-
-u16 capi20_release(struct capi20_appl *ap)
-{
-	int i;
-
-	DBG("applid %#x", ap->applid);
-
-	mutex_lock(&capi_controller_lock);
-
-	ap->release_in_progress = 1;
-	capi_applications[ap->applid - 1] = NULL;
-
-	synchronize_rcu();
-
-	for (i = 0; i < CAPI_MAXCONTR; i++) {
-		if (!capi_controller[i] ||
-		    capi_controller[i]->state != CAPI_CTR_RUNNING)
-			continue;
-		release_appl(capi_controller[i], ap->applid);
-	}
-
-	mutex_unlock(&capi_controller_lock);
-
-	flush_workqueue(kcapi_wq);
-	skb_queue_purge(&ap->recv_queue);
-
-	if (showcapimsgs & 1) {
-		printk(KERN_DEBUG "kcapi: appl %d down\n", ap->applid);
-	}
-
-	return CAPI_NOERROR;
-}
-
-/**
- * capi20_put_message() - CAPI 2.0 operation CAPI_PUT_MESSAGE
- * @ap:		CAPI application descriptor structure.
- * @skb:	CAPI message.
- *
- * Transfer a single message to CAPI.
- * Return value: CAPI result code
- */
-
-u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
-{
-	struct capi_ctr *ctr;
-	int showctl = 0;
-	u8 cmd, subcmd;
-
-	DBG("applid %#x", ap->applid);
-
-	if (ncontrollers == 0)
-		return CAPI_REGNOTINSTALLED;
-	if ((ap->applid == 0) || ap->release_in_progress)
-		return CAPI_ILLAPPNR;
-	if (skb->len < 12
-	    || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
-	    || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data)))
-		return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
-
-	/*
-	 * The controller reference is protected by the existence of the
-	 * application passed to us. We assume that the caller properly
-	 * synchronizes this service with capi20_release.
-	 */
-	ctr = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data));
-	if (!ctr || ctr->state != CAPI_CTR_RUNNING)
-		return CAPI_REGNOTINSTALLED;
-	if (ctr->blocked)
-		return CAPI_SENDQUEUEFULL;
-
-	cmd = CAPIMSG_COMMAND(skb->data);
-	subcmd = CAPIMSG_SUBCOMMAND(skb->data);
-
-	if (cmd == CAPI_DATA_B3 && subcmd == CAPI_REQ) {
-		ctr->nsentdatapkt++;
-		ap->nsentdatapkt++;
-		if (ctr->traceflag > 2)
-			showctl |= 2;
-	} else {
-		ctr->nsentctlpkt++;
-		ap->nsentctlpkt++;
-		if (ctr->traceflag)
-			showctl |= 2;
-	}
-	showctl |= (ctr->traceflag & 1);
-	if (showctl & 2) {
-		if (showctl & 1) {
-			printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n",
-			       CAPIMSG_CONTROLLER(skb->data),
-			       CAPIMSG_APPID(skb->data),
-			       capi_cmd2str(cmd, subcmd),
-			       CAPIMSG_LEN(skb->data));
-		} else {
-			_cdebbuf *cdb = capi_message2str(skb->data);
-			if (cdb) {
-				printk(KERN_DEBUG "kcapi: put [%03d] %s\n",
-				       CAPIMSG_CONTROLLER(skb->data),
-				       cdb->buf);
-				cdebbuf_free(cdb);
-			} else
-				printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u cannot trace\n",
-				       CAPIMSG_CONTROLLER(skb->data),
-				       CAPIMSG_APPID(skb->data),
-				       capi_cmd2str(cmd, subcmd),
-				       CAPIMSG_LEN(skb->data));
-		}
-	}
-	return ctr->send_message(ctr, skb);
-}
-
-/**
- * capi20_get_manufacturer() - CAPI 2.0 operation CAPI_GET_MANUFACTURER
- * @contr:	controller number.
- * @buf:	result buffer (64 bytes).
- *
- * Retrieve information about the manufacturer of the specified ISDN controller
- * or (for @contr == 0) the driver itself.
- * Return value: CAPI result code
- */
-
-u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN])
-{
-	struct capi_ctr *ctr;
-	u16 ret;
-
-	if (contr == 0) {
-		strscpy_pad(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
-		return CAPI_NOERROR;
-	}
-
-	mutex_lock(&capi_controller_lock);
-
-	ctr = get_capi_ctr_by_nr(contr);
-	if (ctr && ctr->state == CAPI_CTR_RUNNING) {
-		strscpy_pad(buf, ctr->manu, CAPI_MANUFACTURER_LEN);
-		ret = CAPI_NOERROR;
-	} else
-		ret = CAPI_REGNOTINSTALLED;
-
-	mutex_unlock(&capi_controller_lock);
-	return ret;
-}
-
-/**
- * capi20_get_version() - CAPI 2.0 operation CAPI_GET_VERSION
- * @contr:	controller number.
- * @verp:	result structure.
- *
- * Retrieve version information for the specified ISDN controller
- * or (for @contr == 0) the driver itself.
- * Return value: CAPI result code
- */
-
-u16 capi20_get_version(u32 contr, struct capi_version *verp)
-{
-	struct capi_ctr *ctr;
-	u16 ret;
-
-	if (contr == 0) {
-		*verp = driver_version;
-		return CAPI_NOERROR;
-	}
-
-	mutex_lock(&capi_controller_lock);
-
-	ctr = get_capi_ctr_by_nr(contr);
-	if (ctr && ctr->state == CAPI_CTR_RUNNING) {
-		memcpy(verp, &ctr->version, sizeof(capi_version));
-		ret = CAPI_NOERROR;
-	} else
-		ret = CAPI_REGNOTINSTALLED;
-
-	mutex_unlock(&capi_controller_lock);
-	return ret;
-}
-
-/**
- * capi20_get_serial() - CAPI 2.0 operation CAPI_GET_SERIAL_NUMBER
- * @contr:	controller number.
- * @serial:	result buffer (8 bytes).
- *
- * Retrieve the serial number of the specified ISDN controller
- * or (for @contr == 0) the driver itself.
- * Return value: CAPI result code
- */
-
-u16 capi20_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN])
-{
-	struct capi_ctr *ctr;
-	u16 ret;
-
-	if (contr == 0) {
-		strscpy(serial, driver_serial, CAPI_SERIAL_LEN);
-		return CAPI_NOERROR;
-	}
-
-	mutex_lock(&capi_controller_lock);
-
-	ctr = get_capi_ctr_by_nr(contr);
-	if (ctr && ctr->state == CAPI_CTR_RUNNING) {
-		strscpy(serial, ctr->serial, CAPI_SERIAL_LEN);
-		ret = CAPI_NOERROR;
-	} else
-		ret = CAPI_REGNOTINSTALLED;
-
-	mutex_unlock(&capi_controller_lock);
-	return ret;
-}
-
-/**
- * capi20_get_profile() - CAPI 2.0 operation CAPI_GET_PROFILE
- * @contr:	controller number.
- * @profp:	result structure.
- *
- * Retrieve capability information for the specified ISDN controller
- * or (for @contr == 0) the number of installed controllers.
- * Return value: CAPI result code
- */
-
-u16 capi20_get_profile(u32 contr, struct capi_profile *profp)
-{
-	struct capi_ctr *ctr;
-	u16 ret;
-
-	if (contr == 0) {
-		profp->ncontroller = ncontrollers;
-		return CAPI_NOERROR;
-	}
-
-	mutex_lock(&capi_controller_lock);
-
-	ctr = get_capi_ctr_by_nr(contr);
-	if (ctr && ctr->state == CAPI_CTR_RUNNING) {
-		memcpy(profp, &ctr->profile, sizeof(struct capi_profile));
-		ret = CAPI_NOERROR;
-	} else
-		ret = CAPI_REGNOTINSTALLED;
-
-	mutex_unlock(&capi_controller_lock);
-	return ret;
-}
-
-/**
- * capi20_manufacturer() - CAPI 2.0 operation CAPI_MANUFACTURER
- * @cmd:	command.
- * @data:	parameter.
- *
- * Perform manufacturer specific command.
- * Return value: CAPI result code
- */
-
-int capi20_manufacturer(unsigned long cmd, void __user *data)
-{
-	struct capi_ctr *ctr;
-	int retval;
-
-	switch (cmd) {
-	case KCAPI_CMD_TRACE:
-	{
-		kcapi_flagdef fdef;
-
-		if (copy_from_user(&fdef, data, sizeof(kcapi_flagdef)))
-			return -EFAULT;
-
-		mutex_lock(&capi_controller_lock);
-
-		ctr = get_capi_ctr_by_nr(fdef.contr);
-		if (ctr) {
-			ctr->traceflag = fdef.flag;
-			printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n",
-			       ctr->cnr, ctr->traceflag);
-			retval = 0;
-		} else
-			retval = -ESRCH;
-
-		mutex_unlock(&capi_controller_lock);
-
-		return retval;
-	}
-
-	default:
-		printk(KERN_ERR "kcapi: manufacturer command %lu unknown.\n",
-		       cmd);
-		break;
-
-	}
-	return -EINVAL;
-}
-
-/* ------------------------------------------------------------- */
-/* -------- Init & Cleanup ------------------------------------- */
-/* ------------------------------------------------------------- */
-
-/*
- * init / exit functions
- */
-
-int __init kcapi_init(void)
-{
-	int err;
-
-	kcapi_wq = alloc_workqueue("kcapi", WQ_PERCPU, 0);
-	if (!kcapi_wq)
-		return -ENOMEM;
-
-	err = cdebug_init();
-	if (err) {
-		destroy_workqueue(kcapi_wq);
-		return err;
-	}
-
-	if (IS_ENABLED(CONFIG_PROC_FS))
-		kcapi_proc_init();
-
-	return 0;
-}
-
-void kcapi_exit(void)
-{
-	if (IS_ENABLED(CONFIG_PROC_FS))
-		kcapi_proc_exit();
-
-	cdebug_exit();
-	destroy_workqueue(kcapi_wq);
-}
diff --git a/drivers/isdn/capi/kcapi_proc.c b/drivers/isdn/capi/kcapi_proc.c
deleted file mode 100644
index 77e951206809..000000000000
--- a/drivers/isdn/capi/kcapi_proc.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Kernel CAPI 2.0 Module - /proc/capi handling
- *
- * Copyright 1999 by Carsten Paeth <calle@calle.de>
- * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-
-#include "kcapi.h"
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/init.h>
-#include <linux/export.h>
-
-static char *state2str(unsigned short state)
-{
-	switch (state) {
-	case CAPI_CTR_DETECTED:	return "detected";
-	case CAPI_CTR_LOADING:	return "loading";
-	case CAPI_CTR_RUNNING:	return "running";
-	default:	        return "???";
-	}
-}
-
-// /proc/capi
-// ===========================================================================
-
-// /proc/capi/controller:
-//      cnr driver cardstate name driverinfo
-// /proc/capi/contrstats:
-//      cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
-// ---------------------------------------------------------------------------
-
-static void *controller_start(struct seq_file *seq, loff_t *pos)
-	__acquires(capi_controller_lock)
-{
-	mutex_lock(&capi_controller_lock);
-
-	if (*pos < CAPI_MAXCONTR)
-		return &capi_controller[*pos];
-
-	return NULL;
-}
-
-static void *controller_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	++*pos;
-	if (*pos < CAPI_MAXCONTR)
-		return &capi_controller[*pos];
-
-	return NULL;
-}
-
-static void controller_stop(struct seq_file *seq, void *v)
-	__releases(capi_controller_lock)
-{
-	mutex_unlock(&capi_controller_lock);
-}
-
-static int controller_show(struct seq_file *seq, void *v)
-{
-	struct capi_ctr *ctr = *(struct capi_ctr **) v;
-
-	if (!ctr)
-		return 0;
-
-	seq_printf(seq, "%d %-10s %-8s %-16s %s\n",
-		   ctr->cnr, ctr->driver_name,
-		   state2str(ctr->state),
-		   ctr->name,
-		   ctr->procinfo ?  ctr->procinfo(ctr) : "");
-
-	return 0;
-}
-
-static int contrstats_show(struct seq_file *seq, void *v)
-{
-	struct capi_ctr *ctr = *(struct capi_ctr **) v;
-
-	if (!ctr)
-		return 0;
-
-	seq_printf(seq, "%d %lu %lu %lu %lu\n",
-		   ctr->cnr,
-		   ctr->nrecvctlpkt,
-		   ctr->nrecvdatapkt,
-		   ctr->nsentctlpkt,
-		   ctr->nsentdatapkt);
-
-	return 0;
-}
-
-static const struct seq_operations seq_controller_ops = {
-	.start	= controller_start,
-	.next	= controller_next,
-	.stop	= controller_stop,
-	.show	= controller_show,
-};
-
-static const struct seq_operations seq_contrstats_ops = {
-	.start	= controller_start,
-	.next	= controller_next,
-	.stop	= controller_stop,
-	.show	= contrstats_show,
-};
-
-// /proc/capi/applications:
-//      applid l3cnt dblkcnt dblklen #ncci recvqueuelen
-// /proc/capi/applstats:
-//      applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
-// ---------------------------------------------------------------------------
-
-static void *applications_start(struct seq_file *seq, loff_t *pos)
-	__acquires(capi_controller_lock)
-{
-	mutex_lock(&capi_controller_lock);
-
-	if (*pos < CAPI_MAXAPPL)
-		return &capi_applications[*pos];
-
-	return NULL;
-}
-
-static void *
-applications_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	++*pos;
-	if (*pos < CAPI_MAXAPPL)
-		return &capi_applications[*pos];
-
-	return NULL;
-}
-
-static void applications_stop(struct seq_file *seq, void *v)
-	__releases(capi_controller_lock)
-{
-	mutex_unlock(&capi_controller_lock);
-}
-
-static int
-applications_show(struct seq_file *seq, void *v)
-{
-	struct capi20_appl *ap = *(struct capi20_appl **) v;
-
-	if (!ap)
-		return 0;
-
-	seq_printf(seq, "%u %d %d %d\n",
-		   ap->applid,
-		   ap->rparam.level3cnt,
-		   ap->rparam.datablkcnt,
-		   ap->rparam.datablklen);
-
-	return 0;
-}
-
-static int
-applstats_show(struct seq_file *seq, void *v)
-{
-	struct capi20_appl *ap = *(struct capi20_appl **) v;
-
-	if (!ap)
-		return 0;
-
-	seq_printf(seq, "%u %lu %lu %lu %lu\n",
-		   ap->applid,
-		   ap->nrecvctlpkt,
-		   ap->nrecvdatapkt,
-		   ap->nsentctlpkt,
-		   ap->nsentdatapkt);
-
-	return 0;
-}
-
-static const struct seq_operations seq_applications_ops = {
-	.start	= applications_start,
-	.next	= applications_next,
-	.stop	= applications_stop,
-	.show	= applications_show,
-};
-
-static const struct seq_operations seq_applstats_ops = {
-	.start	= applications_start,
-	.next	= applications_next,
-	.stop	= applications_stop,
-	.show	= applstats_show,
-};
-
-// ---------------------------------------------------------------------------
-
-/* /proc/capi/drivers is always empty */
-static ssize_t empty_read(struct file *file, char __user *buf,
-			  size_t size, loff_t *off)
-{
-	return 0;
-}
-
-static const struct proc_ops empty_proc_ops = {
-	.proc_read	= empty_read,
-	.proc_lseek	= default_llseek,
-};
-
-// ---------------------------------------------------------------------------
-
-void __init
-kcapi_proc_init(void)
-{
-	proc_mkdir("capi",             NULL);
-	proc_mkdir("capi/controllers", NULL);
-	proc_create_seq("capi/controller",   0, NULL, &seq_controller_ops);
-	proc_create_seq("capi/contrstats",   0, NULL, &seq_contrstats_ops);
-	proc_create_seq("capi/applications", 0, NULL, &seq_applications_ops);
-	proc_create_seq("capi/applstats",    0, NULL, &seq_applstats_ops);
-	proc_create("capi/driver",           0, NULL, &empty_proc_ops);
-}
-
-void
-kcapi_proc_exit(void)
-{
-	remove_proc_entry("capi/driver",       NULL);
-	remove_proc_entry("capi/controller",   NULL);
-	remove_proc_entry("capi/contrstats",   NULL);
-	remove_proc_entry("capi/applications", NULL);
-	remove_proc_entry("capi/applstats",    NULL);
-	remove_proc_entry("capi/controllers",  NULL);
-	remove_proc_entry("capi",              NULL);
-}
diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c
deleted file mode 100644
index 55e0b9efa194..000000000000
--- a/drivers/isdn/hardware/mISDN/avmfritz.c
+++ /dev/null
@@ -1,1164 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * avm_fritz.c    low level stuff for AVM FRITZ!CARD PCI ISDN cards
- *                Thanks to AVM, Berlin for informations
- *
- * Author       Karsten Keil <keil@isdn4linux.de>
- *
- * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
- */
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/mISDNhw.h>
-#include <linux/slab.h>
-#include <linux/unaligned.h>
-#include "ipac.h"
-
-
-#define AVMFRITZ_REV	"2.3"
-
-static int AVM_cnt;
-static int debug;
-
-enum {
-	AVM_FRITZ_PCI,
-	AVM_FRITZ_PCIV2,
-};
-
-#define HDLC_FIFO		0x0
-#define HDLC_STATUS		0x4
-#define CHIP_WINDOW		0x10
-
-#define CHIP_INDEX		0x4
-#define AVM_HDLC_1		0x00
-#define AVM_HDLC_2		0x01
-#define AVM_ISAC_FIFO		0x02
-#define AVM_ISAC_REG_LOW	0x04
-#define AVM_ISAC_REG_HIGH	0x06
-
-#define AVM_STATUS0_IRQ_ISAC	0x01
-#define AVM_STATUS0_IRQ_HDLC	0x02
-#define AVM_STATUS0_IRQ_TIMER	0x04
-#define AVM_STATUS0_IRQ_MASK	0x07
-
-#define AVM_STATUS0_RESET	0x01
-#define AVM_STATUS0_DIS_TIMER	0x02
-#define AVM_STATUS0_RES_TIMER	0x04
-#define AVM_STATUS0_ENA_IRQ	0x08
-#define AVM_STATUS0_TESTBIT	0x10
-
-#define AVM_STATUS1_INT_SEL	0x0f
-#define AVM_STATUS1_ENA_IOM	0x80
-
-#define HDLC_MODE_ITF_FLG	0x01
-#define HDLC_MODE_TRANS		0x02
-#define HDLC_MODE_CCR_7		0x04
-#define HDLC_MODE_CCR_16	0x08
-#define HDLC_FIFO_SIZE_128	0x20
-#define HDLC_MODE_TESTLOOP	0x80
-
-#define HDLC_INT_XPR		0x80
-#define HDLC_INT_XDU		0x40
-#define HDLC_INT_RPR		0x20
-#define HDLC_INT_MASK		0xE0
-
-#define HDLC_STAT_RME		0x01
-#define HDLC_STAT_RDO		0x10
-#define HDLC_STAT_CRCVFRRAB	0x0E
-#define HDLC_STAT_CRCVFR	0x06
-#define HDLC_STAT_RML_MASK_V1	0x3f00
-#define HDLC_STAT_RML_MASK_V2	0x7f00
-
-#define HDLC_CMD_XRS		0x80
-#define HDLC_CMD_XME		0x01
-#define HDLC_CMD_RRS		0x20
-#define HDLC_CMD_XML_MASK	0x3f00
-
-#define HDLC_FIFO_SIZE_V1	32
-#define HDLC_FIFO_SIZE_V2	128
-
-/* Fritz PCI v2.0 */
-
-#define AVM_HDLC_FIFO_1		0x10
-#define AVM_HDLC_FIFO_2		0x18
-
-#define AVM_HDLC_STATUS_1	0x14
-#define AVM_HDLC_STATUS_2	0x1c
-
-#define AVM_ISACX_INDEX		0x04
-#define AVM_ISACX_DATA		0x08
-
-/* data struct */
-#define LOG_SIZE		63
-
-struct hdlc_stat_reg {
-#ifdef __BIG_ENDIAN
-	u8 fill;
-	u8 mode;
-	u8 xml;
-	u8 cmd;
-#else
-	u8 cmd;
-	u8 xml;
-	u8 mode;
-	u8 fill;
-#endif
-} __attribute__((packed));
-
-struct hdlc_hw {
-	union {
-		u32 ctrl;
-		struct hdlc_stat_reg sr;
-	} ctrl;
-	u32 stat;
-};
-
-struct fritzcard {
-	struct list_head	list;
-	struct pci_dev		*pdev;
-	char			name[MISDN_MAX_IDLEN];
-	u8			type;
-	u8			ctrlreg;
-	u16			irq;
-	u32			irqcnt;
-	u32			addr;
-	spinlock_t		lock; /* hw lock */
-	struct isac_hw		isac;
-	struct hdlc_hw		hdlc[2];
-	struct bchannel		bch[2];
-	char			log[LOG_SIZE + 1];
-};
-
-static LIST_HEAD(Cards);
-static DEFINE_RWLOCK(card_lock); /* protect Cards */
-
-static void
-_set_debug(struct fritzcard *card)
-{
-	card->isac.dch.debug = debug;
-	card->bch[0].debug = debug;
-	card->bch[1].debug = debug;
-}
-
-static int
-set_debug(const char *val, const struct kernel_param *kp)
-{
-	int ret;
-	struct fritzcard *card;
-
-	ret = param_set_uint(val, kp);
-	if (!ret) {
-		read_lock(&card_lock);
-		list_for_each_entry(card, &Cards, list)
-			_set_debug(card);
-		read_unlock(&card_lock);
-	}
-	return ret;
-}
-
-MODULE_AUTHOR("Karsten Keil");
-MODULE_DESCRIPTION("mISDN driver for AVM FRITZ!CARD PCI ISDN cards");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(AVMFRITZ_REV);
-module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "avmfritz debug mask");
-
-/* Interface functions */
-
-static u8
-ReadISAC_V1(void *p, u8 offset)
-{
-	struct fritzcard *fc = p;
-	u8 idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
-
-	outb(idx, fc->addr + CHIP_INDEX);
-	return inb(fc->addr + CHIP_WINDOW + (offset & 0xf));
-}
-
-static void
-WriteISAC_V1(void *p, u8 offset, u8 value)
-{
-	struct fritzcard *fc = p;
-	u8 idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
-
-	outb(idx, fc->addr + CHIP_INDEX);
-	outb(value, fc->addr + CHIP_WINDOW + (offset & 0xf));
-}
-
-static void
-ReadFiFoISAC_V1(void *p, u8 off, u8 *data, int size)
-{
-	struct fritzcard *fc = p;
-
-	outb(AVM_ISAC_FIFO, fc->addr + CHIP_INDEX);
-	insb(fc->addr + CHIP_WINDOW, data, size);
-}
-
-static void
-WriteFiFoISAC_V1(void *p, u8 off, u8 *data, int size)
-{
-	struct fritzcard *fc = p;
-
-	outb(AVM_ISAC_FIFO, fc->addr + CHIP_INDEX);
-	outsb(fc->addr + CHIP_WINDOW, data, size);
-}
-
-static u8
-ReadISAC_V2(void *p, u8 offset)
-{
-	struct fritzcard *fc = p;
-
-	outl(offset, fc->addr + AVM_ISACX_INDEX);
-	return 0xff & inl(fc->addr + AVM_ISACX_DATA);
-}
-
-static void
-WriteISAC_V2(void *p, u8 offset, u8 value)
-{
-	struct fritzcard *fc = p;
-
-	outl(offset, fc->addr + AVM_ISACX_INDEX);
-	outl(value, fc->addr + AVM_ISACX_DATA);
-}
-
-static void
-ReadFiFoISAC_V2(void *p, u8 off, u8 *data, int size)
-{
-	struct fritzcard *fc = p;
-	int i;
-
-	outl(off, fc->addr + AVM_ISACX_INDEX);
-	for (i = 0; i < size; i++)
-		data[i] = 0xff & inl(fc->addr + AVM_ISACX_DATA);
-}
-
-static void
-WriteFiFoISAC_V2(void *p, u8 off, u8 *data, int size)
-{
-	struct fritzcard *fc = p;
-	int i;
-
-	outl(off, fc->addr + AVM_ISACX_INDEX);
-	for (i = 0; i < size; i++)
-		outl(data[i], fc->addr + AVM_ISACX_DATA);
-}
-
-static struct bchannel *
-Sel_BCS(struct fritzcard *fc, u32 channel)
-{
-	if (test_bit(FLG_ACTIVE, &fc->bch[0].Flags) &&
-	    (fc->bch[0].nr & channel))
-		return &fc->bch[0];
-	else if (test_bit(FLG_ACTIVE, &fc->bch[1].Flags) &&
-		 (fc->bch[1].nr & channel))
-		return &fc->bch[1];
-	else
-		return NULL;
-}
-
-static inline void
-__write_ctrl_pci(struct fritzcard *fc, struct hdlc_hw *hdlc, u32 channel) {
-	u32 idx = channel == 2 ? AVM_HDLC_2 : AVM_HDLC_1;
-
-	outl(idx, fc->addr + CHIP_INDEX);
-	outl(hdlc->ctrl.ctrl, fc->addr + CHIP_WINDOW + HDLC_STATUS);
-}
-
-static inline void
-__write_ctrl_pciv2(struct fritzcard *fc, struct hdlc_hw *hdlc, u32 channel) {
-	outl(hdlc->ctrl.ctrl, fc->addr + (channel == 2 ? AVM_HDLC_STATUS_2 :
-					  AVM_HDLC_STATUS_1));
-}
-
-static void
-write_ctrl(struct bchannel *bch, int which) {
-	struct fritzcard *fc = bch->hw;
-	struct hdlc_hw *hdlc;
-
-	hdlc = &fc->hdlc[(bch->nr - 1) & 1];
-	pr_debug("%s: hdlc %c wr%x ctrl %x\n", fc->name, '@' + bch->nr,
-		 which, hdlc->ctrl.ctrl);
-	switch (fc->type) {
-	case AVM_FRITZ_PCIV2:
-		__write_ctrl_pciv2(fc, hdlc, bch->nr);
-		break;
-	case AVM_FRITZ_PCI:
-		__write_ctrl_pci(fc, hdlc, bch->nr);
-		break;
-	}
-}
-
-
-static inline u32
-__read_status_pci(u_long addr, u32 channel)
-{
-	outl(channel == 2 ? AVM_HDLC_2 : AVM_HDLC_1, addr + CHIP_INDEX);
-	return inl(addr + CHIP_WINDOW + HDLC_STATUS);
-}
-
-static inline u32
-__read_status_pciv2(u_long addr, u32 channel)
-{
-	return inl(addr + (channel == 2 ? AVM_HDLC_STATUS_2 :
-			   AVM_HDLC_STATUS_1));
-}
-
-
-static u32
-read_status(struct fritzcard *fc, u32 channel)
-{
-	switch (fc->type) {
-	case AVM_FRITZ_PCIV2:
-		return __read_status_pciv2(fc->addr, channel);
-	case AVM_FRITZ_PCI:
-		return __read_status_pci(fc->addr, channel);
-	}
-	/* dummy */
-	return 0;
-}
-
-static void
-enable_hwirq(struct fritzcard *fc)
-{
-	fc->ctrlreg |= AVM_STATUS0_ENA_IRQ;
-	outb(fc->ctrlreg, fc->addr + 2);
-}
-
-static void
-disable_hwirq(struct fritzcard *fc)
-{
-	fc->ctrlreg &= ~AVM_STATUS0_ENA_IRQ;
-	outb(fc->ctrlreg, fc->addr + 2);
-}
-
-static int
-modehdlc(struct bchannel *bch, int protocol)
-{
-	struct fritzcard *fc = bch->hw;
-	struct hdlc_hw *hdlc;
-	u8 mode;
-
-	hdlc = &fc->hdlc[(bch->nr - 1) & 1];
-	pr_debug("%s: hdlc %c protocol %x-->%x ch %d\n", fc->name,
-		 '@' + bch->nr, bch->state, protocol, bch->nr);
-	hdlc->ctrl.ctrl = 0;
-	mode = (fc->type == AVM_FRITZ_PCIV2) ? HDLC_FIFO_SIZE_128 : 0;
-
-	switch (protocol) {
-	case -1: /* used for init */
-		bch->state = -1;
-		fallthrough;
-	case ISDN_P_NONE:
-		if (bch->state == ISDN_P_NONE)
-			break;
-		hdlc->ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
-		hdlc->ctrl.sr.mode = mode | HDLC_MODE_TRANS;
-		write_ctrl(bch, 5);
-		bch->state = ISDN_P_NONE;
-		test_and_clear_bit(FLG_HDLC, &bch->Flags);
-		test_and_clear_bit(FLG_TRANSPARENT, &bch->Flags);
-		break;
-	case ISDN_P_B_RAW:
-		bch->state = protocol;
-		hdlc->ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
-		hdlc->ctrl.sr.mode = mode | HDLC_MODE_TRANS;
-		write_ctrl(bch, 5);
-		hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
-		write_ctrl(bch, 1);
-		hdlc->ctrl.sr.cmd = 0;
-		test_and_set_bit(FLG_TRANSPARENT, &bch->Flags);
-		break;
-	case ISDN_P_B_HDLC:
-		bch->state = protocol;
-		hdlc->ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
-		hdlc->ctrl.sr.mode = mode | HDLC_MODE_ITF_FLG;
-		write_ctrl(bch, 5);
-		hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
-		write_ctrl(bch, 1);
-		hdlc->ctrl.sr.cmd = 0;
-		test_and_set_bit(FLG_HDLC, &bch->Flags);
-		break;
-	default:
-		pr_info("%s: protocol not known %x\n", fc->name, protocol);
-		return -ENOPROTOOPT;
-	}
-	return 0;
-}
-
-static void
-hdlc_empty_fifo(struct bchannel *bch, int count)
-{
-	u32 *ptr;
-	u8 *p;
-	u32  val, addr;
-	int cnt;
-	struct fritzcard *fc = bch->hw;
-
-	pr_debug("%s: %s %d\n", fc->name, __func__, count);
-	if (test_bit(FLG_RX_OFF, &bch->Flags)) {
-		p = NULL;
-		bch->dropcnt += count;
-	} else {
-		cnt = bchannel_get_rxbuf(bch, count);
-		if (cnt < 0) {
-			pr_warn("%s.B%d: No bufferspace for %d bytes\n",
-				fc->name, bch->nr, count);
-			return;
-		}
-		p = skb_put(bch->rx_skb, count);
-	}
-	ptr = (u32 *)p;
-	if (fc->type == AVM_FRITZ_PCIV2)
-		addr = fc->addr + (bch->nr == 2 ?
-				   AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1);
-	else {
-		addr = fc->addr + CHIP_WINDOW;
-		outl(bch->nr == 2 ? AVM_HDLC_2 : AVM_HDLC_1, fc->addr);
-	}
-	cnt = 0;
-	while (cnt < count) {
-		val = le32_to_cpu(inl(addr));
-		if (p) {
-			put_unaligned(val, ptr);
-			ptr++;
-		}
-		cnt += 4;
-	}
-	if (p && (debug & DEBUG_HW_BFIFO)) {
-		snprintf(fc->log, LOG_SIZE, "B%1d-recv %s %d ",
-			 bch->nr, fc->name, count);
-		print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count);
-	}
-}
-
-static void
-hdlc_fill_fifo(struct bchannel *bch)
-{
-	struct fritzcard *fc = bch->hw;
-	struct hdlc_hw *hdlc;
-	int count, fs, cnt = 0, idx;
-	bool fillempty = false;
-	u8 *p;
-	u32 *ptr, val, addr;
-
-	idx = (bch->nr - 1) & 1;
-	hdlc = &fc->hdlc[idx];
-	fs = (fc->type == AVM_FRITZ_PCIV2) ?
-		HDLC_FIFO_SIZE_V2 : HDLC_FIFO_SIZE_V1;
-	if (!bch->tx_skb) {
-		if (!test_bit(FLG_TX_EMPTY, &bch->Flags))
-			return;
-		count = fs;
-		p = bch->fill;
-		fillempty = true;
-	} else {
-		count = bch->tx_skb->len - bch->tx_idx;
-		if (count <= 0)
-			return;
-		p = bch->tx_skb->data + bch->tx_idx;
-	}
-	hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XME;
-	if (count > fs) {
-		count = fs;
-	} else {
-		if (test_bit(FLG_HDLC, &bch->Flags))
-			hdlc->ctrl.sr.cmd |= HDLC_CMD_XME;
-	}
-	ptr = (u32 *)p;
-	if (!fillempty) {
-		pr_debug("%s.B%d: %d/%d/%d", fc->name, bch->nr, count,
-			 bch->tx_idx, bch->tx_skb->len);
-		bch->tx_idx += count;
-	} else {
-		pr_debug("%s.B%d: fillempty %d\n", fc->name, bch->nr, count);
-	}
-	hdlc->ctrl.sr.xml = ((count == fs) ? 0 : count);
-	if (fc->type == AVM_FRITZ_PCIV2) {
-		__write_ctrl_pciv2(fc, hdlc, bch->nr);
-		addr = fc->addr + (bch->nr == 2 ?
-				   AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1);
-	} else {
-		__write_ctrl_pci(fc, hdlc, bch->nr);
-		addr = fc->addr + CHIP_WINDOW;
-	}
-	if (fillempty) {
-		while (cnt < count) {
-			/* all bytes the same - no worry about endian */
-			outl(*ptr, addr);
-			cnt += 4;
-		}
-	} else {
-		while (cnt < count) {
-			val = get_unaligned(ptr);
-			outl(cpu_to_le32(val), addr);
-			ptr++;
-			cnt += 4;
-		}
-	}
-	if ((debug & DEBUG_HW_BFIFO) && !fillempty) {
-		snprintf(fc->log, LOG_SIZE, "B%1d-send %s %d ",
-			 bch->nr, fc->name, count);
-		print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count);
-	}
-}
-
-static void
-HDLC_irq_xpr(struct bchannel *bch)
-{
-	if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len) {
-		hdlc_fill_fifo(bch);
-	} else {
-		dev_kfree_skb(bch->tx_skb);
-		if (get_next_bframe(bch)) {
-			hdlc_fill_fifo(bch);
-			test_and_clear_bit(FLG_TX_EMPTY, &bch->Flags);
-		} else if (test_bit(FLG_TX_EMPTY, &bch->Flags)) {
-			hdlc_fill_fifo(bch);
-		}
-	}
-}
-
-static void
-HDLC_irq(struct bchannel *bch, u32 stat)
-{
-	struct fritzcard *fc = bch->hw;
-	int		len, fs;
-	u32		rmlMask;
-	struct hdlc_hw	*hdlc;
-
-	hdlc = &fc->hdlc[(bch->nr - 1) & 1];
-	pr_debug("%s: ch%d stat %#x\n", fc->name, bch->nr, stat);
-	if (fc->type == AVM_FRITZ_PCIV2) {
-		rmlMask = HDLC_STAT_RML_MASK_V2;
-		fs = HDLC_FIFO_SIZE_V2;
-	} else {
-		rmlMask = HDLC_STAT_RML_MASK_V1;
-		fs = HDLC_FIFO_SIZE_V1;
-	}
-	if (stat & HDLC_INT_RPR) {
-		if (stat & HDLC_STAT_RDO) {
-			pr_warn("%s: ch%d stat %x RDO\n",
-				fc->name, bch->nr, stat);
-			hdlc->ctrl.sr.xml = 0;
-			hdlc->ctrl.sr.cmd |= HDLC_CMD_RRS;
-			write_ctrl(bch, 1);
-			hdlc->ctrl.sr.cmd &= ~HDLC_CMD_RRS;
-			write_ctrl(bch, 1);
-			if (bch->rx_skb)
-				skb_trim(bch->rx_skb, 0);
-		} else {
-			len = (stat & rmlMask) >> 8;
-			if (!len)
-				len = fs;
-			hdlc_empty_fifo(bch, len);
-			if (!bch->rx_skb)
-				goto handle_tx;
-			if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
-				recv_Bchannel(bch, 0, false);
-			} else if (stat & HDLC_STAT_RME) {
-				if ((stat & HDLC_STAT_CRCVFRRAB) ==
-				    HDLC_STAT_CRCVFR) {
-					recv_Bchannel(bch, 0, false);
-				} else {
-					pr_warn("%s: got invalid frame\n",
-						fc->name);
-					skb_trim(bch->rx_skb, 0);
-				}
-			}
-		}
-	}
-handle_tx:
-	if (stat & HDLC_INT_XDU) {
-		/* Here we lost an TX interrupt, so
-		 * restart transmitting the whole frame on HDLC
-		 * in transparent mode we send the next data
-		 */
-		pr_warn("%s: ch%d stat %x XDU %s\n", fc->name, bch->nr,
-			stat, bch->tx_skb ? "tx_skb" : "no tx_skb");
-		if (bch->tx_skb && bch->tx_skb->len) {
-			if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
-				bch->tx_idx = 0;
-		} else if (test_bit(FLG_FILLEMPTY, &bch->Flags)) {
-			test_and_set_bit(FLG_TX_EMPTY, &bch->Flags);
-		}
-		hdlc->ctrl.sr.xml = 0;
-		hdlc->ctrl.sr.cmd |= HDLC_CMD_XRS;
-		write_ctrl(bch, 1);
-		hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XRS;
-		HDLC_irq_xpr(bch);
-		return;
-	} else if (stat & HDLC_INT_XPR)
-		HDLC_irq_xpr(bch);
-}
-
-static inline void
-HDLC_irq_main(struct fritzcard *fc)
-{
-	u32 stat;
-	struct bchannel *bch;
-
-	stat = read_status(fc, 1);
-	if (stat & HDLC_INT_MASK) {
-		bch = Sel_BCS(fc, 1);
-		if (bch)
-			HDLC_irq(bch, stat);
-		else
-			pr_debug("%s: spurious ch1 IRQ\n", fc->name);
-	}
-	stat = read_status(fc, 2);
-	if (stat & HDLC_INT_MASK) {
-		bch = Sel_BCS(fc, 2);
-		if (bch)
-			HDLC_irq(bch, stat);
-		else
-			pr_debug("%s: spurious ch2 IRQ\n", fc->name);
-	}
-}
-
-static irqreturn_t
-avm_fritz_interrupt(int intno, void *dev_id)
-{
-	struct fritzcard *fc = dev_id;
-	u8 val;
-	u8 sval;
-
-	spin_lock(&fc->lock);
-	sval = inb(fc->addr + 2);
-	pr_debug("%s: irq stat0 %x\n", fc->name, sval);
-	if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK) {
-		/* shared  IRQ from other HW */
-		spin_unlock(&fc->lock);
-		return IRQ_NONE;
-	}
-	fc->irqcnt++;
-
-	if (!(sval & AVM_STATUS0_IRQ_ISAC)) {
-		val = ReadISAC_V1(fc, ISAC_ISTA);
-		mISDNisac_irq(&fc->isac, val);
-	}
-	if (!(sval & AVM_STATUS0_IRQ_HDLC))
-		HDLC_irq_main(fc);
-	spin_unlock(&fc->lock);
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t
-avm_fritzv2_interrupt(int intno, void *dev_id)
-{
-	struct fritzcard *fc = dev_id;
-	u8 val;
-	u8 sval;
-
-	spin_lock(&fc->lock);
-	sval = inb(fc->addr + 2);
-	pr_debug("%s: irq stat0 %x\n", fc->name, sval);
-	if (!(sval & AVM_STATUS0_IRQ_MASK)) {
-		/* shared  IRQ from other HW */
-		spin_unlock(&fc->lock);
-		return IRQ_NONE;
-	}
-	fc->irqcnt++;
-
-	if (sval & AVM_STATUS0_IRQ_HDLC)
-		HDLC_irq_main(fc);
-	if (sval & AVM_STATUS0_IRQ_ISAC) {
-		val = ReadISAC_V2(fc, ISACX_ISTA);
-		mISDNisac_irq(&fc->isac, val);
-	}
-	if (sval & AVM_STATUS0_IRQ_TIMER) {
-		pr_debug("%s: timer irq\n", fc->name);
-		outb(fc->ctrlreg | AVM_STATUS0_RES_TIMER, fc->addr + 2);
-		udelay(1);
-		outb(fc->ctrlreg, fc->addr + 2);
-	}
-	spin_unlock(&fc->lock);
-	return IRQ_HANDLED;
-}
-
-static int
-avm_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct bchannel *bch = container_of(ch, struct bchannel, ch);
-	struct fritzcard *fc = bch->hw;
-	int ret = -EINVAL;
-	struct mISDNhead *hh = mISDN_HEAD_P(skb);
-	unsigned long flags;
-
-	switch (hh->prim) {
-	case PH_DATA_REQ:
-		spin_lock_irqsave(&fc->lock, flags);
-		ret = bchannel_senddata(bch, skb);
-		if (ret > 0) { /* direct TX */
-			hdlc_fill_fifo(bch);
-			ret = 0;
-		}
-		spin_unlock_irqrestore(&fc->lock, flags);
-		return ret;
-	case PH_ACTIVATE_REQ:
-		spin_lock_irqsave(&fc->lock, flags);
-		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
-			ret = modehdlc(bch, ch->protocol);
-		else
-			ret = 0;
-		spin_unlock_irqrestore(&fc->lock, flags);
-		if (!ret)
-			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-				    NULL, GFP_KERNEL);
-		break;
-	case PH_DEACTIVATE_REQ:
-		spin_lock_irqsave(&fc->lock, flags);
-		mISDN_clear_bchannel(bch);
-		modehdlc(bch, ISDN_P_NONE);
-		spin_unlock_irqrestore(&fc->lock, flags);
-		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			    NULL, GFP_KERNEL);
-		ret = 0;
-		break;
-	}
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-static void
-inithdlc(struct fritzcard *fc)
-{
-	modehdlc(&fc->bch[0], -1);
-	modehdlc(&fc->bch[1], -1);
-}
-
-static void
-clear_pending_hdlc_ints(struct fritzcard *fc)
-{
-	u32 val;
-
-	val = read_status(fc, 1);
-	pr_debug("%s: HDLC 1 STA %x\n", fc->name, val);
-	val = read_status(fc, 2);
-	pr_debug("%s: HDLC 2 STA %x\n", fc->name, val);
-}
-
-static void
-reset_avm(struct fritzcard *fc)
-{
-	switch (fc->type) {
-	case AVM_FRITZ_PCI:
-		fc->ctrlreg = AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER;
-		break;
-	case AVM_FRITZ_PCIV2:
-		fc->ctrlreg = AVM_STATUS0_RESET;
-		break;
-	}
-	if (debug & DEBUG_HW)
-		pr_notice("%s: reset\n", fc->name);
-	disable_hwirq(fc);
-	mdelay(5);
-	switch (fc->type) {
-	case AVM_FRITZ_PCI:
-		fc->ctrlreg = AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER;
-		disable_hwirq(fc);
-		outb(AVM_STATUS1_ENA_IOM, fc->addr + 3);
-		break;
-	case AVM_FRITZ_PCIV2:
-		fc->ctrlreg = 0;
-		disable_hwirq(fc);
-		break;
-	}
-	mdelay(1);
-	if (debug & DEBUG_HW)
-		pr_notice("%s: S0/S1 %x/%x\n", fc->name,
-			  inb(fc->addr + 2), inb(fc->addr + 3));
-}
-
-static int
-init_card(struct fritzcard *fc)
-{
-	int		ret, cnt = 3;
-	u_long		flags;
-
-	reset_avm(fc); /* disable IRQ */
-	if (fc->type == AVM_FRITZ_PCIV2)
-		ret = request_irq(fc->irq, avm_fritzv2_interrupt,
-				  IRQF_SHARED, fc->name, fc);
-	else
-		ret = request_irq(fc->irq, avm_fritz_interrupt,
-				  IRQF_SHARED, fc->name, fc);
-	if (ret) {
-		pr_info("%s: couldn't get interrupt %d\n",
-			fc->name, fc->irq);
-		return ret;
-	}
-	while (cnt--) {
-		spin_lock_irqsave(&fc->lock, flags);
-		ret = fc->isac.init(&fc->isac);
-		if (ret) {
-			spin_unlock_irqrestore(&fc->lock, flags);
-			pr_info("%s: ISAC init failed with %d\n",
-				fc->name, ret);
-			break;
-		}
-		clear_pending_hdlc_ints(fc);
-		inithdlc(fc);
-		enable_hwirq(fc);
-		/* RESET Receiver and Transmitter */
-		if (fc->type == AVM_FRITZ_PCIV2) {
-			WriteISAC_V2(fc, ISACX_MASK, 0);
-			WriteISAC_V2(fc, ISACX_CMDRD, 0x41);
-		} else {
-			WriteISAC_V1(fc, ISAC_MASK, 0);
-			WriteISAC_V1(fc, ISAC_CMDR, 0x41);
-		}
-		spin_unlock_irqrestore(&fc->lock, flags);
-		/* Timeout 10ms */
-		msleep_interruptible(10);
-		if (debug & DEBUG_HW)
-			pr_notice("%s: IRQ %d count %d\n", fc->name,
-				  fc->irq, fc->irqcnt);
-		if (!fc->irqcnt) {
-			pr_info("%s: IRQ(%d) getting no IRQs during init %d\n",
-				fc->name, fc->irq, 3 - cnt);
-			reset_avm(fc);
-		} else
-			return 0;
-	}
-	free_irq(fc->irq, fc);
-	return -EIO;
-}
-
-static int
-channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
-{
-	return mISDN_ctrl_bchannel(bch, cq);
-}
-
-static int
-avm_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
-{
-	struct bchannel *bch = container_of(ch, struct bchannel, ch);
-	struct fritzcard *fc = bch->hw;
-	int ret = -EINVAL;
-	u_long flags;
-
-	pr_debug("%s: %s cmd:%x %p\n", fc->name, __func__, cmd, arg);
-	switch (cmd) {
-	case CLOSE_CHANNEL:
-		test_and_clear_bit(FLG_OPEN, &bch->Flags);
-		cancel_work_sync(&bch->workq);
-		spin_lock_irqsave(&fc->lock, flags);
-		mISDN_clear_bchannel(bch);
-		modehdlc(bch, ISDN_P_NONE);
-		spin_unlock_irqrestore(&fc->lock, flags);
-		ch->protocol = ISDN_P_NONE;
-		ch->peer = NULL;
-		module_put(THIS_MODULE);
-		ret = 0;
-		break;
-	case CONTROL_CHANNEL:
-		ret = channel_bctrl(bch, arg);
-		break;
-	default:
-		pr_info("%s: %s unknown prim(%x)\n", fc->name, __func__, cmd);
-	}
-	return ret;
-}
-
-static int
-channel_ctrl(struct fritzcard  *fc, struct mISDN_ctrl_req *cq)
-{
-	int	ret = 0;
-
-	switch (cq->op) {
-	case MISDN_CTRL_GETOP:
-		cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
-		break;
-	case MISDN_CTRL_LOOP:
-		/* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
-		if (cq->channel < 0 || cq->channel > 3) {
-			ret = -EINVAL;
-			break;
-		}
-		ret = fc->isac.ctrl(&fc->isac, HW_TESTLOOP, cq->channel);
-		break;
-	case MISDN_CTRL_L1_TIMER3:
-		ret = fc->isac.ctrl(&fc->isac, HW_TIMER3_VALUE, cq->p1);
-		break;
-	default:
-		pr_info("%s: %s unknown Op %x\n", fc->name, __func__, cq->op);
-		ret = -EINVAL;
-		break;
-	}
-	return ret;
-}
-
-static int
-open_bchannel(struct fritzcard *fc, struct channel_req *rq)
-{
-	struct bchannel		*bch;
-
-	if (rq->adr.channel == 0 || rq->adr.channel > 2)
-		return -EINVAL;
-	if (rq->protocol == ISDN_P_NONE)
-		return -EINVAL;
-	bch = &fc->bch[rq->adr.channel - 1];
-	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
-		return -EBUSY; /* b-channel can be only open once */
-	bch->ch.protocol = rq->protocol;
-	rq->ch = &bch->ch;
-	return 0;
-}
-
-/*
- * device control function
- */
-static int
-avm_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
-{
-	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
-	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
-	struct fritzcard	*fc = dch->hw;
-	struct channel_req	*rq;
-	int			err = 0;
-
-	pr_debug("%s: %s cmd:%x %p\n", fc->name, __func__, cmd, arg);
-	switch (cmd) {
-	case OPEN_CHANNEL:
-		rq = arg;
-		if (rq->protocol == ISDN_P_TE_S0)
-			err = fc->isac.open(&fc->isac, rq);
-		else
-			err = open_bchannel(fc, rq);
-		if (err)
-			break;
-		if (!try_module_get(THIS_MODULE))
-			pr_info("%s: cannot get module\n", fc->name);
-		break;
-	case CLOSE_CHANNEL:
-		pr_debug("%s: dev(%d) close from %p\n", fc->name, dch->dev.id,
-			 __builtin_return_address(0));
-		module_put(THIS_MODULE);
-		break;
-	case CONTROL_CHANNEL:
-		err = channel_ctrl(fc, arg);
-		break;
-	default:
-		pr_debug("%s: %s unknown command %x\n",
-			 fc->name, __func__, cmd);
-		return -EINVAL;
-	}
-	return err;
-}
-
-static int
-setup_fritz(struct fritzcard *fc)
-{
-	u32 val, ver;
-
-	if (!request_region(fc->addr, 32, fc->name)) {
-		pr_info("%s: AVM config port %x-%x already in use\n",
-			fc->name, fc->addr, fc->addr + 31);
-		return -EIO;
-	}
-	switch (fc->type) {
-	case AVM_FRITZ_PCI:
-		val = inl(fc->addr);
-		outl(AVM_HDLC_1, fc->addr + CHIP_INDEX);
-		ver = inl(fc->addr + CHIP_WINDOW + HDLC_STATUS) >> 24;
-		if (debug & DEBUG_HW) {
-			pr_notice("%s: PCI stat %#x\n", fc->name, val);
-			pr_notice("%s: PCI Class %X Rev %d\n", fc->name,
-				  val & 0xff, (val >> 8) & 0xff);
-			pr_notice("%s: HDLC version %x\n", fc->name, ver & 0xf);
-		}
-		ASSIGN_FUNC(V1, ISAC, fc->isac);
-		fc->isac.type = IPAC_TYPE_ISAC;
-		break;
-	case AVM_FRITZ_PCIV2:
-		val = inl(fc->addr);
-		ver = inl(fc->addr + AVM_HDLC_STATUS_1) >> 24;
-		if (debug & DEBUG_HW) {
-			pr_notice("%s: PCI V2 stat %#x\n", fc->name, val);
-			pr_notice("%s: PCI V2 Class %X Rev %d\n", fc->name,
-				  val & 0xff, (val >> 8) & 0xff);
-			pr_notice("%s: HDLC version %x\n", fc->name, ver & 0xf);
-		}
-		ASSIGN_FUNC(V2, ISAC, fc->isac);
-		fc->isac.type = IPAC_TYPE_ISACX;
-		break;
-	default:
-		release_region(fc->addr, 32);
-		pr_info("%s: AVM unknown type %d\n", fc->name, fc->type);
-		return -ENODEV;
-	}
-	pr_notice("%s: %s config irq:%d base:0x%X\n", fc->name,
-		  (fc->type == AVM_FRITZ_PCI) ? "AVM Fritz!CARD PCI" :
-		  "AVM Fritz!CARD PCIv2", fc->irq, fc->addr);
-	return 0;
-}
-
-static void
-release_card(struct fritzcard *card)
-{
-	u_long flags;
-
-	disable_hwirq(card);
-	spin_lock_irqsave(&card->lock, flags);
-	modehdlc(&card->bch[0], ISDN_P_NONE);
-	modehdlc(&card->bch[1], ISDN_P_NONE);
-	spin_unlock_irqrestore(&card->lock, flags);
-	card->isac.release(&card->isac);
-	free_irq(card->irq, card);
-	mISDN_freebchannel(&card->bch[1]);
-	mISDN_freebchannel(&card->bch[0]);
-	mISDN_unregister_device(&card->isac.dch.dev);
-	release_region(card->addr, 32);
-	pci_disable_device(card->pdev);
-	pci_set_drvdata(card->pdev, NULL);
-	write_lock_irqsave(&card_lock, flags);
-	list_del(&card->list);
-	write_unlock_irqrestore(&card_lock, flags);
-	kfree(card);
-	AVM_cnt--;
-}
-
-static int
-setup_instance(struct fritzcard *card)
-{
-	int i, err;
-	unsigned short minsize;
-	u_long flags;
-
-	snprintf(card->name, MISDN_MAX_IDLEN - 1, "AVM.%d", AVM_cnt + 1);
-	write_lock_irqsave(&card_lock, flags);
-	list_add_tail(&card->list, &Cards);
-	write_unlock_irqrestore(&card_lock, flags);
-
-	_set_debug(card);
-	card->isac.name = card->name;
-	spin_lock_init(&card->lock);
-	card->isac.hwlock = &card->lock;
-	mISDNisac_init(&card->isac, card);
-
-	card->isac.dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
-	card->isac.dch.dev.D.ctrl = avm_dctrl;
-	for (i = 0; i < 2; i++) {
-		card->bch[i].nr = i + 1;
-		set_channelmap(i + 1, card->isac.dch.dev.channelmap);
-		if (AVM_FRITZ_PCIV2 == card->type)
-			minsize = HDLC_FIFO_SIZE_V2;
-		else
-			minsize = HDLC_FIFO_SIZE_V1;
-		mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, minsize);
-		card->bch[i].hw = card;
-		card->bch[i].ch.send = avm_l2l1B;
-		card->bch[i].ch.ctrl = avm_bctrl;
-		card->bch[i].ch.nr = i + 1;
-		list_add(&card->bch[i].ch.list, &card->isac.dch.dev.bchannels);
-	}
-	err = setup_fritz(card);
-	if (err)
-		goto error;
-	err = mISDN_register_device(&card->isac.dch.dev, &card->pdev->dev,
-				    card->name);
-	if (err)
-		goto error_reg;
-	err = init_card(card);
-	if (!err)  {
-		AVM_cnt++;
-		pr_notice("AVM %d cards installed DEBUG\n", AVM_cnt);
-		return 0;
-	}
-	mISDN_unregister_device(&card->isac.dch.dev);
-error_reg:
-	release_region(card->addr, 32);
-error:
-	card->isac.release(&card->isac);
-	mISDN_freebchannel(&card->bch[1]);
-	mISDN_freebchannel(&card->bch[0]);
-	write_lock_irqsave(&card_lock, flags);
-	list_del(&card->list);
-	write_unlock_irqrestore(&card_lock, flags);
-	kfree(card);
-	return err;
-}
-
-static int
-fritzpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	int err = -ENOMEM;
-	struct fritzcard *card;
-
-	card = kzalloc_obj(struct fritzcard);
-	if (!card) {
-		pr_info("No kmem for fritzcard\n");
-		return err;
-	}
-	if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2)
-		card->type = AVM_FRITZ_PCIV2;
-	else
-		card->type = AVM_FRITZ_PCI;
-	card->pdev = pdev;
-	err = pci_enable_device(pdev);
-	if (err) {
-		kfree(card);
-		return err;
-	}
-
-	pr_notice("mISDN: found adapter %s at %s\n",
-		  (char *) ent->driver_data, pci_name(pdev));
-
-	card->addr = pci_resource_start(pdev, 1);
-	card->irq = pdev->irq;
-	pci_set_drvdata(pdev, card);
-	err = setup_instance(card);
-	if (err)
-		pci_set_drvdata(pdev, NULL);
-	return err;
-}
-
-static void
-fritz_remove_pci(struct pci_dev *pdev)
-{
-	struct fritzcard *card = pci_get_drvdata(pdev);
-
-	if (card)
-		release_card(card);
-	else
-		if (debug)
-			pr_info("%s: drvdata already removed\n", __func__);
-}
-
-static const struct pci_device_id fcpci_ids[] = {
-	{ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, PCI_ANY_ID, PCI_ANY_ID,
-	  0, 0, (unsigned long) "Fritz!Card PCI"},
-	{ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1_V2, PCI_ANY_ID, PCI_ANY_ID,
-	  0, 0, (unsigned long) "Fritz!Card PCI v2" },
-	{ }
-};
-MODULE_DEVICE_TABLE(pci, fcpci_ids);
-
-static struct pci_driver fcpci_driver = {
-	.name = "fcpci",
-	.probe = fritzpci_probe,
-	.remove = fritz_remove_pci,
-	.id_table = fcpci_ids,
-};
-
-static int __init AVM_init(void)
-{
-	int err;
-
-	pr_notice("AVM Fritz PCI driver Rev. %s\n", AVMFRITZ_REV);
-	err = pci_register_driver(&fcpci_driver);
-	return err;
-}
-
-static void __exit AVM_cleanup(void)
-{
-	pci_unregister_driver(&fcpci_driver);
-}
-
-module_init(AVM_init);
-module_exit(AVM_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
deleted file mode 100644
index b3d28976b33a..000000000000
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ /dev/null
@@ -1,5540 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * hfcmulti.c  low level driver for hfc-4s/hfc-8s/hfc-e1 based cards
- *
- * Author	Andreas Eversberg (jolly@eversberg.eu)
- * ported to mqueue mechanism:
- *		Peter Sprenger (sprengermoving-bytes.de)
- *
- * inspired by existing hfc-pci driver:
- * Copyright 1999  by Werner Cornelius (werner@isdn-development.de)
- * Copyright 2008  by Karsten Keil (kkeil@suse.de)
- * Copyright 2008  by Andreas Eversberg (jolly@eversberg.eu)
- *
- * Thanks to Cologne Chip AG for this great controller!
- */
-
-/*
- * module parameters:
- * type:
- *	By default (0), the card is automatically detected.
- *	Or use the following combinations:
- *	Bit 0-7   = 0x00001 = HFC-E1 (1 port)
- * or	Bit 0-7   = 0x00004 = HFC-4S (4 ports)
- * or	Bit 0-7   = 0x00008 = HFC-8S (8 ports)
- *	Bit 8     = 0x00100 = uLaw (instead of aLaw)
- *	Bit 9     = 0x00200 = Disable DTMF detect on all B-channels via hardware
- *	Bit 10    = spare
- *	Bit 11    = 0x00800 = Force PCM bus into slave mode. (otherwise auto)
- * or   Bit 12    = 0x01000 = Force PCM bus into master mode. (otherwise auto)
- *	Bit 13	  = spare
- *	Bit 14    = 0x04000 = Use external ram (128K)
- *	Bit 15    = 0x08000 = Use external ram (512K)
- *	Bit 16    = 0x10000 = Use 64 timeslots instead of 32
- * or	Bit 17    = 0x20000 = Use 128 timeslots instead of anything else
- *	Bit 18    = spare
- *	Bit 19    = 0x80000 = Send the Watchdog a Signal (Dual E1 with Watchdog)
- * (all other bits are reserved and shall be 0)
- *	example: 0x20204 one HFC-4S with dtmf detection and 128 timeslots on PCM
- *		 bus (PCM master)
- *
- * port: (optional or required for all ports on all installed cards)
- *	HFC-4S/HFC-8S only bits:
- *	Bit 0	  = 0x001 = Use master clock for this S/T interface
- *			    (only once per chip).
- *	Bit 1     = 0x002 = transmitter line setup (non capacitive mode)
- *			    Don't use this unless you know what you are doing!
- *	Bit 2     = 0x004 = Disable E-channel. (No E-channel processing)
- *	example: 0x0001,0x0000,0x0000,0x0000 one HFC-4S with master clock
- *		 received from port 1
- *
- *	HFC-E1 only bits:
- *	Bit 0     = 0x0001 = interface: 0=copper, 1=optical
- *	Bit 1     = 0x0002 = reserved (later for 32 B-channels transparent mode)
- *	Bit 2     = 0x0004 = Report LOS
- *	Bit 3     = 0x0008 = Report AIS
- *	Bit 4     = 0x0010 = Report SLIP
- *	Bit 5     = 0x0020 = Report RDI
- *	Bit 8     = 0x0100 = Turn off CRC-4 Multiframe Mode, use double frame
- *			     mode instead.
- *	Bit 9	  = 0x0200 = Force get clock from interface, even in NT mode.
- * or	Bit 10	  = 0x0400 = Force put clock to interface, even in TE mode.
- *	Bit 11    = 0x0800 = Use direct RX clock for PCM sync rather than PLL.
- *			     (E1 only)
- *	Bit 12-13 = 0xX000 = elastic jitter buffer (1-3), Set both bits to 0
- *			     for default.
- * (all other bits are reserved and shall be 0)
- *
- * debug:
- *	NOTE: only one debug value must be given for all cards
- *	enable debugging (see hfc_multi.h for debug options)
- *
- * poll:
- *	NOTE: only one poll value must be given for all cards
- *	Give the number of samples for each fifo process.
- *	By default 128 is used. Decrease to reduce delay, increase to
- *	reduce cpu load. If unsure, don't mess with it!
- *	Valid is 8, 16, 32, 64, 128, 256.
- *
- * pcm:
- *	NOTE: only one pcm value must be given for every card.
- *	The PCM bus id tells the mISDNdsp module about the connected PCM bus.
- *	By default (0), the PCM bus id is 100 for the card that is PCM master.
- *	If multiple cards are PCM master (because they are not interconnected),
- *	each card with PCM master will have increasing PCM id.
- *	All PCM buses with the same ID are expected to be connected and have
- *	common time slots slots.
- *	Only one chip of the PCM bus must be master, the others slave.
- *	-1 means no support of PCM bus not even.
- *	Omit this value, if all cards are interconnected or none is connected.
- *	If unsure, don't give this parameter.
- *
- * dmask and bmask:
- *	NOTE: One dmask value must be given for every HFC-E1 card.
- *	If omitted, the E1 card has D-channel on time slot 16, which is default.
- *	dmask is a 32 bit mask. The bit must be set for an alternate time slot.
- *	If multiple bits are set, multiple virtual card fragments are created.
- *	For each bit set, a bmask value must be given. Each bit on the bmask
- *	value stands for a B-channel. The bmask may not overlap with dmask or
- *	with other bmask values for that card.
- *	Example: dmask=0x00020002 bmask=0x0000fffc,0xfffc0000
- *		This will create one fragment with D-channel on slot 1 with
- *		B-channels on slots 2..15, and a second fragment with D-channel
- *		on slot 17 with B-channels on slot 18..31. Slot 16 is unused.
- *	If bit 0 is set (dmask=0x00000001) the D-channel is on slot 0 and will
- *	not function.
- *	Example: dmask=0x00000001 bmask=0xfffffffe
- *		This will create a port with all 31 usable timeslots as
- *		B-channels.
- *	If no bits are set on bmask, no B-channel is created for that fragment.
- *	Example: dmask=0xfffffffe bmask=0,0,0,0.... (31 0-values for bmask)
- *		This will create 31 ports with one D-channel only.
- *	If you don't know how to use it, you don't need it!
- *
- * iomode:
- *	NOTE: only one mode value must be given for every card.
- *	-> See hfc_multi.h for HFC_IO_MODE_* values
- *	By default, the IO mode is pci memory IO (MEMIO).
- *	Some cards require specific IO mode, so it cannot be changed.
- *	It may be useful to set IO mode to register io (REGIO) to solve
- *	PCI bridge problems.
- *	If unsure, don't give this parameter.
- *
- * clockdelay_nt:
- *	NOTE: only one clockdelay_nt value must be given once for all cards.
- *	Give the value of the clock control register (A_ST_CLK_DLY)
- *	of the S/T interfaces in NT mode.
- *	This register is needed for the TBR3 certification, so don't change it.
- *
- * clockdelay_te:
- *	NOTE: only one clockdelay_te value must be given once
- *	Give the value of the clock control register (A_ST_CLK_DLY)
- *	of the S/T interfaces in TE mode.
- *	This register is needed for the TBR3 certification, so don't change it.
- *
- * clock:
- *	NOTE: only one clock value must be given once
- *	Selects interface with clock source for mISDN and applications.
- *	Set to card number starting with 1. Set to -1 to disable.
- *	By default, the first card is used as clock source.
- *
- * hwid:
- *	NOTE: only one hwid value must be given once
- *	Enable special embedded devices with XHFC controllers.
- */
-
-/*
- * debug register access (never use this, it will flood your system log)
- * #define HFC_REGISTER_DEBUG
- */
-
-#define HFC_MULTI_VERSION	"2.03"
-
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/mISDNhw.h>
-#include <linux/mISDNdsp.h>
-
-/*
-  #define IRQCOUNT_DEBUG
-  #define IRQ_DEBUG
-*/
-
-#include "hfc_multi.h"
-#ifdef ECHOPREP
-#include "gaintab.h"
-#endif
-
-#define	MAX_CARDS	8
-#define	MAX_PORTS	(8 * MAX_CARDS)
-#define	MAX_FRAGS	(32 * MAX_CARDS)
-
-static LIST_HEAD(HFClist);
-static DEFINE_SPINLOCK(HFClock); /* global hfc list lock */
-
-static void ph_state_change(struct dchannel *);
-
-static struct hfc_multi *syncmaster;
-static int plxsd_master; /* if we have a master card (yet) */
-static DEFINE_SPINLOCK(plx_lock); /* may not acquire other lock inside */
-
-#define	TYP_E1		1
-#define	TYP_4S		4
-#define TYP_8S		8
-
-static int poll_timer = 6;	/* default = 128 samples = 16ms */
-/* number of POLL_TIMER interrupts for G2 timeout (ca 1s) */
-static int nt_t1_count[] = { 3840, 1920, 960, 480, 240, 120, 60, 30  };
-#define	CLKDEL_TE	0x0f	/* CLKDEL in TE mode */
-#define	CLKDEL_NT	0x6c	/* CLKDEL in NT mode
-				   (0x60 MUST be included!) */
-
-#define	DIP_4S	0x1		/* DIP Switches for Beronet 1S/2S/4S cards */
-#define	DIP_8S	0x2		/* DIP Switches for Beronet 8S+ cards */
-#define	DIP_E1	0x3		/* DIP Switches for Beronet E1 cards */
-
-/*
- * module stuff
- */
-
-static uint	type[MAX_CARDS];
-static int	pcm[MAX_CARDS];
-static uint	dmask[MAX_CARDS];
-static uint	bmask[MAX_FRAGS];
-static uint	iomode[MAX_CARDS];
-static uint	port[MAX_PORTS];
-static uint	debug;
-static uint	poll;
-static int	clock;
-static uint	timer;
-static uint	clockdelay_te = CLKDEL_TE;
-static uint	clockdelay_nt = CLKDEL_NT;
-#define HWID_NONE	0
-#define HWID_MINIP4	1
-#define HWID_MINIP8	2
-#define HWID_MINIP16	3
-static uint	hwid = HWID_NONE;
-
-static int	HFC_cnt, E1_cnt, bmask_cnt, Port_cnt, PCM_cnt = 99;
-
-MODULE_AUTHOR("Andreas Eversberg");
-MODULE_DESCRIPTION("mISDN driver for hfc-4s/hfc-8s/hfc-e1 based cards");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(HFC_MULTI_VERSION);
-module_param(debug, uint, S_IRUGO | S_IWUSR);
-module_param(poll, uint, S_IRUGO | S_IWUSR);
-module_param(clock, int, S_IRUGO | S_IWUSR);
-module_param(timer, uint, S_IRUGO | S_IWUSR);
-module_param(clockdelay_te, uint, S_IRUGO | S_IWUSR);
-module_param(clockdelay_nt, uint, S_IRUGO | S_IWUSR);
-module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR);
-module_param_array(pcm, int, NULL, S_IRUGO | S_IWUSR);
-module_param_array(dmask, uint, NULL, S_IRUGO | S_IWUSR);
-module_param_array(bmask, uint, NULL, S_IRUGO | S_IWUSR);
-module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR);
-module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);
-module_param(hwid, uint, S_IRUGO | S_IWUSR); /* The hardware ID */
-
-#ifdef HFC_REGISTER_DEBUG
-#define HFC_outb(hc, reg, val)					\
-	(hc->HFC_outb(hc, reg, val, __func__, __LINE__))
-#define HFC_outb_nodebug(hc, reg, val)					\
-	(hc->HFC_outb_nodebug(hc, reg, val, __func__, __LINE__))
-#define HFC_inb(hc, reg)				\
-	(hc->HFC_inb(hc, reg, __func__, __LINE__))
-#define HFC_inb_nodebug(hc, reg)				\
-	(hc->HFC_inb_nodebug(hc, reg, __func__, __LINE__))
-#define HFC_inw(hc, reg)				\
-	(hc->HFC_inw(hc, reg, __func__, __LINE__))
-#define HFC_inw_nodebug(hc, reg)				\
-	(hc->HFC_inw_nodebug(hc, reg, __func__, __LINE__))
-#define HFC_wait(hc)				\
-	(hc->HFC_wait(hc, __func__, __LINE__))
-#define HFC_wait_nodebug(hc)				\
-	(hc->HFC_wait_nodebug(hc, __func__, __LINE__))
-#else
-#define HFC_outb(hc, reg, val)		(hc->HFC_outb(hc, reg, val))
-#define HFC_outb_nodebug(hc, reg, val)	(hc->HFC_outb_nodebug(hc, reg, val))
-#define HFC_inb(hc, reg)		(hc->HFC_inb(hc, reg))
-#define HFC_inb_nodebug(hc, reg)	(hc->HFC_inb_nodebug(hc, reg))
-#define HFC_inw(hc, reg)		(hc->HFC_inw(hc, reg))
-#define HFC_inw_nodebug(hc, reg)	(hc->HFC_inw_nodebug(hc, reg))
-#define HFC_wait(hc)			(hc->HFC_wait(hc))
-#define HFC_wait_nodebug(hc)		(hc->HFC_wait_nodebug(hc))
-#endif
-
-#ifdef CONFIG_MISDN_HFCMULTI_8xx
-#include "hfc_multi_8xx.h"
-#endif
-
-/* HFC_IO_MODE_PCIMEM */
-static void
-#ifdef HFC_REGISTER_DEBUG
-HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val,
-		const char *function, int line)
-#else
-	HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val)
-#endif
-{
-	writeb(val, hc->pci_membase + reg);
-}
-static u_char
-#ifdef HFC_REGISTER_DEBUG
-HFC_inb_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line)
-#else
-	HFC_inb_pcimem(struct hfc_multi *hc, u_char reg)
-#endif
-{
-	return readb(hc->pci_membase + reg);
-}
-static u_short
-#ifdef HFC_REGISTER_DEBUG
-HFC_inw_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line)
-#else
-	HFC_inw_pcimem(struct hfc_multi *hc, u_char reg)
-#endif
-{
-	return readw(hc->pci_membase + reg);
-}
-static void
-#ifdef HFC_REGISTER_DEBUG
-HFC_wait_pcimem(struct hfc_multi *hc, const char *function, int line)
-#else
-	HFC_wait_pcimem(struct hfc_multi *hc)
-#endif
-{
-	while (readb(hc->pci_membase + R_STATUS) & V_BUSY)
-		cpu_relax();
-}
-
-/* HFC_IO_MODE_REGIO */
-static void
-#ifdef HFC_REGISTER_DEBUG
-HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val,
-	       const char *function, int line)
-#else
-	HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val)
-#endif
-{
-	outb(reg, hc->pci_iobase + 4);
-	outb(val, hc->pci_iobase);
-}
-static u_char
-#ifdef HFC_REGISTER_DEBUG
-HFC_inb_regio(struct hfc_multi *hc, u_char reg, const char *function, int line)
-#else
-	HFC_inb_regio(struct hfc_multi *hc, u_char reg)
-#endif
-{
-	outb(reg, hc->pci_iobase + 4);
-	return inb(hc->pci_iobase);
-}
-static u_short
-#ifdef HFC_REGISTER_DEBUG
-HFC_inw_regio(struct hfc_multi *hc, u_char reg, const char *function, int line)
-#else
-	HFC_inw_regio(struct hfc_multi *hc, u_char reg)
-#endif
-{
-	outb(reg, hc->pci_iobase + 4);
-	return inw(hc->pci_iobase);
-}
-static void
-#ifdef HFC_REGISTER_DEBUG
-HFC_wait_regio(struct hfc_multi *hc, const char *function, int line)
-#else
-	HFC_wait_regio(struct hfc_multi *hc)
-#endif
-{
-	outb(R_STATUS, hc->pci_iobase + 4);
-	while (inb(hc->pci_iobase) & V_BUSY)
-		cpu_relax();
-}
-
-#ifdef HFC_REGISTER_DEBUG
-static void
-HFC_outb_debug(struct hfc_multi *hc, u_char reg, u_char val,
-	       const char *function, int line)
-{
-	char regname[256] = "", bits[9] = "xxxxxxxx";
-	int i;
-
-	i = -1;
-	while (hfc_register_names[++i].name) {
-		if (hfc_register_names[i].reg == reg)
-			strcat(regname, hfc_register_names[i].name);
-	}
-	if (regname[0] == '\0')
-		strcpy(regname, "register");
-
-	bits[7] = '0' + (!!(val & 1));
-	bits[6] = '0' + (!!(val & 2));
-	bits[5] = '0' + (!!(val & 4));
-	bits[4] = '0' + (!!(val & 8));
-	bits[3] = '0' + (!!(val & 16));
-	bits[2] = '0' + (!!(val & 32));
-	bits[1] = '0' + (!!(val & 64));
-	bits[0] = '0' + (!!(val & 128));
-	printk(KERN_DEBUG
-	       "HFC_outb(chip %d, %02x=%s, 0x%02x=%s); in %s() line %d\n",
-	       hc->id, reg, regname, val, bits, function, line);
-	HFC_outb_nodebug(hc, reg, val);
-}
-static u_char
-HFC_inb_debug(struct hfc_multi *hc, u_char reg, const char *function, int line)
-{
-	char regname[256] = "", bits[9] = "xxxxxxxx";
-	u_char val = HFC_inb_nodebug(hc, reg);
-	int i;
-
-	i = 0;
-	while (hfc_register_names[i++].name)
-		;
-	while (hfc_register_names[++i].name) {
-		if (hfc_register_names[i].reg == reg)
-			strcat(regname, hfc_register_names[i].name);
-	}
-	if (regname[0] == '\0')
-		strcpy(regname, "register");
-
-	bits[7] = '0' + (!!(val & 1));
-	bits[6] = '0' + (!!(val & 2));
-	bits[5] = '0' + (!!(val & 4));
-	bits[4] = '0' + (!!(val & 8));
-	bits[3] = '0' + (!!(val & 16));
-	bits[2] = '0' + (!!(val & 32));
-	bits[1] = '0' + (!!(val & 64));
-	bits[0] = '0' + (!!(val & 128));
-	printk(KERN_DEBUG
-	       "HFC_inb(chip %d, %02x=%s) = 0x%02x=%s; in %s() line %d\n",
-	       hc->id, reg, regname, val, bits, function, line);
-	return val;
-}
-static u_short
-HFC_inw_debug(struct hfc_multi *hc, u_char reg, const char *function, int line)
-{
-	char regname[256] = "";
-	u_short val = HFC_inw_nodebug(hc, reg);
-	int i;
-
-	i = 0;
-	while (hfc_register_names[i++].name)
-		;
-	while (hfc_register_names[++i].name) {
-		if (hfc_register_names[i].reg == reg)
-			strcat(regname, hfc_register_names[i].name);
-	}
-	if (regname[0] == '\0')
-		strcpy(regname, "register");
-
-	printk(KERN_DEBUG
-	       "HFC_inw(chip %d, %02x=%s) = 0x%04x; in %s() line %d\n",
-	       hc->id, reg, regname, val, function, line);
-	return val;
-}
-static void
-HFC_wait_debug(struct hfc_multi *hc, const char *function, int line)
-{
-	printk(KERN_DEBUG "HFC_wait(chip %d); in %s() line %d\n",
-	       hc->id, function, line);
-	HFC_wait_nodebug(hc);
-}
-#endif
-
-/* write fifo data (REGIO) */
-static void
-write_fifo_regio(struct hfc_multi *hc, u_char *data, int len)
-{
-	outb(A_FIFO_DATA0, (hc->pci_iobase) + 4);
-	while (len >> 2) {
-		outl(cpu_to_le32(*(u32 *)data), hc->pci_iobase);
-		data += 4;
-		len -= 4;
-	}
-	while (len >> 1) {
-		outw(cpu_to_le16(*(u16 *)data), hc->pci_iobase);
-		data += 2;
-		len -= 2;
-	}
-	while (len) {
-		outb(*data, hc->pci_iobase);
-		data++;
-		len--;
-	}
-}
-/* write fifo data (PCIMEM) */
-static void
-write_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)
-{
-	while (len >> 2) {
-		writel(cpu_to_le32(*(u32 *)data),
-		       hc->pci_membase + A_FIFO_DATA0);
-		data += 4;
-		len -= 4;
-	}
-	while (len >> 1) {
-		writew(cpu_to_le16(*(u16 *)data),
-		       hc->pci_membase + A_FIFO_DATA0);
-		data += 2;
-		len -= 2;
-	}
-	while (len) {
-		writeb(*data, hc->pci_membase + A_FIFO_DATA0);
-		data++;
-		len--;
-	}
-}
-
-/* read fifo data (REGIO) */
-static void
-read_fifo_regio(struct hfc_multi *hc, u_char *data, int len)
-{
-	outb(A_FIFO_DATA0, (hc->pci_iobase) + 4);
-	while (len >> 2) {
-		*(u32 *)data = le32_to_cpu(inl(hc->pci_iobase));
-		data += 4;
-		len -= 4;
-	}
-	while (len >> 1) {
-		*(u16 *)data = le16_to_cpu(inw(hc->pci_iobase));
-		data += 2;
-		len -= 2;
-	}
-	while (len) {
-		*data = inb(hc->pci_iobase);
-		data++;
-		len--;
-	}
-}
-
-/* read fifo data (PCIMEM) */
-static void
-read_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)
-{
-	while (len >> 2) {
-		*(u32 *)data =
-			le32_to_cpu(readl(hc->pci_membase + A_FIFO_DATA0));
-		data += 4;
-		len -= 4;
-	}
-	while (len >> 1) {
-		*(u16 *)data =
-			le16_to_cpu(readw(hc->pci_membase + A_FIFO_DATA0));
-		data += 2;
-		len -= 2;
-	}
-	while (len) {
-		*data = readb(hc->pci_membase + A_FIFO_DATA0);
-		data++;
-		len--;
-	}
-}
-
-static void
-enable_hwirq(struct hfc_multi *hc)
-{
-	hc->hw.r_irq_ctrl |= V_GLOB_IRQ_EN;
-	HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl);
-}
-
-static void
-disable_hwirq(struct hfc_multi *hc)
-{
-	hc->hw.r_irq_ctrl &= ~((u_char)V_GLOB_IRQ_EN);
-	HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl);
-}
-
-#define	NUM_EC 2
-#define	MAX_TDM_CHAN 32
-
-
-static inline void
-enablepcibridge(struct hfc_multi *c)
-{
-	HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); /* was _io before */
-}
-
-static inline void
-disablepcibridge(struct hfc_multi *c)
-{
-	HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x2); /* was _io before */
-}
-
-static inline unsigned char
-readpcibridge(struct hfc_multi *hc, unsigned char address)
-{
-	unsigned short cipv;
-	unsigned char data;
-
-	if (!hc->pci_iobase)
-		return 0;
-
-	/* slow down a PCI read access by 1 PCI clock cycle */
-	HFC_outb(hc, R_CTRL, 0x4); /*was _io before*/
-
-	if (address == 0)
-		cipv = 0x4000;
-	else
-		cipv = 0x5800;
-
-	/* select local bridge port address by writing to CIP port */
-	/* data = HFC_inb(c, cipv); * was _io before */
-	outw(cipv, hc->pci_iobase + 4);
-	data = inb(hc->pci_iobase);
-
-	/* restore R_CTRL for normal PCI read cycle speed */
-	HFC_outb(hc, R_CTRL, 0x0); /* was _io before */
-
-	return data;
-}
-
-static inline void
-writepcibridge(struct hfc_multi *hc, unsigned char address, unsigned char data)
-{
-	unsigned short cipv;
-	unsigned int datav;
-
-	if (!hc->pci_iobase)
-		return;
-
-	if (address == 0)
-		cipv = 0x4000;
-	else
-		cipv = 0x5800;
-
-	/* select local bridge port address by writing to CIP port */
-	outw(cipv, hc->pci_iobase + 4);
-	/* define a 32 bit dword with 4 identical bytes for write sequence */
-	datav = data | ((__u32) data << 8) | ((__u32) data << 16) |
-		((__u32) data << 24);
-
-	/*
-	 * write this 32 bit dword to the bridge data port
-	 * this will initiate a write sequence of up to 4 writes to the same
-	 * address on the local bus interface the number of write accesses
-	 * is undefined but >=1 and depends on the next PCI transaction
-	 * during write sequence on the local bus
-	 */
-	outl(datav, hc->pci_iobase);
-}
-
-static inline void
-cpld_set_reg(struct hfc_multi *hc, unsigned char reg)
-{
-	/* Do data pin read low byte */
-	HFC_outb(hc, R_GPIO_OUT1, reg);
-}
-
-static inline void
-cpld_write_reg(struct hfc_multi *hc, unsigned char reg, unsigned char val)
-{
-	cpld_set_reg(hc, reg);
-
-	enablepcibridge(hc);
-	writepcibridge(hc, 1, val);
-	disablepcibridge(hc);
-
-	return;
-}
-
-static inline void
-vpm_write_address(struct hfc_multi *hc, unsigned short addr)
-{
-	cpld_write_reg(hc, 0, 0xff & addr);
-	cpld_write_reg(hc, 1, 0x01 & (addr >> 8));
-}
-
-static inline unsigned char
-vpm_in(struct hfc_multi *c, int which, unsigned short addr)
-{
-	unsigned char res;
-
-	vpm_write_address(c, addr);
-
-	if (!which)
-		cpld_set_reg(c, 2);
-	else
-		cpld_set_reg(c, 3);
-
-	enablepcibridge(c);
-	res = readpcibridge(c, 1);
-	disablepcibridge(c);
-
-	cpld_set_reg(c, 0);
-
-	return res;
-}
-
-static inline void
-vpm_out(struct hfc_multi *c, int which, unsigned short addr,
-	unsigned char data)
-{
-	vpm_write_address(c, addr);
-
-	enablepcibridge(c);
-
-	if (!which)
-		cpld_set_reg(c, 2);
-	else
-		cpld_set_reg(c, 3);
-
-	writepcibridge(c, 1, data);
-
-	cpld_set_reg(c, 0);
-
-	disablepcibridge(c);
-
-	{
-		unsigned char regin;
-		regin = vpm_in(c, which, addr);
-		if (regin != data)
-			printk(KERN_DEBUG "Wrote 0x%x to register 0x%x but got back "
-			       "0x%x\n", data, addr, regin);
-	}
-
-}
-
-
-static void
-vpm_init(struct hfc_multi *wc)
-{
-	unsigned char reg;
-	unsigned int mask;
-	unsigned int i, x, y;
-	unsigned int ver;
-
-	for (x = 0; x < NUM_EC; x++) {
-		/* Setup GPIO's */
-		if (!x) {
-			ver = vpm_in(wc, x, 0x1a0);
-			printk(KERN_DEBUG "VPM: Chip %d: ver %02x\n", x, ver);
-		}
-
-		for (y = 0; y < 4; y++) {
-			vpm_out(wc, x, 0x1a8 + y, 0x00); /* GPIO out */
-			vpm_out(wc, x, 0x1ac + y, 0x00); /* GPIO dir */
-			vpm_out(wc, x, 0x1b0 + y, 0x00); /* GPIO sel */
-		}
-
-		/* Setup TDM path - sets fsync and tdm_clk as inputs */
-		reg = vpm_in(wc, x, 0x1a3); /* misc_con */
-		vpm_out(wc, x, 0x1a3, reg & ~2);
-
-		/* Setup Echo length (256 taps) */
-		vpm_out(wc, x, 0x022, 1);
-		vpm_out(wc, x, 0x023, 0xff);
-
-		/* Setup timeslots */
-		vpm_out(wc, x, 0x02f, 0x00);
-		mask = 0x02020202 << (x * 4);
-
-		/* Setup the tdm channel masks for all chips */
-		for (i = 0; i < 4; i++)
-			vpm_out(wc, x, 0x33 - i, (mask >> (i << 3)) & 0xff);
-
-		/* Setup convergence rate */
-		printk(KERN_DEBUG "VPM: A-law mode\n");
-		reg = 0x00 | 0x10 | 0x01;
-		vpm_out(wc, x, 0x20, reg);
-		printk(KERN_DEBUG "VPM reg 0x20 is %x\n", reg);
-		/*vpm_out(wc, x, 0x20, (0x00 | 0x08 | 0x20 | 0x10)); */
-
-		vpm_out(wc, x, 0x24, 0x02);
-		reg = vpm_in(wc, x, 0x24);
-		printk(KERN_DEBUG "NLP Thresh is set to %d (0x%x)\n", reg, reg);
-
-		/* Initialize echo cans */
-		for (i = 0; i < MAX_TDM_CHAN; i++) {
-			if (mask & (0x00000001 << i))
-				vpm_out(wc, x, i, 0x00);
-		}
-
-		/*
-		 * ARM arch at least disallows a udelay of
-		 * more than 2ms... it gives a fake "__bad_udelay"
-		 * reference at link-time.
-		 * long delays in kernel code are pretty sucky anyway
-		 * for now work around it using 5 x 2ms instead of 1 x 10ms
-		 */
-
-		udelay(2000);
-		udelay(2000);
-		udelay(2000);
-		udelay(2000);
-		udelay(2000);
-
-		/* Put in bypass mode */
-		for (i = 0; i < MAX_TDM_CHAN; i++) {
-			if (mask & (0x00000001 << i))
-				vpm_out(wc, x, i, 0x01);
-		}
-
-		/* Enable bypass */
-		for (i = 0; i < MAX_TDM_CHAN; i++) {
-			if (mask & (0x00000001 << i))
-				vpm_out(wc, x, 0x78 + i, 0x01);
-		}
-
-	}
-}
-
-#ifdef UNUSED
-static void
-vpm_check(struct hfc_multi *hctmp)
-{
-	unsigned char gpi2;
-
-	gpi2 = HFC_inb(hctmp, R_GPI_IN2);
-
-	if ((gpi2 & 0x3) != 0x3)
-		printk(KERN_DEBUG "Got interrupt 0x%x from VPM!\n", gpi2);
-}
-#endif /* UNUSED */
-
-
-/*
- * Interface to enable/disable the HW Echocan
- *
- * these functions are called within a spin_lock_irqsave on
- * the channel instance lock, so we are not disturbed by irqs
- *
- * we can later easily change the interface to make  other
- * things configurable, for now we configure the taps
- *
- */
-
-static void
-vpm_echocan_on(struct hfc_multi *hc, int ch, int taps)
-{
-	unsigned int timeslot;
-	unsigned int unit;
-	struct bchannel *bch = hc->chan[ch].bch;
-#ifdef TXADJ
-	int txadj = -4;
-	struct sk_buff *skb;
-#endif
-	if (hc->chan[ch].protocol != ISDN_P_B_RAW)
-		return;
-
-	if (!bch)
-		return;
-
-#ifdef TXADJ
-	skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX,
-			       sizeof(int), &txadj, GFP_ATOMIC);
-	if (skb)
-		recv_Bchannel_skb(bch, skb);
-#endif
-
-	timeslot = ((ch / 4) * 8) + ((ch % 4) * 4) + 1;
-	unit = ch % 4;
-
-	printk(KERN_NOTICE "vpm_echocan_on called taps [%d] on timeslot %d\n",
-	       taps, timeslot);
-
-	vpm_out(hc, unit, timeslot, 0x7e);
-}
-
-static void
-vpm_echocan_off(struct hfc_multi *hc, int ch)
-{
-	unsigned int timeslot;
-	unsigned int unit;
-	struct bchannel *bch = hc->chan[ch].bch;
-#ifdef TXADJ
-	int txadj = 0;
-	struct sk_buff *skb;
-#endif
-
-	if (hc->chan[ch].protocol != ISDN_P_B_RAW)
-		return;
-
-	if (!bch)
-		return;
-
-#ifdef TXADJ
-	skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX,
-			       sizeof(int), &txadj, GFP_ATOMIC);
-	if (skb)
-		recv_Bchannel_skb(bch, skb);
-#endif
-
-	timeslot = ((ch / 4) * 8) + ((ch % 4) * 4) + 1;
-	unit = ch % 4;
-
-	printk(KERN_NOTICE "vpm_echocan_off called on timeslot %d\n",
-	       timeslot);
-	/* FILLME */
-	vpm_out(hc, unit, timeslot, 0x01);
-}
-
-
-/*
- * Speech Design resync feature
- * NOTE: This is called sometimes outside interrupt handler.
- * We must lock irqsave, so no other interrupt (other card) will occur!
- * Also multiple interrupts may nest, so must lock each access (lists, card)!
- */
-static inline void
-hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
-{
-	struct hfc_multi *hc, *next, *pcmmaster = NULL;
-	void __iomem *plx_acc_32;
-	u_int pv;
-	u_long flags;
-
-	spin_lock_irqsave(&HFClock, flags);
-	spin_lock(&plx_lock); /* must be locked inside other locks */
-
-	if (debug & DEBUG_HFCMULTI_PLXSD)
-		printk(KERN_DEBUG "%s: RESYNC(syncmaster=0x%p)\n",
-		       __func__, syncmaster);
-
-	/* select new master */
-	if (newmaster) {
-		if (debug & DEBUG_HFCMULTI_PLXSD)
-			printk(KERN_DEBUG "using provided controller\n");
-	} else {
-		list_for_each_entry_safe(hc, next, &HFClist, list) {
-			if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-				if (hc->syncronized) {
-					newmaster = hc;
-					break;
-				}
-			}
-		}
-	}
-
-	/* Disable sync of all cards */
-	list_for_each_entry_safe(hc, next, &HFClist, list) {
-		if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-			plx_acc_32 = hc->plx_membase + PLX_GPIOC;
-			pv = readl(plx_acc_32);
-			pv &= ~PLX_SYNC_O_EN;
-			writel(pv, plx_acc_32);
-			if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) {
-				pcmmaster = hc;
-				if (hc->ctype == HFC_TYPE_E1) {
-					if (debug & DEBUG_HFCMULTI_PLXSD)
-						printk(KERN_DEBUG
-						       "Schedule SYNC_I\n");
-					hc->e1_resync |= 1; /* get SYNC_I */
-				}
-			}
-		}
-	}
-
-	if (newmaster) {
-		hc = newmaster;
-		if (debug & DEBUG_HFCMULTI_PLXSD)
-			printk(KERN_DEBUG "id=%d (0x%p) = synchronized with "
-			       "interface.\n", hc->id, hc);
-		/* Enable new sync master */
-		plx_acc_32 = hc->plx_membase + PLX_GPIOC;
-		pv = readl(plx_acc_32);
-		pv |= PLX_SYNC_O_EN;
-		writel(pv, plx_acc_32);
-		/* switch to jatt PLL, if not disabled by RX_SYNC */
-		if (hc->ctype == HFC_TYPE_E1
-		    && !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) {
-			if (debug & DEBUG_HFCMULTI_PLXSD)
-				printk(KERN_DEBUG "Schedule jatt PLL\n");
-			hc->e1_resync |= 2; /* switch to jatt */
-		}
-	} else {
-		if (pcmmaster) {
-			hc = pcmmaster;
-			if (debug & DEBUG_HFCMULTI_PLXSD)
-				printk(KERN_DEBUG
-				       "id=%d (0x%p) = PCM master synchronized "
-				       "with QUARTZ\n", hc->id, hc);
-			if (hc->ctype == HFC_TYPE_E1) {
-				/* Use the crystal clock for the PCM
-				   master card */
-				if (debug & DEBUG_HFCMULTI_PLXSD)
-					printk(KERN_DEBUG
-					       "Schedule QUARTZ for HFC-E1\n");
-				hc->e1_resync |= 4; /* switch quartz */
-			} else {
-				if (debug & DEBUG_HFCMULTI_PLXSD)
-					printk(KERN_DEBUG
-					       "QUARTZ is automatically "
-					       "enabled by HFC-%dS\n", hc->ctype);
-			}
-			plx_acc_32 = hc->plx_membase + PLX_GPIOC;
-			pv = readl(plx_acc_32);
-			pv |= PLX_SYNC_O_EN;
-			writel(pv, plx_acc_32);
-		} else
-			if (!rm)
-				printk(KERN_ERR "%s no pcm master, this MUST "
-				       "not happen!\n", __func__);
-	}
-	syncmaster = newmaster;
-
-	spin_unlock(&plx_lock);
-	spin_unlock_irqrestore(&HFClock, flags);
-}
-
-/* This must be called AND hc must be locked irqsave!!! */
-static inline void
-plxsd_checksync(struct hfc_multi *hc, int rm)
-{
-	if (hc->syncronized) {
-		if (syncmaster == NULL) {
-			if (debug & DEBUG_HFCMULTI_PLXSD)
-				printk(KERN_DEBUG "%s: GOT sync on card %d"
-				       " (id=%d)\n", __func__, hc->id + 1,
-				       hc->id);
-			hfcmulti_resync(hc, hc, rm);
-		}
-	} else {
-		if (syncmaster == hc) {
-			if (debug & DEBUG_HFCMULTI_PLXSD)
-				printk(KERN_DEBUG "%s: LOST sync on card %d"
-				       " (id=%d)\n", __func__, hc->id + 1,
-				       hc->id);
-			hfcmulti_resync(hc, NULL, rm);
-		}
-	}
-}
-
-
-/*
- * free hardware resources used by driver
- */
-static void
-release_io_hfcmulti(struct hfc_multi *hc)
-{
-	void __iomem *plx_acc_32;
-	u_int	pv;
-	u_long	plx_flags;
-
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: entered\n", __func__);
-
-	/* soft reset also masks all interrupts */
-	hc->hw.r_cirm |= V_SRES;
-	HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
-	udelay(1000);
-	hc->hw.r_cirm &= ~V_SRES;
-	HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
-	udelay(1000); /* instead of 'wait' that may cause locking */
-
-	/* release Speech Design card, if PLX was initialized */
-	if (test_bit(HFC_CHIP_PLXSD, &hc->chip) && hc->plx_membase) {
-		if (debug & DEBUG_HFCMULTI_PLXSD)
-			printk(KERN_DEBUG "%s: release PLXSD card %d\n",
-			       __func__, hc->id + 1);
-		spin_lock_irqsave(&plx_lock, plx_flags);
-		plx_acc_32 = hc->plx_membase + PLX_GPIOC;
-		writel(PLX_GPIOC_INIT, plx_acc_32);
-		pv = readl(plx_acc_32);
-		/* Termination off */
-		pv &= ~PLX_TERM_ON;
-		/* Disconnect the PCM */
-		pv |= PLX_SLAVE_EN_N;
-		pv &= ~PLX_MASTER_EN;
-		pv &= ~PLX_SYNC_O_EN;
-		/* Put the DSP in Reset */
-		pv &= ~PLX_DSP_RES_N;
-		writel(pv, plx_acc_32);
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: PCM off: PLX_GPIO=%x\n",
-			       __func__, pv);
-		spin_unlock_irqrestore(&plx_lock, plx_flags);
-	}
-
-	/* disable memory mapped ports / io ports */
-	test_and_clear_bit(HFC_CHIP_PLXSD, &hc->chip); /* prevent resync */
-	if (hc->pci_dev)
-		pci_write_config_word(hc->pci_dev, PCI_COMMAND, 0);
-	if (hc->pci_membase)
-		iounmap(hc->pci_membase);
-	if (hc->plx_membase)
-		iounmap(hc->plx_membase);
-	if (hc->pci_iobase)
-		release_region(hc->pci_iobase, 8);
-	if (hc->xhfc_membase)
-		iounmap((void *)hc->xhfc_membase);
-
-	if (hc->pci_dev) {
-		pci_disable_device(hc->pci_dev);
-		pci_set_drvdata(hc->pci_dev, NULL);
-	}
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: done\n", __func__);
-}
-
-/*
- * function called to reset the HFC chip. A complete software reset of chip
- * and fifos is done. All configuration of the chip is done.
- */
-
-static int
-init_chip(struct hfc_multi *hc)
-{
-	u_long			flags, val, val2 = 0, rev;
-	int			i, err = 0;
-	u_char			r_conf_en, rval;
-	void __iomem		*plx_acc_32;
-	u_int			pv;
-	u_long			plx_flags, hfc_flags;
-	int			plx_count;
-	struct hfc_multi	*pos, *next, *plx_last_hc;
-
-	spin_lock_irqsave(&hc->lock, flags);
-	/* reset all registers */
-	memset(&hc->hw, 0, sizeof(struct hfcm_hw));
-
-	/* revision check */
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: entered\n", __func__);
-	val = HFC_inb(hc, R_CHIP_ID);
-	if ((val >> 4) != 0x8 && (val >> 4) != 0xc && (val >> 4) != 0xe &&
-	    (val >> 1) != 0x31) {
-		printk(KERN_INFO "HFC_multi: unknown CHIP_ID:%x\n", (u_int)val);
-		err = -EIO;
-		goto out;
-	}
-	rev = HFC_inb(hc, R_CHIP_RV);
-	printk(KERN_INFO
-	       "HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n",
-	       val, rev, (rev == 0 && (hc->ctype != HFC_TYPE_XHFC)) ?
-	       " (old FIFO handling)" : "");
-	if (hc->ctype != HFC_TYPE_XHFC && rev == 0) {
-		test_and_set_bit(HFC_CHIP_REVISION0, &hc->chip);
-		printk(KERN_WARNING
-		       "HFC_multi: NOTE: Your chip is revision 0, "
-		       "ask Cologne Chip for update. Newer chips "
-		       "have a better FIFO handling. Old chips "
-		       "still work but may have slightly lower "
-		       "HDLC transmit performance.\n");
-	}
-	if (rev > 1) {
-		printk(KERN_WARNING "HFC_multi: WARNING: This driver doesn't "
-		       "consider chip revision = %ld. The chip / "
-		       "bridge may not work.\n", rev);
-	}
-
-	/* set s-ram size */
-	hc->Flen = 0x10;
-	hc->Zmin = 0x80;
-	hc->Zlen = 384;
-	hc->DTMFbase = 0x1000;
-	if (test_bit(HFC_CHIP_EXRAM_128, &hc->chip)) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: changing to 128K external RAM\n",
-			       __func__);
-		hc->hw.r_ctrl |= V_EXT_RAM;
-		hc->hw.r_ram_sz = 1;
-		hc->Flen = 0x20;
-		hc->Zmin = 0xc0;
-		hc->Zlen = 1856;
-		hc->DTMFbase = 0x2000;
-	}
-	if (test_bit(HFC_CHIP_EXRAM_512, &hc->chip)) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: changing to 512K external RAM\n",
-			       __func__);
-		hc->hw.r_ctrl |= V_EXT_RAM;
-		hc->hw.r_ram_sz = 2;
-		hc->Flen = 0x20;
-		hc->Zmin = 0xc0;
-		hc->Zlen = 8000;
-		hc->DTMFbase = 0x2000;
-	}
-	if (hc->ctype == HFC_TYPE_XHFC) {
-		hc->Flen = 0x8;
-		hc->Zmin = 0x0;
-		hc->Zlen = 64;
-		hc->DTMFbase = 0x0;
-	}
-	hc->max_trans = poll << 1;
-	if (hc->max_trans > hc->Zlen)
-		hc->max_trans = hc->Zlen;
-
-	/* Speech Design PLX bridge */
-	if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-		if (debug & DEBUG_HFCMULTI_PLXSD)
-			printk(KERN_DEBUG "%s: initializing PLXSD card %d\n",
-			       __func__, hc->id + 1);
-		spin_lock_irqsave(&plx_lock, plx_flags);
-		plx_acc_32 = hc->plx_membase + PLX_GPIOC;
-		writel(PLX_GPIOC_INIT, plx_acc_32);
-		pv = readl(plx_acc_32);
-		/* The first and the last cards are terminating the PCM bus */
-		pv |= PLX_TERM_ON; /* hc is currently the last */
-		/* Disconnect the PCM */
-		pv |= PLX_SLAVE_EN_N;
-		pv &= ~PLX_MASTER_EN;
-		pv &= ~PLX_SYNC_O_EN;
-		/* Put the DSP in Reset */
-		pv &= ~PLX_DSP_RES_N;
-		writel(pv, plx_acc_32);
-		spin_unlock_irqrestore(&plx_lock, plx_flags);
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: slave/term: PLX_GPIO=%x\n",
-			       __func__, pv);
-		/*
-		 * If we are the 3rd PLXSD card or higher, we must turn
-		 * termination of last PLXSD card off.
-		 */
-		spin_lock_irqsave(&HFClock, hfc_flags);
-		plx_count = 0;
-		plx_last_hc = NULL;
-		list_for_each_entry_safe(pos, next, &HFClist, list) {
-			if (test_bit(HFC_CHIP_PLXSD, &pos->chip)) {
-				plx_count++;
-				if (pos != hc)
-					plx_last_hc = pos;
-			}
-		}
-		if (plx_count >= 3) {
-			if (debug & DEBUG_HFCMULTI_PLXSD)
-				printk(KERN_DEBUG "%s: card %d is between, so "
-				       "we disable termination\n",
-				       __func__, plx_last_hc->id + 1);
-			spin_lock_irqsave(&plx_lock, plx_flags);
-			plx_acc_32 = plx_last_hc->plx_membase + PLX_GPIOC;
-			pv = readl(plx_acc_32);
-			pv &= ~PLX_TERM_ON;
-			writel(pv, plx_acc_32);
-			spin_unlock_irqrestore(&plx_lock, plx_flags);
-			if (debug & DEBUG_HFCMULTI_INIT)
-				printk(KERN_DEBUG
-				       "%s: term off: PLX_GPIO=%x\n",
-				       __func__, pv);
-		}
-		spin_unlock_irqrestore(&HFClock, hfc_flags);
-		hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */
-	}
-
-	if (test_bit(HFC_CHIP_EMBSD, &hc->chip))
-		hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */
-
-	/* we only want the real Z2 read-pointer for revision > 0 */
-	if (!test_bit(HFC_CHIP_REVISION0, &hc->chip))
-		hc->hw.r_ram_sz |= V_FZ_MD;
-
-	/* select pcm mode */
-	if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: setting PCM into slave mode\n",
-			       __func__);
-	} else
-		if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip) && !plxsd_master) {
-			if (debug & DEBUG_HFCMULTI_INIT)
-				printk(KERN_DEBUG "%s: setting PCM into master mode\n",
-				       __func__);
-			hc->hw.r_pcm_md0 |= V_PCM_MD;
-		} else {
-			if (debug & DEBUG_HFCMULTI_INIT)
-				printk(KERN_DEBUG "%s: performing PCM auto detect\n",
-				       __func__);
-		}
-
-	/* soft reset */
-	HFC_outb(hc, R_CTRL, hc->hw.r_ctrl);
-	if (hc->ctype == HFC_TYPE_XHFC)
-		HFC_outb(hc, 0x0C /* R_FIFO_THRES */,
-			 0x11 /* 16 Bytes TX/RX */);
-	else
-		HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);
-	HFC_outb(hc, R_FIFO_MD, 0);
-	if (hc->ctype == HFC_TYPE_XHFC)
-		hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES;
-	else
-		hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES
-			| V_RLD_EPR;
-	HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
-	udelay(100);
-	hc->hw.r_cirm = 0;
-	HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
-	udelay(100);
-	if (hc->ctype != HFC_TYPE_XHFC)
-		HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);
-
-	/* Speech Design PLX bridge pcm and sync mode */
-	if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-		spin_lock_irqsave(&plx_lock, plx_flags);
-		plx_acc_32 = hc->plx_membase + PLX_GPIOC;
-		pv = readl(plx_acc_32);
-		/* Connect PCM */
-		if (hc->hw.r_pcm_md0 & V_PCM_MD) {
-			pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N;
-			pv |= PLX_SYNC_O_EN;
-			if (debug & DEBUG_HFCMULTI_INIT)
-				printk(KERN_DEBUG "%s: master: PLX_GPIO=%x\n",
-				       __func__, pv);
-		} else {
-			pv &= ~(PLX_MASTER_EN | PLX_SLAVE_EN_N);
-			pv &= ~PLX_SYNC_O_EN;
-			if (debug & DEBUG_HFCMULTI_INIT)
-				printk(KERN_DEBUG "%s: slave: PLX_GPIO=%x\n",
-				       __func__, pv);
-		}
-		writel(pv, plx_acc_32);
-		spin_unlock_irqrestore(&plx_lock, plx_flags);
-	}
-
-	/* PCM setup */
-	HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x90);
-	if (hc->slots == 32)
-		HFC_outb(hc, R_PCM_MD1, 0x00);
-	if (hc->slots == 64)
-		HFC_outb(hc, R_PCM_MD1, 0x10);
-	if (hc->slots == 128)
-		HFC_outb(hc, R_PCM_MD1, 0x20);
-	HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0xa0);
-	if (test_bit(HFC_CHIP_PLXSD, &hc->chip))
-		HFC_outb(hc, R_PCM_MD2, V_SYNC_SRC); /* sync via SYNC_I / O */
-	else if (test_bit(HFC_CHIP_EMBSD, &hc->chip))
-		HFC_outb(hc, R_PCM_MD2, 0x10); /* V_C2O_EN */
-	else
-		HFC_outb(hc, R_PCM_MD2, 0x00); /* sync from interface */
-	HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00);
-	for (i = 0; i < 256; i++) {
-		HFC_outb_nodebug(hc, R_SLOT, i);
-		HFC_outb_nodebug(hc, A_SL_CFG, 0);
-		if (hc->ctype != HFC_TYPE_XHFC)
-			HFC_outb_nodebug(hc, A_CONF, 0);
-		hc->slot_owner[i] = -1;
-	}
-
-	/* set clock speed */
-	if (test_bit(HFC_CHIP_CLOCK2, &hc->chip)) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG
-			       "%s: setting double clock\n", __func__);
-		HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK);
-	}
-
-	if (test_bit(HFC_CHIP_EMBSD, &hc->chip))
-		HFC_outb(hc, 0x02 /* R_CLK_CFG */, 0x40 /* V_CLKO_OFF */);
-
-	/* B410P GPIO */
-	if (test_bit(HFC_CHIP_B410P, &hc->chip)) {
-		printk(KERN_NOTICE "Setting GPIOs\n");
-		HFC_outb(hc, R_GPIO_SEL, 0x30);
-		HFC_outb(hc, R_GPIO_EN1, 0x3);
-		udelay(1000);
-		printk(KERN_NOTICE "calling vpm_init\n");
-		vpm_init(hc);
-	}
-
-	/* check if R_F0_CNT counts (8 kHz frame count) */
-	val = HFC_inb(hc, R_F0_CNTL);
-	val += HFC_inb(hc, R_F0_CNTH) << 8;
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG
-		       "HFC_multi F0_CNT %ld after reset\n", val);
-	spin_unlock_irqrestore(&hc->lock, flags);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout((HZ / 100) ? : 1); /* Timeout minimum 10ms */
-	spin_lock_irqsave(&hc->lock, flags);
-	val2 = HFC_inb(hc, R_F0_CNTL);
-	val2 += HFC_inb(hc, R_F0_CNTH) << 8;
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG
-		       "HFC_multi F0_CNT %ld after 10 ms (1st try)\n",
-		       val2);
-	if (val2 >= val + 8) { /* 1 ms */
-		/* it counts, so we keep the pcm mode */
-		if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip))
-			printk(KERN_INFO "controller is PCM bus MASTER\n");
-		else
-			if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip))
-				printk(KERN_INFO "controller is PCM bus SLAVE\n");
-			else {
-				test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
-				printk(KERN_INFO "controller is PCM bus SLAVE "
-				       "(auto detected)\n");
-			}
-	} else {
-		/* does not count */
-		if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) {
-		controller_fail:
-			printk(KERN_ERR "HFC_multi ERROR, getting no 125us "
-			       "pulse. Seems that controller fails.\n");
-			err = -EIO;
-			goto out;
-		}
-		if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
-			printk(KERN_INFO "controller is PCM bus SLAVE "
-			       "(ignoring missing PCM clock)\n");
-		} else {
-			/* only one pcm master */
-			if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
-			    && plxsd_master) {
-				printk(KERN_ERR "HFC_multi ERROR, no clock "
-				       "on another Speech Design card found. "
-				       "Please be sure to connect PCM cable.\n");
-				err = -EIO;
-				goto out;
-			}
-			/* retry with master clock */
-			if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-				spin_lock_irqsave(&plx_lock, plx_flags);
-				plx_acc_32 = hc->plx_membase + PLX_GPIOC;
-				pv = readl(plx_acc_32);
-				pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N;
-				pv |= PLX_SYNC_O_EN;
-				writel(pv, plx_acc_32);
-				spin_unlock_irqrestore(&plx_lock, plx_flags);
-				if (debug & DEBUG_HFCMULTI_INIT)
-					printk(KERN_DEBUG "%s: master: "
-					       "PLX_GPIO=%x\n", __func__, pv);
-			}
-			hc->hw.r_pcm_md0 |= V_PCM_MD;
-			HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00);
-			spin_unlock_irqrestore(&hc->lock, flags);
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout((HZ / 100) ?: 1); /* Timeout min. 10ms */
-			spin_lock_irqsave(&hc->lock, flags);
-			val2 = HFC_inb(hc, R_F0_CNTL);
-			val2 += HFC_inb(hc, R_F0_CNTH) << 8;
-			if (debug & DEBUG_HFCMULTI_INIT)
-				printk(KERN_DEBUG "HFC_multi F0_CNT %ld after "
-				       "10 ms (2nd try)\n", val2);
-			if (val2 >= val + 8) { /* 1 ms */
-				test_and_set_bit(HFC_CHIP_PCM_MASTER,
-						 &hc->chip);
-				printk(KERN_INFO "controller is PCM bus MASTER "
-				       "(auto detected)\n");
-			} else
-				goto controller_fail;
-		}
-	}
-
-	/* Release the DSP Reset */
-	if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-		if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip))
-			plxsd_master = 1;
-		spin_lock_irqsave(&plx_lock, plx_flags);
-		plx_acc_32 = hc->plx_membase + PLX_GPIOC;
-		pv = readl(plx_acc_32);
-		pv |=  PLX_DSP_RES_N;
-		writel(pv, plx_acc_32);
-		spin_unlock_irqrestore(&plx_lock, plx_flags);
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: reset off: PLX_GPIO=%x\n",
-			       __func__, pv);
-	}
-
-	/* pcm id */
-	if (hc->pcm)
-		printk(KERN_INFO "controller has given PCM BUS ID %d\n",
-		       hc->pcm);
-	else {
-		if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)
-		    || test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-			PCM_cnt++; /* SD has proprietary bridging */
-		}
-		hc->pcm = PCM_cnt;
-		printk(KERN_INFO "controller has PCM BUS ID %d "
-		       "(auto selected)\n", hc->pcm);
-	}
-
-	/* set up timer */
-	HFC_outb(hc, R_TI_WD, poll_timer);
-	hc->hw.r_irqmsk_misc |= V_TI_IRQMSK;
-
-	/* set E1 state machine IRQ */
-	if (hc->ctype == HFC_TYPE_E1)
-		hc->hw.r_irqmsk_misc |= V_STA_IRQMSK;
-
-	/* set DTMF detection */
-	if (test_bit(HFC_CHIP_DTMF, &hc->chip)) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: enabling DTMF detection "
-			       "for all B-channel\n", __func__);
-		hc->hw.r_dtmf = V_DTMF_EN | V_DTMF_STOP;
-		if (test_bit(HFC_CHIP_ULAW, &hc->chip))
-			hc->hw.r_dtmf |= V_ULAW_SEL;
-		HFC_outb(hc, R_DTMF_N, 102 - 1);
-		hc->hw.r_irqmsk_misc |= V_DTMF_IRQMSK;
-	}
-
-	/* conference engine */
-	if (test_bit(HFC_CHIP_ULAW, &hc->chip))
-		r_conf_en = V_CONF_EN | V_ULAW;
-	else
-		r_conf_en = V_CONF_EN;
-	if (hc->ctype != HFC_TYPE_XHFC)
-		HFC_outb(hc, R_CONF_EN, r_conf_en);
-
-	/* setting leds */
-	switch (hc->leds) {
-	case 1: /* HFC-E1 OEM */
-		if (test_bit(HFC_CHIP_WATCHDOG, &hc->chip))
-			HFC_outb(hc, R_GPIO_SEL, 0x32);
-		else
-			HFC_outb(hc, R_GPIO_SEL, 0x30);
-
-		HFC_outb(hc, R_GPIO_EN1, 0x0f);
-		HFC_outb(hc, R_GPIO_OUT1, 0x00);
-
-		HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3);
-		break;
-
-	case 2: /* HFC-4S OEM */
-	case 3:
-		HFC_outb(hc, R_GPIO_SEL, 0xf0);
-		HFC_outb(hc, R_GPIO_EN1, 0xff);
-		HFC_outb(hc, R_GPIO_OUT1, 0x00);
-		break;
-	}
-
-	if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) {
-		hc->hw.r_st_sync = 0x10; /* V_AUTO_SYNCI */
-		HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync);
-	}
-
-	/* set master clock */
-	if (hc->masterclk >= 0) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: setting ST master clock "
-			       "to port %d (0..%d)\n",
-			       __func__, hc->masterclk, hc->ports - 1);
-		hc->hw.r_st_sync |= (hc->masterclk | V_AUTO_SYNC);
-		HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync);
-	}
-
-
-
-	/* setting misc irq */
-	HFC_outb(hc, R_IRQMSK_MISC, hc->hw.r_irqmsk_misc);
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "r_irqmsk_misc.2: 0x%x\n",
-		       hc->hw.r_irqmsk_misc);
-
-	/* RAM access test */
-	HFC_outb(hc, R_RAM_ADDR0, 0);
-	HFC_outb(hc, R_RAM_ADDR1, 0);
-	HFC_outb(hc, R_RAM_ADDR2, 0);
-	for (i = 0; i < 256; i++) {
-		HFC_outb_nodebug(hc, R_RAM_ADDR0, i);
-		HFC_outb_nodebug(hc, R_RAM_DATA, ((i * 3) & 0xff));
-	}
-	for (i = 0; i < 256; i++) {
-		HFC_outb_nodebug(hc, R_RAM_ADDR0, i);
-		HFC_inb_nodebug(hc, R_RAM_DATA);
-		rval = HFC_inb_nodebug(hc, R_INT_DATA);
-		if (rval != ((i * 3) & 0xff)) {
-			printk(KERN_DEBUG
-			       "addr:%x val:%x should:%x\n", i, rval,
-			       (i * 3) & 0xff);
-			err++;
-		}
-	}
-	if (err) {
-		printk(KERN_DEBUG "aborting - %d RAM access errors\n", err);
-		err = -EIO;
-		goto out;
-	}
-
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: done\n", __func__);
-out:
-	spin_unlock_irqrestore(&hc->lock, flags);
-	return err;
-}
-
-
-/*
- * control the watchdog
- */
-static void
-hfcmulti_watchdog(struct hfc_multi *hc)
-{
-	hc->wdcount++;
-
-	if (hc->wdcount > 10) {
-		hc->wdcount = 0;
-		hc->wdbyte = hc->wdbyte == V_GPIO_OUT2 ?
-			V_GPIO_OUT3 : V_GPIO_OUT2;
-
-		/* printk("Sending Watchdog Kill %x\n",hc->wdbyte); */
-		HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3);
-		HFC_outb(hc, R_GPIO_OUT0, hc->wdbyte);
-	}
-}
-
-
-
-/*
- * output leds
- */
-static void
-hfcmulti_leds(struct hfc_multi *hc)
-{
-	unsigned long lled;
-	unsigned long leddw;
-	int i, state, active, leds;
-	struct dchannel *dch;
-	int led[4];
-
-	switch (hc->leds) {
-	case 1: /* HFC-E1 OEM */
-		/* 2 red steady:       LOS
-		 * 1 red steady:       L1 not active
-		 * 2 green steady:     L1 active
-		 * 1st green flashing: activity on TX
-		 * 2nd green flashing: activity on RX
-		 */
-		led[0] = 0;
-		led[1] = 0;
-		led[2] = 0;
-		led[3] = 0;
-		dch = hc->chan[hc->dnum[0]].dch;
-		if (dch) {
-			if (hc->chan[hc->dnum[0]].los)
-				led[1] = 1;
-			if (hc->e1_state != 1) {
-				led[0] = 1;
-				hc->flash[2] = 0;
-				hc->flash[3] = 0;
-			} else {
-				led[2] = 1;
-				led[3] = 1;
-				if (!hc->flash[2] && hc->activity_tx)
-					hc->flash[2] = poll;
-				if (!hc->flash[3] && hc->activity_rx)
-					hc->flash[3] = poll;
-				if (hc->flash[2] && hc->flash[2] < 1024)
-					led[2] = 0;
-				if (hc->flash[3] && hc->flash[3] < 1024)
-					led[3] = 0;
-				if (hc->flash[2] >= 2048)
-					hc->flash[2] = 0;
-				if (hc->flash[3] >= 2048)
-					hc->flash[3] = 0;
-				if (hc->flash[2])
-					hc->flash[2] += poll;
-				if (hc->flash[3])
-					hc->flash[3] += poll;
-			}
-		}
-		leds = (led[0] | (led[1]<<2) | (led[2]<<1) | (led[3]<<3))^0xF;
-		/* leds are inverted */
-		if (leds != (int)hc->ledstate) {
-			HFC_outb_nodebug(hc, R_GPIO_OUT1, leds);
-			hc->ledstate = leds;
-		}
-		break;
-
-	case 2: /* HFC-4S OEM */
-		/* red steady:     PH_DEACTIVATE
-		 * green steady:   PH_ACTIVATE
-		 * green flashing: activity on TX
-		 */
-		for (i = 0; i < 4; i++) {
-			state = 0;
-			active = -1;
-			dch = hc->chan[(i << 2) | 2].dch;
-			if (dch) {
-				state = dch->state;
-				if (dch->dev.D.protocol == ISDN_P_NT_S0)
-					active = 3;
-				else
-					active = 7;
-			}
-			if (state) {
-				if (state == active) {
-					led[i] = 1; /* led green */
-					hc->activity_tx |= hc->activity_rx;
-					if (!hc->flash[i] &&
-						(hc->activity_tx & (1 << i)))
-							hc->flash[i] = poll;
-					if (hc->flash[i] && hc->flash[i] < 1024)
-						led[i] = 0; /* led off */
-					if (hc->flash[i] >= 2048)
-						hc->flash[i] = 0;
-					if (hc->flash[i])
-						hc->flash[i] += poll;
-				} else {
-					led[i] = 2; /* led red */
-					hc->flash[i] = 0;
-				}
-			} else
-				led[i] = 0; /* led off */
-		}
-		if (test_bit(HFC_CHIP_B410P, &hc->chip)) {
-			leds = 0;
-			for (i = 0; i < 4; i++) {
-				if (led[i] == 1) {
-					/*green*/
-					leds |= (0x2 << (i * 2));
-				} else if (led[i] == 2) {
-					/*red*/
-					leds |= (0x1 << (i * 2));
-				}
-			}
-			if (leds != (int)hc->ledstate) {
-				vpm_out(hc, 0, 0x1a8 + 3, leds);
-				hc->ledstate = leds;
-			}
-		} else {
-			leds = ((led[3] > 0) << 0) | ((led[1] > 0) << 1) |
-				((led[0] > 0) << 2) | ((led[2] > 0) << 3) |
-				((led[3] & 1) << 4) | ((led[1] & 1) << 5) |
-				((led[0] & 1) << 6) | ((led[2] & 1) << 7);
-			if (leds != (int)hc->ledstate) {
-				HFC_outb_nodebug(hc, R_GPIO_EN1, leds & 0x0F);
-				HFC_outb_nodebug(hc, R_GPIO_OUT1, leds >> 4);
-				hc->ledstate = leds;
-			}
-		}
-		break;
-
-	case 3: /* HFC 1S/2S Beronet */
-		/* red steady:     PH_DEACTIVATE
-		 * green steady:   PH_ACTIVATE
-		 * green flashing: activity on TX
-		 */
-		for (i = 0; i < 2; i++) {
-			state = 0;
-			active = -1;
-			dch = hc->chan[(i << 2) | 2].dch;
-			if (dch) {
-				state = dch->state;
-				if (dch->dev.D.protocol == ISDN_P_NT_S0)
-					active = 3;
-				else
-					active = 7;
-			}
-			if (state) {
-				if (state == active) {
-					led[i] = 1; /* led green */
-					hc->activity_tx |= hc->activity_rx;
-					if (!hc->flash[i] &&
-						(hc->activity_tx & (1 << i)))
-							hc->flash[i] = poll;
-					if (hc->flash[i] < 1024)
-						led[i] = 0; /* led off */
-					if (hc->flash[i] >= 2048)
-						hc->flash[i] = 0;
-					if (hc->flash[i])
-						hc->flash[i] += poll;
-				} else {
-					led[i] = 2; /* led red */
-					hc->flash[i] = 0;
-				}
-			} else
-				led[i] = 0; /* led off */
-		}
-		leds = (led[0] > 0) | ((led[1] > 0) << 1) | ((led[0]&1) << 2)
-			| ((led[1]&1) << 3);
-		if (leds != (int)hc->ledstate) {
-			HFC_outb_nodebug(hc, R_GPIO_EN1,
-					 ((led[0] > 0) << 2) | ((led[1] > 0) << 3));
-			HFC_outb_nodebug(hc, R_GPIO_OUT1,
-					 ((led[0] & 1) << 2) | ((led[1] & 1) << 3));
-			hc->ledstate = leds;
-		}
-		break;
-	case 8: /* HFC 8S+ Beronet */
-		/* off:      PH_DEACTIVATE
-		 * steady:   PH_ACTIVATE
-		 * flashing: activity on TX
-		 */
-		lled = 0xff; /* leds off */
-		for (i = 0; i < 8; i++) {
-			state = 0;
-			active = -1;
-			dch = hc->chan[(i << 2) | 2].dch;
-			if (dch) {
-				state = dch->state;
-				if (dch->dev.D.protocol == ISDN_P_NT_S0)
-					active = 3;
-				else
-					active = 7;
-			}
-			if (state) {
-				if (state == active) {
-					lled &= ~(1 << i); /* led on */
-					hc->activity_tx |= hc->activity_rx;
-					if (!hc->flash[i] &&
-						(hc->activity_tx & (1 << i)))
-							hc->flash[i] = poll;
-					if (hc->flash[i] < 1024)
-						lled |= 1 << i; /* led off */
-					if (hc->flash[i] >= 2048)
-						hc->flash[i] = 0;
-					if (hc->flash[i])
-						hc->flash[i] += poll;
-				} else
-					hc->flash[i] = 0;
-			}
-		}
-		leddw = lled << 24 | lled << 16 | lled << 8 | lled;
-		if (leddw != hc->ledstate) {
-			/* HFC_outb(hc, R_BRG_PCM_CFG, 1);
-			   HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); */
-			/* was _io before */
-			HFC_outb_nodebug(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK);
-			outw(0x4000, hc->pci_iobase + 4);
-			outl(leddw, hc->pci_iobase);
-			HFC_outb_nodebug(hc, R_BRG_PCM_CFG, V_PCM_CLK);
-			hc->ledstate = leddw;
-		}
-		break;
-	}
-	hc->activity_tx = 0;
-	hc->activity_rx = 0;
-}
-/*
- * read dtmf coefficients
- */
-
-static void
-hfcmulti_dtmf(struct hfc_multi *hc)
-{
-	s32		*coeff;
-	u_int		mantissa;
-	int		co, ch;
-	struct bchannel	*bch = NULL;
-	u8		exponent;
-	int		dtmf = 0;
-	int		addr;
-	u16		w_float;
-	struct sk_buff	*skb;
-	struct mISDNhead *hh;
-
-	if (debug & DEBUG_HFCMULTI_DTMF)
-		printk(KERN_DEBUG "%s: dtmf detection irq\n", __func__);
-	for (ch = 0; ch <= 31; ch++) {
-		/* only process enabled B-channels */
-		bch = hc->chan[ch].bch;
-		if (!bch)
-			continue;
-		if (!hc->created[hc->chan[ch].port])
-			continue;
-		if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
-			continue;
-		if (debug & DEBUG_HFCMULTI_DTMF)
-			printk(KERN_DEBUG "%s: dtmf channel %d:",
-			       __func__, ch);
-		coeff = &(hc->chan[ch].coeff[hc->chan[ch].coeff_count * 16]);
-		dtmf = 1;
-		for (co = 0; co < 8; co++) {
-			/* read W(n-1) coefficient */
-			addr = hc->DTMFbase + ((co << 7) | (ch << 2));
-			HFC_outb_nodebug(hc, R_RAM_ADDR0, addr);
-			HFC_outb_nodebug(hc, R_RAM_ADDR1, addr >> 8);
-			HFC_outb_nodebug(hc, R_RAM_ADDR2, (addr >> 16)
-					 | V_ADDR_INC);
-			w_float = HFC_inb_nodebug(hc, R_RAM_DATA);
-			w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8);
-			if (debug & DEBUG_HFCMULTI_DTMF)
-				printk(" %04x", w_float);
-
-			/* decode float (see chip doc) */
-			mantissa = w_float & 0x0fff;
-			if (w_float & 0x8000)
-				mantissa |= 0xfffff000;
-			exponent = (w_float >> 12) & 0x7;
-			if (exponent) {
-				mantissa ^= 0x1000;
-				mantissa <<= (exponent - 1);
-			}
-
-			/* store coefficient */
-			coeff[co << 1] = mantissa;
-
-			/* read W(n) coefficient */
-			w_float = HFC_inb_nodebug(hc, R_RAM_DATA);
-			w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8);
-			if (debug & DEBUG_HFCMULTI_DTMF)
-				printk(" %04x", w_float);
-
-			/* decode float (see chip doc) */
-			mantissa = w_float & 0x0fff;
-			if (w_float & 0x8000)
-				mantissa |= 0xfffff000;
-			exponent = (w_float >> 12) & 0x7;
-			if (exponent) {
-				mantissa ^= 0x1000;
-				mantissa <<= (exponent - 1);
-			}
-
-			/* store coefficient */
-			coeff[(co << 1) | 1] = mantissa;
-		}
-		if (debug & DEBUG_HFCMULTI_DTMF)
-			printk(" DTMF ready %08x %08x %08x %08x "
-			       "%08x %08x %08x %08x\n",
-			       coeff[0], coeff[1], coeff[2], coeff[3],
-			       coeff[4], coeff[5], coeff[6], coeff[7]);
-		hc->chan[ch].coeff_count++;
-		if (hc->chan[ch].coeff_count == 8) {
-			hc->chan[ch].coeff_count = 0;
-			skb = mI_alloc_skb(512, GFP_ATOMIC);
-			if (!skb) {
-				printk(KERN_DEBUG "%s: No memory for skb\n",
-				       __func__);
-				continue;
-			}
-			hh = mISDN_HEAD_P(skb);
-			hh->prim = PH_CONTROL_IND;
-			hh->id = DTMF_HFC_COEF;
-			skb_put_data(skb, hc->chan[ch].coeff, 512);
-			recv_Bchannel_skb(bch, skb);
-		}
-	}
-
-	/* restart DTMF processing */
-	hc->dtmf = dtmf;
-	if (dtmf)
-		HFC_outb_nodebug(hc, R_DTMF, hc->hw.r_dtmf | V_RST_DTMF);
-}
-
-
-/*
- * fill fifo as much as possible
- */
-
-static void
-hfcmulti_tx(struct hfc_multi *hc, int ch)
-{
-	int i, ii, temp, tmp_len, len = 0;
-	int Zspace, z1, z2; /* must be int for calculation */
-	int Fspace, f1, f2;
-	u_char *d;
-	int *txpending, slot_tx;
-	struct	bchannel *bch;
-	struct  dchannel *dch;
-	struct  sk_buff **sp = NULL;
-	int *idxp;
-
-	bch = hc->chan[ch].bch;
-	dch = hc->chan[ch].dch;
-	if ((!dch) && (!bch))
-		return;
-
-	txpending = &hc->chan[ch].txpending;
-	slot_tx = hc->chan[ch].slot_tx;
-	if (dch) {
-		if (!test_bit(FLG_ACTIVE, &dch->Flags))
-			return;
-		sp = &dch->tx_skb;
-		idxp = &dch->tx_idx;
-	} else {
-		if (!test_bit(FLG_ACTIVE, &bch->Flags))
-			return;
-		sp = &bch->tx_skb;
-		idxp = &bch->tx_idx;
-	}
-	if (*sp)
-		len = (*sp)->len;
-
-	if ((!len) && *txpending != 1)
-		return; /* no data */
-
-	if (test_bit(HFC_CHIP_B410P, &hc->chip) &&
-	    (hc->chan[ch].protocol == ISDN_P_B_RAW) &&
-	    (hc->chan[ch].slot_rx < 0) &&
-	    (hc->chan[ch].slot_tx < 0))
-		HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch << 1));
-	else
-		HFC_outb_nodebug(hc, R_FIFO, ch << 1);
-	HFC_wait_nodebug(hc);
-
-	if (*txpending == 2) {
-		/* reset fifo */
-		HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F);
-		HFC_wait_nodebug(hc);
-		HFC_outb(hc, A_SUBCH_CFG, 0);
-		*txpending = 1;
-	}
-next_frame:
-	if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
-		f1 = HFC_inb_nodebug(hc, A_F1);
-		f2 = HFC_inb_nodebug(hc, A_F2);
-		while (f2 != (temp = HFC_inb_nodebug(hc, A_F2))) {
-			if (debug & DEBUG_HFCMULTI_FIFO)
-				printk(KERN_DEBUG
-				       "%s(card %d): reread f2 because %d!=%d\n",
-				       __func__, hc->id + 1, temp, f2);
-			f2 = temp; /* repeat until F2 is equal */
-		}
-		Fspace = f2 - f1 - 1;
-		if (Fspace < 0)
-			Fspace += hc->Flen;
-		/*
-		 * Old FIFO handling doesn't give us the current Z2 read
-		 * pointer, so we cannot send the next frame before the fifo
-		 * is empty. It makes no difference except for a slightly
-		 * lower performance.
-		 */
-		if (test_bit(HFC_CHIP_REVISION0, &hc->chip)) {
-			if (f1 != f2)
-				Fspace = 0;
-			else
-				Fspace = 1;
-		}
-		/* one frame only for ST D-channels, to allow resending */
-		if (hc->ctype != HFC_TYPE_E1 && dch) {
-			if (f1 != f2)
-				Fspace = 0;
-		}
-		/* F-counter full condition */
-		if (Fspace == 0)
-			return;
-	}
-	z1 = HFC_inw_nodebug(hc, A_Z1) - hc->Zmin;
-	z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin;
-	while (z2 != (temp = (HFC_inw_nodebug(hc, A_Z2) - hc->Zmin))) {
-		if (debug & DEBUG_HFCMULTI_FIFO)
-			printk(KERN_DEBUG "%s(card %d): reread z2 because "
-			       "%d!=%d\n", __func__, hc->id + 1, temp, z2);
-		z2 = temp; /* repeat unti Z2 is equal */
-	}
-	hc->chan[ch].Zfill = z1 - z2;
-	if (hc->chan[ch].Zfill < 0)
-		hc->chan[ch].Zfill += hc->Zlen;
-	Zspace = z2 - z1;
-	if (Zspace <= 0)
-		Zspace += hc->Zlen;
-	Zspace -= 4; /* keep not too full, so pointers will not overrun */
-	/* fill transparent data only to maximum transparent load (minus 4) */
-	if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags))
-		Zspace = Zspace - hc->Zlen + hc->max_trans;
-	if (Zspace <= 0) /* no space of 4 bytes */
-		return;
-
-	/* if no data */
-	if (!len) {
-		if (z1 == z2) { /* empty */
-			/* if done with FIFO audio data during PCM connection */
-			if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) &&
-			    *txpending && slot_tx >= 0) {
-				if (debug & DEBUG_HFCMULTI_MODE)
-					printk(KERN_DEBUG
-					       "%s: reconnecting PCM due to no "
-					       "more FIFO data: channel %d "
-					       "slot_tx %d\n",
-					       __func__, ch, slot_tx);
-				/* connect slot */
-				if (hc->ctype == HFC_TYPE_XHFC)
-					HFC_outb(hc, A_CON_HDLC, 0xc0
-						 | 0x07 << 2 | V_HDLC_TRP | V_IFF);
-				/* Enable FIFO, no interrupt */
-				else
-					HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
-						 V_HDLC_TRP | V_IFF);
-				HFC_outb_nodebug(hc, R_FIFO, ch << 1 | 1);
-				HFC_wait_nodebug(hc);
-				if (hc->ctype == HFC_TYPE_XHFC)
-					HFC_outb(hc, A_CON_HDLC, 0xc0
-						 | 0x07 << 2 | V_HDLC_TRP | V_IFF);
-				/* Enable FIFO, no interrupt */
-				else
-					HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
-						 V_HDLC_TRP | V_IFF);
-				HFC_outb_nodebug(hc, R_FIFO, ch << 1);
-				HFC_wait_nodebug(hc);
-			}
-			*txpending = 0;
-		}
-		return; /* no data */
-	}
-
-	/* "fill fifo if empty" feature */
-	if (bch && test_bit(FLG_FILLEMPTY, &bch->Flags)
-	    && !test_bit(FLG_HDLC, &bch->Flags) && z2 == z1) {
-		if (debug & DEBUG_HFCMULTI_FILL)
-			printk(KERN_DEBUG "%s: buffer empty, so we have "
-			       "underrun\n", __func__);
-		/* fill buffer, to prevent future underrun */
-		hc->write_fifo(hc, hc->silence_data, poll >> 1);
-		Zspace -= (poll >> 1);
-	}
-
-	/* if audio data and connected slot */
-	if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && (!*txpending)
-	    && slot_tx >= 0) {
-		if (debug & DEBUG_HFCMULTI_MODE)
-			printk(KERN_DEBUG "%s: disconnecting PCM due to "
-			       "FIFO data: channel %d slot_tx %d\n",
-			       __func__, ch, slot_tx);
-		/* disconnect slot */
-		if (hc->ctype == HFC_TYPE_XHFC)
-			HFC_outb(hc, A_CON_HDLC, 0x80
-				 | 0x07 << 2 | V_HDLC_TRP | V_IFF);
-		/* Enable FIFO, no interrupt */
-		else
-			HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 |
-				 V_HDLC_TRP | V_IFF);
-		HFC_outb_nodebug(hc, R_FIFO, ch << 1 | 1);
-		HFC_wait_nodebug(hc);
-		if (hc->ctype == HFC_TYPE_XHFC)
-			HFC_outb(hc, A_CON_HDLC, 0x80
-				 | 0x07 << 2 | V_HDLC_TRP | V_IFF);
-		/* Enable FIFO, no interrupt */
-		else
-			HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 |
-				 V_HDLC_TRP | V_IFF);
-		HFC_outb_nodebug(hc, R_FIFO, ch << 1);
-		HFC_wait_nodebug(hc);
-	}
-	*txpending = 1;
-
-	/* show activity */
-	if (dch)
-		hc->activity_tx |= 1 << hc->chan[ch].port;
-
-	/* fill fifo to what we have left */
-	ii = len;
-	if (dch || test_bit(FLG_HDLC, &bch->Flags))
-		temp = 1;
-	else
-		temp = 0;
-	i = *idxp;
-	d = (*sp)->data + i;
-	if (ii - i > Zspace)
-		ii = Zspace + i;
-	if (debug & DEBUG_HFCMULTI_FIFO)
-		printk(KERN_DEBUG "%s(card %d): fifo(%d) has %d bytes space "
-		       "left (z1=%04x, z2=%04x) sending %d of %d bytes %s\n",
-		       __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i,
-		       temp ? "HDLC" : "TRANS");
-
-	/* Have to prep the audio data */
-	hc->write_fifo(hc, d, ii - i);
-	hc->chan[ch].Zfill += ii - i;
-	*idxp = ii;
-
-	/* if not all data has been written */
-	if (ii != len) {
-		/* NOTE: fifo is started by the calling function */
-		return;
-	}
-
-	/* if all data has been written, terminate frame */
-	if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
-		/* increment f-counter */
-		HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_INC_F);
-		HFC_wait_nodebug(hc);
-	}
-
-	tmp_len = (*sp)->len;
-	dev_kfree_skb(*sp);
-	/* check for next frame */
-	if (bch && get_next_bframe(bch)) {
-		len = tmp_len;
-		goto next_frame;
-	}
-	if (dch && get_next_dframe(dch)) {
-		len = tmp_len;
-		goto next_frame;
-	}
-
-	/*
-	 * now we have no more data, so in case of transparent,
-	 * we set the last byte in fifo to 'silence' in case we will get
-	 * no more data at all. this prevents sending an undefined value.
-	 */
-	if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags))
-		HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
-}
-
-
-/* NOTE: only called if E1 card is in active state */
-static void
-hfcmulti_rx(struct hfc_multi *hc, int ch)
-{
-	int temp;
-	int Zsize, z1, z2 = 0; /* = 0, to make GCC happy */
-	int f1 = 0, f2 = 0; /* = 0, to make GCC happy */
-	int again = 0;
-	struct	bchannel *bch;
-	struct  dchannel *dch = NULL;
-	struct sk_buff	*skb, **sp = NULL;
-	int	maxlen;
-
-	bch = hc->chan[ch].bch;
-	if (bch) {
-		if (!test_bit(FLG_ACTIVE, &bch->Flags))
-			return;
-	} else if (hc->chan[ch].dch) {
-		dch = hc->chan[ch].dch;
-		if (!test_bit(FLG_ACTIVE, &dch->Flags))
-			return;
-	} else {
-		return;
-	}
-next_frame:
-	/* on first AND before getting next valid frame, R_FIFO must be written
-	   to. */
-	if (test_bit(HFC_CHIP_B410P, &hc->chip) &&
-	    (hc->chan[ch].protocol == ISDN_P_B_RAW) &&
-	    (hc->chan[ch].slot_rx < 0) &&
-	    (hc->chan[ch].slot_tx < 0))
-		HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch << 1) | 1);
-	else
-		HFC_outb_nodebug(hc, R_FIFO, (ch << 1) | 1);
-	HFC_wait_nodebug(hc);
-
-	/* ignore if rx is off BUT change fifo (above) to start pending TX */
-	if (hc->chan[ch].rx_off) {
-		if (bch)
-			bch->dropcnt += poll; /* not exact but fair enough */
-		return;
-	}
-
-	if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
-		f1 = HFC_inb_nodebug(hc, A_F1);
-		while (f1 != (temp = HFC_inb_nodebug(hc, A_F1))) {
-			if (debug & DEBUG_HFCMULTI_FIFO)
-				printk(KERN_DEBUG
-				       "%s(card %d): reread f1 because %d!=%d\n",
-				       __func__, hc->id + 1, temp, f1);
-			f1 = temp; /* repeat until F1 is equal */
-		}
-		f2 = HFC_inb_nodebug(hc, A_F2);
-	}
-	z1 = HFC_inw_nodebug(hc, A_Z1) - hc->Zmin;
-	while (z1 != (temp = (HFC_inw_nodebug(hc, A_Z1) - hc->Zmin))) {
-		if (debug & DEBUG_HFCMULTI_FIFO)
-			printk(KERN_DEBUG "%s(card %d): reread z2 because "
-			       "%d!=%d\n", __func__, hc->id + 1, temp, z2);
-		z1 = temp; /* repeat until Z1 is equal */
-	}
-	z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin;
-	Zsize = z1 - z2;
-	if ((dch || test_bit(FLG_HDLC, &bch->Flags)) && f1 != f2)
-		/* complete hdlc frame */
-		Zsize++;
-	if (Zsize < 0)
-		Zsize += hc->Zlen;
-	/* if buffer is empty */
-	if (Zsize <= 0)
-		return;
-
-	if (bch) {
-		maxlen = bchannel_get_rxbuf(bch, Zsize);
-		if (maxlen < 0) {
-			pr_warn("card%d.B%d: No bufferspace for %d bytes\n",
-				hc->id + 1, bch->nr, Zsize);
-			return;
-		}
-		sp = &bch->rx_skb;
-		maxlen = bch->maxlen;
-	} else { /* Dchannel */
-		sp = &dch->rx_skb;
-		maxlen = dch->maxlen + 3;
-		if (*sp == NULL) {
-			*sp = mI_alloc_skb(maxlen, GFP_ATOMIC);
-			if (*sp == NULL) {
-				pr_warn("card%d: No mem for dch rx_skb\n",
-					hc->id + 1);
-				return;
-			}
-		}
-	}
-	/* show activity */
-	if (dch)
-		hc->activity_rx |= 1 << hc->chan[ch].port;
-
-	/* empty fifo with what we have */
-	if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
-		if (debug & DEBUG_HFCMULTI_FIFO)
-			printk(KERN_DEBUG "%s(card %d): fifo(%d) reading %d "
-			       "bytes (z1=%04x, z2=%04x) HDLC %s (f1=%d, f2=%d) "
-			       "got=%d (again %d)\n", __func__, hc->id + 1, ch,
-			       Zsize, z1, z2, (f1 == f2) ? "fragment" : "COMPLETE",
-			       f1, f2, Zsize + (*sp)->len, again);
-		/* HDLC */
-		if ((Zsize + (*sp)->len) > maxlen) {
-			if (debug & DEBUG_HFCMULTI_FIFO)
-				printk(KERN_DEBUG
-				       "%s(card %d): hdlc-frame too large.\n",
-				       __func__, hc->id + 1);
-			skb_trim(*sp, 0);
-			HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F);
-			HFC_wait_nodebug(hc);
-			return;
-		}
-
-		hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize);
-
-		if (f1 != f2) {
-			/* increment Z2,F2-counter */
-			HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_INC_F);
-			HFC_wait_nodebug(hc);
-			/* check size */
-			if ((*sp)->len < 4) {
-				if (debug & DEBUG_HFCMULTI_FIFO)
-					printk(KERN_DEBUG
-					       "%s(card %d): Frame below minimum "
-					       "size\n", __func__, hc->id + 1);
-				skb_trim(*sp, 0);
-				goto next_frame;
-			}
-			/* there is at least one complete frame, check crc */
-			if ((*sp)->data[(*sp)->len - 1]) {
-				if (debug & DEBUG_HFCMULTI_CRC)
-					printk(KERN_DEBUG
-					       "%s: CRC-error\n", __func__);
-				skb_trim(*sp, 0);
-				goto next_frame;
-			}
-			skb_trim(*sp, (*sp)->len - 3);
-			if ((*sp)->len < MISDN_COPY_SIZE) {
-				skb = *sp;
-				*sp = mI_alloc_skb(skb->len, GFP_ATOMIC);
-				if (*sp) {
-					skb_put_data(*sp, skb->data, skb->len);
-					skb_trim(skb, 0);
-				} else {
-					printk(KERN_DEBUG "%s: No mem\n",
-					       __func__);
-					*sp = skb;
-					skb = NULL;
-				}
-			} else {
-				skb = NULL;
-			}
-			if (debug & DEBUG_HFCMULTI_FIFO) {
-				printk(KERN_DEBUG "%s(card %d):",
-				       __func__, hc->id + 1);
-				temp = 0;
-				while (temp < (*sp)->len)
-					printk(" %02x", (*sp)->data[temp++]);
-				printk("\n");
-			}
-			if (dch)
-				recv_Dchannel(dch);
-			else
-				recv_Bchannel(bch, MISDN_ID_ANY, false);
-			*sp = skb;
-			again++;
-			goto next_frame;
-		}
-		/* there is an incomplete frame */
-	} else {
-		/* transparent */
-		hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize);
-		if (debug & DEBUG_HFCMULTI_FIFO)
-			printk(KERN_DEBUG
-			       "%s(card %d): fifo(%d) reading %d bytes "
-			       "(z1=%04x, z2=%04x) TRANS\n",
-			       __func__, hc->id + 1, ch, Zsize, z1, z2);
-		/* only bch is transparent */
-		recv_Bchannel(bch, hc->chan[ch].Zfill, false);
-	}
-}
-
-
-/*
- * Interrupt handler
- */
-static void
-signal_state_up(struct dchannel *dch, int info, char *msg)
-{
-	struct sk_buff	*skb;
-	int		id, data = info;
-
-	if (debug & DEBUG_HFCMULTI_STATE)
-		printk(KERN_DEBUG "%s: %s\n", __func__, msg);
-
-	id = TEI_SAPI | (GROUP_TEI << 8); /* manager address */
-
-	skb = _alloc_mISDN_skb(MPH_INFORMATION_IND, id, sizeof(data), &data,
-			       GFP_ATOMIC);
-	if (!skb)
-		return;
-	recv_Dchannel_skb(dch, skb);
-}
-
-static inline void
-handle_timer_irq(struct hfc_multi *hc)
-{
-	int		ch, temp;
-	struct dchannel	*dch;
-	u_long		flags;
-
-	/* process queued resync jobs */
-	if (hc->e1_resync) {
-		/* lock, so e1_resync gets not changed */
-		spin_lock_irqsave(&HFClock, flags);
-		if (hc->e1_resync & 1) {
-			if (debug & DEBUG_HFCMULTI_PLXSD)
-				printk(KERN_DEBUG "Enable SYNC_I\n");
-			HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC);
-			/* disable JATT, if RX_SYNC is set */
-			if (test_bit(HFC_CHIP_RX_SYNC, &hc->chip))
-				HFC_outb(hc, R_SYNC_OUT, V_SYNC_E1_RX);
-		}
-		if (hc->e1_resync & 2) {
-			if (debug & DEBUG_HFCMULTI_PLXSD)
-				printk(KERN_DEBUG "Enable jatt PLL\n");
-			HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS);
-		}
-		if (hc->e1_resync & 4) {
-			if (debug & DEBUG_HFCMULTI_PLXSD)
-				printk(KERN_DEBUG
-				       "Enable QUARTZ for HFC-E1\n");
-			/* set jatt to quartz */
-			HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC
-				 | V_JATT_OFF);
-			/* switch to JATT, in case it is not already */
-			HFC_outb(hc, R_SYNC_OUT, 0);
-		}
-		hc->e1_resync = 0;
-		spin_unlock_irqrestore(&HFClock, flags);
-	}
-
-	if (hc->ctype != HFC_TYPE_E1 || hc->e1_state == 1)
-		for (ch = 0; ch <= 31; ch++) {
-			if (hc->created[hc->chan[ch].port]) {
-				hfcmulti_tx(hc, ch);
-				/* fifo is started when switching to rx-fifo */
-				hfcmulti_rx(hc, ch);
-				if (hc->chan[ch].dch &&
-				    hc->chan[ch].nt_timer > -1) {
-					dch = hc->chan[ch].dch;
-					if (!(--hc->chan[ch].nt_timer)) {
-						schedule_event(dch,
-							       FLG_PHCHANGE);
-						if (debug &
-						    DEBUG_HFCMULTI_STATE)
-							printk(KERN_DEBUG
-							       "%s: nt_timer at "
-							       "state %x\n",
-							       __func__,
-							       dch->state);
-					}
-				}
-			}
-		}
-	if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) {
-		dch = hc->chan[hc->dnum[0]].dch;
-		/* LOS */
-		temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;
-		hc->chan[hc->dnum[0]].los = temp;
-		if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
-			if (!temp && hc->chan[hc->dnum[0]].los)
-				signal_state_up(dch, L1_SIGNAL_LOS_ON,
-						"LOS detected");
-			if (temp && !hc->chan[hc->dnum[0]].los)
-				signal_state_up(dch, L1_SIGNAL_LOS_OFF,
-						"LOS gone");
-		}
-		if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dnum[0]].cfg)) {
-			/* AIS */
-			temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS;
-			if (!temp && hc->chan[hc->dnum[0]].ais)
-				signal_state_up(dch, L1_SIGNAL_AIS_ON,
-						"AIS detected");
-			if (temp && !hc->chan[hc->dnum[0]].ais)
-				signal_state_up(dch, L1_SIGNAL_AIS_OFF,
-						"AIS gone");
-			hc->chan[hc->dnum[0]].ais = temp;
-		}
-		if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dnum[0]].cfg)) {
-			/* SLIP */
-			temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX;
-			if (!temp && hc->chan[hc->dnum[0]].slip_rx)
-				signal_state_up(dch, L1_SIGNAL_SLIP_RX,
-						" bit SLIP detected RX");
-			hc->chan[hc->dnum[0]].slip_rx = temp;
-			temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX;
-			if (!temp && hc->chan[hc->dnum[0]].slip_tx)
-				signal_state_up(dch, L1_SIGNAL_SLIP_TX,
-						" bit SLIP detected TX");
-			hc->chan[hc->dnum[0]].slip_tx = temp;
-		}
-		if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dnum[0]].cfg)) {
-			/* RDI */
-			temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A;
-			if (!temp && hc->chan[hc->dnum[0]].rdi)
-				signal_state_up(dch, L1_SIGNAL_RDI_ON,
-						"RDI detected");
-			if (temp && !hc->chan[hc->dnum[0]].rdi)
-				signal_state_up(dch, L1_SIGNAL_RDI_OFF,
-						"RDI gone");
-			hc->chan[hc->dnum[0]].rdi = temp;
-		}
-		temp = HFC_inb_nodebug(hc, R_JATT_DIR);
-		switch (hc->chan[hc->dnum[0]].sync) {
-		case 0:
-			if ((temp & 0x60) == 0x60) {
-				if (debug & DEBUG_HFCMULTI_SYNC)
-					printk(KERN_DEBUG
-					       "%s: (id=%d) E1 now "
-					       "in clock sync\n",
-					       __func__, hc->id);
-				HFC_outb(hc, R_RX_OFF,
-				    hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
-				HFC_outb(hc, R_TX_OFF,
-				    hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
-				hc->chan[hc->dnum[0]].sync = 1;
-				goto check_framesync;
-			}
-			break;
-		case 1:
-			if ((temp & 0x60) != 0x60) {
-				if (debug & DEBUG_HFCMULTI_SYNC)
-					printk(KERN_DEBUG
-					       "%s: (id=%d) E1 "
-					       "lost clock sync\n",
-					       __func__, hc->id);
-				hc->chan[hc->dnum[0]].sync = 0;
-				break;
-			}
-		check_framesync:
-			temp = HFC_inb_nodebug(hc, R_SYNC_STA);
-			if (temp == 0x27) {
-				if (debug & DEBUG_HFCMULTI_SYNC)
-					printk(KERN_DEBUG
-					       "%s: (id=%d) E1 "
-					       "now in frame sync\n",
-					       __func__, hc->id);
-				hc->chan[hc->dnum[0]].sync = 2;
-			}
-			break;
-		case 2:
-			if ((temp & 0x60) != 0x60) {
-				if (debug & DEBUG_HFCMULTI_SYNC)
-					printk(KERN_DEBUG
-					       "%s: (id=%d) E1 lost "
-					       "clock & frame sync\n",
-					       __func__, hc->id);
-				hc->chan[hc->dnum[0]].sync = 0;
-				break;
-			}
-			temp = HFC_inb_nodebug(hc, R_SYNC_STA);
-			if (temp != 0x27) {
-				if (debug & DEBUG_HFCMULTI_SYNC)
-					printk(KERN_DEBUG
-					       "%s: (id=%d) E1 "
-					       "lost frame sync\n",
-					       __func__, hc->id);
-				hc->chan[hc->dnum[0]].sync = 1;
-			}
-			break;
-		}
-	}
-
-	if (test_bit(HFC_CHIP_WATCHDOG, &hc->chip))
-		hfcmulti_watchdog(hc);
-
-	if (hc->leds)
-		hfcmulti_leds(hc);
-}
-
-static void
-ph_state_irq(struct hfc_multi *hc, u_char r_irq_statech)
-{
-	struct dchannel	*dch;
-	int		ch;
-	int		active;
-	u_char		st_status, temp;
-
-	/* state machine */
-	for (ch = 0; ch <= 31; ch++) {
-		if (hc->chan[ch].dch) {
-			dch = hc->chan[ch].dch;
-			if (r_irq_statech & 1) {
-				HFC_outb_nodebug(hc, R_ST_SEL,
-						 hc->chan[ch].port);
-				/* undocumented: delay after R_ST_SEL */
-				udelay(1);
-				/* undocumented: status changes during read */
-				st_status = HFC_inb_nodebug(hc, A_ST_RD_STATE);
-				while (st_status != (temp =
-						     HFC_inb_nodebug(hc, A_ST_RD_STATE))) {
-					if (debug & DEBUG_HFCMULTI_STATE)
-						printk(KERN_DEBUG "%s: reread "
-						       "STATE because %d!=%d\n",
-						       __func__, temp,
-						       st_status);
-					st_status = temp; /* repeat */
-				}
-
-				/* Speech Design TE-sync indication */
-				if (test_bit(HFC_CHIP_PLXSD, &hc->chip) &&
-				    dch->dev.D.protocol == ISDN_P_TE_S0) {
-					if (st_status & V_FR_SYNC_ST)
-						hc->syncronized |=
-							(1 << hc->chan[ch].port);
-					else
-						hc->syncronized &=
-							~(1 << hc->chan[ch].port);
-				}
-				dch->state = st_status & 0x0f;
-				if (dch->dev.D.protocol == ISDN_P_NT_S0)
-					active = 3;
-				else
-					active = 7;
-				if (dch->state == active) {
-					HFC_outb_nodebug(hc, R_FIFO,
-							 (ch << 1) | 1);
-					HFC_wait_nodebug(hc);
-					HFC_outb_nodebug(hc,
-							 R_INC_RES_FIFO, V_RES_F);
-					HFC_wait_nodebug(hc);
-					dch->tx_idx = 0;
-				}
-				schedule_event(dch, FLG_PHCHANGE);
-				if (debug & DEBUG_HFCMULTI_STATE)
-					printk(KERN_DEBUG
-					       "%s: S/T newstate %x port %d\n",
-					       __func__, dch->state,
-					       hc->chan[ch].port);
-			}
-			r_irq_statech >>= 1;
-		}
-	}
-	if (test_bit(HFC_CHIP_PLXSD, &hc->chip))
-		plxsd_checksync(hc, 0);
-}
-
-static void
-fifo_irq(struct hfc_multi *hc, int block)
-{
-	int	ch, j;
-	struct dchannel	*dch;
-	struct bchannel	*bch;
-	u_char r_irq_fifo_bl;
-
-	r_irq_fifo_bl = HFC_inb_nodebug(hc, R_IRQ_FIFO_BL0 + block);
-	j = 0;
-	while (j < 8) {
-		ch = (block << 2) + (j >> 1);
-		dch = hc->chan[ch].dch;
-		bch = hc->chan[ch].bch;
-		if (((!dch) && (!bch)) || (!hc->created[hc->chan[ch].port])) {
-			j += 2;
-			continue;
-		}
-		if (dch && (r_irq_fifo_bl & (1 << j)) &&
-		    test_bit(FLG_ACTIVE, &dch->Flags)) {
-			hfcmulti_tx(hc, ch);
-			/* start fifo */
-			HFC_outb_nodebug(hc, R_FIFO, 0);
-			HFC_wait_nodebug(hc);
-		}
-		if (bch && (r_irq_fifo_bl & (1 << j)) &&
-		    test_bit(FLG_ACTIVE, &bch->Flags)) {
-			hfcmulti_tx(hc, ch);
-			/* start fifo */
-			HFC_outb_nodebug(hc, R_FIFO, 0);
-			HFC_wait_nodebug(hc);
-		}
-		j++;
-		if (dch && (r_irq_fifo_bl & (1 << j)) &&
-		    test_bit(FLG_ACTIVE, &dch->Flags)) {
-			hfcmulti_rx(hc, ch);
-		}
-		if (bch && (r_irq_fifo_bl & (1 << j)) &&
-		    test_bit(FLG_ACTIVE, &bch->Flags)) {
-			hfcmulti_rx(hc, ch);
-		}
-		j++;
-	}
-}
-
-#ifdef IRQ_DEBUG
-int irqsem;
-#endif
-static irqreturn_t
-hfcmulti_interrupt(int intno, void *dev_id)
-{
-#ifdef IRQCOUNT_DEBUG
-	static int iq1 = 0, iq2 = 0, iq3 = 0, iq4 = 0,
-		iq5 = 0, iq6 = 0, iqcnt = 0;
-#endif
-	struct hfc_multi	*hc = dev_id;
-	struct dchannel		*dch;
-	u_char			r_irq_statech, status, r_irq_misc, r_irq_oview;
-	int			i;
-	void __iomem		*plx_acc;
-	u_short			wval;
-	u_char			e1_syncsta, temp, temp2;
-	u_long			flags;
-
-	if (!hc) {
-		printk(KERN_ERR "HFC-multi: Spurious interrupt!\n");
-		return IRQ_NONE;
-	}
-
-	spin_lock(&hc->lock);
-
-#ifdef IRQ_DEBUG
-	if (irqsem)
-		printk(KERN_ERR "irq for card %d during irq from "
-		       "card %d, this is no bug.\n", hc->id + 1, irqsem);
-	irqsem = hc->id + 1;
-#endif
-#ifdef CONFIG_MISDN_HFCMULTI_8xx
-	if (hc->immap->im_cpm.cp_pbdat & hc->pb_irqmsk)
-		goto irq_notforus;
-#endif
-	if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-		spin_lock_irqsave(&plx_lock, flags);
-		plx_acc = hc->plx_membase + PLX_INTCSR;
-		wval = readw(plx_acc);
-		spin_unlock_irqrestore(&plx_lock, flags);
-		if (!(wval & PLX_INTCSR_LINTI1_STATUS))
-			goto irq_notforus;
-	}
-
-	status = HFC_inb_nodebug(hc, R_STATUS);
-	r_irq_statech = HFC_inb_nodebug(hc, R_IRQ_STATECH);
-#ifdef IRQCOUNT_DEBUG
-	if (r_irq_statech)
-		iq1++;
-	if (status & V_DTMF_STA)
-		iq2++;
-	if (status & V_LOST_STA)
-		iq3++;
-	if (status & V_EXT_IRQSTA)
-		iq4++;
-	if (status & V_MISC_IRQSTA)
-		iq5++;
-	if (status & V_FR_IRQSTA)
-		iq6++;
-	if (iqcnt++ > 5000) {
-		printk(KERN_ERR "iq1:%x iq2:%x iq3:%x iq4:%x iq5:%x iq6:%x\n",
-		       iq1, iq2, iq3, iq4, iq5, iq6);
-		iqcnt = 0;
-	}
-#endif
-
-	if (!r_irq_statech &&
-	    !(status & (V_DTMF_STA | V_LOST_STA | V_EXT_IRQSTA |
-			V_MISC_IRQSTA | V_FR_IRQSTA))) {
-		/* irq is not for us */
-		goto irq_notforus;
-	}
-	hc->irqcnt++;
-	if (r_irq_statech) {
-		if (hc->ctype != HFC_TYPE_E1)
-			ph_state_irq(hc, r_irq_statech);
-	}
-	if (status & V_LOST_STA) {
-		/* LOST IRQ */
-		HFC_outb(hc, R_INC_RES_FIFO, V_RES_LOST); /* clear irq! */
-	}
-	if (status & V_MISC_IRQSTA) {
-		/* misc IRQ */
-		r_irq_misc = HFC_inb_nodebug(hc, R_IRQ_MISC);
-		r_irq_misc &= hc->hw.r_irqmsk_misc; /* ignore disabled irqs */
-		if (r_irq_misc & V_STA_IRQ) {
-			if (hc->ctype == HFC_TYPE_E1) {
-				/* state machine */
-				dch = hc->chan[hc->dnum[0]].dch;
-				e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA);
-				if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
-				    && hc->e1_getclock) {
-					if (e1_syncsta & V_FR_SYNC_E1)
-						hc->syncronized = 1;
-					else
-						hc->syncronized = 0;
-				}
-				/* undocumented: status changes during read */
-				temp = HFC_inb_nodebug(hc, R_E1_RD_STA);
-				while (temp != (temp2 =
-						      HFC_inb_nodebug(hc, R_E1_RD_STA))) {
-					if (debug & DEBUG_HFCMULTI_STATE)
-						printk(KERN_DEBUG "%s: reread "
-						       "STATE because %d!=%d\n",
-						    __func__, temp, temp2);
-					temp = temp2; /* repeat */
-				}
-				/* broadcast state change to all fragments */
-				if (debug & DEBUG_HFCMULTI_STATE)
-					printk(KERN_DEBUG
-					       "%s: E1 (id=%d) newstate %x\n",
-					    __func__, hc->id, temp & 0x7);
-				for (i = 0; i < hc->ports; i++) {
-					dch = hc->chan[hc->dnum[i]].dch;
-					dch->state = temp & 0x7;
-					schedule_event(dch, FLG_PHCHANGE);
-				}
-
-				if (test_bit(HFC_CHIP_PLXSD, &hc->chip))
-					plxsd_checksync(hc, 0);
-			}
-		}
-		if (r_irq_misc & V_TI_IRQ) {
-			if (hc->iclock_on)
-				mISDN_clock_update(hc->iclock, poll, NULL);
-			handle_timer_irq(hc);
-		}
-
-		if (r_irq_misc & V_DTMF_IRQ)
-			hfcmulti_dtmf(hc);
-
-		if (r_irq_misc & V_IRQ_PROC) {
-			static int irq_proc_cnt;
-			if (!irq_proc_cnt++)
-				printk(KERN_DEBUG "%s: got V_IRQ_PROC -"
-				       " this should not happen\n", __func__);
-		}
-
-	}
-	if (status & V_FR_IRQSTA) {
-		/* FIFO IRQ */
-		r_irq_oview = HFC_inb_nodebug(hc, R_IRQ_OVIEW);
-		for (i = 0; i < 8; i++) {
-			if (r_irq_oview & (1 << i))
-				fifo_irq(hc, i);
-		}
-	}
-
-#ifdef IRQ_DEBUG
-	irqsem = 0;
-#endif
-	spin_unlock(&hc->lock);
-	return IRQ_HANDLED;
-
-irq_notforus:
-#ifdef IRQ_DEBUG
-	irqsem = 0;
-#endif
-	spin_unlock(&hc->lock);
-	return IRQ_NONE;
-}
-
-
-/*
- * timer callback for D-chan busy resolution. Currently no function
- */
-
-static void
-hfcmulti_dbusy_timer(struct timer_list *t)
-{
-}
-
-
-/*
- * activate/deactivate hardware for selected channels and mode
- *
- * configure B-channel with the given protocol
- * ch eqals to the HFC-channel (0-31)
- * ch is the number of channel (0-4,4-7,8-11,12-15,16-19,20-23,24-27,28-31
- * for S/T, 1-31 for E1)
- * the hdlc interrupts will be set/unset
- */
-static int
-mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
-	      int bank_tx, int slot_rx, int bank_rx)
-{
-	int flow_tx = 0, flow_rx = 0, routing = 0;
-	int oslot_tx, oslot_rx;
-	int conf;
-
-	if (ch < 0 || ch > 31)
-		return -EINVAL;
-	oslot_tx = hc->chan[ch].slot_tx;
-	oslot_rx = hc->chan[ch].slot_rx;
-	conf = hc->chan[ch].conf;
-
-	if (debug & DEBUG_HFCMULTI_MODE)
-		printk(KERN_DEBUG
-		       "%s: card %d channel %d protocol %x slot old=%d new=%d "
-		       "bank new=%d (TX) slot old=%d new=%d bank new=%d (RX)\n",
-		       __func__, hc->id, ch, protocol, oslot_tx, slot_tx,
-		       bank_tx, oslot_rx, slot_rx, bank_rx);
-
-	if (oslot_tx >= 0 && slot_tx != oslot_tx) {
-		/* remove from slot */
-		if (debug & DEBUG_HFCMULTI_MODE)
-			printk(KERN_DEBUG "%s: remove from slot %d (TX)\n",
-			       __func__, oslot_tx);
-		if (hc->slot_owner[oslot_tx << 1] == ch) {
-			HFC_outb(hc, R_SLOT, oslot_tx << 1);
-			HFC_outb(hc, A_SL_CFG, 0);
-			if (hc->ctype != HFC_TYPE_XHFC)
-				HFC_outb(hc, A_CONF, 0);
-			hc->slot_owner[oslot_tx << 1] = -1;
-		} else {
-			if (debug & DEBUG_HFCMULTI_MODE)
-				printk(KERN_DEBUG
-				       "%s: we are not owner of this tx slot "
-				       "anymore, channel %d is.\n",
-				       __func__, hc->slot_owner[oslot_tx << 1]);
-		}
-	}
-
-	if (oslot_rx >= 0 && slot_rx != oslot_rx) {
-		/* remove from slot */
-		if (debug & DEBUG_HFCMULTI_MODE)
-			printk(KERN_DEBUG
-			       "%s: remove from slot %d (RX)\n",
-			       __func__, oslot_rx);
-		if (hc->slot_owner[(oslot_rx << 1) | 1] == ch) {
-			HFC_outb(hc, R_SLOT, (oslot_rx << 1) | V_SL_DIR);
-			HFC_outb(hc, A_SL_CFG, 0);
-			hc->slot_owner[(oslot_rx << 1) | 1] = -1;
-		} else {
-			if (debug & DEBUG_HFCMULTI_MODE)
-				printk(KERN_DEBUG
-				       "%s: we are not owner of this rx slot "
-				       "anymore, channel %d is.\n",
-				       __func__,
-				       hc->slot_owner[(oslot_rx << 1) | 1]);
-		}
-	}
-
-	if (slot_tx < 0) {
-		flow_tx = 0x80; /* FIFO->ST */
-		/* disable pcm slot */
-		hc->chan[ch].slot_tx = -1;
-		hc->chan[ch].bank_tx = 0;
-	} else {
-		/* set pcm slot */
-		if (hc->chan[ch].txpending)
-			flow_tx = 0x80; /* FIFO->ST */
-		else
-			flow_tx = 0xc0; /* PCM->ST */
-		/* put on slot */
-		routing = bank_tx ? 0xc0 : 0x80;
-		if (conf >= 0 || bank_tx > 1)
-			routing = 0x40; /* loop */
-		if (debug & DEBUG_HFCMULTI_MODE)
-			printk(KERN_DEBUG "%s: put channel %d to slot %d bank"
-			       " %d flow %02x routing %02x conf %d (TX)\n",
-			       __func__, ch, slot_tx, bank_tx,
-			       flow_tx, routing, conf);
-		HFC_outb(hc, R_SLOT, slot_tx << 1);
-		HFC_outb(hc, A_SL_CFG, (ch << 1) | routing);
-		if (hc->ctype != HFC_TYPE_XHFC)
-			HFC_outb(hc, A_CONF,
-				 (conf < 0) ? 0 : (conf | V_CONF_SL));
-		hc->slot_owner[slot_tx << 1] = ch;
-		hc->chan[ch].slot_tx = slot_tx;
-		hc->chan[ch].bank_tx = bank_tx;
-	}
-	if (slot_rx < 0) {
-		/* disable pcm slot */
-		flow_rx = 0x80; /* ST->FIFO */
-		hc->chan[ch].slot_rx = -1;
-		hc->chan[ch].bank_rx = 0;
-	} else {
-		/* set pcm slot */
-		if (hc->chan[ch].txpending)
-			flow_rx = 0x80; /* ST->FIFO */
-		else
-			flow_rx = 0xc0; /* ST->(FIFO,PCM) */
-		/* put on slot */
-		routing = bank_rx ? 0x80 : 0xc0; /* reversed */
-		if (conf >= 0 || bank_rx > 1)
-			routing = 0x40; /* loop */
-		if (debug & DEBUG_HFCMULTI_MODE)
-			printk(KERN_DEBUG "%s: put channel %d to slot %d bank"
-			       " %d flow %02x routing %02x conf %d (RX)\n",
-			       __func__, ch, slot_rx, bank_rx,
-			       flow_rx, routing, conf);
-		HFC_outb(hc, R_SLOT, (slot_rx << 1) | V_SL_DIR);
-		HFC_outb(hc, A_SL_CFG, (ch << 1) | V_CH_DIR | routing);
-		hc->slot_owner[(slot_rx << 1) | 1] = ch;
-		hc->chan[ch].slot_rx = slot_rx;
-		hc->chan[ch].bank_rx = bank_rx;
-	}
-
-	switch (protocol) {
-	case (ISDN_P_NONE):
-		/* disable TX fifo */
-		HFC_outb(hc, R_FIFO, ch << 1);
-		HFC_wait(hc);
-		HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 | V_IFF);
-		HFC_outb(hc, A_SUBCH_CFG, 0);
-		HFC_outb(hc, A_IRQ_MSK, 0);
-		HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
-		HFC_wait(hc);
-		/* disable RX fifo */
-		HFC_outb(hc, R_FIFO, (ch << 1) | 1);
-		HFC_wait(hc);
-		HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00);
-		HFC_outb(hc, A_SUBCH_CFG, 0);
-		HFC_outb(hc, A_IRQ_MSK, 0);
-		HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
-		HFC_wait(hc);
-		if (hc->chan[ch].bch && hc->ctype != HFC_TYPE_E1) {
-			hc->hw.a_st_ctrl0[hc->chan[ch].port] &=
-				((ch & 0x3) == 0) ? ~V_B1_EN : ~V_B2_EN;
-			HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
-			/* undocumented: delay after R_ST_SEL */
-			udelay(1);
-			HFC_outb(hc, A_ST_CTRL0,
-				 hc->hw.a_st_ctrl0[hc->chan[ch].port]);
-		}
-		if (hc->chan[ch].bch) {
-			test_and_clear_bit(FLG_HDLC, &hc->chan[ch].bch->Flags);
-			test_and_clear_bit(FLG_TRANSPARENT,
-					   &hc->chan[ch].bch->Flags);
-		}
-		break;
-	case (ISDN_P_B_RAW): /* B-channel */
-
-		if (test_bit(HFC_CHIP_B410P, &hc->chip) &&
-		    (hc->chan[ch].slot_rx < 0) &&
-		    (hc->chan[ch].slot_tx < 0)) {
-
-			printk(KERN_DEBUG
-			       "Setting B-channel %d to echo cancelable "
-			       "state on PCM slot %d\n", ch,
-			       ((ch / 4) * 8) + ((ch % 4) * 4) + 1);
-			printk(KERN_DEBUG
-			       "Enabling pass through for channel\n");
-			vpm_out(hc, ch, ((ch / 4) * 8) +
-				((ch % 4) * 4) + 1, 0x01);
-			/* rx path */
-			/* S/T -> PCM */
-			HFC_outb(hc, R_FIFO, (ch << 1));
-			HFC_wait(hc);
-			HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF);
-			HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +
-					      ((ch % 4) * 4) + 1) << 1);
-			HFC_outb(hc, A_SL_CFG, 0x80 | (ch << 1));
-
-			/* PCM -> FIFO */
-			HFC_outb(hc, R_FIFO, 0x20 | (ch << 1) | 1);
-			HFC_wait(hc);
-			HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF);
-			HFC_outb(hc, A_SUBCH_CFG, 0);
-			HFC_outb(hc, A_IRQ_MSK, 0);
-			if (hc->chan[ch].protocol != protocol) {
-				HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
-				HFC_wait(hc);
-			}
-			HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) +
-					       ((ch % 4) * 4) + 1) << 1) | 1);
-			HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1) | 1);
-
-			/* tx path */
-			/* PCM -> S/T */
-			HFC_outb(hc, R_FIFO, (ch << 1) | 1);
-			HFC_wait(hc);
-			HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF);
-			HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) +
-					       ((ch % 4) * 4)) << 1) | 1);
-			HFC_outb(hc, A_SL_CFG, 0x80 | 0x40 | (ch << 1) | 1);
-
-			/* FIFO -> PCM */
-			HFC_outb(hc, R_FIFO, 0x20 | (ch << 1));
-			HFC_wait(hc);
-			HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF);
-			HFC_outb(hc, A_SUBCH_CFG, 0);
-			HFC_outb(hc, A_IRQ_MSK, 0);
-			if (hc->chan[ch].protocol != protocol) {
-				HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
-				HFC_wait(hc);
-			}
-			/* tx silence */
-			HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
-			HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +
-					      ((ch % 4) * 4)) << 1);
-			HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1));
-		} else {
-			/* enable TX fifo */
-			HFC_outb(hc, R_FIFO, ch << 1);
-			HFC_wait(hc);
-			if (hc->ctype == HFC_TYPE_XHFC)
-				HFC_outb(hc, A_CON_HDLC, flow_tx | 0x07 << 2 |
-					 V_HDLC_TRP | V_IFF);
-			/* Enable FIFO, no interrupt */
-			else
-				HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 |
-					 V_HDLC_TRP | V_IFF);
-			HFC_outb(hc, A_SUBCH_CFG, 0);
-			HFC_outb(hc, A_IRQ_MSK, 0);
-			if (hc->chan[ch].protocol != protocol) {
-				HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
-				HFC_wait(hc);
-			}
-			/* tx silence */
-			HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
-			/* enable RX fifo */
-			HFC_outb(hc, R_FIFO, (ch << 1) | 1);
-			HFC_wait(hc);
-			if (hc->ctype == HFC_TYPE_XHFC)
-				HFC_outb(hc, A_CON_HDLC, flow_rx | 0x07 << 2 |
-					 V_HDLC_TRP);
-			/* Enable FIFO, no interrupt*/
-			else
-				HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 |
-					 V_HDLC_TRP);
-			HFC_outb(hc, A_SUBCH_CFG, 0);
-			HFC_outb(hc, A_IRQ_MSK, 0);
-			if (hc->chan[ch].protocol != protocol) {
-				HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
-				HFC_wait(hc);
-			}
-		}
-		if (hc->ctype != HFC_TYPE_E1) {
-			hc->hw.a_st_ctrl0[hc->chan[ch].port] |=
-				((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN;
-			HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
-			/* undocumented: delay after R_ST_SEL */
-			udelay(1);
-			HFC_outb(hc, A_ST_CTRL0,
-				 hc->hw.a_st_ctrl0[hc->chan[ch].port]);
-		}
-		if (hc->chan[ch].bch)
-			test_and_set_bit(FLG_TRANSPARENT,
-					 &hc->chan[ch].bch->Flags);
-		break;
-	case (ISDN_P_B_HDLC): /* B-channel */
-	case (ISDN_P_TE_S0): /* D-channel */
-	case (ISDN_P_NT_S0):
-	case (ISDN_P_TE_E1):
-	case (ISDN_P_NT_E1):
-		/* enable TX fifo */
-		HFC_outb(hc, R_FIFO, ch << 1);
-		HFC_wait(hc);
-		if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch) {
-			/* E1 or B-channel */
-			HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04);
-			HFC_outb(hc, A_SUBCH_CFG, 0);
-		} else {
-			/* D-Channel without HDLC fill flags */
-			HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04 | V_IFF);
-			HFC_outb(hc, A_SUBCH_CFG, 2);
-		}
-		HFC_outb(hc, A_IRQ_MSK, V_IRQ);
-		HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
-		HFC_wait(hc);
-		/* enable RX fifo */
-		HFC_outb(hc, R_FIFO, (ch << 1) | 1);
-		HFC_wait(hc);
-		HFC_outb(hc, A_CON_HDLC, flow_rx | 0x04);
-		if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch)
-			HFC_outb(hc, A_SUBCH_CFG, 0); /* full 8 bits */
-		else
-			HFC_outb(hc, A_SUBCH_CFG, 2); /* 2 bits dchannel */
-		HFC_outb(hc, A_IRQ_MSK, V_IRQ);
-		HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
-		HFC_wait(hc);
-		if (hc->chan[ch].bch) {
-			test_and_set_bit(FLG_HDLC, &hc->chan[ch].bch->Flags);
-			if (hc->ctype != HFC_TYPE_E1) {
-				hc->hw.a_st_ctrl0[hc->chan[ch].port] |=
-					((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN;
-				HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
-				/* undocumented: delay after R_ST_SEL */
-				udelay(1);
-				HFC_outb(hc, A_ST_CTRL0,
-					 hc->hw.a_st_ctrl0[hc->chan[ch].port]);
-			}
-		}
-		break;
-	default:
-		printk(KERN_DEBUG "%s: protocol not known %x\n",
-		       __func__, protocol);
-		hc->chan[ch].protocol = ISDN_P_NONE;
-		return -ENOPROTOOPT;
-	}
-	hc->chan[ch].protocol = protocol;
-	return 0;
-}
-
-
-/*
- * connect/disconnect PCM
- */
-
-static void
-hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx,
-	     int slot_rx, int bank_rx)
-{
-	if (slot_tx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) {
-		/* disable PCM */
-		mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0);
-		return;
-	}
-
-	/* enable pcm */
-	mode_hfcmulti(hc, ch, hc->chan[ch].protocol, slot_tx, bank_tx,
-		      slot_rx, bank_rx);
-}
-
-/*
- * set/disable conference
- */
-
-static void
-hfcmulti_conf(struct hfc_multi *hc, int ch, int num)
-{
-	if (num >= 0 && num <= 7)
-		hc->chan[ch].conf = num;
-	else
-		hc->chan[ch].conf = -1;
-	mode_hfcmulti(hc, ch, hc->chan[ch].protocol, hc->chan[ch].slot_tx,
-		      hc->chan[ch].bank_tx, hc->chan[ch].slot_rx,
-		      hc->chan[ch].bank_rx);
-}
-
-
-/*
- * set/disable sample loop
- */
-
-/* NOTE: this function is experimental and therefore disabled */
-
-/*
- * Layer 1 callback function
- */
-static int
-hfcm_l1callback(struct dchannel *dch, u_int cmd)
-{
-	struct hfc_multi	*hc = dch->hw;
-	struct sk_buff_head	free_queue;
-	u_long	flags;
-
-	switch (cmd) {
-	case INFO3_P8:
-	case INFO3_P10:
-		break;
-	case HW_RESET_REQ:
-		/* start activation */
-		spin_lock_irqsave(&hc->lock, flags);
-		if (hc->ctype == HFC_TYPE_E1) {
-			if (debug & DEBUG_HFCMULTI_MSG)
-				printk(KERN_DEBUG
-				       "%s: HW_RESET_REQ no BRI\n",
-				       __func__);
-		} else {
-			HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);
-			/* undocumented: delay after R_ST_SEL */
-			udelay(1);
-			HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 3); /* F3 */
-			udelay(6); /* wait at least 5,21us */
-			HFC_outb(hc, A_ST_WR_STATE, 3);
-			HFC_outb(hc, A_ST_WR_STATE, 3 | (V_ST_ACT * 3));
-			/* activate */
-		}
-		spin_unlock_irqrestore(&hc->lock, flags);
-		l1_event(dch->l1, HW_POWERUP_IND);
-		break;
-	case HW_DEACT_REQ:
-		__skb_queue_head_init(&free_queue);
-		/* start deactivation */
-		spin_lock_irqsave(&hc->lock, flags);
-		if (hc->ctype == HFC_TYPE_E1) {
-			if (debug & DEBUG_HFCMULTI_MSG)
-				printk(KERN_DEBUG
-				       "%s: HW_DEACT_REQ no BRI\n",
-				       __func__);
-		} else {
-			HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);
-			/* undocumented: delay after R_ST_SEL */
-			udelay(1);
-			HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT * 2);
-			/* deactivate */
-			if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-				hc->syncronized &=
-					~(1 << hc->chan[dch->slot].port);
-				plxsd_checksync(hc, 0);
-			}
-		}
-		skb_queue_splice_init(&dch->squeue, &free_queue);
-		if (dch->tx_skb) {
-			__skb_queue_tail(&free_queue, dch->tx_skb);
-			dch->tx_skb = NULL;
-		}
-		dch->tx_idx = 0;
-		if (dch->rx_skb) {
-			__skb_queue_tail(&free_queue, dch->rx_skb);
-			dch->rx_skb = NULL;
-		}
-		test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
-		if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
-			timer_delete(&dch->timer);
-		spin_unlock_irqrestore(&hc->lock, flags);
-		__skb_queue_purge(&free_queue);
-		break;
-	case HW_POWERUP_REQ:
-		spin_lock_irqsave(&hc->lock, flags);
-		if (hc->ctype == HFC_TYPE_E1) {
-			if (debug & DEBUG_HFCMULTI_MSG)
-				printk(KERN_DEBUG
-				       "%s: HW_POWERUP_REQ no BRI\n",
-				       __func__);
-		} else {
-			HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);
-			/* undocumented: delay after R_ST_SEL */
-			udelay(1);
-			HFC_outb(hc, A_ST_WR_STATE, 3 | 0x10); /* activate */
-			udelay(6); /* wait at least 5,21us */
-			HFC_outb(hc, A_ST_WR_STATE, 3); /* activate */
-		}
-		spin_unlock_irqrestore(&hc->lock, flags);
-		break;
-	case PH_ACTIVATE_IND:
-		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
-		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			    GFP_ATOMIC);
-		break;
-	case PH_DEACTIVATE_IND:
-		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
-		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			    GFP_ATOMIC);
-		break;
-	default:
-		if (dch->debug & DEBUG_HW)
-			printk(KERN_DEBUG "%s: unknown command %x\n",
-			       __func__, cmd);
-		return -1;
-	}
-	return 0;
-}
-
-/*
- * Layer2 -> Layer 1 Transfer
- */
-
-static int
-handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
-	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
-	struct hfc_multi	*hc = dch->hw;
-	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
-	int			ret = -EINVAL;
-	unsigned int		id;
-	u_long			flags;
-
-	switch (hh->prim) {
-	case PH_DATA_REQ:
-		if (skb->len < 1)
-			break;
-		spin_lock_irqsave(&hc->lock, flags);
-		ret = dchannel_senddata(dch, skb);
-		if (ret > 0) { /* direct TX */
-			id = hh->id; /* skb can be freed */
-			hfcmulti_tx(hc, dch->slot);
-			ret = 0;
-			/* start fifo */
-			HFC_outb(hc, R_FIFO, 0);
-			HFC_wait(hc);
-			spin_unlock_irqrestore(&hc->lock, flags);
-			queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
-		} else
-			spin_unlock_irqrestore(&hc->lock, flags);
-		return ret;
-	case PH_ACTIVATE_REQ:
-		if (dch->dev.D.protocol != ISDN_P_TE_S0) {
-			spin_lock_irqsave(&hc->lock, flags);
-			ret = 0;
-			if (debug & DEBUG_HFCMULTI_MSG)
-				printk(KERN_DEBUG
-				       "%s: PH_ACTIVATE port %d (0..%d)\n",
-				       __func__, hc->chan[dch->slot].port,
-				       hc->ports - 1);
-			/* start activation */
-			if (hc->ctype == HFC_TYPE_E1) {
-				ph_state_change(dch);
-				if (debug & DEBUG_HFCMULTI_STATE)
-					printk(KERN_DEBUG
-					       "%s: E1 report state %x \n",
-					       __func__, dch->state);
-			} else {
-				HFC_outb(hc, R_ST_SEL,
-					 hc->chan[dch->slot].port);
-				/* undocumented: delay after R_ST_SEL */
-				udelay(1);
-				HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 1);
-				/* G1 */
-				udelay(6); /* wait at least 5,21us */
-				HFC_outb(hc, A_ST_WR_STATE, 1);
-				HFC_outb(hc, A_ST_WR_STATE, 1 |
-					 (V_ST_ACT * 3)); /* activate */
-				dch->state = 1;
-			}
-			spin_unlock_irqrestore(&hc->lock, flags);
-		} else
-			ret = l1_event(dch->l1, hh->prim);
-		break;
-	case PH_DEACTIVATE_REQ:
-		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
-		if (dch->dev.D.protocol != ISDN_P_TE_S0) {
-			struct sk_buff_head free_queue;
-
-			__skb_queue_head_init(&free_queue);
-			spin_lock_irqsave(&hc->lock, flags);
-			if (debug & DEBUG_HFCMULTI_MSG)
-				printk(KERN_DEBUG
-				       "%s: PH_DEACTIVATE port %d (0..%d)\n",
-				       __func__, hc->chan[dch->slot].port,
-				       hc->ports - 1);
-			/* start deactivation */
-			if (hc->ctype == HFC_TYPE_E1) {
-				if (debug & DEBUG_HFCMULTI_MSG)
-					printk(KERN_DEBUG
-					       "%s: PH_DEACTIVATE no BRI\n",
-					       __func__);
-			} else {
-				HFC_outb(hc, R_ST_SEL,
-					 hc->chan[dch->slot].port);
-				/* undocumented: delay after R_ST_SEL */
-				udelay(1);
-				HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT * 2);
-				/* deactivate */
-				dch->state = 1;
-			}
-			skb_queue_splice_init(&dch->squeue, &free_queue);
-			if (dch->tx_skb) {
-				__skb_queue_tail(&free_queue, dch->tx_skb);
-				dch->tx_skb = NULL;
-			}
-			dch->tx_idx = 0;
-			if (dch->rx_skb) {
-				__skb_queue_tail(&free_queue, dch->rx_skb);
-				dch->rx_skb = NULL;
-			}
-			test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
-			if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
-				timer_delete(&dch->timer);
-#ifdef FIXME
-			if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
-				dchannel_sched_event(&hc->dch, D_CLEARBUSY);
-#endif
-			ret = 0;
-			spin_unlock_irqrestore(&hc->lock, flags);
-			__skb_queue_purge(&free_queue);
-		} else
-			ret = l1_event(dch->l1, hh->prim);
-		break;
-	}
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-static void
-deactivate_bchannel(struct bchannel *bch)
-{
-	struct hfc_multi	*hc = bch->hw;
-	u_long			flags;
-
-	spin_lock_irqsave(&hc->lock, flags);
-	mISDN_clear_bchannel(bch);
-	hc->chan[bch->slot].coeff_count = 0;
-	hc->chan[bch->slot].rx_off = 0;
-	hc->chan[bch->slot].conf = -1;
-	mode_hfcmulti(hc, bch->slot, ISDN_P_NONE, -1, 0, -1, 0);
-	spin_unlock_irqrestore(&hc->lock, flags);
-}
-
-static int
-handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct bchannel		*bch = container_of(ch, struct bchannel, ch);
-	struct hfc_multi	*hc = bch->hw;
-	int			ret = -EINVAL;
-	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
-	unsigned long		flags;
-
-	switch (hh->prim) {
-	case PH_DATA_REQ:
-		if (!skb->len)
-			break;
-		spin_lock_irqsave(&hc->lock, flags);
-		ret = bchannel_senddata(bch, skb);
-		if (ret > 0) { /* direct TX */
-			hfcmulti_tx(hc, bch->slot);
-			ret = 0;
-			/* start fifo */
-			HFC_outb_nodebug(hc, R_FIFO, 0);
-			HFC_wait_nodebug(hc);
-		}
-		spin_unlock_irqrestore(&hc->lock, flags);
-		return ret;
-	case PH_ACTIVATE_REQ:
-		if (debug & DEBUG_HFCMULTI_MSG)
-			printk(KERN_DEBUG "%s: PH_ACTIVATE ch %d (0..32)\n",
-			       __func__, bch->slot);
-		spin_lock_irqsave(&hc->lock, flags);
-		/* activate B-channel if not already activated */
-		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) {
-			hc->chan[bch->slot].txpending = 0;
-			ret = mode_hfcmulti(hc, bch->slot,
-					    ch->protocol,
-					    hc->chan[bch->slot].slot_tx,
-					    hc->chan[bch->slot].bank_tx,
-					    hc->chan[bch->slot].slot_rx,
-					    hc->chan[bch->slot].bank_rx);
-			if (!ret) {
-				if (ch->protocol == ISDN_P_B_RAW && !hc->dtmf
-				    && test_bit(HFC_CHIP_DTMF, &hc->chip)) {
-					/* start decoder */
-					hc->dtmf = 1;
-					if (debug & DEBUG_HFCMULTI_DTMF)
-						printk(KERN_DEBUG
-						       "%s: start dtmf decoder\n",
-						       __func__);
-					HFC_outb(hc, R_DTMF, hc->hw.r_dtmf |
-						 V_RST_DTMF);
-				}
-			}
-		} else
-			ret = 0;
-		spin_unlock_irqrestore(&hc->lock, flags);
-		if (!ret)
-			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, NULL,
-				    GFP_KERNEL);
-		break;
-	case PH_CONTROL_REQ:
-		spin_lock_irqsave(&hc->lock, flags);
-		switch (hh->id) {
-		case HFC_SPL_LOOP_ON: /* set sample loop */
-			if (debug & DEBUG_HFCMULTI_MSG)
-				printk(KERN_DEBUG
-				       "%s: HFC_SPL_LOOP_ON (len = %d)\n",
-				       __func__, skb->len);
-			ret = 0;
-			break;
-		case HFC_SPL_LOOP_OFF: /* set silence */
-			if (debug & DEBUG_HFCMULTI_MSG)
-				printk(KERN_DEBUG "%s: HFC_SPL_LOOP_OFF\n",
-				       __func__);
-			ret = 0;
-			break;
-		default:
-			printk(KERN_ERR
-			       "%s: unknown PH_CONTROL_REQ info %x\n",
-			       __func__, hh->id);
-			ret = -EINVAL;
-		}
-		spin_unlock_irqrestore(&hc->lock, flags);
-		break;
-	case PH_DEACTIVATE_REQ:
-		deactivate_bchannel(bch); /* locked there */
-		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, NULL,
-			    GFP_KERNEL);
-		ret = 0;
-		break;
-	}
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-/*
- * bchannel control function
- */
-static int
-channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
-{
-	int			ret = 0;
-	struct dsp_features	*features =
-		(struct dsp_features *)(*((u_long *)&cq->p1));
-	struct hfc_multi	*hc = bch->hw;
-	int			slot_tx;
-	int			bank_tx;
-	int			slot_rx;
-	int			bank_rx;
-	int			num;
-
-	switch (cq->op) {
-	case MISDN_CTRL_GETOP:
-		ret = mISDN_ctrl_bchannel(bch, cq);
-		cq->op |= MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP;
-		break;
-	case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */
-		ret = mISDN_ctrl_bchannel(bch, cq);
-		hc->chan[bch->slot].rx_off = !!cq->p1;
-		if (!hc->chan[bch->slot].rx_off) {
-			/* reset fifo on rx on */
-			HFC_outb_nodebug(hc, R_FIFO, (bch->slot << 1) | 1);
-			HFC_wait_nodebug(hc);
-			HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F);
-			HFC_wait_nodebug(hc);
-		}
-		if (debug & DEBUG_HFCMULTI_MSG)
-			printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n",
-			       __func__, bch->nr, hc->chan[bch->slot].rx_off);
-		break;
-	case MISDN_CTRL_FILL_EMPTY:
-		ret = mISDN_ctrl_bchannel(bch, cq);
-		hc->silence = bch->fill[0];
-		memset(hc->silence_data, hc->silence, sizeof(hc->silence_data));
-		break;
-	case MISDN_CTRL_HW_FEATURES: /* fill features structure */
-		if (debug & DEBUG_HFCMULTI_MSG)
-			printk(KERN_DEBUG "%s: HW_FEATURE request\n",
-			       __func__);
-		/* create confirm */
-		features->hfc_id = hc->id;
-		if (test_bit(HFC_CHIP_DTMF, &hc->chip))
-			features->hfc_dtmf = 1;
-		if (test_bit(HFC_CHIP_CONF, &hc->chip))
-			features->hfc_conf = 1;
-		features->hfc_loops = 0;
-		if (test_bit(HFC_CHIP_B410P, &hc->chip)) {
-			features->hfc_echocanhw = 1;
-		} else {
-			features->pcm_id = hc->pcm;
-			features->pcm_slots = hc->slots;
-			features->pcm_banks = 2;
-		}
-		break;
-	case MISDN_CTRL_HFC_PCM_CONN: /* connect to pcm timeslot (0..N) */
-		slot_tx = cq->p1 & 0xff;
-		bank_tx = cq->p1 >> 8;
-		slot_rx = cq->p2 & 0xff;
-		bank_rx = cq->p2 >> 8;
-		if (debug & DEBUG_HFCMULTI_MSG)
-			printk(KERN_DEBUG
-			       "%s: HFC_PCM_CONN slot %d bank %d (TX) "
-			       "slot %d bank %d (RX)\n",
-			       __func__, slot_tx, bank_tx,
-			       slot_rx, bank_rx);
-		if (slot_tx < hc->slots && bank_tx <= 2 &&
-		    slot_rx < hc->slots && bank_rx <= 2)
-			hfcmulti_pcm(hc, bch->slot,
-				     slot_tx, bank_tx, slot_rx, bank_rx);
-		else {
-			printk(KERN_WARNING
-			       "%s: HFC_PCM_CONN slot %d bank %d (TX) "
-			       "slot %d bank %d (RX) out of range\n",
-			       __func__, slot_tx, bank_tx,
-			       slot_rx, bank_rx);
-			ret = -EINVAL;
-		}
-		break;
-	case MISDN_CTRL_HFC_PCM_DISC: /* release interface from pcm timeslot */
-		if (debug & DEBUG_HFCMULTI_MSG)
-			printk(KERN_DEBUG "%s: HFC_PCM_DISC\n",
-			       __func__);
-		hfcmulti_pcm(hc, bch->slot, -1, 0, -1, 0);
-		break;
-	case MISDN_CTRL_HFC_CONF_JOIN: /* join conference (0..7) */
-		num = cq->p1 & 0xff;
-		if (debug & DEBUG_HFCMULTI_MSG)
-			printk(KERN_DEBUG "%s: HFC_CONF_JOIN conf %d\n",
-			       __func__, num);
-		if (num <= 7)
-			hfcmulti_conf(hc, bch->slot, num);
-		else {
-			printk(KERN_WARNING
-			       "%s: HW_CONF_JOIN conf %d out of range\n",
-			       __func__, num);
-			ret = -EINVAL;
-		}
-		break;
-	case MISDN_CTRL_HFC_CONF_SPLIT: /* split conference */
-		if (debug & DEBUG_HFCMULTI_MSG)
-			printk(KERN_DEBUG "%s: HFC_CONF_SPLIT\n", __func__);
-		hfcmulti_conf(hc, bch->slot, -1);
-		break;
-	case MISDN_CTRL_HFC_ECHOCAN_ON:
-		if (debug & DEBUG_HFCMULTI_MSG)
-			printk(KERN_DEBUG "%s: HFC_ECHOCAN_ON\n", __func__);
-		if (test_bit(HFC_CHIP_B410P, &hc->chip))
-			vpm_echocan_on(hc, bch->slot, cq->p1);
-		else
-			ret = -EINVAL;
-		break;
-
-	case MISDN_CTRL_HFC_ECHOCAN_OFF:
-		if (debug & DEBUG_HFCMULTI_MSG)
-			printk(KERN_DEBUG "%s: HFC_ECHOCAN_OFF\n",
-			       __func__);
-		if (test_bit(HFC_CHIP_B410P, &hc->chip))
-			vpm_echocan_off(hc, bch->slot);
-		else
-			ret = -EINVAL;
-		break;
-	default:
-		ret = mISDN_ctrl_bchannel(bch, cq);
-		break;
-	}
-	return ret;
-}
-
-static int
-hfcm_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
-{
-	struct bchannel		*bch = container_of(ch, struct bchannel, ch);
-	struct hfc_multi	*hc = bch->hw;
-	int			err = -EINVAL;
-	u_long	flags;
-
-	if (bch->debug & DEBUG_HW)
-		printk(KERN_DEBUG "%s: cmd:%x %p\n",
-		       __func__, cmd, arg);
-	switch (cmd) {
-	case CLOSE_CHANNEL:
-		test_and_clear_bit(FLG_OPEN, &bch->Flags);
-		deactivate_bchannel(bch); /* locked there */
-		ch->protocol = ISDN_P_NONE;
-		ch->peer = NULL;
-		module_put(THIS_MODULE);
-		err = 0;
-		break;
-	case CONTROL_CHANNEL:
-		spin_lock_irqsave(&hc->lock, flags);
-		err = channel_bctrl(bch, arg);
-		spin_unlock_irqrestore(&hc->lock, flags);
-		break;
-	default:
-		printk(KERN_WARNING "%s: unknown prim(%x)\n",
-		       __func__, cmd);
-	}
-	return err;
-}
-
-/*
- * handle D-channel events
- *
- * handle state change event
- */
-static void
-ph_state_change(struct dchannel *dch)
-{
-	struct hfc_multi *hc;
-	int ch, i;
-
-	if (!dch) {
-		printk(KERN_WARNING "%s: ERROR given dch is NULL\n", __func__);
-		return;
-	}
-	hc = dch->hw;
-	ch = dch->slot;
-
-	if (hc->ctype == HFC_TYPE_E1) {
-		if (dch->dev.D.protocol == ISDN_P_TE_E1) {
-			if (debug & DEBUG_HFCMULTI_STATE)
-				printk(KERN_DEBUG
-				       "%s: E1 TE (id=%d) newstate %x\n",
-				       __func__, hc->id, dch->state);
-		} else {
-			if (debug & DEBUG_HFCMULTI_STATE)
-				printk(KERN_DEBUG
-				       "%s: E1 NT (id=%d) newstate %x\n",
-				       __func__, hc->id, dch->state);
-		}
-		switch (dch->state) {
-		case (1):
-			if (hc->e1_state != 1) {
-				for (i = 1; i <= 31; i++) {
-					/* reset fifos on e1 activation */
-					HFC_outb_nodebug(hc, R_FIFO,
-							 (i << 1) | 1);
-					HFC_wait_nodebug(hc);
-					HFC_outb_nodebug(hc, R_INC_RES_FIFO,
-							 V_RES_F);
-					HFC_wait_nodebug(hc);
-				}
-			}
-			test_and_set_bit(FLG_ACTIVE, &dch->Flags);
-			_queue_data(&dch->dev.D, PH_ACTIVATE_IND,
-				    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
-			break;
-
-		default:
-			if (hc->e1_state != 1)
-				return;
-			test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
-			_queue_data(&dch->dev.D, PH_DEACTIVATE_IND,
-				    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
-		}
-		hc->e1_state = dch->state;
-	} else {
-		if (dch->dev.D.protocol == ISDN_P_TE_S0) {
-			if (debug & DEBUG_HFCMULTI_STATE)
-				printk(KERN_DEBUG
-				       "%s: S/T TE newstate %x\n",
-				       __func__, dch->state);
-			switch (dch->state) {
-			case (0):
-				l1_event(dch->l1, HW_RESET_IND);
-				break;
-			case (3):
-				l1_event(dch->l1, HW_DEACT_IND);
-				break;
-			case (5):
-			case (8):
-				l1_event(dch->l1, ANYSIGNAL);
-				break;
-			case (6):
-				l1_event(dch->l1, INFO2);
-				break;
-			case (7):
-				l1_event(dch->l1, INFO4_P8);
-				break;
-			}
-		} else {
-			if (debug & DEBUG_HFCMULTI_STATE)
-				printk(KERN_DEBUG "%s: S/T NT newstate %x\n",
-				       __func__, dch->state);
-			switch (dch->state) {
-			case (2):
-				if (hc->chan[ch].nt_timer == 0) {
-					hc->chan[ch].nt_timer = -1;
-					HFC_outb(hc, R_ST_SEL,
-						 hc->chan[ch].port);
-					/* undocumented: delay after R_ST_SEL */
-					udelay(1);
-					HFC_outb(hc, A_ST_WR_STATE, 4 |
-						 V_ST_LD_STA); /* G4 */
-					udelay(6); /* wait at least 5,21us */
-					HFC_outb(hc, A_ST_WR_STATE, 4);
-					dch->state = 4;
-				} else {
-					/* one extra count for the next event */
-					hc->chan[ch].nt_timer =
-						nt_t1_count[poll_timer] + 1;
-					HFC_outb(hc, R_ST_SEL,
-						 hc->chan[ch].port);
-					/* undocumented: delay after R_ST_SEL */
-					udelay(1);
-					/* allow G2 -> G3 transition */
-					HFC_outb(hc, A_ST_WR_STATE, 2 |
-						 V_SET_G2_G3);
-				}
-				break;
-			case (1):
-				hc->chan[ch].nt_timer = -1;
-				test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
-				_queue_data(&dch->dev.D, PH_DEACTIVATE_IND,
-					    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
-				break;
-			case (4):
-				hc->chan[ch].nt_timer = -1;
-				break;
-			case (3):
-				hc->chan[ch].nt_timer = -1;
-				test_and_set_bit(FLG_ACTIVE, &dch->Flags);
-				_queue_data(&dch->dev.D, PH_ACTIVATE_IND,
-					    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
-				break;
-			}
-		}
-	}
-}
-
-/*
- * called for card mode init message
- */
-
-static void
-hfcmulti_initmode(struct dchannel *dch)
-{
-	struct hfc_multi *hc = dch->hw;
-	u_char		a_st_wr_state, r_e1_wr_sta;
-	int		i, pt;
-
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: entered\n", __func__);
-
-	i = dch->slot;
-	pt = hc->chan[i].port;
-	if (hc->ctype == HFC_TYPE_E1) {
-		/* E1 */
-		hc->chan[hc->dnum[pt]].slot_tx = -1;
-		hc->chan[hc->dnum[pt]].slot_rx = -1;
-		hc->chan[hc->dnum[pt]].conf = -1;
-		if (hc->dnum[pt]) {
-			mode_hfcmulti(hc, dch->slot, dch->dev.D.protocol,
-				      -1, 0, -1, 0);
-			timer_setup(&dch->timer, hfcmulti_dbusy_timer, 0);
-		}
-		for (i = 1; i <= 31; i++) {
-			if (!((1 << i) & hc->bmask[pt])) /* skip unused chan */
-				continue;
-			hc->chan[i].slot_tx = -1;
-			hc->chan[i].slot_rx = -1;
-			hc->chan[i].conf = -1;
-			mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0);
-		}
-	}
-	if (hc->ctype == HFC_TYPE_E1 && pt == 0) {
-		/* E1, port 0 */
-		dch = hc->chan[hc->dnum[0]].dch;
-		if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
-			HFC_outb(hc, R_LOS0, 255); /* 2 ms */
-			HFC_outb(hc, R_LOS1, 255); /* 512 ms */
-		}
-		if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dnum[0]].cfg)) {
-			HFC_outb(hc, R_RX0, 0);
-			hc->hw.r_tx0 = 0 | V_OUT_EN;
-		} else {
-			HFC_outb(hc, R_RX0, 1);
-			hc->hw.r_tx0 = 1 | V_OUT_EN;
-		}
-		hc->hw.r_tx1 = V_ATX | V_NTRI;
-		HFC_outb(hc, R_TX0, hc->hw.r_tx0);
-		HFC_outb(hc, R_TX1, hc->hw.r_tx1);
-		HFC_outb(hc, R_TX_FR0, 0x00);
-		HFC_outb(hc, R_TX_FR1, 0xf8);
-
-		if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg))
-			HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E);
-
-		HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0);
-
-		if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg))
-			HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC);
-
-		if (dch->dev.D.protocol == ISDN_P_NT_E1) {
-			if (debug & DEBUG_HFCMULTI_INIT)
-				printk(KERN_DEBUG "%s: E1 port is NT-mode\n",
-				       __func__);
-			r_e1_wr_sta = 0; /* G0 */
-			hc->e1_getclock = 0;
-		} else {
-			if (debug & DEBUG_HFCMULTI_INIT)
-				printk(KERN_DEBUG "%s: E1 port is TE-mode\n",
-				       __func__);
-			r_e1_wr_sta = 0; /* F0 */
-			hc->e1_getclock = 1;
-		}
-		if (test_bit(HFC_CHIP_RX_SYNC, &hc->chip))
-			HFC_outb(hc, R_SYNC_OUT, V_SYNC_E1_RX);
-		else
-			HFC_outb(hc, R_SYNC_OUT, 0);
-		if (test_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip))
-			hc->e1_getclock = 1;
-		if (test_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip))
-			hc->e1_getclock = 0;
-		if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
-			/* SLAVE (clock master) */
-			if (debug & DEBUG_HFCMULTI_INIT)
-				printk(KERN_DEBUG
-				       "%s: E1 port is clock master "
-				       "(clock from PCM)\n", __func__);
-			HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC | V_PCM_SYNC);
-		} else {
-			if (hc->e1_getclock) {
-				/* MASTER (clock slave) */
-				if (debug & DEBUG_HFCMULTI_INIT)
-					printk(KERN_DEBUG
-					       "%s: E1 port is clock slave "
-					       "(clock to PCM)\n", __func__);
-				HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS);
-			} else {
-				/* MASTER (clock master) */
-				if (debug & DEBUG_HFCMULTI_INIT)
-					printk(KERN_DEBUG "%s: E1 port is "
-					       "clock master "
-					       "(clock from QUARTZ)\n",
-					       __func__);
-				HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC |
-					 V_PCM_SYNC | V_JATT_OFF);
-				HFC_outb(hc, R_SYNC_OUT, 0);
-			}
-		}
-		HFC_outb(hc, R_JATT_ATT, 0x9c); /* undoc register */
-		HFC_outb(hc, R_PWM_MD, V_PWM0_MD);
-		HFC_outb(hc, R_PWM0, 0x50);
-		HFC_outb(hc, R_PWM1, 0xff);
-		/* state machine setup */
-		HFC_outb(hc, R_E1_WR_STA, r_e1_wr_sta | V_E1_LD_STA);
-		udelay(6); /* wait at least 5,21us */
-		HFC_outb(hc, R_E1_WR_STA, r_e1_wr_sta);
-		if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-			hc->syncronized = 0;
-			plxsd_checksync(hc, 0);
-		}
-	}
-	if (hc->ctype != HFC_TYPE_E1) {
-		/* ST */
-		hc->chan[i].slot_tx = -1;
-		hc->chan[i].slot_rx = -1;
-		hc->chan[i].conf = -1;
-		mode_hfcmulti(hc, i, dch->dev.D.protocol, -1, 0, -1, 0);
-		timer_setup(&dch->timer, hfcmulti_dbusy_timer, 0);
-		hc->chan[i - 2].slot_tx = -1;
-		hc->chan[i - 2].slot_rx = -1;
-		hc->chan[i - 2].conf = -1;
-		mode_hfcmulti(hc, i - 2, ISDN_P_NONE, -1, 0, -1, 0);
-		hc->chan[i - 1].slot_tx = -1;
-		hc->chan[i - 1].slot_rx = -1;
-		hc->chan[i - 1].conf = -1;
-		mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0);
-		/* select interface */
-		HFC_outb(hc, R_ST_SEL, pt);
-		/* undocumented: delay after R_ST_SEL */
-		udelay(1);
-		if (dch->dev.D.protocol == ISDN_P_NT_S0) {
-			if (debug & DEBUG_HFCMULTI_INIT)
-				printk(KERN_DEBUG
-				       "%s: ST port %d is NT-mode\n",
-				       __func__, pt);
-			/* clock delay */
-			HFC_outb(hc, A_ST_CLK_DLY, clockdelay_nt);
-			a_st_wr_state = 1; /* G1 */
-			hc->hw.a_st_ctrl0[pt] = V_ST_MD;
-		} else {
-			if (debug & DEBUG_HFCMULTI_INIT)
-				printk(KERN_DEBUG
-				       "%s: ST port %d is TE-mode\n",
-				       __func__, pt);
-			/* clock delay */
-			HFC_outb(hc, A_ST_CLK_DLY, clockdelay_te);
-			a_st_wr_state = 2; /* F2 */
-			hc->hw.a_st_ctrl0[pt] = 0;
-		}
-		if (!test_bit(HFC_CFG_NONCAP_TX, &hc->chan[i].cfg))
-			hc->hw.a_st_ctrl0[pt] |= V_TX_LI;
-		if (hc->ctype == HFC_TYPE_XHFC) {
-			hc->hw.a_st_ctrl0[pt] |= 0x40 /* V_ST_PU_CTRL */;
-			HFC_outb(hc, 0x35 /* A_ST_CTRL3 */,
-				 0x7c << 1 /* V_ST_PULSE */);
-		}
-		/* line setup */
-		HFC_outb(hc, A_ST_CTRL0,  hc->hw.a_st_ctrl0[pt]);
-		/* disable E-channel */
-		if ((dch->dev.D.protocol == ISDN_P_NT_S0) ||
-		    test_bit(HFC_CFG_DIS_ECHANNEL, &hc->chan[i].cfg))
-			HFC_outb(hc, A_ST_CTRL1, V_E_IGNO);
-		else
-			HFC_outb(hc, A_ST_CTRL1, 0);
-		/* enable B-channel receive */
-		HFC_outb(hc, A_ST_CTRL2,  V_B1_RX_EN | V_B2_RX_EN);
-		/* state machine setup */
-		HFC_outb(hc, A_ST_WR_STATE, a_st_wr_state | V_ST_LD_STA);
-		udelay(6); /* wait at least 5,21us */
-		HFC_outb(hc, A_ST_WR_STATE, a_st_wr_state);
-		hc->hw.r_sci_msk |= 1 << pt;
-		/* state machine interrupts */
-		HFC_outb(hc, R_SCI_MSK, hc->hw.r_sci_msk);
-		/* unset sync on port */
-		if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-			hc->syncronized &=
-				~(1 << hc->chan[dch->slot].port);
-			plxsd_checksync(hc, 0);
-		}
-	}
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk("%s: done\n", __func__);
-}
-
-
-static int
-open_dchannel(struct hfc_multi *hc, struct dchannel *dch,
-	      struct channel_req *rq)
-{
-	int	err = 0;
-	u_long	flags;
-
-	if (debug & DEBUG_HW_OPEN)
-		printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,
-		       dch->dev.id, __builtin_return_address(0));
-	if (rq->protocol == ISDN_P_NONE)
-		return -EINVAL;
-	if ((dch->dev.D.protocol != ISDN_P_NONE) &&
-	    (dch->dev.D.protocol != rq->protocol)) {
-		if (debug & DEBUG_HFCMULTI_MODE)
-			printk(KERN_DEBUG "%s: change protocol %x to %x\n",
-			       __func__, dch->dev.D.protocol, rq->protocol);
-	}
-	if ((dch->dev.D.protocol == ISDN_P_TE_S0) &&
-	    (rq->protocol != ISDN_P_TE_S0))
-		l1_event(dch->l1, CLOSE_CHANNEL);
-	if (dch->dev.D.protocol != rq->protocol) {
-		if (rq->protocol == ISDN_P_TE_S0) {
-			err = create_l1(dch, hfcm_l1callback);
-			if (err)
-				return err;
-		}
-		dch->dev.D.protocol = rq->protocol;
-		spin_lock_irqsave(&hc->lock, flags);
-		hfcmulti_initmode(dch);
-		spin_unlock_irqrestore(&hc->lock, flags);
-	}
-	if (test_bit(FLG_ACTIVE, &dch->Flags))
-		_queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY,
-			    0, NULL, GFP_KERNEL);
-	rq->ch = &dch->dev.D;
-	if (!try_module_get(THIS_MODULE))
-		printk(KERN_WARNING "%s:cannot get module\n", __func__);
-	return 0;
-}
-
-static int
-open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
-	      struct channel_req *rq)
-{
-	struct bchannel	*bch;
-	int		ch;
-
-	if (!test_channelmap(rq->adr.channel, dch->dev.channelmap))
-		return -EINVAL;
-	if (rq->protocol == ISDN_P_NONE)
-		return -EINVAL;
-	if (hc->ctype == HFC_TYPE_E1)
-		ch = rq->adr.channel;
-	else
-		ch = (rq->adr.channel - 1) + (dch->slot - 2);
-	bch = hc->chan[ch].bch;
-	if (!bch) {
-		printk(KERN_ERR "%s:internal error ch %d has no bch\n",
-		       __func__, ch);
-		return -EINVAL;
-	}
-	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
-		return -EBUSY; /* b-channel can be only open once */
-	bch->ch.protocol = rq->protocol;
-	hc->chan[ch].rx_off = 0;
-	rq->ch = &bch->ch;
-	if (!try_module_get(THIS_MODULE))
-		printk(KERN_WARNING "%s:cannot get module\n", __func__);
-	return 0;
-}
-
-/*
- * device control function
- */
-static int
-channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
-{
-	struct hfc_multi	*hc = dch->hw;
-	int	ret = 0;
-	int	wd_mode, wd_cnt;
-
-	switch (cq->op) {
-	case MISDN_CTRL_GETOP:
-		cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_L1_TIMER3;
-		break;
-	case MISDN_CTRL_HFC_WD_INIT: /* init the watchdog */
-		wd_cnt = cq->p1 & 0xf;
-		wd_mode = !!(cq->p1 >> 4);
-		if (debug & DEBUG_HFCMULTI_MSG)
-			printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_INIT mode %s"
-			       ", counter 0x%x\n", __func__,
-			       wd_mode ? "AUTO" : "MANUAL", wd_cnt);
-		/* set the watchdog timer */
-		HFC_outb(hc, R_TI_WD, poll_timer | (wd_cnt << 4));
-		hc->hw.r_bert_wd_md = (wd_mode ? V_AUTO_WD_RES : 0);
-		if (hc->ctype == HFC_TYPE_XHFC)
-			hc->hw.r_bert_wd_md |= 0x40 /* V_WD_EN */;
-		/* init the watchdog register and reset the counter */
-		HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);
-		if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-			/* enable the watchdog output for Speech-Design */
-			HFC_outb(hc, R_GPIO_SEL,  V_GPIO_SEL7);
-			HFC_outb(hc, R_GPIO_EN1,  V_GPIO_EN15);
-			HFC_outb(hc, R_GPIO_OUT1, 0);
-			HFC_outb(hc, R_GPIO_OUT1, V_GPIO_OUT15);
-		}
-		break;
-	case MISDN_CTRL_HFC_WD_RESET: /* reset the watchdog counter */
-		if (debug & DEBUG_HFCMULTI_MSG)
-			printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_RESET\n",
-			       __func__);
-		HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);
-		break;
-	case MISDN_CTRL_L1_TIMER3:
-		ret = l1_event(dch->l1, HW_TIMER3_VALUE | (cq->p1 & 0xff));
-		break;
-	default:
-		printk(KERN_WARNING "%s: unknown Op %x\n",
-		       __func__, cq->op);
-		ret = -EINVAL;
-		break;
-	}
-	return ret;
-}
-
-static int
-hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
-{
-	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
-	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
-	struct hfc_multi	*hc = dch->hw;
-	struct channel_req	*rq;
-	int			err = 0;
-	u_long			flags;
-
-	if (dch->debug & DEBUG_HW)
-		printk(KERN_DEBUG "%s: cmd:%x %p\n",
-		       __func__, cmd, arg);
-	switch (cmd) {
-	case OPEN_CHANNEL:
-		rq = arg;
-		switch (rq->protocol) {
-		case ISDN_P_TE_S0:
-		case ISDN_P_NT_S0:
-			if (hc->ctype == HFC_TYPE_E1) {
-				err = -EINVAL;
-				break;
-			}
-			err = open_dchannel(hc, dch, rq); /* locked there */
-			break;
-		case ISDN_P_TE_E1:
-		case ISDN_P_NT_E1:
-			if (hc->ctype != HFC_TYPE_E1) {
-				err = -EINVAL;
-				break;
-			}
-			err = open_dchannel(hc, dch, rq); /* locked there */
-			break;
-		default:
-			spin_lock_irqsave(&hc->lock, flags);
-			err = open_bchannel(hc, dch, rq);
-			spin_unlock_irqrestore(&hc->lock, flags);
-		}
-		break;
-	case CLOSE_CHANNEL:
-		if (debug & DEBUG_HW_OPEN)
-			printk(KERN_DEBUG "%s: dev(%d) close from %p\n",
-			       __func__, dch->dev.id,
-			       __builtin_return_address(0));
-		module_put(THIS_MODULE);
-		break;
-	case CONTROL_CHANNEL:
-		spin_lock_irqsave(&hc->lock, flags);
-		err = channel_dctrl(dch, arg);
-		spin_unlock_irqrestore(&hc->lock, flags);
-		break;
-	default:
-		if (dch->debug & DEBUG_HW)
-			printk(KERN_DEBUG "%s: unknown command %x\n",
-			       __func__, cmd);
-		err = -EINVAL;
-	}
-	return err;
-}
-
-static int
-clockctl(void *priv, int enable)
-{
-	struct hfc_multi *hc = priv;
-
-	hc->iclock_on = enable;
-	return 0;
-}
-
-/*
- * initialize the card
- */
-
-/*
- * start timer irq, wait some time and check if we have interrupts.
- * if not, reset chip and try again.
- */
-static int
-init_card(struct hfc_multi *hc)
-{
-	int	err = -EIO;
-	u_long	flags;
-	void	__iomem *plx_acc;
-	u_long	plx_flags;
-
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: entered\n", __func__);
-
-	spin_lock_irqsave(&hc->lock, flags);
-	/* set interrupts but leave global interrupt disabled */
-	hc->hw.r_irq_ctrl = V_FIFO_IRQ;
-	disable_hwirq(hc);
-	spin_unlock_irqrestore(&hc->lock, flags);
-
-	if (request_irq(hc->irq, hfcmulti_interrupt, IRQF_SHARED,
-			"HFC-multi", hc)) {
-		printk(KERN_WARNING "mISDN: Could not get interrupt %d.\n",
-		       hc->irq);
-		hc->irq = 0;
-		return -EIO;
-	}
-
-	if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-		spin_lock_irqsave(&plx_lock, plx_flags);
-		plx_acc = hc->plx_membase + PLX_INTCSR;
-		writew((PLX_INTCSR_PCIINT_ENABLE | PLX_INTCSR_LINTI1_ENABLE),
-		       plx_acc); /* enable PCI & LINT1 irq */
-		spin_unlock_irqrestore(&plx_lock, plx_flags);
-	}
-
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: IRQ %d count %d\n",
-		       __func__, hc->irq, hc->irqcnt);
-	err = init_chip(hc);
-	if (err)
-		goto error;
-	/*
-	 * Finally enable IRQ output
-	 * this is only allowed, if an IRQ routine is already
-	 * established for this HFC, so don't do that earlier
-	 */
-	spin_lock_irqsave(&hc->lock, flags);
-	enable_hwirq(hc);
-	spin_unlock_irqrestore(&hc->lock, flags);
-	/* printk(KERN_DEBUG "no master irq set!!!\n"); */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout((100 * HZ) / 1000); /* Timeout 100ms */
-	/* turn IRQ off until chip is completely initialized */
-	spin_lock_irqsave(&hc->lock, flags);
-	disable_hwirq(hc);
-	spin_unlock_irqrestore(&hc->lock, flags);
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: IRQ %d count %d\n",
-		       __func__, hc->irq, hc->irqcnt);
-	if (hc->irqcnt) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: done\n", __func__);
-
-		return 0;
-	}
-	if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
-		printk(KERN_INFO "ignoring missing interrupts\n");
-		return 0;
-	}
-
-	printk(KERN_ERR "HFC PCI: IRQ(%d) getting no interrupts during init.\n",
-	       hc->irq);
-
-	err = -EIO;
-
-error:
-	if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-		spin_lock_irqsave(&plx_lock, plx_flags);
-		plx_acc = hc->plx_membase + PLX_INTCSR;
-		writew(0x00, plx_acc); /*disable IRQs*/
-		spin_unlock_irqrestore(&plx_lock, plx_flags);
-	}
-
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: free irq %d\n", __func__, hc->irq);
-	if (hc->irq) {
-		free_irq(hc->irq, hc);
-		hc->irq = 0;
-	}
-
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: done (err=%d)\n", __func__, err);
-	return err;
-}
-
-/*
- * find pci device and set it up
- */
-
-static int
-setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
-	  const struct pci_device_id *ent)
-{
-	struct hm_map	*m = (struct hm_map *)ent->driver_data;
-
-	printk(KERN_INFO
-	       "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",
-	       m->vendor_name, m->card_name, m->clock2 ? "double" : "normal");
-
-	hc->pci_dev = pdev;
-	if (m->clock2)
-		test_and_set_bit(HFC_CHIP_CLOCK2, &hc->chip);
-
-	if (ent->vendor == PCI_VENDOR_ID_DIGIUM &&
-	    ent->device == PCI_DEVICE_ID_DIGIUM_HFC4S) {
-		test_and_set_bit(HFC_CHIP_B410P, &hc->chip);
-		test_and_set_bit(HFC_CHIP_PCM_MASTER, &hc->chip);
-		test_and_clear_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
-		hc->slots = 32;
-	}
-
-	if (hc->pci_dev->irq <= 0) {
-		printk(KERN_WARNING "HFC-multi: No IRQ for PCI card found.\n");
-		return -EIO;
-	}
-	if (pci_enable_device(hc->pci_dev)) {
-		printk(KERN_WARNING "HFC-multi: Error enabling PCI card.\n");
-		return -EIO;
-	}
-	hc->leds = m->leds;
-	hc->ledstate = 0xAFFEAFFE;
-	hc->opticalsupport = m->opticalsupport;
-
-	hc->pci_iobase = 0;
-	hc->pci_membase = NULL;
-	hc->plx_membase = NULL;
-
-	/* set memory access methods */
-	if (m->io_mode) /* use mode from card config */
-		hc->io_mode = m->io_mode;
-	switch (hc->io_mode) {
-	case HFC_IO_MODE_PLXSD:
-		test_and_set_bit(HFC_CHIP_PLXSD, &hc->chip);
-		hc->slots = 128; /* required */
-		hc->HFC_outb = HFC_outb_pcimem;
-		hc->HFC_inb = HFC_inb_pcimem;
-		hc->HFC_inw = HFC_inw_pcimem;
-		hc->HFC_wait = HFC_wait_pcimem;
-		hc->read_fifo = read_fifo_pcimem;
-		hc->write_fifo = write_fifo_pcimem;
-		hc->plx_origmembase =  hc->pci_dev->resource[0].start;
-		/* MEMBASE 1 is PLX PCI Bridge */
-
-		if (!hc->plx_origmembase) {
-			printk(KERN_WARNING
-			       "HFC-multi: No IO-Memory for PCI PLX bridge found\n");
-			pci_disable_device(hc->pci_dev);
-			return -EIO;
-		}
-
-		hc->plx_membase = ioremap(hc->plx_origmembase, 0x80);
-		if (!hc->plx_membase) {
-			printk(KERN_WARNING
-			       "HFC-multi: failed to remap plx address space. "
-			       "(internal error)\n");
-			pci_disable_device(hc->pci_dev);
-			return -EIO;
-		}
-		printk(KERN_INFO
-		       "HFC-multi: plx_membase:%#lx plx_origmembase:%#lx\n",
-		       (u_long)hc->plx_membase, hc->plx_origmembase);
-
-		hc->pci_origmembase =  hc->pci_dev->resource[2].start;
-		/* MEMBASE 1 is PLX PCI Bridge */
-		if (!hc->pci_origmembase) {
-			printk(KERN_WARNING
-			       "HFC-multi: No IO-Memory for PCI card found\n");
-			pci_disable_device(hc->pci_dev);
-			return -EIO;
-		}
-
-		hc->pci_membase = ioremap(hc->pci_origmembase, 0x400);
-		if (!hc->pci_membase) {
-			printk(KERN_WARNING "HFC-multi: failed to remap io "
-			       "address space. (internal error)\n");
-			pci_disable_device(hc->pci_dev);
-			return -EIO;
-		}
-
-		printk(KERN_INFO
-		       "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d HZ %d "
-		       "leds-type %d\n",
-		       hc->id, (u_long)hc->pci_membase, hc->pci_origmembase,
-		       hc->pci_dev->irq, HZ, hc->leds);
-		pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO);
-		break;
-	case HFC_IO_MODE_PCIMEM:
-		hc->HFC_outb = HFC_outb_pcimem;
-		hc->HFC_inb = HFC_inb_pcimem;
-		hc->HFC_inw = HFC_inw_pcimem;
-		hc->HFC_wait = HFC_wait_pcimem;
-		hc->read_fifo = read_fifo_pcimem;
-		hc->write_fifo = write_fifo_pcimem;
-		hc->pci_origmembase = hc->pci_dev->resource[1].start;
-		if (!hc->pci_origmembase) {
-			printk(KERN_WARNING
-			       "HFC-multi: No IO-Memory for PCI card found\n");
-			pci_disable_device(hc->pci_dev);
-			return -EIO;
-		}
-
-		hc->pci_membase = ioremap(hc->pci_origmembase, 256);
-		if (!hc->pci_membase) {
-			printk(KERN_WARNING
-			       "HFC-multi: failed to remap io address space. "
-			       "(internal error)\n");
-			pci_disable_device(hc->pci_dev);
-			return -EIO;
-		}
-		printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ "
-		       "%d HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase,
-		       hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds);
-		pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO);
-		break;
-	case HFC_IO_MODE_REGIO:
-		hc->HFC_outb = HFC_outb_regio;
-		hc->HFC_inb = HFC_inb_regio;
-		hc->HFC_inw = HFC_inw_regio;
-		hc->HFC_wait = HFC_wait_regio;
-		hc->read_fifo = read_fifo_regio;
-		hc->write_fifo = write_fifo_regio;
-		hc->pci_iobase = (u_int) hc->pci_dev->resource[0].start;
-		if (!hc->pci_iobase) {
-			printk(KERN_WARNING
-			       "HFC-multi: No IO for PCI card found\n");
-			pci_disable_device(hc->pci_dev);
-			return -EIO;
-		}
-
-		if (!request_region(hc->pci_iobase, 8, "hfcmulti")) {
-			printk(KERN_WARNING "HFC-multi: failed to request "
-			       "address space at 0x%08lx (internal error)\n",
-			       hc->pci_iobase);
-			pci_disable_device(hc->pci_dev);
-			return -EIO;
-		}
-
-		printk(KERN_INFO
-		       "%s %s: defined at IOBASE %#x IRQ %d HZ %d leds-type %d\n",
-		       m->vendor_name, m->card_name, (u_int) hc->pci_iobase,
-		       hc->pci_dev->irq, HZ, hc->leds);
-		pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_REGIO);
-		break;
-	default:
-		printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n");
-		pci_disable_device(hc->pci_dev);
-		return -EIO;
-	}
-
-	pci_set_drvdata(hc->pci_dev, hc);
-
-	/* At this point the needed PCI config is done */
-	/* fifos are still not enabled */
-	return 0;
-}
-
-
-/*
- * remove port
- */
-
-static void
-release_port(struct hfc_multi *hc, struct dchannel *dch)
-{
-	int	pt, ci, i = 0;
-	u_long	flags;
-	struct bchannel *pb;
-
-	ci = dch->slot;
-	pt = hc->chan[ci].port;
-
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: entered for port %d\n",
-		       __func__, pt + 1);
-
-	if (pt >= hc->ports) {
-		printk(KERN_WARNING "%s: ERROR port out of range (%d).\n",
-		       __func__, pt + 1);
-		return;
-	}
-
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: releasing port=%d\n",
-		       __func__, pt + 1);
-
-	if (dch->dev.D.protocol == ISDN_P_TE_S0)
-		l1_event(dch->l1, CLOSE_CHANNEL);
-
-	hc->chan[ci].dch = NULL;
-
-	if (hc->created[pt]) {
-		hc->created[pt] = 0;
-		mISDN_unregister_device(&dch->dev);
-	}
-
-	spin_lock_irqsave(&hc->lock, flags);
-
-	if (dch->timer.function) {
-		timer_delete(&dch->timer);
-		dch->timer.function = NULL;
-	}
-
-	if (hc->ctype == HFC_TYPE_E1) { /* E1 */
-		/* remove sync */
-		if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-			hc->syncronized = 0;
-			plxsd_checksync(hc, 1);
-		}
-		/* free channels */
-		for (i = 0; i <= 31; i++) {
-			if (!((1 << i) & hc->bmask[pt])) /* skip unused chan */
-				continue;
-			if (hc->chan[i].bch) {
-				if (debug & DEBUG_HFCMULTI_INIT)
-					printk(KERN_DEBUG
-					       "%s: free port %d channel %d\n",
-					       __func__, hc->chan[i].port + 1, i);
-				pb = hc->chan[i].bch;
-				hc->chan[i].bch = NULL;
-				spin_unlock_irqrestore(&hc->lock, flags);
-				mISDN_freebchannel(pb);
-				kfree(pb);
-				kfree(hc->chan[i].coeff);
-				spin_lock_irqsave(&hc->lock, flags);
-			}
-		}
-	} else {
-		/* remove sync */
-		if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
-			hc->syncronized &=
-				~(1 << hc->chan[ci].port);
-			plxsd_checksync(hc, 1);
-		}
-		/* free channels */
-		if (hc->chan[ci - 2].bch) {
-			if (debug & DEBUG_HFCMULTI_INIT)
-				printk(KERN_DEBUG
-				       "%s: free port %d channel %d\n",
-				       __func__, hc->chan[ci - 2].port + 1,
-				       ci - 2);
-			pb = hc->chan[ci - 2].bch;
-			hc->chan[ci - 2].bch = NULL;
-			spin_unlock_irqrestore(&hc->lock, flags);
-			mISDN_freebchannel(pb);
-			kfree(pb);
-			kfree(hc->chan[ci - 2].coeff);
-			spin_lock_irqsave(&hc->lock, flags);
-		}
-		if (hc->chan[ci - 1].bch) {
-			if (debug & DEBUG_HFCMULTI_INIT)
-				printk(KERN_DEBUG
-				       "%s: free port %d channel %d\n",
-				       __func__, hc->chan[ci - 1].port + 1,
-				       ci - 1);
-			pb = hc->chan[ci - 1].bch;
-			hc->chan[ci - 1].bch = NULL;
-			spin_unlock_irqrestore(&hc->lock, flags);
-			mISDN_freebchannel(pb);
-			kfree(pb);
-			kfree(hc->chan[ci - 1].coeff);
-			spin_lock_irqsave(&hc->lock, flags);
-		}
-	}
-
-	spin_unlock_irqrestore(&hc->lock, flags);
-
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: free port %d channel D(%d)\n", __func__,
-			pt+1, ci);
-	mISDN_freedchannel(dch);
-	kfree(dch);
-
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: done!\n", __func__);
-}
-
-static void
-release_card(struct hfc_multi *hc)
-{
-	u_long	flags;
-	int	ch;
-
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: release card (%d) entered\n",
-		       __func__, hc->id);
-
-	/* unregister clock source */
-	if (hc->iclock)
-		mISDN_unregister_clock(hc->iclock);
-
-	/* disable and free irq */
-	spin_lock_irqsave(&hc->lock, flags);
-	disable_hwirq(hc);
-	spin_unlock_irqrestore(&hc->lock, flags);
-	udelay(1000);
-	if (hc->irq) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: free irq %d (hc=%p)\n",
-			    __func__, hc->irq, hc);
-		free_irq(hc->irq, hc);
-		hc->irq = 0;
-
-	}
-
-	/* disable D-channels & B-channels */
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: disable all channels (d and b)\n",
-		       __func__);
-	for (ch = 0; ch <= 31; ch++) {
-		if (hc->chan[ch].dch)
-			release_port(hc, hc->chan[ch].dch);
-	}
-
-	/* dimm leds */
-	if (hc->leds)
-		hfcmulti_leds(hc);
-
-	/* release hardware */
-	release_io_hfcmulti(hc);
-
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: remove instance from list\n",
-		       __func__);
-	list_del(&hc->list);
-
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: delete instance\n", __func__);
-	if (hc == syncmaster)
-		syncmaster = NULL;
-	kfree(hc);
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: card successfully removed\n",
-		       __func__);
-}
-
-static void
-init_e1_port_hw(struct hfc_multi *hc, struct hm_map *m)
-{
-	/* set optical line type */
-	if (port[Port_cnt] & 0x001) {
-		if (!m->opticalsupport)  {
-			printk(KERN_INFO
-			       "This board has no optical "
-			       "support\n");
-		} else {
-			if (debug & DEBUG_HFCMULTI_INIT)
-				printk(KERN_DEBUG
-				       "%s: PORT set optical "
-				       "interface: card(%d) "
-				       "port(%d)\n",
-				       __func__,
-				       HFC_cnt + 1, 1);
-			test_and_set_bit(HFC_CFG_OPTICAL,
-			    &hc->chan[hc->dnum[0]].cfg);
-		}
-	}
-	/* set LOS report */
-	if (port[Port_cnt] & 0x004) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: PORT set "
-			       "LOS report: card(%d) port(%d)\n",
-			       __func__, HFC_cnt + 1, 1);
-		test_and_set_bit(HFC_CFG_REPORT_LOS,
-		    &hc->chan[hc->dnum[0]].cfg);
-	}
-	/* set AIS report */
-	if (port[Port_cnt] & 0x008) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: PORT set "
-			       "AIS report: card(%d) port(%d)\n",
-			       __func__, HFC_cnt + 1, 1);
-		test_and_set_bit(HFC_CFG_REPORT_AIS,
-		    &hc->chan[hc->dnum[0]].cfg);
-	}
-	/* set SLIP report */
-	if (port[Port_cnt] & 0x010) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG
-			       "%s: PORT set SLIP report: "
-			       "card(%d) port(%d)\n",
-			       __func__, HFC_cnt + 1, 1);
-		test_and_set_bit(HFC_CFG_REPORT_SLIP,
-		    &hc->chan[hc->dnum[0]].cfg);
-	}
-	/* set RDI report */
-	if (port[Port_cnt] & 0x020) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG
-			       "%s: PORT set RDI report: "
-			       "card(%d) port(%d)\n",
-			       __func__, HFC_cnt + 1, 1);
-		test_and_set_bit(HFC_CFG_REPORT_RDI,
-		    &hc->chan[hc->dnum[0]].cfg);
-	}
-	/* set CRC-4 Mode */
-	if (!(port[Port_cnt] & 0x100)) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: PORT turn on CRC4 report:"
-			       " card(%d) port(%d)\n",
-			       __func__, HFC_cnt + 1, 1);
-		test_and_set_bit(HFC_CFG_CRC4,
-		    &hc->chan[hc->dnum[0]].cfg);
-	} else {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: PORT turn off CRC4"
-			       " report: card(%d) port(%d)\n",
-			       __func__, HFC_cnt + 1, 1);
-	}
-	/* set forced clock */
-	if (port[Port_cnt] & 0x0200) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: PORT force getting clock from "
-			       "E1: card(%d) port(%d)\n",
-			       __func__, HFC_cnt + 1, 1);
-		test_and_set_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip);
-	} else
-		if (port[Port_cnt] & 0x0400) {
-			if (debug & DEBUG_HFCMULTI_INIT)
-				printk(KERN_DEBUG "%s: PORT force putting clock to "
-				       "E1: card(%d) port(%d)\n",
-				       __func__, HFC_cnt + 1, 1);
-			test_and_set_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip);
-		}
-	/* set JATT PLL */
-	if (port[Port_cnt] & 0x0800) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: PORT disable JATT PLL on "
-			       "E1: card(%d) port(%d)\n",
-			       __func__, HFC_cnt + 1, 1);
-		test_and_set_bit(HFC_CHIP_RX_SYNC, &hc->chip);
-	}
-	/* set elastic jitter buffer */
-	if (port[Port_cnt] & 0x3000) {
-		hc->chan[hc->dnum[0]].jitter = (port[Port_cnt]>>12) & 0x3;
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG
-			       "%s: PORT set elastic "
-			       "buffer to %d: card(%d) port(%d)\n",
-			    __func__, hc->chan[hc->dnum[0]].jitter,
-			       HFC_cnt + 1, 1);
-	} else
-		hc->chan[hc->dnum[0]].jitter = 2; /* default */
-}
-
-static int
-init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt)
-{
-	struct dchannel	*dch;
-	struct bchannel	*bch;
-	int		ch, ret = 0;
-	char		name[MISDN_MAX_IDLEN];
-	int		bcount = 0;
-
-	dch = kzalloc_obj(struct dchannel);
-	if (!dch)
-		return -ENOMEM;
-	dch->debug = debug;
-	mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change);
-	dch->hw = hc;
-	dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1);
-	dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-	    (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
-	dch->dev.D.send = handle_dmsg;
-	dch->dev.D.ctrl = hfcm_dctrl;
-	dch->slot = hc->dnum[pt];
-	hc->chan[hc->dnum[pt]].dch = dch;
-	hc->chan[hc->dnum[pt]].port = pt;
-	hc->chan[hc->dnum[pt]].nt_timer = -1;
-	for (ch = 1; ch <= 31; ch++) {
-		if (!((1 << ch) & hc->bmask[pt])) /* skip unused channel */
-			continue;
-		bch = kzalloc_obj(struct bchannel);
-		if (!bch) {
-			printk(KERN_ERR "%s: no memory for bchannel\n",
-			    __func__);
-			ret = -ENOMEM;
-			goto free_chan;
-		}
-		hc->chan[ch].coeff = kzalloc(512, GFP_KERNEL);
-		if (!hc->chan[ch].coeff) {
-			printk(KERN_ERR "%s: no memory for coeffs\n",
-			    __func__);
-			ret = -ENOMEM;
-			kfree(bch);
-			goto free_chan;
-		}
-		bch->nr = ch;
-		bch->slot = ch;
-		bch->debug = debug;
-		mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1);
-		bch->hw = hc;
-		bch->ch.send = handle_bmsg;
-		bch->ch.ctrl = hfcm_bctrl;
-		bch->ch.nr = ch;
-		list_add(&bch->ch.list, &dch->dev.bchannels);
-		hc->chan[ch].bch = bch;
-		hc->chan[ch].port = pt;
-		set_channelmap(bch->nr, dch->dev.channelmap);
-		bcount++;
-	}
-	dch->dev.nrbchan = bcount;
-	if (pt == 0)
-		init_e1_port_hw(hc, m);
-	if (hc->ports > 1)
-		snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d-%d",
-				HFC_cnt + 1, pt+1);
-	else
-		snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
-	ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
-	if (ret)
-		goto free_chan;
-	hc->created[pt] = 1;
-	return ret;
-free_chan:
-	release_port(hc, dch);
-	return ret;
-}
-
-static int
-init_multi_port(struct hfc_multi *hc, int pt)
-{
-	struct dchannel	*dch;
-	struct bchannel	*bch;
-	int		ch, i, ret = 0;
-	char		name[MISDN_MAX_IDLEN];
-
-	dch = kzalloc_obj(struct dchannel);
-	if (!dch)
-		return -ENOMEM;
-	dch->debug = debug;
-	mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change);
-	dch->hw = hc;
-	dch->dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
-	dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
-	dch->dev.D.send = handle_dmsg;
-	dch->dev.D.ctrl = hfcm_dctrl;
-	dch->dev.nrbchan = 2;
-	i = pt << 2;
-	dch->slot = i + 2;
-	hc->chan[i + 2].dch = dch;
-	hc->chan[i + 2].port = pt;
-	hc->chan[i + 2].nt_timer = -1;
-	for (ch = 0; ch < dch->dev.nrbchan; ch++) {
-		bch = kzalloc_obj(struct bchannel);
-		if (!bch) {
-			printk(KERN_ERR "%s: no memory for bchannel\n",
-			       __func__);
-			ret = -ENOMEM;
-			goto free_chan;
-		}
-		hc->chan[i + ch].coeff = kzalloc(512, GFP_KERNEL);
-		if (!hc->chan[i + ch].coeff) {
-			printk(KERN_ERR "%s: no memory for coeffs\n",
-			       __func__);
-			ret = -ENOMEM;
-			kfree(bch);
-			goto free_chan;
-		}
-		bch->nr = ch + 1;
-		bch->slot = i + ch;
-		bch->debug = debug;
-		mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1);
-		bch->hw = hc;
-		bch->ch.send = handle_bmsg;
-		bch->ch.ctrl = hfcm_bctrl;
-		bch->ch.nr = ch + 1;
-		list_add(&bch->ch.list, &dch->dev.bchannels);
-		hc->chan[i + ch].bch = bch;
-		hc->chan[i + ch].port = pt;
-		set_channelmap(bch->nr, dch->dev.channelmap);
-	}
-	/* set master clock */
-	if (port[Port_cnt] & 0x001) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG
-			       "%s: PROTOCOL set master clock: "
-			       "card(%d) port(%d)\n",
-			       __func__, HFC_cnt + 1, pt + 1);
-		if (dch->dev.D.protocol != ISDN_P_TE_S0) {
-			printk(KERN_ERR "Error: Master clock "
-			       "for port(%d) of card(%d) is only"
-			       " possible with TE-mode\n",
-			       pt + 1, HFC_cnt + 1);
-			ret = -EINVAL;
-			goto free_chan;
-		}
-		if (hc->masterclk >= 0) {
-			printk(KERN_ERR "Error: Master clock "
-			       "for port(%d) of card(%d) already "
-			       "defined for port(%d)\n",
-			       pt + 1, HFC_cnt + 1, hc->masterclk + 1);
-			ret = -EINVAL;
-			goto free_chan;
-		}
-		hc->masterclk = pt;
-	}
-	/* set transmitter line to non capacitive */
-	if (port[Port_cnt] & 0x002) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG
-			       "%s: PROTOCOL set non capacitive "
-			       "transmitter: card(%d) port(%d)\n",
-			       __func__, HFC_cnt + 1, pt + 1);
-		test_and_set_bit(HFC_CFG_NONCAP_TX,
-				 &hc->chan[i + 2].cfg);
-	}
-	/* disable E-channel */
-	if (port[Port_cnt] & 0x004) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG
-			       "%s: PROTOCOL disable E-channel: "
-			       "card(%d) port(%d)\n",
-			       __func__, HFC_cnt + 1, pt + 1);
-		test_and_set_bit(HFC_CFG_DIS_ECHANNEL,
-				 &hc->chan[i + 2].cfg);
-	}
-	if (hc->ctype == HFC_TYPE_XHFC) {
-		snprintf(name, MISDN_MAX_IDLEN - 1, "xhfc.%d-%d",
-			 HFC_cnt + 1, pt + 1);
-		ret = mISDN_register_device(&dch->dev, NULL, name);
-	} else {
-		snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d-%d",
-			 hc->ctype, HFC_cnt + 1, pt + 1);
-		ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
-	}
-	if (ret)
-		goto free_chan;
-	hc->created[pt] = 1;
-	return ret;
-free_chan:
-	release_port(hc, dch);
-	return ret;
-}
-
-static int
-hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
-	      const struct pci_device_id *ent)
-{
-	int		ret_err = 0;
-	int		pt;
-	struct hfc_multi	*hc;
-	u_long		flags;
-	u_char		dips = 0, pmj = 0; /* dip settings, port mode Jumpers */
-	int		i, ch;
-	u_int		maskcheck;
-
-	if (HFC_cnt >= MAX_CARDS) {
-		printk(KERN_ERR "too many cards (max=%d).\n",
-		       MAX_CARDS);
-		return -EINVAL;
-	}
-	if ((type[HFC_cnt] & 0xff) && (type[HFC_cnt] & 0xff) != m->type) {
-		printk(KERN_WARNING "HFC-MULTI: Card '%s:%s' type %d found but "
-		       "type[%d] %d was supplied as module parameter\n",
-		       m->vendor_name, m->card_name, m->type, HFC_cnt,
-		       type[HFC_cnt] & 0xff);
-		printk(KERN_WARNING "HFC-MULTI: Load module without parameters "
-		       "first, to see cards and their types.");
-		return -EINVAL;
-	}
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: Registering %s:%s chip type %d (0x%x)\n",
-		       __func__, m->vendor_name, m->card_name, m->type,
-		       type[HFC_cnt]);
-
-	/* allocate card+fifo structure */
-	hc = kzalloc_obj(struct hfc_multi);
-	if (!hc) {
-		printk(KERN_ERR "No kmem for HFC-Multi card\n");
-		return -ENOMEM;
-	}
-	spin_lock_init(&hc->lock);
-	hc->mtyp = m;
-	hc->ctype =  m->type;
-	hc->ports = m->ports;
-	hc->id = HFC_cnt;
-	hc->pcm = pcm[HFC_cnt];
-	hc->io_mode = iomode[HFC_cnt];
-	if (hc->ctype == HFC_TYPE_E1 && dmask[E1_cnt]) {
-		/* fragment card */
-		pt = 0;
-		maskcheck = 0;
-		for (ch = 0; ch <= 31; ch++) {
-			if (!((1 << ch) & dmask[E1_cnt]))
-				continue;
-			hc->dnum[pt] = ch;
-			hc->bmask[pt] = bmask[bmask_cnt++];
-			if ((maskcheck & hc->bmask[pt])
-			 || (dmask[E1_cnt] & hc->bmask[pt])) {
-				printk(KERN_INFO
-				       "HFC-E1 #%d has overlapping B-channels on fragment #%d\n",
-				       E1_cnt + 1, pt);
-				kfree(hc);
-				return -EINVAL;
-			}
-			maskcheck |= hc->bmask[pt];
-			printk(KERN_INFO
-			       "HFC-E1 #%d uses D-channel on slot %d and a B-channel map of 0x%08x\n",
-				E1_cnt + 1, ch, hc->bmask[pt]);
-			pt++;
-		}
-		hc->ports = pt;
-	}
-	if (hc->ctype == HFC_TYPE_E1 && !dmask[E1_cnt]) {
-		/* default card layout */
-		hc->dnum[0] = 16;
-		hc->bmask[0] = 0xfffefffe;
-		hc->ports = 1;
-	}
-
-	/* set chip specific features */
-	hc->masterclk = -1;
-	if (type[HFC_cnt] & 0x100) {
-		test_and_set_bit(HFC_CHIP_ULAW, &hc->chip);
-		hc->silence = 0xff; /* ulaw silence */
-	} else
-		hc->silence = 0x2a; /* alaw silence */
-	if ((poll >> 1) > sizeof(hc->silence_data)) {
-		printk(KERN_ERR "HFCMULTI error: silence_data too small, "
-		       "please fix\n");
-		kfree(hc);
-		return -EINVAL;
-	}
-	for (i = 0; i < (poll >> 1); i++)
-		hc->silence_data[i] = hc->silence;
-
-	if (hc->ctype != HFC_TYPE_XHFC) {
-		if (!(type[HFC_cnt] & 0x200))
-			test_and_set_bit(HFC_CHIP_DTMF, &hc->chip);
-		test_and_set_bit(HFC_CHIP_CONF, &hc->chip);
-	}
-
-	if (type[HFC_cnt] & 0x800)
-		test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
-	if (type[HFC_cnt] & 0x1000) {
-		test_and_set_bit(HFC_CHIP_PCM_MASTER, &hc->chip);
-		test_and_clear_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
-	}
-	if (type[HFC_cnt] & 0x4000)
-		test_and_set_bit(HFC_CHIP_EXRAM_128, &hc->chip);
-	if (type[HFC_cnt] & 0x8000)
-		test_and_set_bit(HFC_CHIP_EXRAM_512, &hc->chip);
-	hc->slots = 32;
-	if (type[HFC_cnt] & 0x10000)
-		hc->slots = 64;
-	if (type[HFC_cnt] & 0x20000)
-		hc->slots = 128;
-	if (type[HFC_cnt] & 0x80000) {
-		test_and_set_bit(HFC_CHIP_WATCHDOG, &hc->chip);
-		hc->wdcount = 0;
-		hc->wdbyte = V_GPIO_OUT2;
-		printk(KERN_NOTICE "Watchdog enabled\n");
-	}
-
-	if (pdev && ent)
-		/* setup pci, hc->slots may change due to PLXSD */
-		ret_err = setup_pci(hc, pdev, ent);
-	else
-#ifdef CONFIG_MISDN_HFCMULTI_8xx
-		ret_err = setup_embedded(hc, m);
-#else
-	{
-		printk(KERN_WARNING "Embedded IO Mode not selected\n");
-		ret_err = -EIO;
-	}
-#endif
-	if (ret_err) {
-		if (hc == syncmaster)
-			syncmaster = NULL;
-		kfree(hc);
-		return ret_err;
-	}
-
-	hc->HFC_outb_nodebug = hc->HFC_outb;
-	hc->HFC_inb_nodebug = hc->HFC_inb;
-	hc->HFC_inw_nodebug = hc->HFC_inw;
-	hc->HFC_wait_nodebug = hc->HFC_wait;
-#ifdef HFC_REGISTER_DEBUG
-	hc->HFC_outb = HFC_outb_debug;
-	hc->HFC_inb = HFC_inb_debug;
-	hc->HFC_inw = HFC_inw_debug;
-	hc->HFC_wait = HFC_wait_debug;
-#endif
-	/* create channels */
-	for (pt = 0; pt < hc->ports; pt++) {
-		if (Port_cnt >= MAX_PORTS) {
-			printk(KERN_ERR "too many ports (max=%d).\n",
-			       MAX_PORTS);
-			ret_err = -EINVAL;
-			goto free_card;
-		}
-		if (hc->ctype == HFC_TYPE_E1)
-			ret_err = init_e1_port(hc, m, pt);
-		else
-			ret_err = init_multi_port(hc, pt);
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG
-			    "%s: Registering D-channel, card(%d) port(%d) "
-			       "result %d\n",
-			    __func__, HFC_cnt + 1, pt + 1, ret_err);
-
-		if (ret_err) {
-			while (pt) { /* release already registered ports */
-				pt--;
-				if (hc->ctype == HFC_TYPE_E1)
-					release_port(hc,
-						hc->chan[hc->dnum[pt]].dch);
-				else
-					release_port(hc,
-						hc->chan[(pt << 2) + 2].dch);
-			}
-			goto free_card;
-		}
-		if (hc->ctype != HFC_TYPE_E1)
-			Port_cnt++; /* for each S0 port */
-	}
-	if (hc->ctype == HFC_TYPE_E1) {
-		Port_cnt++; /* for each E1 port */
-		E1_cnt++;
-	}
-
-	/* disp switches */
-	switch (m->dip_type) {
-	case DIP_4S:
-		/*
-		 * Get DIP setting for beroNet 1S/2S/4S cards
-		 * DIP Setting: (collect GPIO 13/14/15 (R_GPIO_IN1) +
-		 * GPI 19/23 (R_GPI_IN2))
-		 */
-		dips = ((~HFC_inb(hc, R_GPIO_IN1) & 0xE0) >> 5) |
-			((~HFC_inb(hc, R_GPI_IN2) & 0x80) >> 3) |
-			(~HFC_inb(hc, R_GPI_IN2) & 0x08);
-
-		/* Port mode (TE/NT) jumpers */
-		pmj = ((HFC_inb(hc, R_GPI_IN3) >> 4)  & 0xf);
-
-		if (test_bit(HFC_CHIP_B410P, &hc->chip))
-			pmj = ~pmj & 0xf;
-
-		printk(KERN_INFO "%s: %s DIPs(0x%x) jumpers(0x%x)\n",
-		       m->vendor_name, m->card_name, dips, pmj);
-		break;
-	case DIP_8S:
-		/*
-		 * Get DIP Setting for beroNet 8S0+ cards
-		 * Enable PCI auxbridge function
-		 */
-		HFC_outb(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK);
-		/* prepare access to auxport */
-		outw(0x4000, hc->pci_iobase + 4);
-		/*
-		 * some dummy reads are required to
-		 * read valid DIP switch data
-		 */
-		dips = inb(hc->pci_iobase);
-		dips = inb(hc->pci_iobase);
-		dips = inb(hc->pci_iobase);
-		dips = ~inb(hc->pci_iobase) & 0x3F;
-		outw(0x0, hc->pci_iobase + 4);
-		/* disable PCI auxbridge function */
-		HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK);
-		printk(KERN_INFO "%s: %s DIPs(0x%x)\n",
-		       m->vendor_name, m->card_name, dips);
-		break;
-	case DIP_E1:
-		/*
-		 * get DIP Setting for beroNet E1 cards
-		 * DIP Setting: collect GPI 4/5/6/7 (R_GPI_IN0)
-		 */
-		dips = (~HFC_inb(hc, R_GPI_IN0) & 0xF0) >> 4;
-		printk(KERN_INFO "%s: %s DIPs(0x%x)\n",
-		       m->vendor_name, m->card_name, dips);
-		break;
-	}
-
-	/* add to list */
-	spin_lock_irqsave(&HFClock, flags);
-	list_add_tail(&hc->list, &HFClist);
-	spin_unlock_irqrestore(&HFClock, flags);
-
-	/* use as clock source */
-	if (clock == HFC_cnt + 1)
-		hc->iclock = mISDN_register_clock("HFCMulti", 0, clockctl, hc);
-
-	/* initialize hardware */
-	hc->irq = (m->irq) ? : hc->pci_dev->irq;
-	ret_err = init_card(hc);
-	if (ret_err) {
-		printk(KERN_ERR "init card returns %d\n", ret_err);
-		release_card(hc);
-		return ret_err;
-	}
-
-	/* start IRQ and return */
-	spin_lock_irqsave(&hc->lock, flags);
-	enable_hwirq(hc);
-	spin_unlock_irqrestore(&hc->lock, flags);
-	return 0;
-
-free_card:
-	release_io_hfcmulti(hc);
-	if (hc == syncmaster)
-		syncmaster = NULL;
-	kfree(hc);
-	return ret_err;
-}
-
-static void hfc_remove_pci(struct pci_dev *pdev)
-{
-	struct hfc_multi	*card = pci_get_drvdata(pdev);
-	u_long			flags;
-
-	if (debug)
-		printk(KERN_INFO "removing hfc_multi card vendor:%x "
-		       "device:%x subvendor:%x subdevice:%x\n",
-		       pdev->vendor, pdev->device,
-		       pdev->subsystem_vendor, pdev->subsystem_device);
-
-	if (card) {
-		spin_lock_irqsave(&HFClock, flags);
-		release_card(card);
-		spin_unlock_irqrestore(&HFClock, flags);
-	}  else {
-		if (debug)
-			printk(KERN_DEBUG "%s: drvdata already removed\n",
-			       __func__);
-	}
-}
-
-#define	VENDOR_CCD	"Cologne Chip AG"
-#define	VENDOR_BN	"beroNet GmbH"
-#define	VENDOR_DIG	"Digium Inc."
-#define VENDOR_JH	"Junghanns.NET GmbH"
-#define VENDOR_PRIM	"PrimuX"
-
-static const struct hm_map hfcm_map[] = {
-	/*0*/	{VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0, 0},
-	/*1*/	{VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
-	/*2*/	{VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
-	/*3*/	{VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
-	/*4*/	{VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0, 0},
-	/*5*/	{VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0, 0},
-	/*6*/	{VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
-	/*7*/	{VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0, 0},
-	/*8*/	{VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO, 0},
-	/*9*/	{VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0, 0},
-	/*10*/	{VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0, 0},
-	/*11*/	{VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0, 0},
-
-	/*12*/	{VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0, 0},
-	/*13*/	{VENDOR_BN, "HFC-8S Card (+)", 8, 8, 1, 8, 0, DIP_8S,
-		 HFC_IO_MODE_REGIO, 0},
-	/*14*/	{VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0, 0},
-	/*15*/	{VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0, 0},
-
-	/*16*/	{VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0, 0},
-	/*17*/	{VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},
-	/*18*/	{VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},
-
-	/*19*/	{VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
-	/*20*/	{VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0, 0},
-	/*21*/	{VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
-	/*22*/	{VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
-
-	/*23*/	{VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0, 0},
-	/*24*/	{VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0, 0},
-	/*25*/	{VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0, 0},
-
-	/*26*/	{VENDOR_CCD, "HFC-4S Speech Design", 4, 4, 0, 0, 0, 0,
-		 HFC_IO_MODE_PLXSD, 0},
-	/*27*/	{VENDOR_CCD, "HFC-E1 Speech Design", 1, 1, 0, 0, 0, 0,
-		 HFC_IO_MODE_PLXSD, 0},
-	/*28*/	{VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0, 0},
-	/*29*/	{VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0, 0},
-	/*30*/	{VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0, 0},
-	/*31*/	{VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0,
-		 HFC_IO_MODE_EMBSD, XHFC_IRQ},
-	/*32*/	{VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0},
-	/*33*/	{VENDOR_BN, "HFC-2S Beronet Card PCIe", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
-	/*34*/	{VENDOR_BN, "HFC-4S Beronet Card PCIe", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
-};
-
-#undef H
-#define H(x)	((unsigned long)&hfcm_map[x])
-static const struct pci_device_id hfmultipci_ids[] = {
-
-	/* Cards with HFC-4S Chip */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_BN1SM, 0, 0, H(0)}, /* BN1S mini PCI */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_BN2S, 0, 0, H(1)}, /* BN2S */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_BN2SM, 0, 0, H(2)}, /* BN2S mini PCI */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_BN4S, 0, 0, H(3)}, /* BN4S */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_BN4SM, 0, 0, H(4)}, /* BN4S mini PCI */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-	  PCI_DEVICE_ID_CCD_HFC4S, 0, 0, H(5)}, /* Old Eval */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_IOB4ST, 0, 0, H(6)}, /* IOB4ST */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_HFC4S, 0, 0, H(7)}, /* 4S */
-	{ PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S,
-	  PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S, 0, 0, H(8)},
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_SWYX4S, 0, 0, H(9)}, /* 4S Swyx */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_JH4S20, 0, 0, H(10)},
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_PMX2S, 0, 0, H(11)}, /* Primux */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-	  0xb761, 0, 0, H(33)}, /* BN2S PCIe */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-	  0xb762, 0, 0, H(34)}, /* BN4S PCIe */
-
-	/* Cards with HFC-8S Chip */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_BN8S, 0, 0, H(12)}, /* BN8S */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_BN8SP, 0, 0, H(13)}, /* BN8S+ */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-	  PCI_DEVICE_ID_CCD_HFC8S, 0, 0, H(14)}, /* old Eval */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_IOB8STR, 0, 0, H(15)}, /* IOB8ST Recording */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_IOB8ST, 0, 0, H(16)}, /* IOB8ST  */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_IOB8ST_1, 0, 0, H(17)}, /* IOB8ST  */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_HFC8S, 0, 0, H(18)}, /* 8S */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_OV8S, 0, 0, H(30)}, /* OpenVox 8 */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_JH8S, 0, 0, H(32)}, /* Junganns 8S  */
-
-
-	/* Cards with HFC-E1 Chip */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_BNE1, 0, 0, H(19)}, /* BNE1 */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_BNE1M, 0, 0, H(20)}, /* BNE1 mini PCI */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_BNE1DP, 0, 0, H(21)}, /* BNE1 + (Dual) */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_BNE1D, 0, 0, H(22)}, /* BNE1 (Dual) */
-
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-	  PCI_DEVICE_ID_CCD_HFCE1, 0, 0, H(23)}, /* Old Eval */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_IOB1E1, 0, 0, H(24)}, /* IOB1E1 */
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_HFCE1, 0, 0, H(25)}, /* E1 */
-
-	{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_SPD4S, 0, 0, H(26)}, /* PLX PCI Bridge */
-	{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_SPDE1, 0, 0, H(27)}, /* PLX PCI Bridge */
-
-	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-	  PCI_SUBDEVICE_ID_CCD_JHSE1, 0, 0, H(25)}, /* Junghanns E1 */
-
-	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFC4S), 0 },
-	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFC8S), 0 },
-	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFCE1), 0 },
-	{0, }
-};
-#undef H
-
-MODULE_DEVICE_TABLE(pci, hfmultipci_ids);
-
-static int
-hfcmulti_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	struct hm_map	*m = (struct hm_map *)ent->driver_data;
-	int		ret;
-
-	if (m == NULL && ent->vendor == PCI_VENDOR_ID_CCD && (
-		    ent->device == PCI_DEVICE_ID_CCD_HFC4S ||
-		    ent->device == PCI_DEVICE_ID_CCD_HFC8S ||
-		    ent->device == PCI_DEVICE_ID_CCD_HFCE1)) {
-		printk(KERN_ERR
-		       "Unknown HFC multiport controller (vendor:%04x device:%04x "
-		       "subvendor:%04x subdevice:%04x)\n", pdev->vendor,
-		       pdev->device, pdev->subsystem_vendor,
-		       pdev->subsystem_device);
-		printk(KERN_ERR
-		       "Please contact the driver maintainer for support.\n");
-		return -ENODEV;
-	}
-	ret = hfcmulti_init(m, pdev, ent);
-	if (ret)
-		return ret;
-	HFC_cnt++;
-	printk(KERN_INFO "%d devices registered\n", HFC_cnt);
-	return 0;
-}
-
-static struct pci_driver hfcmultipci_driver = {
-	.name		= "hfc_multi",
-	.probe		= hfcmulti_probe,
-	.remove		= hfc_remove_pci,
-	.id_table	= hfmultipci_ids,
-};
-
-static void __exit
-HFCmulti_cleanup(void)
-{
-	struct hfc_multi *card, *next;
-
-	/* get rid of all devices of this driver */
-	list_for_each_entry_safe(card, next, &HFClist, list)
-		release_card(card);
-	pci_unregister_driver(&hfcmultipci_driver);
-}
-
-static int __init
-HFCmulti_init(void)
-{
-	int err;
-	int i, xhfc = 0;
-	struct hm_map m;
-
-	printk(KERN_INFO "mISDN: HFC-multi driver %s\n", HFC_MULTI_VERSION);
-
-#ifdef IRQ_DEBUG
-	printk(KERN_DEBUG "%s: IRQ_DEBUG IS ENABLED!\n", __func__);
-#endif
-
-	if (debug & DEBUG_HFCMULTI_INIT)
-		printk(KERN_DEBUG "%s: init entered\n", __func__);
-
-	switch (poll) {
-	case 0:
-		poll_timer = 6;
-		poll = 128;
-		break;
-	case 8:
-		poll_timer = 2;
-		break;
-	case 16:
-		poll_timer = 3;
-		break;
-	case 32:
-		poll_timer = 4;
-		break;
-	case 64:
-		poll_timer = 5;
-		break;
-	case 128:
-		poll_timer = 6;
-		break;
-	case 256:
-		poll_timer = 7;
-		break;
-	default:
-		printk(KERN_ERR
-		       "%s: Wrong poll value (%d).\n", __func__, poll);
-		err = -EINVAL;
-		return err;
-
-	}
-
-	if (!clock)
-		clock = 1;
-
-	/* Register the embedded devices.
-	 * This should be done before the PCI cards registration */
-	switch (hwid) {
-	case HWID_MINIP4:
-		xhfc = 1;
-		m = hfcm_map[31];
-		break;
-	case HWID_MINIP8:
-		xhfc = 2;
-		m = hfcm_map[31];
-		break;
-	case HWID_MINIP16:
-		xhfc = 4;
-		m = hfcm_map[31];
-		break;
-	default:
-		xhfc = 0;
-	}
-
-	for (i = 0; i < xhfc; ++i) {
-		err = hfcmulti_init(&m, NULL, NULL);
-		if (err) {
-			printk(KERN_ERR "error registering embedded driver: "
-			       "%x\n", err);
-			return err;
-		}
-		HFC_cnt++;
-		printk(KERN_INFO "%d devices registered\n", HFC_cnt);
-	}
-
-	/* Register the PCI cards */
-	err = pci_register_driver(&hfcmultipci_driver);
-	if (err < 0) {
-		printk(KERN_ERR "error registering pci driver: %x\n", err);
-		return err;
-	}
-
-	return 0;
-}
-
-
-module_init(HFCmulti_init);
-module_exit(HFCmulti_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
deleted file mode 100644
index 554a1c640321..000000000000
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ /dev/null
@@ -1,2360 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * hfcpci.c     low level driver for CCD's hfc-pci based cards
- *
- * Author     Werner Cornelius (werner@isdn4linux.de)
- *            based on existing driver for CCD hfc ISA cards
- *            type approval valid for HFC-S PCI A based card
- *
- * Copyright 1999  by Werner Cornelius (werner@isdn-development.de)
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- *
- * Module options:
- *
- * debug:
- *	NOTE: only one poll value must be given for all cards
- *	See hfc_pci.h for debug flags.
- *
- * poll:
- *	NOTE: only one poll value must be given for all cards
- *	Give the number of samples for each fifo process.
- *	By default 128 is used. Decrease to reduce delay, increase to
- *	reduce cpu load. If unsure, don't mess with it!
- *	A value of 128 will use controller's interrupt. Other values will
- *	use kernel timer, because the controller will not allow lower values
- *	than 128.
- *	Also note that the value depends on the kernel timer frequency.
- *	If kernel uses a frequency of 1000 Hz, steps of 8 samples are possible.
- *	If the kernel uses 100 Hz, steps of 80 samples are possible.
- *	If the kernel uses 300 Hz, steps of about 26 samples are possible.
- */
-
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/mISDNhw.h>
-#include <linux/slab.h>
-
-#include "hfc_pci.h"
-
-static void hfcpci_softirq(struct timer_list *unused);
-static const char *hfcpci_revision = "2.0";
-
-static int HFC_cnt;
-static uint debug;
-static uint poll, tics;
-static DEFINE_TIMER(hfc_tl, hfcpci_softirq);
-static unsigned long hfc_jiffies;
-
-MODULE_AUTHOR("Karsten Keil");
-MODULE_DESCRIPTION("mISDN driver for CCD's hfc-pci based cards");
-MODULE_LICENSE("GPL");
-module_param(debug, uint, S_IRUGO | S_IWUSR);
-module_param(poll, uint, S_IRUGO | S_IWUSR);
-
-enum {
-	HFC_CCD_2BD0,
-	HFC_CCD_B000,
-	HFC_CCD_B006,
-	HFC_CCD_B007,
-	HFC_CCD_B008,
-	HFC_CCD_B009,
-	HFC_CCD_B00A,
-	HFC_CCD_B00B,
-	HFC_CCD_B00C,
-	HFC_CCD_B100,
-	HFC_CCD_B700,
-	HFC_CCD_B701,
-	HFC_ASUS_0675,
-	HFC_BERKOM_A1T,
-	HFC_BERKOM_TCONCEPT,
-	HFC_ANIGMA_MC145575,
-	HFC_ZOLTRIX_2BD0,
-	HFC_DIGI_DF_M_IOM2_E,
-	HFC_DIGI_DF_M_E,
-	HFC_DIGI_DF_M_IOM2_A,
-	HFC_DIGI_DF_M_A,
-	HFC_ABOCOM_2BD1,
-	HFC_SITECOM_DC105V2,
-};
-
-struct hfcPCI_hw {
-	unsigned char		cirm;
-	unsigned char		ctmt;
-	unsigned char		clkdel;
-	unsigned char		states;
-	unsigned char		conn;
-	unsigned char		mst_m;
-	unsigned char		int_m1;
-	unsigned char		int_m2;
-	unsigned char		sctrl;
-	unsigned char		sctrl_r;
-	unsigned char		sctrl_e;
-	unsigned char		trm;
-	unsigned char		fifo_en;
-	unsigned char		bswapped;
-	unsigned char		protocol;
-	int			nt_timer;
-	unsigned char __iomem	*pci_io; /* start of PCI IO memory */
-	dma_addr_t		dmahandle;
-	void			*fifos; /* FIFO memory */
-	int			last_bfifo_cnt[2];
-	/* marker saving last b-fifo frame count */
-	struct timer_list	timer;
-};
-
-#define	HFC_CFG_MASTER		1
-#define HFC_CFG_SLAVE		2
-#define	HFC_CFG_PCM		3
-#define HFC_CFG_2HFC		4
-#define HFC_CFG_SLAVEHFC	5
-#define HFC_CFG_NEG_F0		6
-#define HFC_CFG_SW_DD_DU	7
-
-#define FLG_HFC_TIMER_T1	16
-#define FLG_HFC_TIMER_T3	17
-
-#define NT_T1_COUNT	1120	/* number of 3.125ms interrupts (3.5s) */
-#define NT_T3_COUNT	31	/* number of 3.125ms interrupts (97 ms) */
-#define CLKDEL_TE	0x0e	/* CLKDEL in TE mode */
-#define CLKDEL_NT	0x6c	/* CLKDEL in NT mode */
-
-
-struct hfc_pci {
-	u_char			subtype;
-	u_char			chanlimit;
-	u_char			initdone;
-	u_long			cfg;
-	u_int			irq;
-	u_int			irqcnt;
-	struct pci_dev		*pdev;
-	struct hfcPCI_hw	hw;
-	spinlock_t		lock;	/* card lock */
-	struct dchannel		dch;
-	struct bchannel		bch[2];
-};
-
-/* Interface functions */
-static void
-enable_hwirq(struct hfc_pci *hc)
-{
-	hc->hw.int_m2 |= HFCPCI_IRQ_ENABLE;
-	Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2);
-}
-
-static void
-disable_hwirq(struct hfc_pci *hc)
-{
-	hc->hw.int_m2 &= ~((u_char)HFCPCI_IRQ_ENABLE);
-	Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2);
-}
-
-/*
- * free hardware resources used by driver
- */
-static void
-release_io_hfcpci(struct hfc_pci *hc)
-{
-	/* disable memory mapped ports + busmaster */
-	pci_write_config_word(hc->pdev, PCI_COMMAND, 0);
-	timer_delete(&hc->hw.timer);
-	dma_free_coherent(&hc->pdev->dev, 0x8000, hc->hw.fifos,
-			  hc->hw.dmahandle);
-	iounmap(hc->hw.pci_io);
-}
-
-/*
- * set mode (NT or TE)
- */
-static void
-hfcpci_setmode(struct hfc_pci *hc)
-{
-	if (hc->hw.protocol == ISDN_P_NT_S0) {
-		hc->hw.clkdel = CLKDEL_NT;	/* ST-Bit delay for NT-Mode */
-		hc->hw.sctrl |= SCTRL_MODE_NT;	/* NT-MODE */
-		hc->hw.states = 1;		/* G1 */
-	} else {
-		hc->hw.clkdel = CLKDEL_TE;	/* ST-Bit delay for TE-Mode */
-		hc->hw.sctrl &= ~SCTRL_MODE_NT;	/* TE-MODE */
-		hc->hw.states = 2;		/* F2 */
-	}
-	Write_hfc(hc, HFCPCI_CLKDEL, hc->hw.clkdel);
-	Write_hfc(hc, HFCPCI_STATES, HFCPCI_LOAD_STATE | hc->hw.states);
-	udelay(10);
-	Write_hfc(hc, HFCPCI_STATES, hc->hw.states | 0x40); /* Deactivate */
-	Write_hfc(hc, HFCPCI_SCTRL, hc->hw.sctrl);
-}
-
-/*
- * function called to reset the HFC PCI chip. A complete software reset of chip
- * and fifos is done.
- */
-static void
-reset_hfcpci(struct hfc_pci *hc)
-{
-	u_char	val;
-	int	cnt = 0;
-
-	printk(KERN_DEBUG "reset_hfcpci: entered\n");
-	val = Read_hfc(hc, HFCPCI_CHIP_ID);
-	printk(KERN_INFO "HFC_PCI: resetting HFC ChipId(%x)\n", val);
-	/* enable memory mapped ports, disable busmaster */
-	pci_write_config_word(hc->pdev, PCI_COMMAND, PCI_ENA_MEMIO);
-	disable_hwirq(hc);
-	/* enable memory ports + busmaster */
-	pci_write_config_word(hc->pdev, PCI_COMMAND,
-			      PCI_ENA_MEMIO + PCI_ENA_MASTER);
-	val = Read_hfc(hc, HFCPCI_STATUS);
-	printk(KERN_DEBUG "HFC-PCI status(%x) before reset\n", val);
-	hc->hw.cirm = HFCPCI_RESET;	/* Reset On */
-	Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	mdelay(10);			/* Timeout 10ms */
-	hc->hw.cirm = 0;		/* Reset Off */
-	Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm);
-	val = Read_hfc(hc, HFCPCI_STATUS);
-	printk(KERN_DEBUG "HFC-PCI status(%x) after reset\n", val);
-	while (cnt < 50000) { /* max 50000 us */
-		udelay(5);
-		cnt += 5;
-		val = Read_hfc(hc, HFCPCI_STATUS);
-		if (!(val & 2))
-			break;
-	}
-	printk(KERN_DEBUG "HFC-PCI status(%x) after %dus\n", val, cnt);
-
-	hc->hw.fifo_en = 0x30;	/* only D fifos enabled */
-
-	hc->hw.bswapped = 0;	/* no exchange */
-	hc->hw.ctmt = HFCPCI_TIM3_125 | HFCPCI_AUTO_TIMER;
-	hc->hw.trm = HFCPCI_BTRANS_THRESMASK; /* no echo connect , threshold */
-	hc->hw.sctrl = 0x40;	/* set tx_lo mode, error in datasheet ! */
-	hc->hw.sctrl_r = 0;
-	hc->hw.sctrl_e = HFCPCI_AUTO_AWAKE;	/* S/T Auto awake */
-	hc->hw.mst_m = 0;
-	if (test_bit(HFC_CFG_MASTER, &hc->cfg))
-		hc->hw.mst_m |= HFCPCI_MASTER;	/* HFC Master Mode */
-	if (test_bit(HFC_CFG_NEG_F0, &hc->cfg))
-		hc->hw.mst_m |= HFCPCI_F0_NEGATIV;
-	Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
-	Write_hfc(hc, HFCPCI_TRM, hc->hw.trm);
-	Write_hfc(hc, HFCPCI_SCTRL_E, hc->hw.sctrl_e);
-	Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt);
-
-	hc->hw.int_m1 = HFCPCI_INTS_DTRANS | HFCPCI_INTS_DREC |
-		HFCPCI_INTS_L1STATE | HFCPCI_INTS_TIMER;
-	Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
-
-	/* Clear already pending ints */
-	val = Read_hfc(hc, HFCPCI_INT_S1);
-
-	/* set NT/TE mode */
-	hfcpci_setmode(hc);
-
-	Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
-	Write_hfc(hc, HFCPCI_SCTRL_R, hc->hw.sctrl_r);
-
-	/*
-	 * Init GCI/IOM2 in master mode
-	 * Slots 0 and 1 are set for B-chan 1 and 2
-	 * D- and monitor/CI channel are not enabled
-	 * STIO1 is used as output for data, B1+B2 from ST->IOM+HFC
-	 * STIO2 is used as data input, B1+B2 from IOM->ST
-	 * ST B-channel send disabled -> continuous 1s
-	 * The IOM slots are always enabled
-	 */
-	if (test_bit(HFC_CFG_PCM, &hc->cfg)) {
-		/* set data flow directions: connect B1,B2: HFC to/from PCM */
-		hc->hw.conn = 0x09;
-	} else {
-		hc->hw.conn = 0x36;	/* set data flow directions */
-		if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) {
-			Write_hfc(hc, HFCPCI_B1_SSL, 0xC0);
-			Write_hfc(hc, HFCPCI_B2_SSL, 0xC1);
-			Write_hfc(hc, HFCPCI_B1_RSL, 0xC0);
-			Write_hfc(hc, HFCPCI_B2_RSL, 0xC1);
-		} else {
-			Write_hfc(hc, HFCPCI_B1_SSL, 0x80);
-			Write_hfc(hc, HFCPCI_B2_SSL, 0x81);
-			Write_hfc(hc, HFCPCI_B1_RSL, 0x80);
-			Write_hfc(hc, HFCPCI_B2_RSL, 0x81);
-		}
-	}
-	Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
-	val = Read_hfc(hc, HFCPCI_INT_S2);
-}
-
-/*
- * Timer function called when kernel timer expires
- */
-static void
-hfcpci_Timer(struct timer_list *t)
-{
-	struct hfc_pci *hc = timer_container_of(hc, t, hw.timer);
-	hc->hw.timer.expires = jiffies + 75;
-	/* WD RESET */
-/*
- *	WriteReg(hc, HFCD_DATA, HFCD_CTMT, hc->hw.ctmt | 0x80);
- *	add_timer(&hc->hw.timer);
- */
-}
-
-
-/*
- * select a b-channel entry matching and active
- */
-static struct bchannel *
-Sel_BCS(struct hfc_pci *hc, int channel)
-{
-	if (test_bit(FLG_ACTIVE, &hc->bch[0].Flags) &&
-	    (hc->bch[0].nr & channel))
-		return &hc->bch[0];
-	else if (test_bit(FLG_ACTIVE, &hc->bch[1].Flags) &&
-		 (hc->bch[1].nr & channel))
-		return &hc->bch[1];
-	else
-		return NULL;
-}
-
-/*
- * clear the desired B-channel rx fifo
- */
-static void
-hfcpci_clear_fifo_rx(struct hfc_pci *hc, int fifo)
-{
-	u_char		fifo_state;
-	struct bzfifo	*bzr;
-
-	if (fifo) {
-		bzr = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2;
-		fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B2RX;
-	} else {
-		bzr = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1;
-		fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B1RX;
-	}
-	if (fifo_state)
-		hc->hw.fifo_en ^= fifo_state;
-	Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
-	hc->hw.last_bfifo_cnt[fifo] = 0;
-	bzr->f1 = MAX_B_FRAMES;
-	bzr->f2 = bzr->f1;	/* init F pointers to remain constant */
-	bzr->za[MAX_B_FRAMES].z1 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 1);
-	bzr->za[MAX_B_FRAMES].z2 = cpu_to_le16(
-		le16_to_cpu(bzr->za[MAX_B_FRAMES].z1));
-	if (fifo_state)
-		hc->hw.fifo_en |= fifo_state;
-	Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
-}
-
-/*
- * clear the desired B-channel tx fifo
- */
-static void hfcpci_clear_fifo_tx(struct hfc_pci *hc, int fifo)
-{
-	u_char		fifo_state;
-	struct bzfifo	*bzt;
-
-	if (fifo) {
-		bzt = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2;
-		fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B2TX;
-	} else {
-		bzt = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1;
-		fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B1TX;
-	}
-	if (fifo_state)
-		hc->hw.fifo_en ^= fifo_state;
-	Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
-	if (hc->bch[fifo].debug & DEBUG_HW_BCHANNEL)
-		printk(KERN_DEBUG "hfcpci_clear_fifo_tx%d f1(%x) f2(%x) "
-		       "z1(%x) z2(%x) state(%x)\n",
-		       fifo, bzt->f1, bzt->f2,
-		       le16_to_cpu(bzt->za[MAX_B_FRAMES].z1),
-		       le16_to_cpu(bzt->za[MAX_B_FRAMES].z2),
-		       fifo_state);
-	bzt->f2 = MAX_B_FRAMES;
-	bzt->f1 = bzt->f2;	/* init F pointers to remain constant */
-	bzt->za[MAX_B_FRAMES].z1 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 1);
-	bzt->za[MAX_B_FRAMES].z2 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 2);
-	if (fifo_state)
-		hc->hw.fifo_en |= fifo_state;
-	Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
-	if (hc->bch[fifo].debug & DEBUG_HW_BCHANNEL)
-		printk(KERN_DEBUG
-		       "hfcpci_clear_fifo_tx%d f1(%x) f2(%x) z1(%x) z2(%x)\n",
-		       fifo, bzt->f1, bzt->f2,
-		       le16_to_cpu(bzt->za[MAX_B_FRAMES].z1),
-		       le16_to_cpu(bzt->za[MAX_B_FRAMES].z2));
-}
-
-/*
- * read a complete B-frame out of the buffer
- */
-static void
-hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz,
-		   u_char *bdata, int count)
-{
-	u_char		*ptr, *ptr1, new_f2;
-	int		maxlen, new_z2;
-	struct zt	*zp;
-
-	if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO))
-		printk(KERN_DEBUG "hfcpci_empty_fifo\n");
-	zp = &bz->za[bz->f2];	/* point to Z-Regs */
-	new_z2 = le16_to_cpu(zp->z2) + count;	/* new position in fifo */
-	if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL))
-		new_z2 -= B_FIFO_SIZE;	/* buffer wrap */
-	new_f2 = (bz->f2 + 1) & MAX_B_FRAMES;
-	if ((count > MAX_DATA_SIZE + 3) || (count < 4) ||
-	    (*(bdata + (le16_to_cpu(zp->z1) - B_SUB_VAL)))) {
-		if (bch->debug & DEBUG_HW)
-			printk(KERN_DEBUG "hfcpci_empty_fifo: incoming packet "
-			       "invalid length %d or crc\n", count);
-#ifdef ERROR_STATISTIC
-		bch->err_inv++;
-#endif
-		bz->za[new_f2].z2 = cpu_to_le16(new_z2);
-		bz->f2 = new_f2;	/* next buffer */
-	} else {
-		bch->rx_skb = mI_alloc_skb(count - 3, GFP_ATOMIC);
-		if (!bch->rx_skb) {
-			printk(KERN_WARNING "HFCPCI: receive out of memory\n");
-			return;
-		}
-		count -= 3;
-		ptr = skb_put(bch->rx_skb, count);
-
-		if (le16_to_cpu(zp->z2) + count <= B_FIFO_SIZE + B_SUB_VAL)
-			maxlen = count;		/* complete transfer */
-		else
-			maxlen = B_FIFO_SIZE + B_SUB_VAL -
-				le16_to_cpu(zp->z2);	/* maximum */
-
-		ptr1 = bdata + (le16_to_cpu(zp->z2) - B_SUB_VAL);
-		/* start of data */
-		memcpy(ptr, ptr1, maxlen);	/* copy data */
-		count -= maxlen;
-
-		if (count) {	/* rest remaining */
-			ptr += maxlen;
-			ptr1 = bdata;	/* start of buffer */
-			memcpy(ptr, ptr1, count);	/* rest */
-		}
-		bz->za[new_f2].z2 = cpu_to_le16(new_z2);
-		bz->f2 = new_f2;	/* next buffer */
-		recv_Bchannel(bch, MISDN_ID_ANY, false);
-	}
-}
-
-/*
- * D-channel receive procedure
- */
-static int
-receive_dmsg(struct hfc_pci *hc)
-{
-	struct dchannel	*dch = &hc->dch;
-	int		maxlen;
-	int		rcnt, total;
-	int		count = 5;
-	u_char		*ptr, *ptr1;
-	struct dfifo	*df;
-	struct zt	*zp;
-
-	df = &((union fifo_area *)(hc->hw.fifos))->d_chan.d_rx;
-	while (((df->f1 & D_FREG_MASK) != (df->f2 & D_FREG_MASK)) && count--) {
-		zp = &df->za[df->f2 & D_FREG_MASK];
-		rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2);
-		if (rcnt < 0)
-			rcnt += D_FIFO_SIZE;
-		rcnt++;
-		if (dch->debug & DEBUG_HW_DCHANNEL)
-			printk(KERN_DEBUG
-			       "hfcpci recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)\n",
-			       df->f1, df->f2,
-			       le16_to_cpu(zp->z1),
-			       le16_to_cpu(zp->z2),
-			       rcnt);
-
-		if ((rcnt > MAX_DFRAME_LEN + 3) || (rcnt < 4) ||
-		    (df->data[le16_to_cpu(zp->z1)])) {
-			if (dch->debug & DEBUG_HW)
-				printk(KERN_DEBUG
-				       "empty_fifo hfcpci packet inv. len "
-				       "%d or crc %d\n",
-				       rcnt,
-				       df->data[le16_to_cpu(zp->z1)]);
-#ifdef ERROR_STATISTIC
-			cs->err_rx++;
-#endif
-			df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) |
-				(MAX_D_FRAMES + 1);	/* next buffer */
-			df->za[df->f2 & D_FREG_MASK].z2 =
-				cpu_to_le16((le16_to_cpu(zp->z2) + rcnt) &
-					    (D_FIFO_SIZE - 1));
-		} else {
-			dch->rx_skb = mI_alloc_skb(rcnt - 3, GFP_ATOMIC);
-			if (!dch->rx_skb) {
-				printk(KERN_WARNING
-				       "HFC-PCI: D receive out of memory\n");
-				break;
-			}
-			total = rcnt;
-			rcnt -= 3;
-			ptr = skb_put(dch->rx_skb, rcnt);
-
-			if (le16_to_cpu(zp->z2) + rcnt <= D_FIFO_SIZE)
-				maxlen = rcnt;	/* complete transfer */
-			else
-				maxlen = D_FIFO_SIZE - le16_to_cpu(zp->z2);
-			/* maximum */
-
-			ptr1 = df->data + le16_to_cpu(zp->z2);
-			/* start of data */
-			memcpy(ptr, ptr1, maxlen);	/* copy data */
-			rcnt -= maxlen;
-
-			if (rcnt) {	/* rest remaining */
-				ptr += maxlen;
-				ptr1 = df->data;	/* start of buffer */
-				memcpy(ptr, ptr1, rcnt);	/* rest */
-			}
-			df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) |
-				(MAX_D_FRAMES + 1);	/* next buffer */
-			df->za[df->f2 & D_FREG_MASK].z2 = cpu_to_le16((
-									      le16_to_cpu(zp->z2) + total) & (D_FIFO_SIZE - 1));
-			recv_Dchannel(dch);
-		}
-	}
-	return 1;
-}
-
-/*
- * check for transparent receive data and read max one 'poll' size if avail
- */
-static void
-hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz,
-			struct bzfifo *txbz, u_char *bdata)
-{
-	__le16	*z1r, *z2r, *z1t, *z2t;
-	int	new_z2, fcnt_rx, fcnt_tx, maxlen;
-	u_char	*ptr, *ptr1;
-
-	z1r = &rxbz->za[MAX_B_FRAMES].z1;	/* pointer to z reg */
-	z2r = z1r + 1;
-	z1t = &txbz->za[MAX_B_FRAMES].z1;
-	z2t = z1t + 1;
-
-	fcnt_rx = le16_to_cpu(*z1r) - le16_to_cpu(*z2r);
-	if (!fcnt_rx)
-		return;	/* no data avail */
-
-	if (fcnt_rx <= 0)
-		fcnt_rx += B_FIFO_SIZE;	/* bytes actually buffered */
-	new_z2 = le16_to_cpu(*z2r) + fcnt_rx;	/* new position in fifo */
-	if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL))
-		new_z2 -= B_FIFO_SIZE;	/* buffer wrap */
-
-	fcnt_tx = le16_to_cpu(*z2t) - le16_to_cpu(*z1t);
-	if (fcnt_tx <= 0)
-		fcnt_tx += B_FIFO_SIZE;
-	/* fcnt_tx contains available bytes in tx-fifo */
-	fcnt_tx = B_FIFO_SIZE - fcnt_tx;
-	/* remaining bytes to send (bytes in tx-fifo) */
-
-	if (test_bit(FLG_RX_OFF, &bch->Flags)) {
-		bch->dropcnt += fcnt_rx;
-		*z2r = cpu_to_le16(new_z2);
-		return;
-	}
-	maxlen = bchannel_get_rxbuf(bch, fcnt_rx);
-	if (maxlen < 0) {
-		pr_warn("B%d: No bufferspace for %d bytes\n", bch->nr, fcnt_rx);
-	} else {
-		ptr = skb_put(bch->rx_skb, fcnt_rx);
-		if (le16_to_cpu(*z2r) + fcnt_rx <= B_FIFO_SIZE + B_SUB_VAL)
-			maxlen = fcnt_rx;	/* complete transfer */
-		else
-			maxlen = B_FIFO_SIZE + B_SUB_VAL - le16_to_cpu(*z2r);
-		/* maximum */
-
-		ptr1 = bdata + (le16_to_cpu(*z2r) - B_SUB_VAL);
-		/* start of data */
-		memcpy(ptr, ptr1, maxlen);	/* copy data */
-		fcnt_rx -= maxlen;
-
-		if (fcnt_rx) {	/* rest remaining */
-			ptr += maxlen;
-			ptr1 = bdata;	/* start of buffer */
-			memcpy(ptr, ptr1, fcnt_rx);	/* rest */
-		}
-		recv_Bchannel(bch, fcnt_tx, false); /* bch, id, !force */
-	}
-	*z2r = cpu_to_le16(new_z2);		/* new position */
-}
-
-/*
- * B-channel main receive routine
- */
-static void
-main_rec_hfcpci(struct bchannel *bch)
-{
-	struct hfc_pci	*hc = bch->hw;
-	int		rcnt, real_fifo;
-	int		receive = 0, count = 5;
-	struct bzfifo	*txbz, *rxbz;
-	u_char		*bdata;
-	struct zt	*zp;
-
-	if ((bch->nr & 2) && (!hc->hw.bswapped)) {
-		rxbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2;
-		txbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2;
-		bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b2;
-		real_fifo = 1;
-	} else {
-		rxbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1;
-		txbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1;
-		bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b1;
-		real_fifo = 0;
-	}
-Begin:
-	count--;
-	if (rxbz->f1 != rxbz->f2) {
-		if (bch->debug & DEBUG_HW_BCHANNEL)
-			printk(KERN_DEBUG "hfcpci rec ch(%x) f1(%d) f2(%d)\n",
-			       bch->nr, rxbz->f1, rxbz->f2);
-		zp = &rxbz->za[rxbz->f2];
-
-		rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2);
-		if (rcnt < 0)
-			rcnt += B_FIFO_SIZE;
-		rcnt++;
-		if (bch->debug & DEBUG_HW_BCHANNEL)
-			printk(KERN_DEBUG
-			       "hfcpci rec ch(%x) z1(%x) z2(%x) cnt(%d)\n",
-			       bch->nr, le16_to_cpu(zp->z1),
-			       le16_to_cpu(zp->z2), rcnt);
-		hfcpci_empty_bfifo(bch, rxbz, bdata, rcnt);
-		rcnt = rxbz->f1 - rxbz->f2;
-		if (rcnt < 0)
-			rcnt += MAX_B_FRAMES + 1;
-		if (hc->hw.last_bfifo_cnt[real_fifo] > rcnt + 1) {
-			rcnt = 0;
-			hfcpci_clear_fifo_rx(hc, real_fifo);
-		}
-		hc->hw.last_bfifo_cnt[real_fifo] = rcnt;
-		if (rcnt > 1)
-			receive = 1;
-		else
-			receive = 0;
-	} else if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
-		hfcpci_empty_fifo_trans(bch, rxbz, txbz, bdata);
-		return;
-	} else
-		receive = 0;
-	if (count && receive)
-		goto Begin;
-
-}
-
-/*
- * D-channel send routine
- */
-static void
-hfcpci_fill_dfifo(struct hfc_pci *hc)
-{
-	struct dchannel	*dch = &hc->dch;
-	int		fcnt;
-	int		count, new_z1, maxlen;
-	struct dfifo	*df;
-	u_char		*src, *dst, new_f1;
-
-	if ((dch->debug & DEBUG_HW_DCHANNEL) && !(dch->debug & DEBUG_HW_DFIFO))
-		printk(KERN_DEBUG "%s\n", __func__);
-
-	if (!dch->tx_skb)
-		return;
-	count = dch->tx_skb->len - dch->tx_idx;
-	if (count <= 0)
-		return;
-	df = &((union fifo_area *) (hc->hw.fifos))->d_chan.d_tx;
-
-	if (dch->debug & DEBUG_HW_DFIFO)
-		printk(KERN_DEBUG "%s:f1(%d) f2(%d) z1(f1)(%x)\n", __func__,
-		       df->f1, df->f2,
-		       le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1));
-	fcnt = df->f1 - df->f2;	/* frame count actually buffered */
-	if (fcnt < 0)
-		fcnt += (MAX_D_FRAMES + 1);	/* if wrap around */
-	if (fcnt > (MAX_D_FRAMES - 1)) {
-		if (dch->debug & DEBUG_HW_DCHANNEL)
-			printk(KERN_DEBUG
-			       "hfcpci_fill_Dfifo more as 14 frames\n");
-#ifdef ERROR_STATISTIC
-		cs->err_tx++;
-#endif
-		return;
-	}
-	/* now determine free bytes in FIFO buffer */
-	maxlen = le16_to_cpu(df->za[df->f2 & D_FREG_MASK].z2) -
-		le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1) - 1;
-	if (maxlen <= 0)
-		maxlen += D_FIFO_SIZE;	/* count now contains available bytes */
-
-	if (dch->debug & DEBUG_HW_DCHANNEL)
-		printk(KERN_DEBUG "hfcpci_fill_Dfifo count(%d/%d)\n",
-		       count, maxlen);
-	if (count > maxlen) {
-		if (dch->debug & DEBUG_HW_DCHANNEL)
-			printk(KERN_DEBUG "hfcpci_fill_Dfifo no fifo mem\n");
-		return;
-	}
-	new_z1 = (le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1) + count) &
-		(D_FIFO_SIZE - 1);
-	new_f1 = ((df->f1 + 1) & D_FREG_MASK) | (D_FREG_MASK + 1);
-	src = dch->tx_skb->data + dch->tx_idx;	/* source pointer */
-	dst = df->data + le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1);
-	maxlen = D_FIFO_SIZE - le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1);
-	/* end fifo */
-	if (maxlen > count)
-		maxlen = count;	/* limit size */
-	memcpy(dst, src, maxlen);	/* first copy */
-
-	count -= maxlen;	/* remaining bytes */
-	if (count) {
-		dst = df->data;	/* start of buffer */
-		src += maxlen;	/* new position */
-		memcpy(dst, src, count);
-	}
-	df->za[new_f1 & D_FREG_MASK].z1 = cpu_to_le16(new_z1);
-	/* for next buffer */
-	df->za[df->f1 & D_FREG_MASK].z1 = cpu_to_le16(new_z1);
-	/* new pos actual buffer */
-	df->f1 = new_f1;	/* next frame */
-	dch->tx_idx = dch->tx_skb->len;
-}
-
-/*
- * B-channel send routine
- */
-static void
-hfcpci_fill_fifo(struct bchannel *bch)
-{
-	struct hfc_pci	*hc = bch->hw;
-	int		maxlen, fcnt;
-	int		count, new_z1;
-	struct bzfifo	*bz;
-	u_char		*bdata;
-	u_char		new_f1, *src, *dst;
-	__le16 *z1t, *z2t;
-
-	if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO))
-		printk(KERN_DEBUG "%s\n", __func__);
-	if ((!bch->tx_skb) || bch->tx_skb->len == 0) {
-		if (!test_bit(FLG_FILLEMPTY, &bch->Flags) &&
-		    !test_bit(FLG_TRANSPARENT, &bch->Flags))
-			return;
-		count = HFCPCI_FILLEMPTY;
-	} else {
-		count = bch->tx_skb->len - bch->tx_idx;
-	}
-	if ((bch->nr & 2) && (!hc->hw.bswapped)) {
-		bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2;
-		bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.txdat_b2;
-	} else {
-		bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1;
-		bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.txdat_b1;
-	}
-
-	if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
-		z1t = &bz->za[MAX_B_FRAMES].z1;
-		z2t = z1t + 1;
-		if (bch->debug & DEBUG_HW_BCHANNEL)
-			printk(KERN_DEBUG "hfcpci_fill_fifo_trans ch(%x) "
-			       "cnt(%d) z1(%x) z2(%x)\n", bch->nr, count,
-			       le16_to_cpu(*z1t), le16_to_cpu(*z2t));
-		fcnt = le16_to_cpu(*z2t) - le16_to_cpu(*z1t);
-		if (fcnt <= 0)
-			fcnt += B_FIFO_SIZE;
-		if (test_bit(FLG_FILLEMPTY, &bch->Flags)) {
-			/* fcnt contains available bytes in fifo */
-			if (count > fcnt)
-				count = fcnt;
-			new_z1 = le16_to_cpu(*z1t) + count;
-			/* new buffer Position */
-			if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))
-				new_z1 -= B_FIFO_SIZE;	/* buffer wrap */
-			dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL);
-			maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t);
-			/* end of fifo */
-			if (bch->debug & DEBUG_HW_BFIFO)
-				printk(KERN_DEBUG "hfcpci_FFt fillempty "
-				       "fcnt(%d) maxl(%d) nz1(%x) dst(%p)\n",
-				       fcnt, maxlen, new_z1, dst);
-			if (maxlen > count)
-				maxlen = count;		/* limit size */
-			memset(dst, bch->fill[0], maxlen); /* first copy */
-			count -= maxlen;		/* remaining bytes */
-			if (count) {
-				dst = bdata;		/* start of buffer */
-				memset(dst, bch->fill[0], count);
-			}
-			*z1t = cpu_to_le16(new_z1);	/* now send data */
-			return;
-		}
-		/* fcnt contains available bytes in fifo */
-		fcnt = B_FIFO_SIZE - fcnt;
-		/* remaining bytes to send (bytes in fifo) */
-
-	next_t_frame:
-		count = bch->tx_skb->len - bch->tx_idx;
-		/* maximum fill shall be poll*2 */
-		if (count > (poll << 1) - fcnt)
-			count = (poll << 1) - fcnt;
-		if (count <= 0)
-			return;
-		/* data is suitable for fifo */
-		new_z1 = le16_to_cpu(*z1t) + count;
-		/* new buffer Position */
-		if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))
-			new_z1 -= B_FIFO_SIZE;	/* buffer wrap */
-		src = bch->tx_skb->data + bch->tx_idx;
-		/* source pointer */
-		dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL);
-		maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t);
-		/* end of fifo */
-		if (bch->debug & DEBUG_HW_BFIFO)
-			printk(KERN_DEBUG "hfcpci_FFt fcnt(%d) "
-			       "maxl(%d) nz1(%x) dst(%p)\n",
-			       fcnt, maxlen, new_z1, dst);
-		fcnt += count;
-		bch->tx_idx += count;
-		if (maxlen > count)
-			maxlen = count;		/* limit size */
-		memcpy(dst, src, maxlen);	/* first copy */
-		count -= maxlen;	/* remaining bytes */
-		if (count) {
-			dst = bdata;	/* start of buffer */
-			src += maxlen;	/* new position */
-			memcpy(dst, src, count);
-		}
-		*z1t = cpu_to_le16(new_z1);	/* now send data */
-		if (bch->tx_idx < bch->tx_skb->len)
-			return;
-		dev_kfree_skb_any(bch->tx_skb);
-		if (get_next_bframe(bch))
-			goto next_t_frame;
-		return;
-	}
-	if (bch->debug & DEBUG_HW_BCHANNEL)
-		printk(KERN_DEBUG
-		       "%s: ch(%x) f1(%d) f2(%d) z1(f1)(%x)\n",
-		       __func__, bch->nr, bz->f1, bz->f2,
-		       bz->za[bz->f1].z1);
-	fcnt = bz->f1 - bz->f2;	/* frame count actually buffered */
-	if (fcnt < 0)
-		fcnt += (MAX_B_FRAMES + 1);	/* if wrap around */
-	if (fcnt > (MAX_B_FRAMES - 1)) {
-		if (bch->debug & DEBUG_HW_BCHANNEL)
-			printk(KERN_DEBUG
-			       "hfcpci_fill_Bfifo more as 14 frames\n");
-		return;
-	}
-	/* now determine free bytes in FIFO buffer */
-	maxlen = le16_to_cpu(bz->za[bz->f2].z2) -
-		le16_to_cpu(bz->za[bz->f1].z1) - 1;
-	if (maxlen <= 0)
-		maxlen += B_FIFO_SIZE;	/* count now contains available bytes */
-
-	if (bch->debug & DEBUG_HW_BCHANNEL)
-		printk(KERN_DEBUG "hfcpci_fill_fifo ch(%x) count(%d/%d)\n",
-		       bch->nr, count, maxlen);
-
-	if (maxlen < count) {
-		if (bch->debug & DEBUG_HW_BCHANNEL)
-			printk(KERN_DEBUG "hfcpci_fill_fifo no fifo mem\n");
-		return;
-	}
-	new_z1 = le16_to_cpu(bz->za[bz->f1].z1) + count;
-	/* new buffer Position */
-	if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))
-		new_z1 -= B_FIFO_SIZE;	/* buffer wrap */
-
-	new_f1 = ((bz->f1 + 1) & MAX_B_FRAMES);
-	src = bch->tx_skb->data + bch->tx_idx;	/* source pointer */
-	dst = bdata + (le16_to_cpu(bz->za[bz->f1].z1) - B_SUB_VAL);
-	maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(bz->za[bz->f1].z1);
-	/* end fifo */
-	if (maxlen > count)
-		maxlen = count;	/* limit size */
-	memcpy(dst, src, maxlen);	/* first copy */
-
-	count -= maxlen;	/* remaining bytes */
-	if (count) {
-		dst = bdata;	/* start of buffer */
-		src += maxlen;	/* new position */
-		memcpy(dst, src, count);
-	}
-	bz->za[new_f1].z1 = cpu_to_le16(new_z1);	/* for next buffer */
-	bz->f1 = new_f1;	/* next frame */
-	dev_kfree_skb_any(bch->tx_skb);
-	get_next_bframe(bch);
-}
-
-
-
-/*
- * handle L1 state changes TE
- */
-
-static void
-ph_state_te(struct dchannel *dch)
-{
-	if (dch->debug)
-		printk(KERN_DEBUG "%s: TE newstate %x\n",
-		       __func__, dch->state);
-	switch (dch->state) {
-	case 0:
-		l1_event(dch->l1, HW_RESET_IND);
-		break;
-	case 3:
-		l1_event(dch->l1, HW_DEACT_IND);
-		break;
-	case 5:
-	case 8:
-		l1_event(dch->l1, ANYSIGNAL);
-		break;
-	case 6:
-		l1_event(dch->l1, INFO2);
-		break;
-	case 7:
-		l1_event(dch->l1, INFO4_P8);
-		break;
-	}
-}
-
-/*
- * handle L1 state changes NT
- */
-
-static void
-handle_nt_timer3(struct dchannel *dch) {
-	struct hfc_pci	*hc = dch->hw;
-
-	test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
-	hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
-	Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
-	hc->hw.nt_timer = 0;
-	test_and_set_bit(FLG_ACTIVE, &dch->Flags);
-	if (test_bit(HFC_CFG_MASTER, &hc->cfg))
-		hc->hw.mst_m |= HFCPCI_MASTER;
-	Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
-	_queue_data(&dch->dev.D, PH_ACTIVATE_IND,
-		    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
-}
-
-static void
-ph_state_nt(struct dchannel *dch)
-{
-	struct hfc_pci	*hc = dch->hw;
-
-	if (dch->debug)
-		printk(KERN_DEBUG "%s: NT newstate %x\n",
-		       __func__, dch->state);
-	switch (dch->state) {
-	case 2:
-		if (hc->hw.nt_timer < 0) {
-			hc->hw.nt_timer = 0;
-			test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
-			test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags);
-			hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
-			Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
-			/* Clear already pending ints */
-			(void) Read_hfc(hc, HFCPCI_INT_S1);
-			Write_hfc(hc, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE);
-			udelay(10);
-			Write_hfc(hc, HFCPCI_STATES, 4);
-			dch->state = 4;
-		} else if (hc->hw.nt_timer == 0) {
-			hc->hw.int_m1 |= HFCPCI_INTS_TIMER;
-			Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
-			hc->hw.nt_timer = NT_T1_COUNT;
-			hc->hw.ctmt &= ~HFCPCI_AUTO_TIMER;
-			hc->hw.ctmt |= HFCPCI_TIM3_125;
-			Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt |
-				  HFCPCI_CLTIMER);
-			test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
-			test_and_set_bit(FLG_HFC_TIMER_T1, &dch->Flags);
-			/* allow G2 -> G3 transition */
-			Write_hfc(hc, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3);
-		} else {
-			Write_hfc(hc, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3);
-		}
-		break;
-	case 1:
-		hc->hw.nt_timer = 0;
-		test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
-		test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags);
-		hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
-		Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
-		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
-		hc->hw.mst_m &= ~HFCPCI_MASTER;
-		Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
-		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
-		_queue_data(&dch->dev.D, PH_DEACTIVATE_IND,
-			    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
-		break;
-	case 4:
-		hc->hw.nt_timer = 0;
-		test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
-		test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags);
-		hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
-		Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
-		break;
-	case 3:
-		if (!test_and_set_bit(FLG_HFC_TIMER_T3, &dch->Flags)) {
-			if (!test_and_clear_bit(FLG_L2_ACTIVATED,
-						&dch->Flags)) {
-				handle_nt_timer3(dch);
-				break;
-			}
-			test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags);
-			hc->hw.int_m1 |= HFCPCI_INTS_TIMER;
-			Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
-			hc->hw.nt_timer = NT_T3_COUNT;
-			hc->hw.ctmt &= ~HFCPCI_AUTO_TIMER;
-			hc->hw.ctmt |= HFCPCI_TIM3_125;
-			Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt |
-				  HFCPCI_CLTIMER);
-		}
-		break;
-	}
-}
-
-static void
-ph_state(struct dchannel *dch)
-{
-	struct hfc_pci	*hc = dch->hw;
-
-	if (hc->hw.protocol == ISDN_P_NT_S0) {
-		if (test_bit(FLG_HFC_TIMER_T3, &dch->Flags) &&
-		    hc->hw.nt_timer < 0)
-			handle_nt_timer3(dch);
-		else
-			ph_state_nt(dch);
-	} else
-		ph_state_te(dch);
-}
-
-/*
- * Layer 1 callback function
- */
-static int
-hfc_l1callback(struct dchannel *dch, u_int cmd)
-{
-	struct hfc_pci		*hc = dch->hw;
-
-	switch (cmd) {
-	case INFO3_P8:
-	case INFO3_P10:
-		if (test_bit(HFC_CFG_MASTER, &hc->cfg))
-			hc->hw.mst_m |= HFCPCI_MASTER;
-		Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
-		break;
-	case HW_RESET_REQ:
-		Write_hfc(hc, HFCPCI_STATES, HFCPCI_LOAD_STATE | 3);
-		/* HFC ST 3 */
-		udelay(6);
-		Write_hfc(hc, HFCPCI_STATES, 3);	/* HFC ST 2 */
-		if (test_bit(HFC_CFG_MASTER, &hc->cfg))
-			hc->hw.mst_m |= HFCPCI_MASTER;
-		Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
-		Write_hfc(hc, HFCPCI_STATES, HFCPCI_ACTIVATE |
-			  HFCPCI_DO_ACTION);
-		l1_event(dch->l1, HW_POWERUP_IND);
-		break;
-	case HW_DEACT_REQ:
-		hc->hw.mst_m &= ~HFCPCI_MASTER;
-		Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
-		skb_queue_purge(&dch->squeue);
-		if (dch->tx_skb) {
-			dev_kfree_skb(dch->tx_skb);
-			dch->tx_skb = NULL;
-		}
-		dch->tx_idx = 0;
-		if (dch->rx_skb) {
-			dev_kfree_skb(dch->rx_skb);
-			dch->rx_skb = NULL;
-		}
-		test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
-		if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
-			timer_delete(&dch->timer);
-		break;
-	case HW_POWERUP_REQ:
-		Write_hfc(hc, HFCPCI_STATES, HFCPCI_DO_ACTION);
-		break;
-	case PH_ACTIVATE_IND:
-		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
-		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			    GFP_ATOMIC);
-		break;
-	case PH_DEACTIVATE_IND:
-		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
-		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			    GFP_ATOMIC);
-		break;
-	default:
-		if (dch->debug & DEBUG_HW)
-			printk(KERN_DEBUG "%s: unknown command %x\n",
-			       __func__, cmd);
-		return -1;
-	}
-	return 0;
-}
-
-/*
- * Interrupt handler
- */
-static inline void
-tx_birq(struct bchannel *bch)
-{
-	if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len)
-		hfcpci_fill_fifo(bch);
-	else {
-		dev_kfree_skb_any(bch->tx_skb);
-		if (get_next_bframe(bch))
-			hfcpci_fill_fifo(bch);
-	}
-}
-
-static inline void
-tx_dirq(struct dchannel *dch)
-{
-	if (dch->tx_skb && dch->tx_idx < dch->tx_skb->len)
-		hfcpci_fill_dfifo(dch->hw);
-	else {
-		dev_kfree_skb(dch->tx_skb);
-		if (get_next_dframe(dch))
-			hfcpci_fill_dfifo(dch->hw);
-	}
-}
-
-static irqreturn_t
-hfcpci_int(int intno, void *dev_id)
-{
-	struct hfc_pci	*hc = dev_id;
-	u_char		exval;
-	struct bchannel	*bch;
-	u_char		val, stat;
-
-	spin_lock(&hc->lock);
-	if (!(hc->hw.int_m2 & 0x08)) {
-		spin_unlock(&hc->lock);
-		return IRQ_NONE; /* not initialised */
-	}
-	stat = Read_hfc(hc, HFCPCI_STATUS);
-	if (HFCPCI_ANYINT & stat) {
-		val = Read_hfc(hc, HFCPCI_INT_S1);
-		if (hc->dch.debug & DEBUG_HW_DCHANNEL)
-			printk(KERN_DEBUG
-			       "HFC-PCI: stat(%02x) s1(%02x)\n", stat, val);
-	} else {
-		/* shared */
-		spin_unlock(&hc->lock);
-		return IRQ_NONE;
-	}
-	hc->irqcnt++;
-
-	if (hc->dch.debug & DEBUG_HW_DCHANNEL)
-		printk(KERN_DEBUG "HFC-PCI irq %x\n", val);
-	val &= hc->hw.int_m1;
-	if (val & 0x40) {	/* state machine irq */
-		exval = Read_hfc(hc, HFCPCI_STATES) & 0xf;
-		if (hc->dch.debug & DEBUG_HW_DCHANNEL)
-			printk(KERN_DEBUG "ph_state chg %d->%d\n",
-			       hc->dch.state, exval);
-		hc->dch.state = exval;
-		schedule_event(&hc->dch, FLG_PHCHANGE);
-		val &= ~0x40;
-	}
-	if (val & 0x80) {	/* timer irq */
-		if (hc->hw.protocol == ISDN_P_NT_S0) {
-			if ((--hc->hw.nt_timer) < 0)
-				schedule_event(&hc->dch, FLG_PHCHANGE);
-		}
-		val &= ~0x80;
-		Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt | HFCPCI_CLTIMER);
-	}
-	if (val & 0x08) {	/* B1 rx */
-		bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
-		if (bch)
-			main_rec_hfcpci(bch);
-		else if (hc->dch.debug)
-			printk(KERN_DEBUG "hfcpci spurious 0x08 IRQ\n");
-	}
-	if (val & 0x10) {	/* B2 rx */
-		bch = Sel_BCS(hc, 2);
-		if (bch)
-			main_rec_hfcpci(bch);
-		else if (hc->dch.debug)
-			printk(KERN_DEBUG "hfcpci spurious 0x10 IRQ\n");
-	}
-	if (val & 0x01) {	/* B1 tx */
-		bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
-		if (bch)
-			tx_birq(bch);
-		else if (hc->dch.debug)
-			printk(KERN_DEBUG "hfcpci spurious 0x01 IRQ\n");
-	}
-	if (val & 0x02) {	/* B2 tx */
-		bch = Sel_BCS(hc, 2);
-		if (bch)
-			tx_birq(bch);
-		else if (hc->dch.debug)
-			printk(KERN_DEBUG "hfcpci spurious 0x02 IRQ\n");
-	}
-	if (val & 0x20)		/* D rx */
-		receive_dmsg(hc);
-	if (val & 0x04) {	/* D tx */
-		if (test_and_clear_bit(FLG_BUSY_TIMER, &hc->dch.Flags))
-			timer_delete(&hc->dch.timer);
-		tx_dirq(&hc->dch);
-	}
-	spin_unlock(&hc->lock);
-	return IRQ_HANDLED;
-}
-
-/*
- * timer callback for D-chan busy resolution. Currently no function
- */
-static void
-hfcpci_dbusy_timer(struct timer_list *t)
-{
-}
-
-/*
- * activate/deactivate hardware for selected channels and mode
- */
-static int
-mode_hfcpci(struct bchannel *bch, int bc, int protocol)
-{
-	struct hfc_pci	*hc = bch->hw;
-	int		fifo2;
-	u_char		rx_slot = 0, tx_slot = 0, pcm_mode;
-
-	if (bch->debug & DEBUG_HW_BCHANNEL)
-		printk(KERN_DEBUG
-		       "HFCPCI bchannel protocol %x-->%x ch %x-->%x\n",
-		       bch->state, protocol, bch->nr, bc);
-
-	fifo2 = bc;
-	pcm_mode = (bc >> 24) & 0xff;
-	if (pcm_mode) { /* PCM SLOT USE */
-		if (!test_bit(HFC_CFG_PCM, &hc->cfg))
-			printk(KERN_WARNING
-			       "%s: pcm channel id without HFC_CFG_PCM\n",
-			       __func__);
-		rx_slot = (bc >> 8) & 0xff;
-		tx_slot = (bc >> 16) & 0xff;
-		bc = bc & 0xff;
-	} else if (test_bit(HFC_CFG_PCM, &hc->cfg) && (protocol > ISDN_P_NONE))
-		printk(KERN_WARNING "%s: no pcm channel id but HFC_CFG_PCM\n",
-		       __func__);
-	if (hc->chanlimit > 1) {
-		hc->hw.bswapped = 0;	/* B1 and B2 normal mode */
-		hc->hw.sctrl_e &= ~0x80;
-	} else {
-		if (bc & 2) {
-			if (protocol != ISDN_P_NONE) {
-				hc->hw.bswapped = 1; /* B1 and B2 exchanged */
-				hc->hw.sctrl_e |= 0x80;
-			} else {
-				hc->hw.bswapped = 0; /* B1 and B2 normal mode */
-				hc->hw.sctrl_e &= ~0x80;
-			}
-			fifo2 = 1;
-		} else {
-			hc->hw.bswapped = 0;	/* B1 and B2 normal mode */
-			hc->hw.sctrl_e &= ~0x80;
-		}
-	}
-	switch (protocol) {
-	case (-1): /* used for init */
-		bch->state = -1;
-		bch->nr = bc;
-		fallthrough;
-	case (ISDN_P_NONE):
-		if (bch->state == ISDN_P_NONE)
-			return 0;
-		if (bc & 2) {
-			hc->hw.sctrl &= ~SCTRL_B2_ENA;
-			hc->hw.sctrl_r &= ~SCTRL_B2_ENA;
-		} else {
-			hc->hw.sctrl &= ~SCTRL_B1_ENA;
-			hc->hw.sctrl_r &= ~SCTRL_B1_ENA;
-		}
-		if (fifo2 & 2) {
-			hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B2;
-			hc->hw.int_m1 &= ~(HFCPCI_INTS_B2TRANS |
-					   HFCPCI_INTS_B2REC);
-		} else {
-			hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B1;
-			hc->hw.int_m1 &= ~(HFCPCI_INTS_B1TRANS |
-					   HFCPCI_INTS_B1REC);
-		}
-#ifdef REVERSE_BITORDER
-		if (bch->nr & 2)
-			hc->hw.cirm &= 0x7f;
-		else
-			hc->hw.cirm &= 0xbf;
-#endif
-		bch->state = ISDN_P_NONE;
-		bch->nr = bc;
-		test_and_clear_bit(FLG_HDLC, &bch->Flags);
-		test_and_clear_bit(FLG_TRANSPARENT, &bch->Flags);
-		break;
-	case (ISDN_P_B_RAW):
-		bch->state = protocol;
-		bch->nr = bc;
-		hfcpci_clear_fifo_rx(hc, (fifo2 & 2) ? 1 : 0);
-		hfcpci_clear_fifo_tx(hc, (fifo2 & 2) ? 1 : 0);
-		if (bc & 2) {
-			hc->hw.sctrl |= SCTRL_B2_ENA;
-			hc->hw.sctrl_r |= SCTRL_B2_ENA;
-#ifdef REVERSE_BITORDER
-			hc->hw.cirm |= 0x80;
-#endif
-		} else {
-			hc->hw.sctrl |= SCTRL_B1_ENA;
-			hc->hw.sctrl_r |= SCTRL_B1_ENA;
-#ifdef REVERSE_BITORDER
-			hc->hw.cirm |= 0x40;
-#endif
-		}
-		if (fifo2 & 2) {
-			hc->hw.fifo_en |= HFCPCI_FIFOEN_B2;
-			if (!tics)
-				hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS |
-						  HFCPCI_INTS_B2REC);
-			hc->hw.ctmt |= 2;
-			hc->hw.conn &= ~0x18;
-		} else {
-			hc->hw.fifo_en |= HFCPCI_FIFOEN_B1;
-			if (!tics)
-				hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS |
-						  HFCPCI_INTS_B1REC);
-			hc->hw.ctmt |= 1;
-			hc->hw.conn &= ~0x03;
-		}
-		test_and_set_bit(FLG_TRANSPARENT, &bch->Flags);
-		break;
-	case (ISDN_P_B_HDLC):
-		bch->state = protocol;
-		bch->nr = bc;
-		hfcpci_clear_fifo_rx(hc, (fifo2 & 2) ? 1 : 0);
-		hfcpci_clear_fifo_tx(hc, (fifo2 & 2) ? 1 : 0);
-		if (bc & 2) {
-			hc->hw.sctrl |= SCTRL_B2_ENA;
-			hc->hw.sctrl_r |= SCTRL_B2_ENA;
-		} else {
-			hc->hw.sctrl |= SCTRL_B1_ENA;
-			hc->hw.sctrl_r |= SCTRL_B1_ENA;
-		}
-		if (fifo2 & 2) {
-			hc->hw.last_bfifo_cnt[1] = 0;
-			hc->hw.fifo_en |= HFCPCI_FIFOEN_B2;
-			hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS |
-					  HFCPCI_INTS_B2REC);
-			hc->hw.ctmt &= ~2;
-			hc->hw.conn &= ~0x18;
-		} else {
-			hc->hw.last_bfifo_cnt[0] = 0;
-			hc->hw.fifo_en |= HFCPCI_FIFOEN_B1;
-			hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS |
-					  HFCPCI_INTS_B1REC);
-			hc->hw.ctmt &= ~1;
-			hc->hw.conn &= ~0x03;
-		}
-		test_and_set_bit(FLG_HDLC, &bch->Flags);
-		break;
-	default:
-		printk(KERN_DEBUG "prot not known %x\n", protocol);
-		return -ENOPROTOOPT;
-	}
-	if (test_bit(HFC_CFG_PCM, &hc->cfg)) {
-		if ((protocol == ISDN_P_NONE) ||
-		    (protocol == -1)) {	/* init case */
-			rx_slot = 0;
-			tx_slot = 0;
-		} else {
-			if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) {
-				rx_slot |= 0xC0;
-				tx_slot |= 0xC0;
-			} else {
-				rx_slot |= 0x80;
-				tx_slot |= 0x80;
-			}
-		}
-		if (bc & 2) {
-			hc->hw.conn &= 0xc7;
-			hc->hw.conn |= 0x08;
-			printk(KERN_DEBUG "%s: Write_hfc: B2_SSL 0x%x\n",
-			       __func__, tx_slot);
-			printk(KERN_DEBUG "%s: Write_hfc: B2_RSL 0x%x\n",
-			       __func__, rx_slot);
-			Write_hfc(hc, HFCPCI_B2_SSL, tx_slot);
-			Write_hfc(hc, HFCPCI_B2_RSL, rx_slot);
-		} else {
-			hc->hw.conn &= 0xf8;
-			hc->hw.conn |= 0x01;
-			printk(KERN_DEBUG "%s: Write_hfc: B1_SSL 0x%x\n",
-			       __func__, tx_slot);
-			printk(KERN_DEBUG "%s: Write_hfc: B1_RSL 0x%x\n",
-			       __func__, rx_slot);
-			Write_hfc(hc, HFCPCI_B1_SSL, tx_slot);
-			Write_hfc(hc, HFCPCI_B1_RSL, rx_slot);
-		}
-	}
-	Write_hfc(hc, HFCPCI_SCTRL_E, hc->hw.sctrl_e);
-	Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
-	Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
-	Write_hfc(hc, HFCPCI_SCTRL, hc->hw.sctrl);
-	Write_hfc(hc, HFCPCI_SCTRL_R, hc->hw.sctrl_r);
-	Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt);
-	Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
-#ifdef REVERSE_BITORDER
-	Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm);
-#endif
-	return 0;
-}
-
-static int
-set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan)
-{
-	struct hfc_pci	*hc = bch->hw;
-
-	if (bch->debug & DEBUG_HW_BCHANNEL)
-		printk(KERN_DEBUG
-		       "HFCPCI bchannel test rx protocol %x-->%x ch %x-->%x\n",
-		       bch->state, protocol, bch->nr, chan);
-	if (bch->nr != chan) {
-		printk(KERN_DEBUG
-		       "HFCPCI rxtest wrong channel parameter %x/%x\n",
-		       bch->nr, chan);
-		return -EINVAL;
-	}
-	switch (protocol) {
-	case (ISDN_P_B_RAW):
-		bch->state = protocol;
-		hfcpci_clear_fifo_rx(hc, (chan & 2) ? 1 : 0);
-		if (chan & 2) {
-			hc->hw.sctrl_r |= SCTRL_B2_ENA;
-			hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX;
-			if (!tics)
-				hc->hw.int_m1 |= HFCPCI_INTS_B2REC;
-			hc->hw.ctmt |= 2;
-			hc->hw.conn &= ~0x18;
-#ifdef REVERSE_BITORDER
-			hc->hw.cirm |= 0x80;
-#endif
-		} else {
-			hc->hw.sctrl_r |= SCTRL_B1_ENA;
-			hc->hw.fifo_en |= HFCPCI_FIFOEN_B1RX;
-			if (!tics)
-				hc->hw.int_m1 |= HFCPCI_INTS_B1REC;
-			hc->hw.ctmt |= 1;
-			hc->hw.conn &= ~0x03;
-#ifdef REVERSE_BITORDER
-			hc->hw.cirm |= 0x40;
-#endif
-		}
-		break;
-	case (ISDN_P_B_HDLC):
-		bch->state = protocol;
-		hfcpci_clear_fifo_rx(hc, (chan & 2) ? 1 : 0);
-		if (chan & 2) {
-			hc->hw.sctrl_r |= SCTRL_B2_ENA;
-			hc->hw.last_bfifo_cnt[1] = 0;
-			hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX;
-			hc->hw.int_m1 |= HFCPCI_INTS_B2REC;
-			hc->hw.ctmt &= ~2;
-			hc->hw.conn &= ~0x18;
-		} else {
-			hc->hw.sctrl_r |= SCTRL_B1_ENA;
-			hc->hw.last_bfifo_cnt[0] = 0;
-			hc->hw.fifo_en |= HFCPCI_FIFOEN_B1RX;
-			hc->hw.int_m1 |= HFCPCI_INTS_B1REC;
-			hc->hw.ctmt &= ~1;
-			hc->hw.conn &= ~0x03;
-		}
-		break;
-	default:
-		printk(KERN_DEBUG "prot not known %x\n", protocol);
-		return -ENOPROTOOPT;
-	}
-	Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
-	Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
-	Write_hfc(hc, HFCPCI_SCTRL_R, hc->hw.sctrl_r);
-	Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt);
-	Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
-#ifdef REVERSE_BITORDER
-	Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm);
-#endif
-	return 0;
-}
-
-static void
-deactivate_bchannel(struct bchannel *bch)
-{
-	struct hfc_pci	*hc = bch->hw;
-	u_long		flags;
-
-	spin_lock_irqsave(&hc->lock, flags);
-	mISDN_clear_bchannel(bch);
-	mode_hfcpci(bch, bch->nr, ISDN_P_NONE);
-	spin_unlock_irqrestore(&hc->lock, flags);
-}
-
-/*
- * Layer 1 B-channel hardware access
- */
-static int
-channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
-{
-	return mISDN_ctrl_bchannel(bch, cq);
-}
-static int
-hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
-{
-	struct bchannel	*bch = container_of(ch, struct bchannel, ch);
-	struct hfc_pci	*hc = bch->hw;
-	int		ret = -EINVAL;
-	u_long		flags;
-
-	if (bch->debug & DEBUG_HW)
-		printk(KERN_DEBUG "%s: cmd:%x %p\n", __func__, cmd, arg);
-	switch (cmd) {
-	case HW_TESTRX_RAW:
-		spin_lock_irqsave(&hc->lock, flags);
-		ret = set_hfcpci_rxtest(bch, ISDN_P_B_RAW, (int)(long)arg);
-		spin_unlock_irqrestore(&hc->lock, flags);
-		break;
-	case HW_TESTRX_HDLC:
-		spin_lock_irqsave(&hc->lock, flags);
-		ret = set_hfcpci_rxtest(bch, ISDN_P_B_HDLC, (int)(long)arg);
-		spin_unlock_irqrestore(&hc->lock, flags);
-		break;
-	case HW_TESTRX_OFF:
-		spin_lock_irqsave(&hc->lock, flags);
-		mode_hfcpci(bch, bch->nr, ISDN_P_NONE);
-		spin_unlock_irqrestore(&hc->lock, flags);
-		ret = 0;
-		break;
-	case CLOSE_CHANNEL:
-		test_and_clear_bit(FLG_OPEN, &bch->Flags);
-		deactivate_bchannel(bch);
-		ch->protocol = ISDN_P_NONE;
-		ch->peer = NULL;
-		module_put(THIS_MODULE);
-		ret = 0;
-		break;
-	case CONTROL_CHANNEL:
-		ret = channel_bctrl(bch, arg);
-		break;
-	default:
-		printk(KERN_WARNING "%s: unknown prim(%x)\n",
-		       __func__, cmd);
-	}
-	return ret;
-}
-
-/*
- * Layer2 -> Layer 1 Dchannel data
- */
-static int
-hfcpci_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
-	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
-	struct hfc_pci		*hc = dch->hw;
-	int			ret = -EINVAL;
-	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
-	unsigned int		id;
-	u_long			flags;
-
-	switch (hh->prim) {
-	case PH_DATA_REQ:
-		spin_lock_irqsave(&hc->lock, flags);
-		ret = dchannel_senddata(dch, skb);
-		if (ret > 0) { /* direct TX */
-			id = hh->id; /* skb can be freed */
-			hfcpci_fill_dfifo(dch->hw);
-			ret = 0;
-			spin_unlock_irqrestore(&hc->lock, flags);
-			queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
-		} else
-			spin_unlock_irqrestore(&hc->lock, flags);
-		return ret;
-	case PH_ACTIVATE_REQ:
-		spin_lock_irqsave(&hc->lock, flags);
-		if (hc->hw.protocol == ISDN_P_NT_S0) {
-			ret = 0;
-			if (test_bit(HFC_CFG_MASTER, &hc->cfg))
-				hc->hw.mst_m |= HFCPCI_MASTER;
-			Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
-			if (test_bit(FLG_ACTIVE, &dch->Flags)) {
-				spin_unlock_irqrestore(&hc->lock, flags);
-				_queue_data(&dch->dev.D, PH_ACTIVATE_IND,
-					    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
-				break;
-			}
-			test_and_set_bit(FLG_L2_ACTIVATED, &dch->Flags);
-			Write_hfc(hc, HFCPCI_STATES, HFCPCI_ACTIVATE |
-				  HFCPCI_DO_ACTION | 1);
-		} else
-			ret = l1_event(dch->l1, hh->prim);
-		spin_unlock_irqrestore(&hc->lock, flags);
-		break;
-	case PH_DEACTIVATE_REQ:
-		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
-		spin_lock_irqsave(&hc->lock, flags);
-		if (hc->hw.protocol == ISDN_P_NT_S0) {
-			struct sk_buff_head free_queue;
-
-			__skb_queue_head_init(&free_queue);
-			/* prepare deactivation */
-			Write_hfc(hc, HFCPCI_STATES, 0x40);
-			skb_queue_splice_init(&dch->squeue, &free_queue);
-			if (dch->tx_skb) {
-				__skb_queue_tail(&free_queue, dch->tx_skb);
-				dch->tx_skb = NULL;
-			}
-			dch->tx_idx = 0;
-			if (dch->rx_skb) {
-				__skb_queue_tail(&free_queue, dch->rx_skb);
-				dch->rx_skb = NULL;
-			}
-			test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
-			if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
-				timer_delete(&dch->timer);
-#ifdef FIXME
-			if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
-				dchannel_sched_event(&hc->dch, D_CLEARBUSY);
-#endif
-			hc->hw.mst_m &= ~HFCPCI_MASTER;
-			Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
-			ret = 0;
-			spin_unlock_irqrestore(&hc->lock, flags);
-			__skb_queue_purge(&free_queue);
-		} else {
-			ret = l1_event(dch->l1, hh->prim);
-			spin_unlock_irqrestore(&hc->lock, flags);
-		}
-		break;
-	}
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-/*
- * Layer2 -> Layer 1 Bchannel data
- */
-static int
-hfcpci_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct bchannel		*bch = container_of(ch, struct bchannel, ch);
-	struct hfc_pci		*hc = bch->hw;
-	int			ret = -EINVAL;
-	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
-	unsigned long		flags;
-
-	switch (hh->prim) {
-	case PH_DATA_REQ:
-		spin_lock_irqsave(&hc->lock, flags);
-		ret = bchannel_senddata(bch, skb);
-		if (ret > 0) { /* direct TX */
-			hfcpci_fill_fifo(bch);
-			ret = 0;
-		}
-		spin_unlock_irqrestore(&hc->lock, flags);
-		return ret;
-	case PH_ACTIVATE_REQ:
-		spin_lock_irqsave(&hc->lock, flags);
-		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
-			ret = mode_hfcpci(bch, bch->nr, ch->protocol);
-		else
-			ret = 0;
-		spin_unlock_irqrestore(&hc->lock, flags);
-		if (!ret)
-			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-				    NULL, GFP_KERNEL);
-		break;
-	case PH_DEACTIVATE_REQ:
-		deactivate_bchannel(bch);
-		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			    NULL, GFP_KERNEL);
-		ret = 0;
-		break;
-	}
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-/*
- * called for card init message
- */
-
-static void
-inithfcpci(struct hfc_pci *hc)
-{
-	printk(KERN_DEBUG "inithfcpci: entered\n");
-	timer_setup(&hc->dch.timer, hfcpci_dbusy_timer, 0);
-	hc->chanlimit = 2;
-	mode_hfcpci(&hc->bch[0], 1, -1);
-	mode_hfcpci(&hc->bch[1], 2, -1);
-}
-
-
-static int
-init_card(struct hfc_pci *hc)
-{
-	int	cnt = 3;
-	u_long	flags;
-
-	printk(KERN_DEBUG "init_card: entered\n");
-
-
-	spin_lock_irqsave(&hc->lock, flags);
-	disable_hwirq(hc);
-	spin_unlock_irqrestore(&hc->lock, flags);
-	if (request_irq(hc->irq, hfcpci_int, IRQF_SHARED, "HFC PCI", hc)) {
-		printk(KERN_WARNING
-		       "mISDN: couldn't get interrupt %d\n", hc->irq);
-		return -EIO;
-	}
-	spin_lock_irqsave(&hc->lock, flags);
-	reset_hfcpci(hc);
-	while (cnt) {
-		inithfcpci(hc);
-		/*
-		 * Finally enable IRQ output
-		 * this is only allowed, if an IRQ routine is already
-		 * established for this HFC, so don't do that earlier
-		 */
-		enable_hwirq(hc);
-		spin_unlock_irqrestore(&hc->lock, flags);
-		/* Timeout 80ms */
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout((80 * HZ) / 1000);
-		printk(KERN_INFO "HFC PCI: IRQ %d count %d\n",
-		       hc->irq, hc->irqcnt);
-		/* now switch timer interrupt off */
-		spin_lock_irqsave(&hc->lock, flags);
-		hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
-		Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
-		/* reinit mode reg */
-		Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
-		if (!hc->irqcnt) {
-			printk(KERN_WARNING
-			       "HFC PCI: IRQ(%d) getting no interrupts "
-			       "during init %d\n", hc->irq, 4 - cnt);
-			if (cnt == 1)
-				break;
-			else {
-				reset_hfcpci(hc);
-				cnt--;
-			}
-		} else {
-			spin_unlock_irqrestore(&hc->lock, flags);
-			hc->initdone = 1;
-			return 0;
-		}
-	}
-	disable_hwirq(hc);
-	spin_unlock_irqrestore(&hc->lock, flags);
-	free_irq(hc->irq, hc);
-	return -EIO;
-}
-
-static int
-channel_ctrl(struct hfc_pci *hc, struct mISDN_ctrl_req *cq)
-{
-	int	ret = 0;
-	u_char	slot;
-
-	switch (cq->op) {
-	case MISDN_CTRL_GETOP:
-		cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_CONNECT |
-			 MISDN_CTRL_DISCONNECT | MISDN_CTRL_L1_TIMER3;
-		break;
-	case MISDN_CTRL_LOOP:
-		/* channel 0 disabled loop */
-		if (cq->channel < 0 || cq->channel > 2) {
-			ret = -EINVAL;
-			break;
-		}
-		if (cq->channel & 1) {
-			if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg))
-				slot = 0xC0;
-			else
-				slot = 0x80;
-			printk(KERN_DEBUG "%s: Write_hfc: B1_SSL/RSL 0x%x\n",
-			       __func__, slot);
-			Write_hfc(hc, HFCPCI_B1_SSL, slot);
-			Write_hfc(hc, HFCPCI_B1_RSL, slot);
-			hc->hw.conn = (hc->hw.conn & ~7) | 6;
-			Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
-		}
-		if (cq->channel & 2) {
-			if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg))
-				slot = 0xC1;
-			else
-				slot = 0x81;
-			printk(KERN_DEBUG "%s: Write_hfc: B2_SSL/RSL 0x%x\n",
-			       __func__, slot);
-			Write_hfc(hc, HFCPCI_B2_SSL, slot);
-			Write_hfc(hc, HFCPCI_B2_RSL, slot);
-			hc->hw.conn = (hc->hw.conn & ~0x38) | 0x30;
-			Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
-		}
-		if (cq->channel & 3)
-			hc->hw.trm |= 0x80;	/* enable IOM-loop */
-		else {
-			hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x09;
-			Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
-			hc->hw.trm &= 0x7f;	/* disable IOM-loop */
-		}
-		Write_hfc(hc, HFCPCI_TRM, hc->hw.trm);
-		break;
-	case MISDN_CTRL_CONNECT:
-		if (cq->channel == cq->p1) {
-			ret = -EINVAL;
-			break;
-		}
-		if (cq->channel < 1 || cq->channel > 2 ||
-		    cq->p1 < 1 || cq->p1 > 2) {
-			ret = -EINVAL;
-			break;
-		}
-		if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg))
-			slot = 0xC0;
-		else
-			slot = 0x80;
-		printk(KERN_DEBUG "%s: Write_hfc: B1_SSL/RSL 0x%x\n",
-		       __func__, slot);
-		Write_hfc(hc, HFCPCI_B1_SSL, slot);
-		Write_hfc(hc, HFCPCI_B2_RSL, slot);
-		if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg))
-			slot = 0xC1;
-		else
-			slot = 0x81;
-		printk(KERN_DEBUG "%s: Write_hfc: B2_SSL/RSL 0x%x\n",
-		       __func__, slot);
-		Write_hfc(hc, HFCPCI_B2_SSL, slot);
-		Write_hfc(hc, HFCPCI_B1_RSL, slot);
-		hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x36;
-		Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
-		hc->hw.trm |= 0x80;
-		Write_hfc(hc, HFCPCI_TRM, hc->hw.trm);
-		break;
-	case MISDN_CTRL_DISCONNECT:
-		hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x09;
-		Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
-		hc->hw.trm &= 0x7f;	/* disable IOM-loop */
-		break;
-	case MISDN_CTRL_L1_TIMER3:
-		ret = l1_event(hc->dch.l1, HW_TIMER3_VALUE | (cq->p1 & 0xff));
-		break;
-	default:
-		printk(KERN_WARNING "%s: unknown Op %x\n",
-		       __func__, cq->op);
-		ret = -EINVAL;
-		break;
-	}
-	return ret;
-}
-
-static int
-open_dchannel(struct hfc_pci *hc, struct mISDNchannel *ch,
-	      struct channel_req *rq)
-{
-	int err = 0;
-
-	if (debug & DEBUG_HW_OPEN)
-		printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,
-		       hc->dch.dev.id, __builtin_return_address(0));
-	if (rq->protocol == ISDN_P_NONE)
-		return -EINVAL;
-	if (rq->adr.channel == 1) {
-		/* TODO: E-Channel */
-		return -EINVAL;
-	}
-	if (!hc->initdone) {
-		if (rq->protocol == ISDN_P_TE_S0) {
-			err = create_l1(&hc->dch, hfc_l1callback);
-			if (err)
-				return err;
-		}
-		hc->hw.protocol = rq->protocol;
-		ch->protocol = rq->protocol;
-		err = init_card(hc);
-		if (err)
-			return err;
-	} else {
-		if (rq->protocol != ch->protocol) {
-			if (hc->hw.protocol == ISDN_P_TE_S0)
-				l1_event(hc->dch.l1, CLOSE_CHANNEL);
-			if (rq->protocol == ISDN_P_TE_S0) {
-				err = create_l1(&hc->dch, hfc_l1callback);
-				if (err)
-					return err;
-			}
-			hc->hw.protocol = rq->protocol;
-			ch->protocol = rq->protocol;
-			hfcpci_setmode(hc);
-		}
-	}
-
-	if (((ch->protocol == ISDN_P_NT_S0) && (hc->dch.state == 3)) ||
-	    ((ch->protocol == ISDN_P_TE_S0) && (hc->dch.state == 7))) {
-		_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
-			    0, NULL, GFP_KERNEL);
-	}
-	rq->ch = ch;
-	if (!try_module_get(THIS_MODULE))
-		printk(KERN_WARNING "%s:cannot get module\n", __func__);
-	return 0;
-}
-
-static int
-open_bchannel(struct hfc_pci *hc, struct channel_req *rq)
-{
-	struct bchannel		*bch;
-
-	if (rq->adr.channel == 0 || rq->adr.channel > 2)
-		return -EINVAL;
-	if (rq->protocol == ISDN_P_NONE)
-		return -EINVAL;
-	bch = &hc->bch[rq->adr.channel - 1];
-	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
-		return -EBUSY; /* b-channel can be only open once */
-	bch->ch.protocol = rq->protocol;
-	rq->ch = &bch->ch; /* TODO: E-channel */
-	if (!try_module_get(THIS_MODULE))
-		printk(KERN_WARNING "%s:cannot get module\n", __func__);
-	return 0;
-}
-
-/*
- * device control function
- */
-static int
-hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
-{
-	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
-	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
-	struct hfc_pci		*hc = dch->hw;
-	struct channel_req	*rq;
-	int			err = 0;
-
-	if (dch->debug & DEBUG_HW)
-		printk(KERN_DEBUG "%s: cmd:%x %p\n",
-		       __func__, cmd, arg);
-	switch (cmd) {
-	case OPEN_CHANNEL:
-		rq = arg;
-		if ((rq->protocol == ISDN_P_TE_S0) ||
-		    (rq->protocol == ISDN_P_NT_S0))
-			err = open_dchannel(hc, ch, rq);
-		else
-			err = open_bchannel(hc, rq);
-		break;
-	case CLOSE_CHANNEL:
-		if (debug & DEBUG_HW_OPEN)
-			printk(KERN_DEBUG "%s: dev(%d) close from %p\n",
-			       __func__, hc->dch.dev.id,
-			       __builtin_return_address(0));
-		module_put(THIS_MODULE);
-		break;
-	case CONTROL_CHANNEL:
-		err = channel_ctrl(hc, arg);
-		break;
-	default:
-		if (dch->debug & DEBUG_HW)
-			printk(KERN_DEBUG "%s: unknown command %x\n",
-			       __func__, cmd);
-		return -EINVAL;
-	}
-	return err;
-}
-
-static int
-setup_hw(struct hfc_pci *hc)
-{
-	void	*buffer;
-
-	printk(KERN_INFO "mISDN: HFC-PCI driver %s\n", hfcpci_revision);
-	hc->hw.cirm = 0;
-	hc->dch.state = 0;
-	pci_set_master(hc->pdev);
-	if (!hc->irq) {
-		printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n");
-		return -EINVAL;
-	}
-	hc->hw.pci_io =
-		(char __iomem *)(unsigned long)hc->pdev->resource[1].start;
-
-	if (!hc->hw.pci_io) {
-		printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");
-		return -ENOMEM;
-	}
-	/* Allocate memory for FIFOS */
-	/* the memory needs to be on a 32k boundary within the first 4G */
-	if (dma_set_mask(&hc->pdev->dev, 0xFFFF8000)) {
-		printk(KERN_WARNING
-		       "HFC-PCI: No usable DMA configuration!\n");
-		return -EIO;
-	}
-	buffer = dma_alloc_coherent(&hc->pdev->dev, 0x8000, &hc->hw.dmahandle,
-				    GFP_KERNEL);
-	/* We silently assume the address is okay if nonzero */
-	if (!buffer) {
-		printk(KERN_WARNING
-		       "HFC-PCI: Error allocating memory for FIFO!\n");
-		return -ENOMEM;
-	}
-	hc->hw.fifos = buffer;
-	pci_write_config_dword(hc->pdev, 0x80, hc->hw.dmahandle);
-	hc->hw.pci_io = ioremap((ulong) hc->hw.pci_io, 256);
-	if (unlikely(!hc->hw.pci_io)) {
-		printk(KERN_WARNING
-		       "HFC-PCI: Error in ioremap for PCI!\n");
-		dma_free_coherent(&hc->pdev->dev, 0x8000, hc->hw.fifos,
-				  hc->hw.dmahandle);
-		return -ENOMEM;
-	}
-
-	printk(KERN_INFO
-	       "HFC-PCI: defined at mem %#lx fifo %p(%pad) IRQ %d HZ %d\n",
-	       (u_long) hc->hw.pci_io, hc->hw.fifos,
-	       &hc->hw.dmahandle, hc->irq, HZ);
-
-	/* enable memory mapped ports, disable busmaster */
-	pci_write_config_word(hc->pdev, PCI_COMMAND, PCI_ENA_MEMIO);
-	hc->hw.int_m2 = 0;
-	disable_hwirq(hc);
-	hc->hw.int_m1 = 0;
-	Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
-	/* At this point the needed PCI config is done */
-	/* fifos are still not enabled */
-	timer_setup(&hc->hw.timer, hfcpci_Timer, 0);
-	/* default PCM master */
-	test_and_set_bit(HFC_CFG_MASTER, &hc->cfg);
-	return 0;
-}
-
-static void
-release_card(struct hfc_pci *hc) {
-	u_long	flags;
-
-	spin_lock_irqsave(&hc->lock, flags);
-	hc->hw.int_m2 = 0; /* interrupt output off ! */
-	disable_hwirq(hc);
-	mode_hfcpci(&hc->bch[0], 1, ISDN_P_NONE);
-	mode_hfcpci(&hc->bch[1], 2, ISDN_P_NONE);
-	if (hc->dch.timer.function != NULL) {
-		timer_delete(&hc->dch.timer);
-		hc->dch.timer.function = NULL;
-	}
-	spin_unlock_irqrestore(&hc->lock, flags);
-	if (hc->hw.protocol == ISDN_P_TE_S0)
-		l1_event(hc->dch.l1, CLOSE_CHANNEL);
-	if (hc->initdone)
-		free_irq(hc->irq, hc);
-	release_io_hfcpci(hc); /* must release after free_irq! */
-	mISDN_unregister_device(&hc->dch.dev);
-	mISDN_freebchannel(&hc->bch[1]);
-	mISDN_freebchannel(&hc->bch[0]);
-	mISDN_freedchannel(&hc->dch);
-	pci_set_drvdata(hc->pdev, NULL);
-	kfree(hc);
-}
-
-static int
-setup_card(struct hfc_pci *card)
-{
-	int		err = -EINVAL;
-	u_int		i;
-	char		name[MISDN_MAX_IDLEN];
-
-	card->dch.debug = debug;
-	spin_lock_init(&card->lock);
-	mISDN_initdchannel(&card->dch, MAX_DFRAME_LEN_L1, ph_state);
-	card->dch.hw = card;
-	card->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
-	card->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
-	card->dch.dev.D.send = hfcpci_l2l1D;
-	card->dch.dev.D.ctrl = hfc_dctrl;
-	card->dch.dev.nrbchan = 2;
-	for (i = 0; i < 2; i++) {
-		card->bch[i].nr = i + 1;
-		set_channelmap(i + 1, card->dch.dev.channelmap);
-		card->bch[i].debug = debug;
-		mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, poll >> 1);
-		card->bch[i].hw = card;
-		card->bch[i].ch.send = hfcpci_l2l1B;
-		card->bch[i].ch.ctrl = hfc_bctrl;
-		card->bch[i].ch.nr = i + 1;
-		list_add(&card->bch[i].ch.list, &card->dch.dev.bchannels);
-	}
-	err = setup_hw(card);
-	if (err)
-		goto error;
-	snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-pci.%d", HFC_cnt + 1);
-	err = mISDN_register_device(&card->dch.dev, &card->pdev->dev, name);
-	if (err)
-		goto error;
-	HFC_cnt++;
-	printk(KERN_INFO "HFC %d cards installed\n", HFC_cnt);
-	return 0;
-error:
-	mISDN_freebchannel(&card->bch[1]);
-	mISDN_freebchannel(&card->bch[0]);
-	mISDN_freedchannel(&card->dch);
-	kfree(card);
-	return err;
-}
-
-/* private data in the PCI devices list */
-struct _hfc_map {
-	u_int	subtype;
-	u_int	flag;
-	char	*name;
-};
-
-static const struct _hfc_map hfc_map[] =
-{
-	{HFC_CCD_2BD0, 0, "CCD/Billion/Asuscom 2BD0"},
-	{HFC_CCD_B000, 0, "Billion B000"},
-	{HFC_CCD_B006, 0, "Billion B006"},
-	{HFC_CCD_B007, 0, "Billion B007"},
-	{HFC_CCD_B008, 0, "Billion B008"},
-	{HFC_CCD_B009, 0, "Billion B009"},
-	{HFC_CCD_B00A, 0, "Billion B00A"},
-	{HFC_CCD_B00B, 0, "Billion B00B"},
-	{HFC_CCD_B00C, 0, "Billion B00C"},
-	{HFC_CCD_B100, 0, "Seyeon B100"},
-	{HFC_CCD_B700, 0, "Primux II S0 B700"},
-	{HFC_CCD_B701, 0, "Primux II S0 NT B701"},
-	{HFC_ABOCOM_2BD1, 0, "Abocom/Magitek 2BD1"},
-	{HFC_ASUS_0675, 0, "Asuscom/Askey 675"},
-	{HFC_BERKOM_TCONCEPT, 0, "German telekom T-Concept"},
-	{HFC_BERKOM_A1T, 0, "German telekom A1T"},
-	{HFC_ANIGMA_MC145575, 0, "Motorola MC145575"},
-	{HFC_ZOLTRIX_2BD0, 0, "Zoltrix 2BD0"},
-	{HFC_DIGI_DF_M_IOM2_E, 0,
-	 "Digi International DataFire Micro V IOM2 (Europe)"},
-	{HFC_DIGI_DF_M_E, 0,
-	 "Digi International DataFire Micro V (Europe)"},
-	{HFC_DIGI_DF_M_IOM2_A, 0,
-	 "Digi International DataFire Micro V IOM2 (North America)"},
-	{HFC_DIGI_DF_M_A, 0,
-	 "Digi International DataFire Micro V (North America)"},
-	{HFC_SITECOM_DC105V2, 0, "Sitecom Connectivity DC-105 ISDN TA"},
-	{},
-};
-
-static const struct pci_device_id hfc_ids[] =
-{
-	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_2BD0),
-	  (unsigned long) &hfc_map[0] },
-	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B000),
-	  (unsigned long) &hfc_map[1] },
-	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B006),
-	  (unsigned long) &hfc_map[2] },
-	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B007),
-	  (unsigned long) &hfc_map[3] },
-	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B008),
-	  (unsigned long) &hfc_map[4] },
-	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B009),
-	  (unsigned long) &hfc_map[5] },
-	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00A),
-	  (unsigned long) &hfc_map[6] },
-	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00B),
-	  (unsigned long) &hfc_map[7] },
-	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00C),
-	  (unsigned long) &hfc_map[8] },
-	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B100),
-	  (unsigned long) &hfc_map[9] },
-	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B700),
-	  (unsigned long) &hfc_map[10] },
-	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B701),
-	  (unsigned long) &hfc_map[11] },
-	{ PCI_VDEVICE(ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1),
-	  (unsigned long) &hfc_map[12] },
-	{ PCI_VDEVICE(ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675),
-	  (unsigned long) &hfc_map[13] },
-	{ PCI_VDEVICE(BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT),
-	  (unsigned long) &hfc_map[14] },
-	{ PCI_VDEVICE(BERKOM, PCI_DEVICE_ID_BERKOM_A1T),
-	  (unsigned long) &hfc_map[15] },
-	{ PCI_VDEVICE(ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575),
-	  (unsigned long) &hfc_map[16] },
-	{ PCI_VDEVICE(ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0),
-	  (unsigned long) &hfc_map[17] },
-	{ PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E),
-	  (unsigned long) &hfc_map[18] },
-	{ PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_E),
-	  (unsigned long) &hfc_map[19] },
-	{ PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A),
-	  (unsigned long) &hfc_map[20] },
-	{ PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_A),
-	  (unsigned long) &hfc_map[21] },
-	{ PCI_VDEVICE(SITECOM, PCI_DEVICE_ID_SITECOM_DC105V2),
-	  (unsigned long) &hfc_map[22] },
-	{},
-};
-
-static int
-hfc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	int		err = -ENOMEM;
-	struct hfc_pci	*card;
-	struct _hfc_map	*m = (struct _hfc_map *)ent->driver_data;
-
-	card = kzalloc_obj(struct hfc_pci);
-	if (!card) {
-		printk(KERN_ERR "No kmem for HFC card\n");
-		return err;
-	}
-	card->pdev = pdev;
-	card->subtype = m->subtype;
-	err = pci_enable_device(pdev);
-	if (err) {
-		kfree(card);
-		return err;
-	}
-
-	printk(KERN_INFO "mISDN_hfcpci: found adapter %s at %s\n",
-	       m->name, pci_name(pdev));
-
-	card->irq = pdev->irq;
-	pci_set_drvdata(pdev, card);
-	err = setup_card(card);
-	if (err)
-		pci_set_drvdata(pdev, NULL);
-	return err;
-}
-
-static void
-hfc_remove_pci(struct pci_dev *pdev)
-{
-	struct hfc_pci	*card = pci_get_drvdata(pdev);
-
-	if (card)
-		release_card(card);
-	else
-		if (debug)
-			printk(KERN_DEBUG "%s: drvdata already removed\n",
-			       __func__);
-}
-
-
-static struct pci_driver hfc_driver = {
-	.name = "hfcpci",
-	.probe = hfc_probe,
-	.remove = hfc_remove_pci,
-	.id_table = hfc_ids,
-};
-
-static int
-_hfcpci_softirq(struct device *dev, void *unused)
-{
-	struct hfc_pci  *hc = dev_get_drvdata(dev);
-	struct bchannel *bch;
-	if (hc == NULL)
-		return 0;
-
-	if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) {
-		spin_lock_irq(&hc->lock);
-		bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
-		if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */
-			main_rec_hfcpci(bch);
-			tx_birq(bch);
-		}
-		bch = Sel_BCS(hc, hc->hw.bswapped ? 1 : 2);
-		if (bch && bch->state == ISDN_P_B_RAW) { /* B2 rx&tx */
-			main_rec_hfcpci(bch);
-			tx_birq(bch);
-		}
-		spin_unlock_irq(&hc->lock);
-	}
-	return 0;
-}
-
-static void
-hfcpci_softirq(struct timer_list *unused)
-{
-	WARN_ON_ONCE(driver_for_each_device(&hfc_driver.driver, NULL, NULL,
-				      _hfcpci_softirq) != 0);
-
-	/* if next event would be in the past ... */
-	if ((s32)(hfc_jiffies + tics - jiffies) <= 0)
-		hfc_jiffies = jiffies + 1;
-	else
-		hfc_jiffies += tics;
-	mod_timer(&hfc_tl, hfc_jiffies);
-}
-
-static int __init
-HFC_init(void)
-{
-	int		err;
-
-	if (!poll)
-		poll = HFCPCI_BTRANS_THRESHOLD;
-
-	if (poll != HFCPCI_BTRANS_THRESHOLD) {
-		tics = (poll * HZ) / 8000;
-		if (tics < 1)
-			tics = 1;
-		poll = (tics * 8000) / HZ;
-		if (poll > 256 || poll < 8) {
-			printk(KERN_ERR "%s: Wrong poll value %d not in range "
-			       "of 8..256.\n", __func__, poll);
-			err = -EINVAL;
-			return err;
-		}
-	}
-	if (poll != HFCPCI_BTRANS_THRESHOLD) {
-		printk(KERN_INFO "%s: Using alternative poll value of %d\n",
-		       __func__, poll);
-		hfc_jiffies = jiffies + tics;
-		mod_timer(&hfc_tl, hfc_jiffies);
-	} else
-		tics = 0; /* indicate the use of controller's timer */
-
-	err = pci_register_driver(&hfc_driver);
-	if (err) {
-		if (timer_pending(&hfc_tl))
-			timer_delete(&hfc_tl);
-	}
-
-	return err;
-}
-
-static void __exit
-HFC_cleanup(void)
-{
-	timer_delete_sync(&hfc_tl);
-
-	pci_unregister_driver(&hfc_driver);
-}
-
-module_init(HFC_init);
-module_exit(HFC_cleanup);
-
-MODULE_DEVICE_TABLE(pci, hfc_ids);
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
deleted file mode 100644
index 227babe83879..000000000000
--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ /dev/null
@@ -1,2157 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* hfcsusb.c
- * mISDN driver for Colognechip HFC-S USB chip
- *
- * Copyright 2001 by Peter Sprenger (sprenger@moving-bytes.de)
- * Copyright 2008 by Martin Bachem (info@bachem-it.com)
- *
- * module params
- *   debug=<n>, default=0, with n=0xHHHHGGGG
- *      H - l1 driver flags described in hfcsusb.h
- *      G - common mISDN debug flags described at mISDNhw.h
- *
- *   poll=<n>, default 128
- *     n : burst size of PH_DATA_IND at transparent rx data
- *
- * Revision: 0.3.3 (socket), 2008-11-05
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/usb.h>
-#include <linux/mISDNhw.h>
-#include <linux/slab.h>
-#include "hfcsusb.h"
-
-static unsigned int debug;
-static int poll = DEFAULT_TRANSP_BURST_SZ;
-
-static LIST_HEAD(HFClist);
-static DEFINE_RWLOCK(HFClock);
-
-
-MODULE_AUTHOR("Martin Bachem");
-MODULE_DESCRIPTION("mISDN driver for Colognechip HFC-S USB chip");
-MODULE_LICENSE("GPL");
-module_param(debug, uint, S_IRUGO | S_IWUSR);
-module_param(poll, int, 0);
-
-static int hfcsusb_cnt;
-
-/* some function prototypes */
-static void hfcsusb_ph_command(struct hfcsusb *hw, u_char command);
-static void release_hw(struct hfcsusb *hw);
-static void reset_hfcsusb(struct hfcsusb *hw);
-static void setPortMode(struct hfcsusb *hw);
-static void hfcsusb_start_endpoint(struct hfcsusb *hw, int channel);
-static void hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel);
-static int  hfcsusb_setup_bch(struct bchannel *bch, int protocol);
-static void deactivate_bchannel(struct bchannel *bch);
-static int  hfcsusb_ph_info(struct hfcsusb *hw);
-
-/* start next background transfer for control channel */
-static void
-ctrl_start_transfer(struct hfcsusb *hw)
-{
-	if (debug & DBG_HFC_CALL_TRACE)
-		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
-
-	if (hw->ctrl_cnt) {
-		hw->ctrl_urb->pipe = hw->ctrl_out_pipe;
-		hw->ctrl_urb->setup_packet = (u_char *)&hw->ctrl_write;
-		hw->ctrl_urb->transfer_buffer = NULL;
-		hw->ctrl_urb->transfer_buffer_length = 0;
-		hw->ctrl_write.wIndex =
-			cpu_to_le16(hw->ctrl_buff[hw->ctrl_out_idx].hfcs_reg);
-		hw->ctrl_write.wValue =
-			cpu_to_le16(hw->ctrl_buff[hw->ctrl_out_idx].reg_val);
-
-		usb_submit_urb(hw->ctrl_urb, GFP_ATOMIC);
-	}
-}
-
-/*
- * queue a control transfer request to write HFC-S USB
- * chip register using CTRL resuest queue
- */
-static int write_reg(struct hfcsusb *hw, __u8 reg, __u8 val)
-{
-	struct ctrl_buf *buf;
-
-	if (debug & DBG_HFC_CALL_TRACE)
-		printk(KERN_DEBUG "%s: %s reg(0x%02x) val(0x%02x)\n",
-		       hw->name, __func__, reg, val);
-
-	spin_lock(&hw->ctrl_lock);
-	if (hw->ctrl_cnt >= HFC_CTRL_BUFSIZE) {
-		spin_unlock(&hw->ctrl_lock);
-		return 1;
-	}
-	buf = &hw->ctrl_buff[hw->ctrl_in_idx];
-	buf->hfcs_reg = reg;
-	buf->reg_val = val;
-	if (++hw->ctrl_in_idx >= HFC_CTRL_BUFSIZE)
-		hw->ctrl_in_idx = 0;
-	if (++hw->ctrl_cnt == 1)
-		ctrl_start_transfer(hw);
-	spin_unlock(&hw->ctrl_lock);
-
-	return 0;
-}
-
-/* control completion routine handling background control cmds */
-static void
-ctrl_complete(struct urb *urb)
-{
-	struct hfcsusb *hw = (struct hfcsusb *) urb->context;
-
-	if (debug & DBG_HFC_CALL_TRACE)
-		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
-
-	urb->dev = hw->dev;
-	if (hw->ctrl_cnt) {
-		hw->ctrl_cnt--;	/* decrement actual count */
-		if (++hw->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
-			hw->ctrl_out_idx = 0;	/* pointer wrap */
-
-		ctrl_start_transfer(hw); /* start next transfer */
-	}
-}
-
-/* handle LED bits   */
-static void
-set_led_bit(struct hfcsusb *hw, signed short led_bits, int set_on)
-{
-	if (set_on) {
-		if (led_bits < 0)
-			hw->led_state &= ~abs(led_bits);
-		else
-			hw->led_state |= led_bits;
-	} else {
-		if (led_bits < 0)
-			hw->led_state |= abs(led_bits);
-		else
-			hw->led_state &= ~led_bits;
-	}
-}
-
-/* handle LED requests  */
-static void
-handle_led(struct hfcsusb *hw, int event)
-{
-	struct hfcsusb_vdata *driver_info = (struct hfcsusb_vdata *)
-		hfcsusb_idtab[hw->vend_idx].driver_info;
-	__u8 tmpled;
-
-	if (driver_info->led_scheme == LED_OFF)
-		return;
-	tmpled = hw->led_state;
-
-	switch (event) {
-	case LED_POWER_ON:
-		set_led_bit(hw, driver_info->led_bits[0], 1);
-		set_led_bit(hw, driver_info->led_bits[1], 0);
-		set_led_bit(hw, driver_info->led_bits[2], 0);
-		set_led_bit(hw, driver_info->led_bits[3], 0);
-		break;
-	case LED_POWER_OFF:
-		set_led_bit(hw, driver_info->led_bits[0], 0);
-		set_led_bit(hw, driver_info->led_bits[1], 0);
-		set_led_bit(hw, driver_info->led_bits[2], 0);
-		set_led_bit(hw, driver_info->led_bits[3], 0);
-		break;
-	case LED_S0_ON:
-		set_led_bit(hw, driver_info->led_bits[1], 1);
-		break;
-	case LED_S0_OFF:
-		set_led_bit(hw, driver_info->led_bits[1], 0);
-		break;
-	case LED_B1_ON:
-		set_led_bit(hw, driver_info->led_bits[2], 1);
-		break;
-	case LED_B1_OFF:
-		set_led_bit(hw, driver_info->led_bits[2], 0);
-		break;
-	case LED_B2_ON:
-		set_led_bit(hw, driver_info->led_bits[3], 1);
-		break;
-	case LED_B2_OFF:
-		set_led_bit(hw, driver_info->led_bits[3], 0);
-		break;
-	}
-
-	if (hw->led_state != tmpled) {
-		if (debug & DBG_HFC_CALL_TRACE)
-			printk(KERN_DEBUG "%s: %s reg(0x%02x) val(x%02x)\n",
-			       hw->name, __func__,
-			       HFCUSB_P_DATA, hw->led_state);
-
-		write_reg(hw, HFCUSB_P_DATA, hw->led_state);
-	}
-}
-
-/*
- * Layer2 -> Layer 1 Bchannel data
- */
-static int
-hfcusb_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct bchannel		*bch = container_of(ch, struct bchannel, ch);
-	struct hfcsusb		*hw = bch->hw;
-	int			ret = -EINVAL;
-	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
-	u_long			flags;
-
-	if (debug & DBG_HFC_CALL_TRACE)
-		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
-
-	switch (hh->prim) {
-	case PH_DATA_REQ:
-		spin_lock_irqsave(&hw->lock, flags);
-		ret = bchannel_senddata(bch, skb);
-		spin_unlock_irqrestore(&hw->lock, flags);
-		if (debug & DBG_HFC_CALL_TRACE)
-			printk(KERN_DEBUG "%s: %s PH_DATA_REQ ret(%i)\n",
-			       hw->name, __func__, ret);
-		if (ret > 0)
-			ret = 0;
-		return ret;
-	case PH_ACTIVATE_REQ:
-		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) {
-			hfcsusb_start_endpoint(hw, bch->nr - 1);
-			ret = hfcsusb_setup_bch(bch, ch->protocol);
-		} else
-			ret = 0;
-		if (!ret)
-			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
-				    0, NULL, GFP_KERNEL);
-		break;
-	case PH_DEACTIVATE_REQ:
-		deactivate_bchannel(bch);
-		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY,
-			    0, NULL, GFP_KERNEL);
-		ret = 0;
-		break;
-	}
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-/*
- * send full D/B channel status information
- * as MPH_INFORMATION_IND
- */
-static int
-hfcsusb_ph_info(struct hfcsusb *hw)
-{
-	struct ph_info *phi;
-	struct dchannel *dch = &hw->dch;
-	int i;
-
-	phi = kzalloc_flex(*phi, bch, dch->dev.nrbchan, GFP_ATOMIC);
-	if (!phi)
-		return -ENOMEM;
-
-	phi->dch.ch.protocol = hw->protocol;
-	phi->dch.ch.Flags = dch->Flags;
-	phi->dch.state = dch->state;
-	phi->dch.num_bch = dch->dev.nrbchan;
-	for (i = 0; i < dch->dev.nrbchan; i++) {
-		phi->bch[i].protocol = hw->bch[i].ch.protocol;
-		phi->bch[i].Flags = hw->bch[i].Flags;
-	}
-	_queue_data(&dch->dev.D, MPH_INFORMATION_IND, MISDN_ID_ANY,
-		    struct_size(phi, bch, dch->dev.nrbchan), phi, GFP_ATOMIC);
-	kfree(phi);
-
-	return 0;
-}
-
-/*
- * Layer2 -> Layer 1 Dchannel data
- */
-static int
-hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
-	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
-	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
-	struct hfcsusb		*hw = dch->hw;
-	int			ret = -EINVAL;
-	u_long			flags;
-
-	switch (hh->prim) {
-	case PH_DATA_REQ:
-		if (debug & DBG_HFC_CALL_TRACE)
-			printk(KERN_DEBUG "%s: %s: PH_DATA_REQ\n",
-			       hw->name, __func__);
-
-		spin_lock_irqsave(&hw->lock, flags);
-		ret = dchannel_senddata(dch, skb);
-		spin_unlock_irqrestore(&hw->lock, flags);
-		if (ret > 0) {
-			ret = 0;
-			queue_ch_frame(ch, PH_DATA_CNF, hh->id, NULL);
-		}
-		break;
-
-	case PH_ACTIVATE_REQ:
-		if (debug & DBG_HFC_CALL_TRACE)
-			printk(KERN_DEBUG "%s: %s: PH_ACTIVATE_REQ %s\n",
-			       hw->name, __func__,
-			       (hw->protocol == ISDN_P_NT_S0) ? "NT" : "TE");
-
-		if (hw->protocol == ISDN_P_NT_S0) {
-			ret = 0;
-			if (test_bit(FLG_ACTIVE, &dch->Flags)) {
-				_queue_data(&dch->dev.D,
-					    PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-					    NULL, GFP_ATOMIC);
-			} else {
-				hfcsusb_ph_command(hw,
-						   HFC_L1_ACTIVATE_NT);
-				test_and_set_bit(FLG_L2_ACTIVATED,
-						 &dch->Flags);
-			}
-		} else {
-			hfcsusb_ph_command(hw, HFC_L1_ACTIVATE_TE);
-			ret = l1_event(dch->l1, hh->prim);
-		}
-		break;
-
-	case PH_DEACTIVATE_REQ:
-		if (debug & DBG_HFC_CALL_TRACE)
-			printk(KERN_DEBUG "%s: %s: PH_DEACTIVATE_REQ\n",
-			       hw->name, __func__);
-		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
-
-		if (hw->protocol == ISDN_P_NT_S0) {
-			struct sk_buff_head free_queue;
-
-			__skb_queue_head_init(&free_queue);
-			hfcsusb_ph_command(hw, HFC_L1_DEACTIVATE_NT);
-			spin_lock_irqsave(&hw->lock, flags);
-			skb_queue_splice_init(&dch->squeue, &free_queue);
-			if (dch->tx_skb) {
-				__skb_queue_tail(&free_queue, dch->tx_skb);
-				dch->tx_skb = NULL;
-			}
-			dch->tx_idx = 0;
-			if (dch->rx_skb) {
-				__skb_queue_tail(&free_queue, dch->rx_skb);
-				dch->rx_skb = NULL;
-			}
-			test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
-			spin_unlock_irqrestore(&hw->lock, flags);
-			__skb_queue_purge(&free_queue);
-#ifdef FIXME
-			if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
-				dchannel_sched_event(&hc->dch, D_CLEARBUSY);
-#endif
-			ret = 0;
-		} else
-			ret = l1_event(dch->l1, hh->prim);
-		break;
-	case MPH_INFORMATION_REQ:
-		ret = hfcsusb_ph_info(hw);
-		break;
-	}
-
-	return ret;
-}
-
-/*
- * Layer 1 callback function
- */
-static int
-hfc_l1callback(struct dchannel *dch, u_int cmd)
-{
-	struct hfcsusb *hw = dch->hw;
-
-	if (debug & DBG_HFC_CALL_TRACE)
-		printk(KERN_DEBUG "%s: %s cmd 0x%x\n",
-		       hw->name, __func__, cmd);
-
-	switch (cmd) {
-	case INFO3_P8:
-	case INFO3_P10:
-	case HW_RESET_REQ:
-	case HW_POWERUP_REQ:
-		break;
-
-	case HW_DEACT_REQ:
-		skb_queue_purge(&dch->squeue);
-		if (dch->tx_skb) {
-			dev_kfree_skb(dch->tx_skb);
-			dch->tx_skb = NULL;
-		}
-		dch->tx_idx = 0;
-		if (dch->rx_skb) {
-			dev_kfree_skb(dch->rx_skb);
-			dch->rx_skb = NULL;
-		}
-		test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
-		break;
-	case PH_ACTIVATE_IND:
-		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
-		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			    GFP_ATOMIC);
-		break;
-	case PH_DEACTIVATE_IND:
-		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
-		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			    GFP_ATOMIC);
-		break;
-	default:
-		if (dch->debug & DEBUG_HW)
-			printk(KERN_DEBUG "%s: %s: unknown cmd %x\n",
-			       hw->name, __func__, cmd);
-		return -1;
-	}
-	return hfcsusb_ph_info(hw);
-}
-
-static int
-open_dchannel(struct hfcsusb *hw, struct mISDNchannel *ch,
-	      struct channel_req *rq)
-{
-	int err = 0;
-
-	if (debug & DEBUG_HW_OPEN)
-		printk(KERN_DEBUG "%s: %s: dev(%d) open addr(%i) from %p\n",
-		       hw->name, __func__, hw->dch.dev.id, rq->adr.channel,
-		       __builtin_return_address(0));
-	if (rq->protocol == ISDN_P_NONE)
-		return -EINVAL;
-
-	test_and_clear_bit(FLG_ACTIVE, &hw->dch.Flags);
-	test_and_clear_bit(FLG_ACTIVE, &hw->ech.Flags);
-	hfcsusb_start_endpoint(hw, HFC_CHAN_D);
-
-	/* E-Channel logging */
-	if (rq->adr.channel == 1) {
-		if (hw->fifos[HFCUSB_PCM_RX].pipe) {
-			hfcsusb_start_endpoint(hw, HFC_CHAN_E);
-			set_bit(FLG_ACTIVE, &hw->ech.Flags);
-			_queue_data(&hw->ech.dev.D, PH_ACTIVATE_IND,
-				    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
-		} else
-			return -EINVAL;
-	}
-
-	if (!hw->initdone) {
-		hw->protocol = rq->protocol;
-		if (rq->protocol == ISDN_P_TE_S0) {
-			err = create_l1(&hw->dch, hfc_l1callback);
-			if (err)
-				return err;
-		}
-		setPortMode(hw);
-		ch->protocol = rq->protocol;
-		hw->initdone = 1;
-	} else {
-		if (rq->protocol != ch->protocol)
-			return -EPROTONOSUPPORT;
-	}
-
-	if (((ch->protocol == ISDN_P_NT_S0) && (hw->dch.state == 3)) ||
-	    ((ch->protocol == ISDN_P_TE_S0) && (hw->dch.state == 7)))
-		_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
-			    0, NULL, GFP_KERNEL);
-	rq->ch = ch;
-	if (!try_module_get(THIS_MODULE))
-		printk(KERN_WARNING "%s: %s: cannot get module\n",
-		       hw->name, __func__);
-	return 0;
-}
-
-static int
-open_bchannel(struct hfcsusb *hw, struct channel_req *rq)
-{
-	struct bchannel		*bch;
-
-	if (rq->adr.channel == 0 || rq->adr.channel > 2)
-		return -EINVAL;
-	if (rq->protocol == ISDN_P_NONE)
-		return -EINVAL;
-
-	if (debug & DBG_HFC_CALL_TRACE)
-		printk(KERN_DEBUG "%s: %s B%i\n",
-		       hw->name, __func__, rq->adr.channel);
-
-	bch = &hw->bch[rq->adr.channel - 1];
-	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
-		return -EBUSY; /* b-channel can be only open once */
-	bch->ch.protocol = rq->protocol;
-	rq->ch = &bch->ch;
-
-	if (!try_module_get(THIS_MODULE))
-		printk(KERN_WARNING "%s: %s:cannot get module\n",
-		       hw->name, __func__);
-	return 0;
-}
-
-static int
-channel_ctrl(struct hfcsusb *hw, struct mISDN_ctrl_req *cq)
-{
-	int ret = 0;
-
-	if (debug & DBG_HFC_CALL_TRACE)
-		printk(KERN_DEBUG "%s: %s op(0x%x) channel(0x%x)\n",
-		       hw->name, __func__, (cq->op), (cq->channel));
-
-	switch (cq->op) {
-	case MISDN_CTRL_GETOP:
-		cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_CONNECT |
-			MISDN_CTRL_DISCONNECT;
-		break;
-	default:
-		printk(KERN_WARNING "%s: %s: unknown Op %x\n",
-		       hw->name, __func__, cq->op);
-		ret = -EINVAL;
-		break;
-	}
-	return ret;
-}
-
-/*
- * device control function
- */
-static int
-hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
-{
-	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
-	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
-	struct hfcsusb		*hw = dch->hw;
-	struct channel_req	*rq;
-	int			err = 0;
-
-	if (dch->debug & DEBUG_HW)
-		printk(KERN_DEBUG "%s: %s: cmd:%x %p\n",
-		       hw->name, __func__, cmd, arg);
-	switch (cmd) {
-	case OPEN_CHANNEL:
-		rq = arg;
-		if ((rq->protocol == ISDN_P_TE_S0) ||
-		    (rq->protocol == ISDN_P_NT_S0))
-			err = open_dchannel(hw, ch, rq);
-		else
-			err = open_bchannel(hw, rq);
-		if (!err)
-			hw->open++;
-		break;
-	case CLOSE_CHANNEL:
-		hw->open--;
-		if (debug & DEBUG_HW_OPEN)
-			printk(KERN_DEBUG
-			       "%s: %s: dev(%d) close from %p (open %d)\n",
-			       hw->name, __func__, hw->dch.dev.id,
-			       __builtin_return_address(0), hw->open);
-		if (!hw->open) {
-			hfcsusb_stop_endpoint(hw, HFC_CHAN_D);
-			if (hw->fifos[HFCUSB_PCM_RX].pipe)
-				hfcsusb_stop_endpoint(hw, HFC_CHAN_E);
-			handle_led(hw, LED_POWER_ON);
-		}
-		module_put(THIS_MODULE);
-		break;
-	case CONTROL_CHANNEL:
-		err = channel_ctrl(hw, arg);
-		break;
-	default:
-		if (dch->debug & DEBUG_HW)
-			printk(KERN_DEBUG "%s: %s: unknown command %x\n",
-			       hw->name, __func__, cmd);
-		return -EINVAL;
-	}
-	return err;
-}
-
-/*
- * S0 TE state change event handler
- */
-static void
-ph_state_te(struct dchannel *dch)
-{
-	struct hfcsusb *hw = dch->hw;
-
-	if (debug & DEBUG_HW) {
-		if (dch->state <= HFC_MAX_TE_LAYER1_STATE)
-			printk(KERN_DEBUG "%s: %s: %s\n", hw->name, __func__,
-			       HFC_TE_LAYER1_STATES[dch->state]);
-		else
-			printk(KERN_DEBUG "%s: %s: TE F%d\n",
-			       hw->name, __func__, dch->state);
-	}
-
-	switch (dch->state) {
-	case 0:
-		l1_event(dch->l1, HW_RESET_IND);
-		break;
-	case 3:
-		l1_event(dch->l1, HW_DEACT_IND);
-		break;
-	case 5:
-	case 8:
-		l1_event(dch->l1, ANYSIGNAL);
-		break;
-	case 6:
-		l1_event(dch->l1, INFO2);
-		break;
-	case 7:
-		l1_event(dch->l1, INFO4_P8);
-		break;
-	}
-	if (dch->state == 7)
-		handle_led(hw, LED_S0_ON);
-	else
-		handle_led(hw, LED_S0_OFF);
-}
-
-/*
- * S0 NT state change event handler
- */
-static void
-ph_state_nt(struct dchannel *dch)
-{
-	struct hfcsusb *hw = dch->hw;
-
-	if (debug & DEBUG_HW) {
-		if (dch->state <= HFC_MAX_NT_LAYER1_STATE)
-			printk(KERN_DEBUG "%s: %s: %s\n",
-			       hw->name, __func__,
-			       HFC_NT_LAYER1_STATES[dch->state]);
-
-		else
-			printk(KERN_INFO DRIVER_NAME "%s: %s: NT G%d\n",
-			       hw->name, __func__, dch->state);
-	}
-
-	switch (dch->state) {
-	case (1):
-		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
-		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
-		hw->nt_timer = 0;
-		hw->timers &= ~NT_ACTIVATION_TIMER;
-		handle_led(hw, LED_S0_OFF);
-		break;
-
-	case (2):
-		if (hw->nt_timer < 0) {
-			hw->nt_timer = 0;
-			hw->timers &= ~NT_ACTIVATION_TIMER;
-			hfcsusb_ph_command(dch->hw, HFC_L1_DEACTIVATE_NT);
-		} else {
-			hw->timers |= NT_ACTIVATION_TIMER;
-			hw->nt_timer = NT_T1_COUNT;
-			/* allow G2 -> G3 transition */
-			write_reg(hw, HFCUSB_STATES, 2 | HFCUSB_NT_G2_G3);
-		}
-		break;
-	case (3):
-		hw->nt_timer = 0;
-		hw->timers &= ~NT_ACTIVATION_TIMER;
-		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
-		_queue_data(&dch->dev.D, PH_ACTIVATE_IND,
-			    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
-		handle_led(hw, LED_S0_ON);
-		break;
-	case (4):
-		hw->nt_timer = 0;
-		hw->timers &= ~NT_ACTIVATION_TIMER;
-		break;
-	default:
-		break;
-	}
-	hfcsusb_ph_info(hw);
-}
-
-static void
-ph_state(struct dchannel *dch)
-{
-	struct hfcsusb *hw = dch->hw;
-
-	if (hw->protocol == ISDN_P_NT_S0)
-		ph_state_nt(dch);
-	else if (hw->protocol == ISDN_P_TE_S0)
-		ph_state_te(dch);
-}
-
-/*
- * disable/enable BChannel for desired protocol
- */
-static int
-hfcsusb_setup_bch(struct bchannel *bch, int protocol)
-{
-	struct hfcsusb *hw = bch->hw;
-	__u8 conhdlc, sctrl, sctrl_r;
-
-	if (debug & DEBUG_HW)
-		printk(KERN_DEBUG "%s: %s: protocol %x-->%x B%d\n",
-		       hw->name, __func__, bch->state, protocol,
-		       bch->nr);
-
-	/* setup val for CON_HDLC */
-	conhdlc = 0;
-	if (protocol > ISDN_P_NONE)
-		conhdlc = 8;	/* enable FIFO */
-
-	switch (protocol) {
-	case (-1):	/* used for init */
-		bch->state = -1;
-		fallthrough;
-	case (ISDN_P_NONE):
-		if (bch->state == ISDN_P_NONE)
-			return 0; /* already in idle state */
-		bch->state = ISDN_P_NONE;
-		clear_bit(FLG_HDLC, &bch->Flags);
-		clear_bit(FLG_TRANSPARENT, &bch->Flags);
-		break;
-	case (ISDN_P_B_RAW):
-		conhdlc |= 2;
-		bch->state = protocol;
-		set_bit(FLG_TRANSPARENT, &bch->Flags);
-		break;
-	case (ISDN_P_B_HDLC):
-		bch->state = protocol;
-		set_bit(FLG_HDLC, &bch->Flags);
-		break;
-	default:
-		if (debug & DEBUG_HW)
-			printk(KERN_DEBUG "%s: %s: prot not known %x\n",
-			       hw->name, __func__, protocol);
-		return -ENOPROTOOPT;
-	}
-
-	if (protocol >= ISDN_P_NONE) {
-		write_reg(hw, HFCUSB_FIFO, (bch->nr == 1) ? 0 : 2);
-		write_reg(hw, HFCUSB_CON_HDLC, conhdlc);
-		write_reg(hw, HFCUSB_INC_RES_F, 2);
-		write_reg(hw, HFCUSB_FIFO, (bch->nr == 1) ? 1 : 3);
-		write_reg(hw, HFCUSB_CON_HDLC, conhdlc);
-		write_reg(hw, HFCUSB_INC_RES_F, 2);
-
-		sctrl = 0x40 + ((hw->protocol == ISDN_P_TE_S0) ? 0x00 : 0x04);
-		sctrl_r = 0x0;
-		if (test_bit(FLG_ACTIVE, &hw->bch[0].Flags)) {
-			sctrl |= 1;
-			sctrl_r |= 1;
-		}
-		if (test_bit(FLG_ACTIVE, &hw->bch[1].Flags)) {
-			sctrl |= 2;
-			sctrl_r |= 2;
-		}
-		write_reg(hw, HFCUSB_SCTRL, sctrl);
-		write_reg(hw, HFCUSB_SCTRL_R, sctrl_r);
-
-		if (protocol > ISDN_P_NONE)
-			handle_led(hw, (bch->nr == 1) ? LED_B1_ON : LED_B2_ON);
-		else
-			handle_led(hw, (bch->nr == 1) ? LED_B1_OFF :
-				   LED_B2_OFF);
-	}
-	return hfcsusb_ph_info(hw);
-}
-
-static void
-hfcsusb_ph_command(struct hfcsusb *hw, u_char command)
-{
-	if (debug & DEBUG_HW)
-		printk(KERN_DEBUG "%s: %s: %x\n",
-		       hw->name, __func__, command);
-
-	switch (command) {
-	case HFC_L1_ACTIVATE_TE:
-		/* force sending sending INFO1 */
-		write_reg(hw, HFCUSB_STATES, 0x14);
-		/* start l1 activation */
-		write_reg(hw, HFCUSB_STATES, 0x04);
-		break;
-
-	case HFC_L1_FORCE_DEACTIVATE_TE:
-		write_reg(hw, HFCUSB_STATES, 0x10);
-		write_reg(hw, HFCUSB_STATES, 0x03);
-		break;
-
-	case HFC_L1_ACTIVATE_NT:
-		if (hw->dch.state == 3)
-			_queue_data(&hw->dch.dev.D, PH_ACTIVATE_IND,
-				    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
-		else
-			write_reg(hw, HFCUSB_STATES, HFCUSB_ACTIVATE |
-				  HFCUSB_DO_ACTION | HFCUSB_NT_G2_G3);
-		break;
-
-	case HFC_L1_DEACTIVATE_NT:
-		write_reg(hw, HFCUSB_STATES,
-			  HFCUSB_DO_ACTION);
-		break;
-	}
-}
-
-/*
- * Layer 1 B-channel hardware access
- */
-static int
-channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
-{
-	return mISDN_ctrl_bchannel(bch, cq);
-}
-
-/* collect data from incoming interrupt or isochron USB data */
-static void
-hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
-		 int finish)
-{
-	struct hfcsusb	*hw = fifo->hw;
-	struct sk_buff	*rx_skb = NULL;
-	int		maxlen = 0;
-	int		fifon = fifo->fifonum;
-	int		i;
-	int		hdlc = 0;
-	unsigned long	flags;
-
-	if (debug & DBG_HFC_CALL_TRACE)
-		printk(KERN_DEBUG "%s: %s: fifo(%i) len(%i) "
-		       "dch(%p) bch(%p) ech(%p)\n",
-		       hw->name, __func__, fifon, len,
-		       fifo->dch, fifo->bch, fifo->ech);
-
-	if (!len)
-		return;
-
-	if ((!!fifo->dch + !!fifo->bch + !!fifo->ech) != 1) {
-		printk(KERN_DEBUG "%s: %s: undefined channel\n",
-		       hw->name, __func__);
-		return;
-	}
-
-	spin_lock_irqsave(&hw->lock, flags);
-	if (fifo->dch) {
-		rx_skb = fifo->dch->rx_skb;
-		maxlen = fifo->dch->maxlen;
-		hdlc = 1;
-	}
-	if (fifo->bch) {
-		if (test_bit(FLG_RX_OFF, &fifo->bch->Flags)) {
-			fifo->bch->dropcnt += len;
-			spin_unlock_irqrestore(&hw->lock, flags);
-			return;
-		}
-		maxlen = bchannel_get_rxbuf(fifo->bch, len);
-		rx_skb = fifo->bch->rx_skb;
-		if (maxlen < 0) {
-			if (rx_skb)
-				skb_trim(rx_skb, 0);
-			pr_warn("%s.B%d: No bufferspace for %d bytes\n",
-				hw->name, fifo->bch->nr, len);
-			spin_unlock_irqrestore(&hw->lock, flags);
-			return;
-		}
-		maxlen = fifo->bch->maxlen;
-		hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags);
-	}
-	if (fifo->ech) {
-		rx_skb = fifo->ech->rx_skb;
-		maxlen = fifo->ech->maxlen;
-		hdlc = 1;
-	}
-
-	if (fifo->dch || fifo->ech) {
-		if (!rx_skb) {
-			rx_skb = mI_alloc_skb(maxlen, GFP_ATOMIC);
-			if (rx_skb) {
-				if (fifo->dch)
-					fifo->dch->rx_skb = rx_skb;
-				if (fifo->ech)
-					fifo->ech->rx_skb = rx_skb;
-				skb_trim(rx_skb, 0);
-			} else {
-				printk(KERN_DEBUG "%s: %s: No mem for rx_skb\n",
-				       hw->name, __func__);
-				spin_unlock_irqrestore(&hw->lock, flags);
-				return;
-			}
-		}
-		/* D/E-Channel SKB range check */
-		if ((rx_skb->len + len) >= MAX_DFRAME_LEN_L1) {
-			printk(KERN_DEBUG "%s: %s: sbk mem exceeded "
-			       "for fifo(%d) HFCUSB_D_RX\n",
-			       hw->name, __func__, fifon);
-			skb_trim(rx_skb, 0);
-			spin_unlock_irqrestore(&hw->lock, flags);
-			return;
-		}
-	}
-
-	skb_put_data(rx_skb, data, len);
-
-	if (hdlc) {
-		/* we have a complete hdlc packet */
-		if (finish) {
-			if ((rx_skb->len > 3) &&
-			    (!(rx_skb->data[rx_skb->len - 1]))) {
-				if (debug & DBG_HFC_FIFO_VERBOSE) {
-					printk(KERN_DEBUG "%s: %s: fifon(%i)"
-					       " new RX len(%i): ",
-					       hw->name, __func__, fifon,
-					       rx_skb->len);
-					i = 0;
-					while (i < rx_skb->len)
-						printk("%02x ",
-						       rx_skb->data[i++]);
-					printk("\n");
-				}
-
-				/* remove CRC & status */
-				skb_trim(rx_skb, rx_skb->len - 3);
-
-				if (fifo->dch)
-					recv_Dchannel(fifo->dch);
-				if (fifo->bch)
-					recv_Bchannel(fifo->bch, MISDN_ID_ANY,
-						      0);
-				if (fifo->ech)
-					recv_Echannel(fifo->ech,
-						      &hw->dch);
-			} else {
-				if (debug & DBG_HFC_FIFO_VERBOSE) {
-					printk(KERN_DEBUG
-					       "%s: CRC or minlen ERROR fifon(%i) "
-					       "RX len(%i): ",
-					       hw->name, fifon, rx_skb->len);
-					i = 0;
-					while (i < rx_skb->len)
-						printk("%02x ",
-						       rx_skb->data[i++]);
-					printk("\n");
-				}
-				skb_trim(rx_skb, 0);
-			}
-		}
-	} else {
-		/* deliver transparent data to layer2 */
-		recv_Bchannel(fifo->bch, MISDN_ID_ANY, false);
-	}
-	spin_unlock_irqrestore(&hw->lock, flags);
-}
-
-static void
-fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
-	      void *buf, int num_packets, int packet_size, int interval,
-	      usb_complete_t complete, void *context)
-{
-	int k;
-
-	usb_fill_bulk_urb(urb, dev, pipe, buf, packet_size * num_packets,
-			  complete, context);
-
-	urb->number_of_packets = num_packets;
-	urb->transfer_flags = URB_ISO_ASAP;
-	urb->actual_length = 0;
-	urb->interval = interval;
-
-	for (k = 0; k < num_packets; k++) {
-		urb->iso_frame_desc[k].offset = packet_size * k;
-		urb->iso_frame_desc[k].length = packet_size;
-		urb->iso_frame_desc[k].actual_length = 0;
-	}
-}
-
-/* receive completion routine for all ISO tx fifos   */
-static void
-rx_iso_complete(struct urb *urb)
-{
-	struct iso_urb *context_iso_urb = (struct iso_urb *) urb->context;
-	struct usb_fifo *fifo = context_iso_urb->owner_fifo;
-	struct hfcsusb *hw = fifo->hw;
-	int k, len, errcode, offset, num_isoc_packets, fifon, maxlen,
-		status, iso_status, i;
-	__u8 *buf;
-	static __u8 eof[8];
-	__u8 s0_state;
-	unsigned long flags;
-
-	fifon = fifo->fifonum;
-	status = urb->status;
-
-	spin_lock_irqsave(&hw->lock, flags);
-	if (fifo->stop_gracefull) {
-		fifo->stop_gracefull = 0;
-		fifo->active = 0;
-		spin_unlock_irqrestore(&hw->lock, flags);
-		return;
-	}
-	spin_unlock_irqrestore(&hw->lock, flags);
-
-	/*
-	 * ISO transfer only partially completed,
-	 * look at individual frame status for details
-	 */
-	if (status == -EXDEV) {
-		if (debug & DEBUG_HW)
-			printk(KERN_DEBUG "%s: %s: with -EXDEV "
-			       "urb->status %d, fifonum %d\n",
-			       hw->name, __func__,  status, fifon);
-
-		/* clear status, so go on with ISO transfers */
-		status = 0;
-	}
-
-	s0_state = 0;
-	if (fifo->active && !status) {
-		num_isoc_packets = iso_packets[fifon];
-		maxlen = fifo->usb_packet_maxlen;
-
-		for (k = 0; k < num_isoc_packets; ++k) {
-			len = urb->iso_frame_desc[k].actual_length;
-			offset = urb->iso_frame_desc[k].offset;
-			buf = context_iso_urb->buffer + offset;
-			iso_status = urb->iso_frame_desc[k].status;
-
-			if (iso_status && (debug & DBG_HFC_FIFO_VERBOSE)) {
-				printk(KERN_DEBUG "%s: %s: "
-				       "ISO packet %i, status: %i\n",
-				       hw->name, __func__, k, iso_status);
-			}
-
-			/* USB data log for every D ISO in */
-			if ((fifon == HFCUSB_D_RX) &&
-			    (debug & DBG_HFC_USB_VERBOSE)) {
-				printk(KERN_DEBUG
-				       "%s: %s: %d (%d/%d) len(%d) ",
-				       hw->name, __func__, urb->start_frame,
-				       k, num_isoc_packets - 1,
-				       len);
-				for (i = 0; i < len; i++)
-					printk("%x ", buf[i]);
-				printk("\n");
-			}
-
-			if (!iso_status) {
-				if (fifo->last_urblen != maxlen) {
-					/*
-					 * save fifo fill-level threshold bits
-					 * to use them later in TX ISO URB
-					 * completions
-					 */
-					hw->threshold_mask = buf[1];
-
-					if (fifon == HFCUSB_D_RX)
-						s0_state = (buf[0] >> 4);
-
-					eof[fifon] = buf[0] & 1;
-					if (len > 2)
-						hfcsusb_rx_frame(fifo, buf + 2,
-								 len - 2, (len < maxlen)
-								 ? eof[fifon] : 0);
-				} else
-					hfcsusb_rx_frame(fifo, buf, len,
-							 (len < maxlen) ?
-							 eof[fifon] : 0);
-				fifo->last_urblen = len;
-			}
-		}
-
-		/* signal S0 layer1 state change */
-		if ((s0_state) && (hw->initdone) &&
-		    (s0_state != hw->dch.state)) {
-			hw->dch.state = s0_state;
-			schedule_event(&hw->dch, FLG_PHCHANGE);
-		}
-
-		fill_isoc_urb(urb, fifo->hw->dev, fifo->pipe,
-			      context_iso_urb->buffer, num_isoc_packets,
-			      fifo->usb_packet_maxlen, fifo->intervall,
-			      (usb_complete_t)rx_iso_complete, urb->context);
-		errcode = usb_submit_urb(urb, GFP_ATOMIC);
-		if (errcode < 0) {
-			if (debug & DEBUG_HW)
-				printk(KERN_DEBUG "%s: %s: error submitting "
-				       "ISO URB: %d\n",
-				       hw->name, __func__, errcode);
-		}
-	} else {
-		if (status && (debug & DBG_HFC_URB_INFO))
-			printk(KERN_DEBUG "%s: %s: rx_iso_complete : "
-			       "urb->status %d, fifonum %d\n",
-			       hw->name, __func__, status, fifon);
-	}
-}
-
-/* receive completion routine for all interrupt rx fifos */
-static void
-rx_int_complete(struct urb *urb)
-{
-	int len, status, i;
-	__u8 *buf, maxlen, fifon;
-	struct usb_fifo *fifo = (struct usb_fifo *) urb->context;
-	struct hfcsusb *hw = fifo->hw;
-	static __u8 eof[8];
-	unsigned long flags;
-
-	spin_lock_irqsave(&hw->lock, flags);
-	if (fifo->stop_gracefull) {
-		fifo->stop_gracefull = 0;
-		fifo->active = 0;
-		spin_unlock_irqrestore(&hw->lock, flags);
-		return;
-	}
-	spin_unlock_irqrestore(&hw->lock, flags);
-
-	fifon = fifo->fifonum;
-	if ((!fifo->active) || (urb->status)) {
-		if (debug & DBG_HFC_URB_ERROR)
-			printk(KERN_DEBUG
-			       "%s: %s: RX-Fifo %i is going down (%i)\n",
-			       hw->name, __func__, fifon, urb->status);
-
-		fifo->urb->interval = 0; /* cancel automatic rescheduling */
-		return;
-	}
-	len = urb->actual_length;
-	buf = fifo->buffer;
-	maxlen = fifo->usb_packet_maxlen;
-
-	/* USB data log for every D INT in */
-	if ((fifon == HFCUSB_D_RX) && (debug & DBG_HFC_USB_VERBOSE)) {
-		printk(KERN_DEBUG "%s: %s: D RX INT len(%d) ",
-		       hw->name, __func__, len);
-		for (i = 0; i < len; i++)
-			printk("%02x ", buf[i]);
-		printk("\n");
-	}
-
-	if (fifo->last_urblen != fifo->usb_packet_maxlen) {
-		/* the threshold mask is in the 2nd status byte */
-		hw->threshold_mask = buf[1];
-
-		/* signal S0 layer1 state change */
-		if (hw->initdone && ((buf[0] >> 4) != hw->dch.state)) {
-			hw->dch.state = (buf[0] >> 4);
-			schedule_event(&hw->dch, FLG_PHCHANGE);
-		}
-
-		eof[fifon] = buf[0] & 1;
-		/* if we have more than the 2 status bytes -> collect data */
-		if (len > 2)
-			hfcsusb_rx_frame(fifo, buf + 2,
-					 urb->actual_length - 2,
-					 (len < maxlen) ? eof[fifon] : 0);
-	} else {
-		hfcsusb_rx_frame(fifo, buf, urb->actual_length,
-				 (len < maxlen) ? eof[fifon] : 0);
-	}
-	fifo->last_urblen = urb->actual_length;
-
-	status = usb_submit_urb(urb, GFP_ATOMIC);
-	if (status) {
-		if (debug & DEBUG_HW)
-			printk(KERN_DEBUG "%s: %s: error resubmitting USB\n",
-			       hw->name, __func__);
-	}
-}
-
-/* transmit completion routine for all ISO tx fifos */
-static void
-tx_iso_complete(struct urb *urb)
-{
-	struct iso_urb *context_iso_urb = (struct iso_urb *) urb->context;
-	struct usb_fifo *fifo = context_iso_urb->owner_fifo;
-	struct hfcsusb *hw = fifo->hw;
-	struct sk_buff *tx_skb;
-	int k, tx_offset, num_isoc_packets, sink, remain, current_len,
-		errcode, hdlc, i;
-	int *tx_idx;
-	int frame_complete, fifon, status, fillempty = 0;
-	__u8 threshbit, *p;
-	unsigned long flags;
-
-	spin_lock_irqsave(&hw->lock, flags);
-	if (fifo->stop_gracefull) {
-		fifo->stop_gracefull = 0;
-		fifo->active = 0;
-		spin_unlock_irqrestore(&hw->lock, flags);
-		return;
-	}
-
-	if (fifo->dch) {
-		tx_skb = fifo->dch->tx_skb;
-		tx_idx = &fifo->dch->tx_idx;
-		hdlc = 1;
-	} else if (fifo->bch) {
-		tx_skb = fifo->bch->tx_skb;
-		tx_idx = &fifo->bch->tx_idx;
-		hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags);
-		if (!tx_skb && !hdlc &&
-		    test_bit(FLG_FILLEMPTY, &fifo->bch->Flags))
-			fillempty = 1;
-	} else {
-		printk(KERN_DEBUG "%s: %s: neither BCH nor DCH\n",
-		       hw->name, __func__);
-		spin_unlock_irqrestore(&hw->lock, flags);
-		return;
-	}
-
-	fifon = fifo->fifonum;
-	status = urb->status;
-
-	tx_offset = 0;
-
-	/*
-	 * ISO transfer only partially completed,
-	 * look at individual frame status for details
-	 */
-	if (status == -EXDEV) {
-		if (debug & DBG_HFC_URB_ERROR)
-			printk(KERN_DEBUG "%s: %s: "
-			       "-EXDEV (%i) fifon (%d)\n",
-			       hw->name, __func__, status, fifon);
-
-		/* clear status, so go on with ISO transfers */
-		status = 0;
-	}
-
-	if (fifo->active && !status) {
-		/* is FifoFull-threshold set for our channel? */
-		threshbit = (hw->threshold_mask & (1 << fifon));
-		num_isoc_packets = iso_packets[fifon];
-
-		/* predict dataflow to avoid fifo overflow */
-		if (fifon >= HFCUSB_D_TX)
-			sink = (threshbit) ? SINK_DMIN : SINK_DMAX;
-		else
-			sink = (threshbit) ? SINK_MIN : SINK_MAX;
-		fill_isoc_urb(urb, fifo->hw->dev, fifo->pipe,
-			      context_iso_urb->buffer, num_isoc_packets,
-			      fifo->usb_packet_maxlen, fifo->intervall,
-			      (usb_complete_t)tx_iso_complete, urb->context);
-		memset(context_iso_urb->buffer, 0,
-		       sizeof(context_iso_urb->buffer));
-		frame_complete = 0;
-
-		for (k = 0; k < num_isoc_packets; ++k) {
-			/* analyze tx success of previous ISO packets */
-			if (debug & DBG_HFC_URB_ERROR) {
-				errcode = urb->iso_frame_desc[k].status;
-				if (errcode) {
-					printk(KERN_DEBUG "%s: %s: "
-					       "ISO packet %i, status: %i\n",
-					       hw->name, __func__, k, errcode);
-				}
-			}
-
-			/* Generate next ISO Packets */
-			if (tx_skb)
-				remain = tx_skb->len - *tx_idx;
-			else if (fillempty)
-				remain = 15; /* > not complete */
-			else
-				remain = 0;
-
-			if (remain > 0) {
-				fifo->bit_line -= sink;
-				current_len = (0 - fifo->bit_line) / 8;
-				if (current_len > 14)
-					current_len = 14;
-				if (current_len < 0)
-					current_len = 0;
-				if (remain < current_len)
-					current_len = remain;
-
-				/* how much bit do we put on the line? */
-				fifo->bit_line += current_len * 8;
-
-				context_iso_urb->buffer[tx_offset] = 0;
-				if (current_len == remain) {
-					if (hdlc) {
-						/* signal frame completion */
-						context_iso_urb->
-							buffer[tx_offset] = 1;
-						/* add 2 byte flags and 16bit
-						 * CRC at end of ISDN frame */
-						fifo->bit_line += 32;
-					}
-					frame_complete = 1;
-				}
-
-				/* copy tx data to iso-urb buffer */
-				p = context_iso_urb->buffer + tx_offset + 1;
-				if (fillempty) {
-					memset(p, fifo->bch->fill[0],
-					       current_len);
-				} else {
-					memcpy(p, (tx_skb->data + *tx_idx),
-					       current_len);
-					*tx_idx += current_len;
-				}
-				urb->iso_frame_desc[k].offset = tx_offset;
-				urb->iso_frame_desc[k].length = current_len + 1;
-
-				/* USB data log for every D ISO out */
-				if ((fifon == HFCUSB_D_RX) && !fillempty &&
-				    (debug & DBG_HFC_USB_VERBOSE)) {
-					printk(KERN_DEBUG
-					       "%s: %s (%d/%d) offs(%d) len(%d) ",
-					       hw->name, __func__,
-					       k, num_isoc_packets - 1,
-					       urb->iso_frame_desc[k].offset,
-					       urb->iso_frame_desc[k].length);
-
-					for (i = urb->iso_frame_desc[k].offset;
-					     i < (urb->iso_frame_desc[k].offset
-						  + urb->iso_frame_desc[k].length);
-					     i++)
-						printk("%x ",
-						       context_iso_urb->buffer[i]);
-
-					printk(" skb->len(%i) tx-idx(%d)\n",
-					       tx_skb->len, *tx_idx);
-				}
-
-				tx_offset += (current_len + 1);
-			} else {
-				urb->iso_frame_desc[k].offset = tx_offset++;
-				urb->iso_frame_desc[k].length = 1;
-				/* we lower data margin every msec */
-				fifo->bit_line -= sink;
-				if (fifo->bit_line < BITLINE_INF)
-					fifo->bit_line = BITLINE_INF;
-			}
-
-			if (frame_complete) {
-				frame_complete = 0;
-
-				if (debug & DBG_HFC_FIFO_VERBOSE) {
-					printk(KERN_DEBUG  "%s: %s: "
-					       "fifon(%i) new TX len(%i): ",
-					       hw->name, __func__,
-					       fifon, tx_skb->len);
-					i = 0;
-					while (i < tx_skb->len)
-						printk("%02x ",
-						       tx_skb->data[i++]);
-					printk("\n");
-				}
-
-				dev_consume_skb_irq(tx_skb);
-				tx_skb = NULL;
-				if (fifo->dch && get_next_dframe(fifo->dch))
-					tx_skb = fifo->dch->tx_skb;
-				else if (fifo->bch &&
-					 get_next_bframe(fifo->bch))
-					tx_skb = fifo->bch->tx_skb;
-			}
-		}
-		errcode = usb_submit_urb(urb, GFP_ATOMIC);
-		if (errcode < 0) {
-			if (debug & DEBUG_HW)
-				printk(KERN_DEBUG
-				       "%s: %s: error submitting ISO URB: %d \n",
-				       hw->name, __func__, errcode);
-		}
-
-		/*
-		 * abuse DChannel tx iso completion to trigger NT mode state
-		 * changes tx_iso_complete is assumed to be called every
-		 * fifo->intervall (ms)
-		 */
-		if ((fifon == HFCUSB_D_TX) && (hw->protocol == ISDN_P_NT_S0)
-		    && (hw->timers & NT_ACTIVATION_TIMER)) {
-			if ((--hw->nt_timer) < 0)
-				schedule_event(&hw->dch, FLG_PHCHANGE);
-		}
-
-	} else {
-		if (status && (debug & DBG_HFC_URB_ERROR))
-			printk(KERN_DEBUG  "%s: %s: urb->status %s (%i)"
-			       "fifonum=%d\n",
-			       hw->name, __func__,
-			       symbolic(urb_errlist, status), status, fifon);
-	}
-	spin_unlock_irqrestore(&hw->lock, flags);
-}
-
-/*
- * allocs urbs and start isoc transfer with two pending urbs to avoid
- * gaps in the transfer chain
- */
-static int
-start_isoc_chain(struct usb_fifo *fifo, int num_packets_per_urb,
-		 usb_complete_t complete, int packet_size)
-{
-	struct hfcsusb *hw = fifo->hw;
-	int i, k, errcode;
-
-	if (debug)
-		printk(KERN_DEBUG "%s: %s: fifo %i\n",
-		       hw->name, __func__, fifo->fifonum);
-
-	/* allocate Memory for Iso out Urbs */
-	for (i = 0; i < 2; i++) {
-		if (!(fifo->iso[i].urb)) {
-			fifo->iso[i].urb =
-				usb_alloc_urb(num_packets_per_urb, GFP_KERNEL);
-			if (!(fifo->iso[i].urb)) {
-				printk(KERN_DEBUG
-				       "%s: %s: alloc urb for fifo %i failed",
-				       hw->name, __func__, fifo->fifonum);
-				continue;
-			}
-			fifo->iso[i].owner_fifo = (struct usb_fifo *) fifo;
-			fifo->iso[i].indx = i;
-
-			/* Init the first iso */
-			if (ISO_BUFFER_SIZE >=
-			    (fifo->usb_packet_maxlen *
-			     num_packets_per_urb)) {
-				fill_isoc_urb(fifo->iso[i].urb,
-					      fifo->hw->dev, fifo->pipe,
-					      fifo->iso[i].buffer,
-					      num_packets_per_urb,
-					      fifo->usb_packet_maxlen,
-					      fifo->intervall, complete,
-					      &fifo->iso[i]);
-				memset(fifo->iso[i].buffer, 0,
-				       sizeof(fifo->iso[i].buffer));
-
-				for (k = 0; k < num_packets_per_urb; k++) {
-					fifo->iso[i].urb->
-						iso_frame_desc[k].offset =
-						k * packet_size;
-					fifo->iso[i].urb->
-						iso_frame_desc[k].length =
-						packet_size;
-				}
-			} else {
-				printk(KERN_DEBUG
-				       "%s: %s: ISO Buffer size to small!\n",
-				       hw->name, __func__);
-			}
-		}
-		fifo->bit_line = BITLINE_INF;
-
-		errcode = usb_submit_urb(fifo->iso[i].urb, GFP_KERNEL);
-		fifo->active = (errcode >= 0) ? 1 : 0;
-		fifo->stop_gracefull = 0;
-		if (errcode < 0) {
-			printk(KERN_DEBUG "%s: %s: %s URB nr:%d\n",
-			       hw->name, __func__,
-			       symbolic(urb_errlist, errcode), i);
-		}
-	}
-	return fifo->active;
-}
-
-static void
-stop_iso_gracefull(struct usb_fifo *fifo)
-{
-	struct hfcsusb *hw = fifo->hw;
-	int i, timeout;
-	u_long flags;
-
-	for (i = 0; i < 2; i++) {
-		spin_lock_irqsave(&hw->lock, flags);
-		if (debug)
-			printk(KERN_DEBUG "%s: %s for fifo %i.%i\n",
-			       hw->name, __func__, fifo->fifonum, i);
-		fifo->stop_gracefull = 1;
-		spin_unlock_irqrestore(&hw->lock, flags);
-	}
-
-	for (i = 0; i < 2; i++) {
-		timeout = 3;
-		while (fifo->stop_gracefull && timeout--)
-			schedule_timeout_interruptible((HZ / 1000) * 16);
-		if (debug && fifo->stop_gracefull)
-			printk(KERN_DEBUG "%s: ERROR %s for fifo %i.%i\n",
-			       hw->name, __func__, fifo->fifonum, i);
-	}
-}
-
-static void
-stop_int_gracefull(struct usb_fifo *fifo)
-{
-	struct hfcsusb *hw = fifo->hw;
-	int timeout;
-	u_long flags;
-
-	spin_lock_irqsave(&hw->lock, flags);
-	if (debug)
-		printk(KERN_DEBUG "%s: %s for fifo %i\n",
-		       hw->name, __func__, fifo->fifonum);
-	fifo->stop_gracefull = 1;
-	spin_unlock_irqrestore(&hw->lock, flags);
-
-	timeout = 3;
-	while (fifo->stop_gracefull && timeout--)
-		schedule_timeout_interruptible((HZ / 1000) * 3);
-	if (debug && fifo->stop_gracefull)
-		printk(KERN_DEBUG "%s: ERROR %s for fifo %i\n",
-		       hw->name, __func__, fifo->fifonum);
-}
-
-/* start the interrupt transfer for the given fifo */
-static void
-start_int_fifo(struct usb_fifo *fifo)
-{
-	struct hfcsusb *hw = fifo->hw;
-	int errcode;
-
-	if (debug)
-		printk(KERN_DEBUG "%s: %s: INT IN fifo:%d\n",
-		       hw->name, __func__, fifo->fifonum);
-
-	if (!fifo->urb) {
-		fifo->urb = usb_alloc_urb(0, GFP_KERNEL);
-		if (!fifo->urb)
-			return;
-	}
-	usb_fill_int_urb(fifo->urb, fifo->hw->dev, fifo->pipe,
-			 fifo->buffer, fifo->usb_packet_maxlen,
-			 (usb_complete_t)rx_int_complete, fifo, fifo->intervall);
-	fifo->active = 1;
-	fifo->stop_gracefull = 0;
-	errcode = usb_submit_urb(fifo->urb, GFP_KERNEL);
-	if (errcode) {
-		printk(KERN_DEBUG "%s: %s: submit URB: status:%i\n",
-		       hw->name, __func__, errcode);
-		fifo->active = 0;
-	}
-}
-
-static void
-setPortMode(struct hfcsusb *hw)
-{
-	if (debug & DEBUG_HW)
-		printk(KERN_DEBUG "%s: %s %s\n", hw->name, __func__,
-		       (hw->protocol == ISDN_P_TE_S0) ? "TE" : "NT");
-
-	if (hw->protocol == ISDN_P_TE_S0) {
-		write_reg(hw, HFCUSB_SCTRL, 0x40);
-		write_reg(hw, HFCUSB_SCTRL_E, 0x00);
-		write_reg(hw, HFCUSB_CLKDEL, CLKDEL_TE);
-		write_reg(hw, HFCUSB_STATES, 3 | 0x10);
-		write_reg(hw, HFCUSB_STATES, 3);
-	} else {
-		write_reg(hw, HFCUSB_SCTRL, 0x44);
-		write_reg(hw, HFCUSB_SCTRL_E, 0x09);
-		write_reg(hw, HFCUSB_CLKDEL, CLKDEL_NT);
-		write_reg(hw, HFCUSB_STATES, 1 | 0x10);
-		write_reg(hw, HFCUSB_STATES, 1);
-	}
-}
-
-static void
-reset_hfcsusb(struct hfcsusb *hw)
-{
-	struct usb_fifo *fifo;
-	int i;
-
-	if (debug & DEBUG_HW)
-		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
-
-	/* do Chip reset */
-	write_reg(hw, HFCUSB_CIRM, 8);
-
-	/* aux = output, reset off */
-	write_reg(hw, HFCUSB_CIRM, 0x10);
-
-	/* set USB_SIZE to match the wMaxPacketSize for INT or BULK transfers */
-	write_reg(hw, HFCUSB_USB_SIZE, (hw->packet_size / 8) |
-		  ((hw->packet_size / 8) << 4));
-
-	/* set USB_SIZE_I to match the wMaxPacketSize for ISO transfers */
-	write_reg(hw, HFCUSB_USB_SIZE_I, hw->iso_packet_size);
-
-	/* enable PCM/GCI master mode */
-	write_reg(hw, HFCUSB_MST_MODE1, 0);	/* set default values */
-	write_reg(hw, HFCUSB_MST_MODE0, 1);	/* enable master mode */
-
-	/* init the fifos */
-	write_reg(hw, HFCUSB_F_THRES,
-		  (HFCUSB_TX_THRESHOLD / 8) | ((HFCUSB_RX_THRESHOLD / 8) << 4));
-
-	fifo = hw->fifos;
-	for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {
-		write_reg(hw, HFCUSB_FIFO, i);	/* select the desired fifo */
-		fifo[i].max_size =
-			(i <= HFCUSB_B2_RX) ? MAX_BCH_SIZE : MAX_DFRAME_LEN;
-		fifo[i].last_urblen = 0;
-
-		/* set 2 bit for D- & E-channel */
-		write_reg(hw, HFCUSB_HDLC_PAR, ((i <= HFCUSB_B2_RX) ? 0 : 2));
-
-		/* enable all fifos */
-		if (i == HFCUSB_D_TX)
-			write_reg(hw, HFCUSB_CON_HDLC,
-				  (hw->protocol == ISDN_P_NT_S0) ? 0x08 : 0x09);
-		else
-			write_reg(hw, HFCUSB_CON_HDLC, 0x08);
-		write_reg(hw, HFCUSB_INC_RES_F, 2); /* reset the fifo */
-	}
-
-	write_reg(hw, HFCUSB_SCTRL_R, 0); /* disable both B receivers */
-	handle_led(hw, LED_POWER_ON);
-}
-
-/* start USB data pipes dependand on device's endpoint configuration */
-static void
-hfcsusb_start_endpoint(struct hfcsusb *hw, int channel)
-{
-	/* quick check if endpoint already running */
-	if ((channel == HFC_CHAN_D) && (hw->fifos[HFCUSB_D_RX].active))
-		return;
-	if ((channel == HFC_CHAN_B1) && (hw->fifos[HFCUSB_B1_RX].active))
-		return;
-	if ((channel == HFC_CHAN_B2) && (hw->fifos[HFCUSB_B2_RX].active))
-		return;
-	if ((channel == HFC_CHAN_E) && (hw->fifos[HFCUSB_PCM_RX].active))
-		return;
-
-	/* start rx endpoints using USB INT IN method */
-	if (hw->cfg_used == CNF_3INT3ISO || hw->cfg_used == CNF_4INT3ISO)
-		start_int_fifo(hw->fifos + channel * 2 + 1);
-
-	/* start rx endpoints using USB ISO IN method */
-	if (hw->cfg_used == CNF_3ISO3ISO || hw->cfg_used == CNF_4ISO3ISO) {
-		switch (channel) {
-		case HFC_CHAN_D:
-			start_isoc_chain(hw->fifos + HFCUSB_D_RX,
-					 ISOC_PACKETS_D,
-					 (usb_complete_t)rx_iso_complete,
-					 16);
-			break;
-		case HFC_CHAN_E:
-			start_isoc_chain(hw->fifos + HFCUSB_PCM_RX,
-					 ISOC_PACKETS_D,
-					 (usb_complete_t)rx_iso_complete,
-					 16);
-			break;
-		case HFC_CHAN_B1:
-			start_isoc_chain(hw->fifos + HFCUSB_B1_RX,
-					 ISOC_PACKETS_B,
-					 (usb_complete_t)rx_iso_complete,
-					 16);
-			break;
-		case HFC_CHAN_B2:
-			start_isoc_chain(hw->fifos + HFCUSB_B2_RX,
-					 ISOC_PACKETS_B,
-					 (usb_complete_t)rx_iso_complete,
-					 16);
-			break;
-		}
-	}
-
-	/* start tx endpoints using USB ISO OUT method */
-	switch (channel) {
-	case HFC_CHAN_D:
-		start_isoc_chain(hw->fifos + HFCUSB_D_TX,
-				 ISOC_PACKETS_B,
-				 (usb_complete_t)tx_iso_complete, 1);
-		break;
-	case HFC_CHAN_B1:
-		start_isoc_chain(hw->fifos + HFCUSB_B1_TX,
-				 ISOC_PACKETS_D,
-				 (usb_complete_t)tx_iso_complete, 1);
-		break;
-	case HFC_CHAN_B2:
-		start_isoc_chain(hw->fifos + HFCUSB_B2_TX,
-				 ISOC_PACKETS_B,
-				 (usb_complete_t)tx_iso_complete, 1);
-		break;
-	}
-}
-
-/* stop USB data pipes dependand on device's endpoint configuration */
-static void
-hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel)
-{
-	/* quick check if endpoint currently running */
-	if ((channel == HFC_CHAN_D) && (!hw->fifos[HFCUSB_D_RX].active))
-		return;
-	if ((channel == HFC_CHAN_B1) && (!hw->fifos[HFCUSB_B1_RX].active))
-		return;
-	if ((channel == HFC_CHAN_B2) && (!hw->fifos[HFCUSB_B2_RX].active))
-		return;
-	if ((channel == HFC_CHAN_E) && (!hw->fifos[HFCUSB_PCM_RX].active))
-		return;
-
-	/* rx endpoints using USB INT IN method */
-	if (hw->cfg_used == CNF_3INT3ISO || hw->cfg_used == CNF_4INT3ISO)
-		stop_int_gracefull(hw->fifos + channel * 2 + 1);
-
-	/* rx endpoints using USB ISO IN method */
-	if (hw->cfg_used == CNF_3ISO3ISO || hw->cfg_used == CNF_4ISO3ISO)
-		stop_iso_gracefull(hw->fifos + channel * 2 + 1);
-
-	/* tx endpoints using USB ISO OUT method */
-	if (channel != HFC_CHAN_E)
-		stop_iso_gracefull(hw->fifos + channel * 2);
-}
-
-
-/* Hardware Initialization */
-static int
-setup_hfcsusb(struct hfcsusb *hw)
-{
-	void *dmabuf = kmalloc_obj(u_char);
-	u_char b;
-	int ret;
-
-	if (debug & DBG_HFC_CALL_TRACE)
-		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
-
-	if (!dmabuf)
-		return -ENOMEM;
-
-	ret = read_reg_atomic(hw, HFCUSB_CHIP_ID, dmabuf);
-
-	memcpy(&b, dmabuf, sizeof(u_char));
-	kfree(dmabuf);
-
-	/* check the chip id */
-	if (ret != 1) {
-		printk(KERN_DEBUG "%s: %s: cannot read chip id\n",
-		       hw->name, __func__);
-		return 1;
-	}
-	if (b != HFCUSB_CHIPID) {
-		printk(KERN_DEBUG "%s: %s: Invalid chip id 0x%02x\n",
-		       hw->name, __func__, b);
-		return 1;
-	}
-
-	/* first set the needed config, interface and alternate */
-	(void) usb_set_interface(hw->dev, hw->if_used, hw->alt_used);
-
-	hw->led_state = 0;
-
-	/* init the background machinery for control requests */
-	hw->ctrl_read.bRequestType = 0xc0;
-	hw->ctrl_read.bRequest = 1;
-	hw->ctrl_read.wLength = cpu_to_le16(1);
-	hw->ctrl_write.bRequestType = 0x40;
-	hw->ctrl_write.bRequest = 0;
-	hw->ctrl_write.wLength = 0;
-	usb_fill_control_urb(hw->ctrl_urb, hw->dev, hw->ctrl_out_pipe,
-			     (u_char *)&hw->ctrl_write, NULL, 0,
-			     (usb_complete_t)ctrl_complete, hw);
-
-	reset_hfcsusb(hw);
-	return 0;
-}
-
-static void
-release_hw(struct hfcsusb *hw)
-{
-	if (debug & DBG_HFC_CALL_TRACE)
-		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
-
-	/*
-	 * stop all endpoints gracefully
-	 * TODO: mISDN_core should generate CLOSE_CHANNEL
-	 *       signals after calling mISDN_unregister_device()
-	 */
-	hfcsusb_stop_endpoint(hw, HFC_CHAN_D);
-	hfcsusb_stop_endpoint(hw, HFC_CHAN_B1);
-	hfcsusb_stop_endpoint(hw, HFC_CHAN_B2);
-	if (hw->fifos[HFCUSB_PCM_RX].pipe)
-		hfcsusb_stop_endpoint(hw, HFC_CHAN_E);
-	if (hw->protocol == ISDN_P_TE_S0)
-		l1_event(hw->dch.l1, CLOSE_CHANNEL);
-
-	mISDN_unregister_device(&hw->dch.dev);
-	mISDN_freebchannel(&hw->bch[1]);
-	mISDN_freebchannel(&hw->bch[0]);
-	mISDN_freedchannel(&hw->dch);
-
-	if (hw->ctrl_urb) {
-		usb_kill_urb(hw->ctrl_urb);
-		usb_free_urb(hw->ctrl_urb);
-		hw->ctrl_urb = NULL;
-	}
-
-	if (hw->intf)
-		usb_set_intfdata(hw->intf, NULL);
-	list_del(&hw->list);
-	kfree(hw);
-	hw = NULL;
-}
-
-static void
-deactivate_bchannel(struct bchannel *bch)
-{
-	struct hfcsusb *hw = bch->hw;
-	u_long flags;
-
-	if (bch->debug & DEBUG_HW)
-		printk(KERN_DEBUG "%s: %s: bch->nr(%i)\n",
-		       hw->name, __func__, bch->nr);
-
-	spin_lock_irqsave(&hw->lock, flags);
-	mISDN_clear_bchannel(bch);
-	spin_unlock_irqrestore(&hw->lock, flags);
-	hfcsusb_setup_bch(bch, ISDN_P_NONE);
-	hfcsusb_stop_endpoint(hw, bch->nr - 1);
-}
-
-/*
- * Layer 1 B-channel hardware access
- */
-static int
-hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
-{
-	struct bchannel	*bch = container_of(ch, struct bchannel, ch);
-	int		ret = -EINVAL;
-
-	if (bch->debug & DEBUG_HW)
-		printk(KERN_DEBUG "%s: cmd:%x %p\n", __func__, cmd, arg);
-
-	switch (cmd) {
-	case HW_TESTRX_RAW:
-	case HW_TESTRX_HDLC:
-	case HW_TESTRX_OFF:
-		ret = -EINVAL;
-		break;
-
-	case CLOSE_CHANNEL:
-		test_and_clear_bit(FLG_OPEN, &bch->Flags);
-		deactivate_bchannel(bch);
-		ch->protocol = ISDN_P_NONE;
-		ch->peer = NULL;
-		module_put(THIS_MODULE);
-		ret = 0;
-		break;
-	case CONTROL_CHANNEL:
-		ret = channel_bctrl(bch, arg);
-		break;
-	default:
-		printk(KERN_WARNING "%s: unknown prim(%x)\n",
-		       __func__, cmd);
-	}
-	return ret;
-}
-
-static int
-setup_instance(struct hfcsusb *hw, struct device *parent)
-{
-	u_long	flags;
-	int	err, i;
-
-	if (debug & DBG_HFC_CALL_TRACE)
-		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
-
-	spin_lock_init(&hw->ctrl_lock);
-	spin_lock_init(&hw->lock);
-
-	mISDN_initdchannel(&hw->dch, MAX_DFRAME_LEN_L1, ph_state);
-	hw->dch.debug = debug & 0xFFFF;
-	hw->dch.hw = hw;
-	hw->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
-	hw->dch.dev.D.send = hfcusb_l2l1D;
-	hw->dch.dev.D.ctrl = hfc_dctrl;
-
-	/* enable E-Channel logging */
-	if (hw->fifos[HFCUSB_PCM_RX].pipe)
-		mISDN_initdchannel(&hw->ech, MAX_DFRAME_LEN_L1, NULL);
-
-	hw->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
-	hw->dch.dev.nrbchan = 2;
-	for (i = 0; i < 2; i++) {
-		hw->bch[i].nr = i + 1;
-		set_channelmap(i + 1, hw->dch.dev.channelmap);
-		hw->bch[i].debug = debug;
-		mISDN_initbchannel(&hw->bch[i], MAX_DATA_MEM, poll >> 1);
-		hw->bch[i].hw = hw;
-		hw->bch[i].ch.send = hfcusb_l2l1B;
-		hw->bch[i].ch.ctrl = hfc_bctrl;
-		hw->bch[i].ch.nr = i + 1;
-		list_add(&hw->bch[i].ch.list, &hw->dch.dev.bchannels);
-	}
-
-	hw->fifos[HFCUSB_B1_TX].bch = &hw->bch[0];
-	hw->fifos[HFCUSB_B1_RX].bch = &hw->bch[0];
-	hw->fifos[HFCUSB_B2_TX].bch = &hw->bch[1];
-	hw->fifos[HFCUSB_B2_RX].bch = &hw->bch[1];
-	hw->fifos[HFCUSB_D_TX].dch = &hw->dch;
-	hw->fifos[HFCUSB_D_RX].dch = &hw->dch;
-	hw->fifos[HFCUSB_PCM_RX].ech = &hw->ech;
-	hw->fifos[HFCUSB_PCM_TX].ech = &hw->ech;
-
-	err = setup_hfcsusb(hw);
-	if (err)
-		goto out;
-
-	snprintf(hw->name, MISDN_MAX_IDLEN - 1, "%s.%d", DRIVER_NAME,
-		 hfcsusb_cnt + 1);
-	printk(KERN_INFO "%s: registered as '%s'\n",
-	       DRIVER_NAME, hw->name);
-
-	err = mISDN_register_device(&hw->dch.dev, parent, hw->name);
-	if (err)
-		goto out;
-
-	hfcsusb_cnt++;
-	write_lock_irqsave(&HFClock, flags);
-	list_add_tail(&hw->list, &HFClist);
-	write_unlock_irqrestore(&HFClock, flags);
-	return 0;
-
-out:
-	mISDN_freebchannel(&hw->bch[1]);
-	mISDN_freebchannel(&hw->bch[0]);
-	mISDN_freedchannel(&hw->dch);
-	return err;
-}
-
-static int
-hfcsusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
-	int err;
-	struct hfcsusb			*hw;
-	struct usb_device		*dev = interface_to_usbdev(intf);
-	struct usb_host_interface	*iface = intf->cur_altsetting;
-	struct usb_host_interface	*iface_used = NULL;
-	struct usb_host_endpoint	*ep;
-	struct hfcsusb_vdata		*driver_info;
-	int ifnum = iface->desc.bInterfaceNumber, i, idx, alt_idx,
-		probe_alt_setting, vend_idx, cfg_used, *vcf, attr, cfg_found,
-		ep_addr, cmptbl[16], small_match, iso_packet_size, packet_size,
-		alt_used = 0;
-
-	vend_idx = 0xffff;
-	for (i = 0; hfcsusb_idtab[i].idVendor; i++) {
-		if ((le16_to_cpu(dev->descriptor.idVendor)
-		     == hfcsusb_idtab[i].idVendor) &&
-		    (le16_to_cpu(dev->descriptor.idProduct)
-		     == hfcsusb_idtab[i].idProduct)) {
-			vend_idx = i;
-			continue;
-		}
-	}
-
-	printk(KERN_DEBUG
-	       "%s: interface(%d) actalt(%d) minor(%d) vend_idx(%d)\n",
-	       __func__, ifnum, iface->desc.bAlternateSetting,
-	       intf->minor, vend_idx);
-
-	if (vend_idx == 0xffff) {
-		printk(KERN_WARNING
-		       "%s: no valid vendor found in USB descriptor\n",
-		       __func__);
-		return -EIO;
-	}
-	/* if vendor and product ID is OK, start probing alternate settings */
-	alt_idx = 0;
-	small_match = -1;
-
-	/* default settings */
-	iso_packet_size = 16;
-	packet_size = 64;
-
-	while (alt_idx < intf->num_altsetting) {
-		iface = intf->altsetting + alt_idx;
-		probe_alt_setting = iface->desc.bAlternateSetting;
-		cfg_used = 0;
-
-		while (validconf[cfg_used][0]) {
-			cfg_found = 1;
-			vcf = validconf[cfg_used];
-			ep = iface->endpoint;
-			memcpy(cmptbl, vcf, 16 * sizeof(int));
-
-			/* check for all endpoints in this alternate setting */
-			for (i = 0; i < iface->desc.bNumEndpoints; i++) {
-				ep_addr = ep->desc.bEndpointAddress;
-
-				/* get endpoint base */
-				idx = ((ep_addr & 0x7f) - 1) * 2;
-				if (idx > 15)
-					return -EIO;
-
-				if (ep_addr & 0x80)
-					idx++;
-				attr = ep->desc.bmAttributes;
-
-				if (cmptbl[idx] != EP_NOP) {
-					if (cmptbl[idx] == EP_NUL)
-						cfg_found = 0;
-					if (attr == USB_ENDPOINT_XFER_INT
-					    && cmptbl[idx] == EP_INT)
-						cmptbl[idx] = EP_NUL;
-					if (attr == USB_ENDPOINT_XFER_BULK
-					    && cmptbl[idx] == EP_BLK)
-						cmptbl[idx] = EP_NUL;
-					if (attr == USB_ENDPOINT_XFER_ISOC
-					    && cmptbl[idx] == EP_ISO)
-						cmptbl[idx] = EP_NUL;
-
-					if (attr == USB_ENDPOINT_XFER_INT &&
-					    ep->desc.bInterval < vcf[17]) {
-						cfg_found = 0;
-					}
-				}
-				ep++;
-			}
-
-			for (i = 0; i < 16; i++)
-				if (cmptbl[i] != EP_NOP && cmptbl[i] != EP_NUL)
-					cfg_found = 0;
-
-			if (cfg_found) {
-				if (small_match < cfg_used) {
-					small_match = cfg_used;
-					alt_used = probe_alt_setting;
-					iface_used = iface;
-				}
-			}
-			cfg_used++;
-		}
-		alt_idx++;
-	}	/* (alt_idx < intf->num_altsetting) */
-
-	/* not found a valid USB Ta Endpoint config */
-	if (small_match == -1)
-		return -EIO;
-
-	iface = iface_used;
-	hw = kzalloc_obj(struct hfcsusb);
-	if (!hw)
-		return -ENOMEM;	/* got no mem */
-	snprintf(hw->name, MISDN_MAX_IDLEN - 1, "%s", DRIVER_NAME);
-
-	ep = iface->endpoint;
-	vcf = validconf[small_match];
-
-	for (i = 0; i < iface->desc.bNumEndpoints; i++) {
-		struct usb_fifo *f;
-
-		ep_addr = ep->desc.bEndpointAddress;
-		/* get endpoint base */
-		idx = ((ep_addr & 0x7f) - 1) * 2;
-		if (ep_addr & 0x80)
-			idx++;
-		f = &hw->fifos[idx & 7];
-
-		/* init Endpoints */
-		if (vcf[idx] == EP_NOP || vcf[idx] == EP_NUL) {
-			ep++;
-			continue;
-		}
-		switch (ep->desc.bmAttributes) {
-		case USB_ENDPOINT_XFER_INT:
-			f->pipe = usb_rcvintpipe(dev,
-						 ep->desc.bEndpointAddress);
-			f->usb_transfer_mode = USB_INT;
-			packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
-			break;
-		case USB_ENDPOINT_XFER_BULK:
-			if (ep_addr & 0x80)
-				f->pipe = usb_rcvbulkpipe(dev,
-							  ep->desc.bEndpointAddress);
-			else
-				f->pipe = usb_sndbulkpipe(dev,
-							  ep->desc.bEndpointAddress);
-			f->usb_transfer_mode = USB_BULK;
-			packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
-			break;
-		case USB_ENDPOINT_XFER_ISOC:
-			if (ep_addr & 0x80)
-				f->pipe = usb_rcvisocpipe(dev,
-							  ep->desc.bEndpointAddress);
-			else
-				f->pipe = usb_sndisocpipe(dev,
-							  ep->desc.bEndpointAddress);
-			f->usb_transfer_mode = USB_ISOC;
-			iso_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
-			break;
-		default:
-			f->pipe = 0;
-		}
-
-		if (f->pipe) {
-			f->fifonum = idx & 7;
-			f->hw = hw;
-			f->usb_packet_maxlen =
-				le16_to_cpu(ep->desc.wMaxPacketSize);
-			f->intervall = ep->desc.bInterval;
-		}
-		ep++;
-	}
-	hw->dev = dev; /* save device */
-	hw->if_used = ifnum; /* save used interface */
-	hw->alt_used = alt_used; /* and alternate config */
-	hw->ctrl_paksize = dev->descriptor.bMaxPacketSize0; /* control size */
-	hw->cfg_used = vcf[16];	/* store used config */
-	hw->vend_idx = vend_idx; /* store found vendor */
-	hw->packet_size = packet_size;
-	hw->iso_packet_size = iso_packet_size;
-
-	/* create the control pipes needed for register access */
-	hw->ctrl_in_pipe = usb_rcvctrlpipe(hw->dev, 0);
-	hw->ctrl_out_pipe = usb_sndctrlpipe(hw->dev, 0);
-
-	driver_info = (struct hfcsusb_vdata *)
-		      hfcsusb_idtab[vend_idx].driver_info;
-
-	hw->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!hw->ctrl_urb) {
-		pr_warn("%s: No memory for control urb\n",
-			driver_info->vend_name);
-		err = -ENOMEM;
-		goto err_free_hw;
-	}
-
-	pr_info("%s: %s: detected \"%s\" (%s, if=%d alt=%d)\n",
-		hw->name, __func__, driver_info->vend_name,
-		conf_str[small_match], ifnum, alt_used);
-
-	if (setup_instance(hw, dev->dev.parent)) {
-		err = -EIO;
-		goto err_free_urb;
-	}
-
-	hw->intf = intf;
-	usb_set_intfdata(hw->intf, hw);
-	return 0;
-
-err_free_urb:
-	usb_free_urb(hw->ctrl_urb);
-err_free_hw:
-	kfree(hw);
-	return err;
-}
-
-/* function called when an active device is removed */
-static void
-hfcsusb_disconnect(struct usb_interface *intf)
-{
-	struct hfcsusb *hw = usb_get_intfdata(intf);
-	struct hfcsusb *next;
-	int cnt = 0;
-
-	printk(KERN_INFO "%s: device disconnected\n", hw->name);
-
-	handle_led(hw, LED_POWER_OFF);
-	release_hw(hw);
-
-	list_for_each_entry_safe(hw, next, &HFClist, list)
-		cnt++;
-	if (!cnt)
-		hfcsusb_cnt = 0;
-
-	usb_set_intfdata(intf, NULL);
-}
-
-static struct usb_driver hfcsusb_drv = {
-	.name = DRIVER_NAME,
-	.id_table = hfcsusb_idtab,
-	.probe = hfcsusb_probe,
-	.disconnect = hfcsusb_disconnect,
-	.disable_hub_initiated_lpm = 1,
-};
-
-module_usb_driver(hfcsusb_drv);
diff --git a/drivers/isdn/hardware/mISDN/isdnhdlc.c b/drivers/isdn/hardware/mISDN/isdnhdlc.c
deleted file mode 100644
index 985367e6711d..000000000000
--- a/drivers/isdn/hardware/mISDN/isdnhdlc.c
+++ /dev/null
@@ -1,617 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * isdnhdlc.c  --  General purpose ISDN HDLC decoder.
- *
- * Copyright (C)
- *	2009	Karsten Keil		<keil@b1-systems.de>
- *	2002	Wolfgang Mües		<wolfgang@iksw-muees.de>
- *	2001	Frode Isaksen		<fisaksen@bewan.com>
- *      2001	Kai Germaschewski	<kai.germaschewski@gmx.de>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/crc-ccitt.h>
-#include <linux/bitrev.h>
-#include "isdnhdlc.h"
-
-/*-------------------------------------------------------------------*/
-
-MODULE_AUTHOR("Wolfgang Mües <wolfgang@iksw-muees.de>, "
-	      "Frode Isaksen <fisaksen@bewan.com>, "
-	      "Kai Germaschewski <kai.germaschewski@gmx.de>");
-MODULE_DESCRIPTION("General purpose ISDN HDLC decoder");
-MODULE_LICENSE("GPL");
-
-/*-------------------------------------------------------------------*/
-
-enum {
-	HDLC_FAST_IDLE, HDLC_GET_FLAG_B0, HDLC_GETFLAG_B1A6, HDLC_GETFLAG_B7,
-	HDLC_GET_DATA, HDLC_FAST_FLAG
-};
-
-enum {
-	HDLC_SEND_DATA, HDLC_SEND_CRC1, HDLC_SEND_FAST_FLAG,
-	HDLC_SEND_FIRST_FLAG, HDLC_SEND_CRC2, HDLC_SEND_CLOSING_FLAG,
-	HDLC_SEND_IDLE1, HDLC_SEND_FAST_IDLE, HDLC_SENDFLAG_B0,
-	HDLC_SENDFLAG_B1A6, HDLC_SENDFLAG_B7, STOPPED, HDLC_SENDFLAG_ONE
-};
-
-void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features)
-{
-	memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
-	hdlc->state = HDLC_GET_DATA;
-	if (features & HDLC_56KBIT)
-		hdlc->do_adapt56 = 1;
-	if (features & HDLC_BITREVERSE)
-		hdlc->do_bitreverse = 1;
-}
-EXPORT_SYMBOL(isdnhdlc_out_init);
-
-void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features)
-{
-	memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
-	if (features & HDLC_DCHANNEL) {
-		hdlc->dchannel = 1;
-		hdlc->state = HDLC_SEND_FIRST_FLAG;
-	} else {
-		hdlc->dchannel = 0;
-		hdlc->state = HDLC_SEND_FAST_FLAG;
-		hdlc->ffvalue = 0x7e;
-	}
-	hdlc->cbin = 0x7e;
-	if (features & HDLC_56KBIT) {
-		hdlc->do_adapt56 = 1;
-		hdlc->state = HDLC_SENDFLAG_B0;
-	} else
-		hdlc->data_bits = 8;
-	if (features & HDLC_BITREVERSE)
-		hdlc->do_bitreverse = 1;
-}
-EXPORT_SYMBOL(isdnhdlc_rcv_init);
-
-static int
-check_frame(struct isdnhdlc_vars *hdlc)
-{
-	int status;
-
-	if (hdlc->dstpos < 2)	/* too small - framing error */
-		status = -HDLC_FRAMING_ERROR;
-	else if (hdlc->crc != 0xf0b8)	/* crc error */
-		status = -HDLC_CRC_ERROR;
-	else {
-		/* remove CRC */
-		hdlc->dstpos -= 2;
-		/* good frame */
-		status = hdlc->dstpos;
-	}
-	return status;
-}
-
-/*
-  isdnhdlc_decode - decodes HDLC frames from a transparent bit stream.
-
-  The source buffer is scanned for valid HDLC frames looking for
-  flags (01111110) to indicate the start of a frame. If the start of
-  the frame is found, the bit stuffing is removed (0 after 5 1's).
-  When a new flag is found, the complete frame has been received
-  and the CRC is checked.
-  If a valid frame is found, the function returns the frame length
-  excluding the CRC with the bit HDLC_END_OF_FRAME set.
-  If the beginning of a valid frame is found, the function returns
-  the length.
-  If a framing error is found (too many 1s and not a flag) the function
-  returns the length with the bit HDLC_FRAMING_ERROR set.
-  If a CRC error is found the function returns the length with the
-  bit HDLC_CRC_ERROR set.
-  If the frame length exceeds the destination buffer size, the function
-  returns the length with the bit HDLC_LENGTH_ERROR set.
-
-  src - source buffer
-  slen - source buffer length
-  count - number of bytes removed (decoded) from the source buffer
-  dst _ destination buffer
-  dsize - destination buffer size
-  returns - number of decoded bytes in the destination buffer and status
-  flag.
-*/
-int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, int slen,
-		    int *count, u8 *dst, int dsize)
-{
-	int status = 0;
-
-	static const unsigned char fast_flag[] = {
-		0x00, 0x00, 0x00, 0x20, 0x30, 0x38, 0x3c, 0x3e, 0x3f
-	};
-
-	static const unsigned char fast_flag_value[] = {
-		0x00, 0x7e, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f
-	};
-
-	static const unsigned char fast_abort[] = {
-		0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
-	};
-
-#define handle_fast_flag(h)						\
-	do {								\
-		if (h->cbin == fast_flag[h->bit_shift]) {		\
-			h->ffvalue = fast_flag_value[h->bit_shift];	\
-			h->state = HDLC_FAST_FLAG;			\
-			h->ffbit_shift = h->bit_shift;			\
-			h->bit_shift = 1;				\
-		} else {						\
-			h->state = HDLC_GET_DATA;			\
-			h->data_received = 0;				\
-		}							\
-	} while (0)
-
-#define handle_abort(h)						\
-	do {							\
-		h->shift_reg = fast_abort[h->ffbit_shift - 1];	\
-		h->hdlc_bits1 = h->ffbit_shift - 2;		\
-		if (h->hdlc_bits1 < 0)				\
-			h->hdlc_bits1 = 0;			\
-		h->data_bits = h->ffbit_shift - 1;		\
-		h->state = HDLC_GET_DATA;			\
-		h->data_received = 0;				\
-	} while (0)
-
-	*count = slen;
-
-	while (slen > 0) {
-		if (hdlc->bit_shift == 0) {
-			/* the code is for bitreverse streams */
-			if (hdlc->do_bitreverse == 0)
-				hdlc->cbin = bitrev8(*src++);
-			else
-				hdlc->cbin = *src++;
-			slen--;
-			hdlc->bit_shift = 8;
-			if (hdlc->do_adapt56)
-				hdlc->bit_shift--;
-		}
-
-		switch (hdlc->state) {
-		case STOPPED:
-			return 0;
-		case HDLC_FAST_IDLE:
-			if (hdlc->cbin == 0xff) {
-				hdlc->bit_shift = 0;
-				break;
-			}
-			hdlc->state = HDLC_GET_FLAG_B0;
-			hdlc->hdlc_bits1 = 0;
-			hdlc->bit_shift = 8;
-			break;
-		case HDLC_GET_FLAG_B0:
-			if (!(hdlc->cbin & 0x80)) {
-				hdlc->state = HDLC_GETFLAG_B1A6;
-				hdlc->hdlc_bits1 = 0;
-			} else {
-				if ((!hdlc->do_adapt56) &&
-				    (++hdlc->hdlc_bits1 >= 8) &&
-				    (hdlc->bit_shift == 1))
-					hdlc->state = HDLC_FAST_IDLE;
-			}
-			hdlc->cbin <<= 1;
-			hdlc->bit_shift--;
-			break;
-		case HDLC_GETFLAG_B1A6:
-			if (hdlc->cbin & 0x80) {
-				hdlc->hdlc_bits1++;
-				if (hdlc->hdlc_bits1 == 6)
-					hdlc->state = HDLC_GETFLAG_B7;
-			} else
-				hdlc->hdlc_bits1 = 0;
-			hdlc->cbin <<= 1;
-			hdlc->bit_shift--;
-			break;
-		case HDLC_GETFLAG_B7:
-			if (hdlc->cbin & 0x80) {
-				hdlc->state = HDLC_GET_FLAG_B0;
-			} else {
-				hdlc->state = HDLC_GET_DATA;
-				hdlc->crc = 0xffff;
-				hdlc->shift_reg = 0;
-				hdlc->hdlc_bits1 = 0;
-				hdlc->data_bits = 0;
-				hdlc->data_received = 0;
-			}
-			hdlc->cbin <<= 1;
-			hdlc->bit_shift--;
-			break;
-		case HDLC_GET_DATA:
-			if (hdlc->cbin & 0x80) {
-				hdlc->hdlc_bits1++;
-				switch (hdlc->hdlc_bits1) {
-				case 6:
-					break;
-				case 7:
-					if (hdlc->data_received)
-						/* bad frame */
-						status = -HDLC_FRAMING_ERROR;
-					if (!hdlc->do_adapt56) {
-						if (hdlc->cbin == fast_abort
-						    [hdlc->bit_shift + 1]) {
-							hdlc->state =
-								HDLC_FAST_IDLE;
-							hdlc->bit_shift = 1;
-							break;
-						}
-					} else
-						hdlc->state = HDLC_GET_FLAG_B0;
-					break;
-				default:
-					hdlc->shift_reg >>= 1;
-					hdlc->shift_reg |= 0x80;
-					hdlc->data_bits++;
-					break;
-				}
-			} else {
-				switch (hdlc->hdlc_bits1) {
-				case 5:
-					break;
-				case 6:
-					if (hdlc->data_received)
-						status = check_frame(hdlc);
-					hdlc->crc = 0xffff;
-					hdlc->shift_reg = 0;
-					hdlc->data_bits = 0;
-					if (!hdlc->do_adapt56)
-						handle_fast_flag(hdlc);
-					else {
-						hdlc->state = HDLC_GET_DATA;
-						hdlc->data_received = 0;
-					}
-					break;
-				default:
-					hdlc->shift_reg >>= 1;
-					hdlc->data_bits++;
-					break;
-				}
-				hdlc->hdlc_bits1 = 0;
-			}
-			if (status) {
-				hdlc->dstpos = 0;
-				*count -= slen;
-				hdlc->cbin <<= 1;
-				hdlc->bit_shift--;
-				return status;
-			}
-			if (hdlc->data_bits == 8) {
-				hdlc->data_bits = 0;
-				hdlc->data_received = 1;
-				hdlc->crc = crc_ccitt_byte(hdlc->crc,
-							   hdlc->shift_reg);
-
-				/* good byte received */
-				if (hdlc->dstpos < dsize)
-					dst[hdlc->dstpos++] = hdlc->shift_reg;
-				else {
-					/* frame too long */
-					status = -HDLC_LENGTH_ERROR;
-					hdlc->dstpos = 0;
-				}
-			}
-			hdlc->cbin <<= 1;
-			hdlc->bit_shift--;
-			break;
-		case HDLC_FAST_FLAG:
-			if (hdlc->cbin == hdlc->ffvalue) {
-				hdlc->bit_shift = 0;
-				break;
-			} else {
-				if (hdlc->cbin == 0xff) {
-					hdlc->state = HDLC_FAST_IDLE;
-					hdlc->bit_shift = 0;
-				} else if (hdlc->ffbit_shift == 8) {
-					hdlc->state = HDLC_GETFLAG_B7;
-					break;
-				} else
-					handle_abort(hdlc);
-			}
-			break;
-		default:
-			break;
-		}
-	}
-	*count -= slen;
-	return 0;
-}
-EXPORT_SYMBOL(isdnhdlc_decode);
-/*
-  isdnhdlc_encode - encodes HDLC frames to a transparent bit stream.
-
-  The bit stream starts with a beginning flag (01111110). After
-  that each byte is added to the bit stream with bit stuffing added
-  (0 after 5 1's).
-  When the last byte has been removed from the source buffer, the
-  CRC (2 bytes is added) and the frame terminates with the ending flag.
-  For the dchannel, the idle character (all 1's) is also added at the end.
-  If this function is called with empty source buffer (slen=0), flags or
-  idle character will be generated.
-
-  src - source buffer
-  slen - source buffer length
-  count - number of bytes removed (encoded) from source buffer
-  dst _ destination buffer
-  dsize - destination buffer size
-  returns - number of encoded bytes in the destination buffer
-*/
-int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, u16 slen,
-		    int *count, u8 *dst, int dsize)
-{
-	static const unsigned char xfast_flag_value[] = {
-		0x7e, 0x3f, 0x9f, 0xcf, 0xe7, 0xf3, 0xf9, 0xfc, 0x7e
-	};
-
-	int len = 0;
-
-	*count = slen;
-
-	/* special handling for one byte frames */
-	if ((slen == 1) && (hdlc->state == HDLC_SEND_FAST_FLAG))
-		hdlc->state = HDLC_SENDFLAG_ONE;
-	while (dsize > 0) {
-		if (hdlc->bit_shift == 0) {
-			if (slen && !hdlc->do_closing) {
-				hdlc->shift_reg = *src++;
-				slen--;
-				if (slen == 0)
-					/* closing sequence, CRC + flag(s) */
-					hdlc->do_closing = 1;
-				hdlc->bit_shift = 8;
-			} else {
-				if (hdlc->state == HDLC_SEND_DATA) {
-					if (hdlc->data_received) {
-						hdlc->state = HDLC_SEND_CRC1;
-						hdlc->crc ^= 0xffff;
-						hdlc->bit_shift = 8;
-						hdlc->shift_reg =
-							hdlc->crc & 0xff;
-					} else if (!hdlc->do_adapt56)
-						hdlc->state =
-							HDLC_SEND_FAST_FLAG;
-					else
-						hdlc->state =
-							HDLC_SENDFLAG_B0;
-				}
-
-			}
-		}
-
-		switch (hdlc->state) {
-		case STOPPED:
-			while (dsize--)
-				*dst++ = 0xff;
-			return dsize;
-		case HDLC_SEND_FAST_FLAG:
-			hdlc->do_closing = 0;
-			if (slen == 0) {
-				/* the code is for bitreverse streams */
-				if (hdlc->do_bitreverse == 0)
-					*dst++ = bitrev8(hdlc->ffvalue);
-				else
-					*dst++ = hdlc->ffvalue;
-				len++;
-				dsize--;
-				break;
-			}
-			fallthrough;
-		case HDLC_SENDFLAG_ONE:
-			if (hdlc->bit_shift == 8) {
-				hdlc->cbin = hdlc->ffvalue >>
-					(8 - hdlc->data_bits);
-				hdlc->state = HDLC_SEND_DATA;
-				hdlc->crc = 0xffff;
-				hdlc->hdlc_bits1 = 0;
-				hdlc->data_received = 1;
-			}
-			break;
-		case HDLC_SENDFLAG_B0:
-			hdlc->do_closing = 0;
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			hdlc->hdlc_bits1 = 0;
-			hdlc->state = HDLC_SENDFLAG_B1A6;
-			break;
-		case HDLC_SENDFLAG_B1A6:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			hdlc->cbin++;
-			if (++hdlc->hdlc_bits1 == 6)
-				hdlc->state = HDLC_SENDFLAG_B7;
-			break;
-		case HDLC_SENDFLAG_B7:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if (slen == 0) {
-				hdlc->state = HDLC_SENDFLAG_B0;
-				break;
-			}
-			if (hdlc->bit_shift == 8) {
-				hdlc->state = HDLC_SEND_DATA;
-				hdlc->crc = 0xffff;
-				hdlc->hdlc_bits1 = 0;
-				hdlc->data_received = 1;
-			}
-			break;
-		case HDLC_SEND_FIRST_FLAG:
-			hdlc->data_received = 1;
-			if (hdlc->data_bits == 8) {
-				hdlc->state = HDLC_SEND_DATA;
-				hdlc->crc = 0xffff;
-				hdlc->hdlc_bits1 = 0;
-				break;
-			}
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if (hdlc->shift_reg & 0x01)
-				hdlc->cbin++;
-			hdlc->shift_reg >>= 1;
-			hdlc->bit_shift--;
-			if (hdlc->bit_shift == 0) {
-				hdlc->state = HDLC_SEND_DATA;
-				hdlc->crc = 0xffff;
-				hdlc->hdlc_bits1 = 0;
-			}
-			break;
-		case HDLC_SEND_DATA:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if (hdlc->hdlc_bits1 == 5) {
-				hdlc->hdlc_bits1 = 0;
-				break;
-			}
-			if (hdlc->bit_shift == 8)
-				hdlc->crc = crc_ccitt_byte(hdlc->crc,
-							   hdlc->shift_reg);
-			if (hdlc->shift_reg & 0x01) {
-				hdlc->hdlc_bits1++;
-				hdlc->cbin++;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			} else {
-				hdlc->hdlc_bits1 = 0;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			}
-			break;
-		case HDLC_SEND_CRC1:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if (hdlc->hdlc_bits1 == 5) {
-				hdlc->hdlc_bits1 = 0;
-				break;
-			}
-			if (hdlc->shift_reg & 0x01) {
-				hdlc->hdlc_bits1++;
-				hdlc->cbin++;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			} else {
-				hdlc->hdlc_bits1 = 0;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			}
-			if (hdlc->bit_shift == 0) {
-				hdlc->shift_reg = (hdlc->crc >> 8);
-				hdlc->state = HDLC_SEND_CRC2;
-				hdlc->bit_shift = 8;
-			}
-			break;
-		case HDLC_SEND_CRC2:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if (hdlc->hdlc_bits1 == 5) {
-				hdlc->hdlc_bits1 = 0;
-				break;
-			}
-			if (hdlc->shift_reg & 0x01) {
-				hdlc->hdlc_bits1++;
-				hdlc->cbin++;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			} else {
-				hdlc->hdlc_bits1 = 0;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			}
-			if (hdlc->bit_shift == 0) {
-				hdlc->shift_reg = 0x7e;
-				hdlc->state = HDLC_SEND_CLOSING_FLAG;
-				hdlc->bit_shift = 8;
-			}
-			break;
-		case HDLC_SEND_CLOSING_FLAG:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if (hdlc->hdlc_bits1 == 5) {
-				hdlc->hdlc_bits1 = 0;
-				break;
-			}
-			if (hdlc->shift_reg & 0x01)
-				hdlc->cbin++;
-			hdlc->shift_reg >>= 1;
-			hdlc->bit_shift--;
-			if (hdlc->bit_shift == 0) {
-				hdlc->ffvalue =
-					xfast_flag_value[hdlc->data_bits];
-				if (hdlc->dchannel) {
-					hdlc->ffvalue = 0x7e;
-					hdlc->state = HDLC_SEND_IDLE1;
-					hdlc->bit_shift = 8-hdlc->data_bits;
-					if (hdlc->bit_shift == 0)
-						hdlc->state =
-							HDLC_SEND_FAST_IDLE;
-				} else {
-					if (!hdlc->do_adapt56) {
-						hdlc->state =
-							HDLC_SEND_FAST_FLAG;
-						hdlc->data_received = 0;
-					} else {
-						hdlc->state = HDLC_SENDFLAG_B0;
-						hdlc->data_received = 0;
-					}
-					/* Finished this frame, send flags */
-					if (dsize > 1)
-						dsize = 1;
-				}
-			}
-			break;
-		case HDLC_SEND_IDLE1:
-			hdlc->do_closing = 0;
-			hdlc->cbin <<= 1;
-			hdlc->cbin++;
-			hdlc->data_bits++;
-			hdlc->bit_shift--;
-			if (hdlc->bit_shift == 0) {
-				hdlc->state = HDLC_SEND_FAST_IDLE;
-				hdlc->bit_shift = 0;
-			}
-			break;
-		case HDLC_SEND_FAST_IDLE:
-			hdlc->do_closing = 0;
-			hdlc->cbin = 0xff;
-			hdlc->data_bits = 8;
-			if (hdlc->bit_shift == 8) {
-				hdlc->cbin = 0x7e;
-				hdlc->state = HDLC_SEND_FIRST_FLAG;
-			} else {
-				/* the code is for bitreverse streams */
-				if (hdlc->do_bitreverse == 0)
-					*dst++ = bitrev8(hdlc->cbin);
-				else
-					*dst++ = hdlc->cbin;
-				hdlc->bit_shift = 0;
-				hdlc->data_bits = 0;
-				len++;
-				dsize = 0;
-			}
-			break;
-		default:
-			break;
-		}
-		if (hdlc->do_adapt56) {
-			if (hdlc->data_bits == 7) {
-				hdlc->cbin <<= 1;
-				hdlc->cbin++;
-				hdlc->data_bits++;
-			}
-		}
-		if (hdlc->data_bits == 8) {
-			/* the code is for bitreverse streams */
-			if (hdlc->do_bitreverse == 0)
-				*dst++ = bitrev8(hdlc->cbin);
-			else
-				*dst++ = hdlc->cbin;
-			hdlc->data_bits = 0;
-			len++;
-			dsize--;
-		}
-	}
-	*count -= slen;
-
-	return len;
-}
-EXPORT_SYMBOL(isdnhdlc_encode);
diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
deleted file mode 100644
index aaa639ad5526..000000000000
--- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c
+++ /dev/null
@@ -1,1168 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * mISDNinfineon.c
- *		Support for cards based on following Infineon ISDN chipsets
- *		- ISAC + HSCX
- *		- IPAC and IPAC-X
- *		- ISAC-SX + HSCX
- *
- * Supported cards:
- *		- Dialogic Diva 2.0
- *		- Dialogic Diva 2.0U
- *		- Dialogic Diva 2.01
- *		- Dialogic Diva 2.02
- *		- Sedlbauer Speedwin
- *		- HST Saphir3
- *		- Develo (former ELSA) Microlink PCI (Quickstep 1000)
- *		- Develo (former ELSA) Quickstep 3000
- *		- Berkom Scitel BRIX Quadro
- *		- Dr.Neuhaus (Sagem) Niccy
- *
- * Author       Karsten Keil <keil@isdn4linux.de>
- *
- * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
- */
-
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/mISDNhw.h>
-#include <linux/slab.h>
-#include "ipac.h"
-
-#define INFINEON_REV	"1.0"
-
-static int inf_cnt;
-static u32 debug;
-static u32 irqloops = 4;
-
-enum inf_types {
-	INF_NONE,
-	INF_DIVA20,
-	INF_DIVA20U,
-	INF_DIVA201,
-	INF_DIVA202,
-	INF_SPEEDWIN,
-	INF_SAPHIR3,
-	INF_QS1000,
-	INF_QS3000,
-	INF_NICCY,
-	INF_SCT_1,
-	INF_SCT_2,
-	INF_SCT_3,
-	INF_SCT_4,
-	INF_GAZEL_R685,
-	INF_GAZEL_R753
-};
-
-enum addr_mode {
-	AM_NONE = 0,
-	AM_IO,
-	AM_MEMIO,
-	AM_IND_IO,
-};
-
-struct inf_cinfo {
-	enum inf_types	typ;
-	const char	*full;
-	const char	*name;
-	enum addr_mode	cfg_mode;
-	enum addr_mode	addr_mode;
-	u8		cfg_bar;
-	u8		addr_bar;
-	void		*irqfunc;
-};
-
-struct _ioaddr {
-	enum addr_mode	mode;
-	union {
-		void __iomem	*p;
-		struct _ioport	io;
-	} a;
-};
-
-struct _iohandle {
-	enum addr_mode	mode;
-	resource_size_t	size;
-	resource_size_t	start;
-	void __iomem	*p;
-};
-
-struct inf_hw {
-	struct list_head	list;
-	struct pci_dev		*pdev;
-	const struct inf_cinfo	*ci;
-	char			name[MISDN_MAX_IDLEN];
-	u32			irq;
-	u32			irqcnt;
-	struct _iohandle	cfg;
-	struct _iohandle	addr;
-	struct _ioaddr		isac;
-	struct _ioaddr		hscx;
-	spinlock_t		lock;	/* HW access lock */
-	struct ipac_hw		ipac;
-	struct inf_hw		*sc[3];	/* slave cards */
-};
-
-
-#define PCI_SUBVENDOR_HST_SAPHIR3       0x52
-#define PCI_SUBVENDOR_SEDLBAUER_PCI     0x53
-#define PCI_SUB_ID_SEDLBAUER            0x01
-
-static struct pci_device_id infineon_ids[] = {
-	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20), INF_DIVA20 },
-	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20_U), INF_DIVA20U },
-	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA201), INF_DIVA201 },
-	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA202), INF_DIVA202 },
-	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
-	  PCI_SUBVENDOR_SEDLBAUER_PCI, PCI_SUB_ID_SEDLBAUER, 0, 0,
-	  INF_SPEEDWIN },
-	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
-	  PCI_SUBVENDOR_HST_SAPHIR3, PCI_SUB_ID_SEDLBAUER, 0, 0, INF_SAPHIR3 },
-	{ PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_MICROLINK), INF_QS1000 },
-	{ PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_QS3000), INF_QS3000 },
-	{ PCI_VDEVICE(SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY), INF_NICCY },
-	{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-	  PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO, 0, 0,
-	  INF_SCT_1 },
-	{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R685), INF_GAZEL_R685 },
-	{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R753), INF_GAZEL_R753 },
-	{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO), INF_GAZEL_R753 },
-	{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_OLITEC), INF_GAZEL_R753 },
-	{ }
-};
-MODULE_DEVICE_TABLE(pci, infineon_ids);
-
-/* PCI interface specific defines */
-/* Diva 2.0/2.0U */
-#define DIVA_HSCX_PORT		0x00
-#define DIVA_HSCX_ALE		0x04
-#define DIVA_ISAC_PORT		0x08
-#define DIVA_ISAC_ALE		0x0C
-#define DIVA_PCI_CTRL           0x10
-
-/* DIVA_PCI_CTRL bits */
-#define DIVA_IRQ_BIT		0x01
-#define DIVA_RESET_BIT		0x08
-#define DIVA_EEPROM_CLK		0x40
-#define DIVA_LED_A		0x10
-#define DIVA_LED_B		0x20
-#define DIVA_IRQ_CLR		0x80
-
-/* Diva 2.01/2.02 */
-/* Siemens PITA */
-#define PITA_ICR_REG		0x00
-#define PITA_INT0_STATUS	0x02
-
-#define PITA_MISC_REG		0x1c
-#define PITA_PARA_SOFTRESET	0x01000000
-#define PITA_SER_SOFTRESET	0x02000000
-#define PITA_PARA_MPX_MODE	0x04000000
-#define PITA_INT0_ENABLE	0x00020000
-
-/* TIGER 100 Registers */
-#define TIGER_RESET_ADDR	0x00
-#define TIGER_EXTERN_RESET	0x01
-#define TIGER_AUX_CTRL		0x02
-#define TIGER_AUX_DATA		0x03
-#define TIGER_AUX_IRQMASK	0x05
-#define TIGER_AUX_STATUS	0x07
-
-/* Tiger AUX BITs */
-#define TIGER_IOMASK		0xdd	/* 1 and 5 are inputs */
-#define TIGER_IRQ_BIT		0x02
-
-#define TIGER_IPAC_ALE		0xC0
-#define TIGER_IPAC_PORT		0xC8
-
-/* ELSA (now Develo) PCI cards */
-#define ELSA_IRQ_ADDR		0x4c
-#define ELSA_IRQ_MASK		0x04
-#define QS1000_IRQ_OFF		0x01
-#define QS3000_IRQ_OFF		0x03
-#define QS1000_IRQ_ON		0x41
-#define QS3000_IRQ_ON		0x43
-
-/* Dr Neuhaus/Sagem Niccy */
-#define NICCY_ISAC_PORT		0x00
-#define NICCY_HSCX_PORT		0x01
-#define NICCY_ISAC_ALE		0x02
-#define NICCY_HSCX_ALE		0x03
-
-#define NICCY_IRQ_CTRL_REG	0x38
-#define NICCY_IRQ_ENABLE	0x001f00
-#define NICCY_IRQ_DISABLE	0xff0000
-#define NICCY_IRQ_BIT		0x800000
-
-
-/* Scitel PLX */
-#define SCT_PLX_IRQ_ADDR	0x4c
-#define SCT_PLX_RESET_ADDR	0x50
-#define SCT_PLX_IRQ_ENABLE	0x41
-#define SCT_PLX_RESET_BIT	0x04
-
-/* Gazel */
-#define	GAZEL_IPAC_DATA_PORT	0x04
-/* Gazel PLX */
-#define GAZEL_CNTRL		0x50
-#define GAZEL_RESET		0x04
-#define GAZEL_RESET_9050	0x40000000
-#define GAZEL_INCSR		0x4C
-#define GAZEL_ISAC_EN		0x08
-#define GAZEL_INT_ISAC		0x20
-#define GAZEL_HSCX_EN		0x01
-#define GAZEL_INT_HSCX		0x04
-#define GAZEL_PCI_EN		0x40
-#define GAZEL_IPAC_EN		0x03
-
-
-static LIST_HEAD(Cards);
-static DEFINE_RWLOCK(card_lock); /* protect Cards */
-
-static void
-_set_debug(struct inf_hw *card)
-{
-	card->ipac.isac.dch.debug = debug;
-	card->ipac.hscx[0].bch.debug = debug;
-	card->ipac.hscx[1].bch.debug = debug;
-}
-
-static int
-set_debug(const char *val, const struct kernel_param *kp)
-{
-	int ret;
-	struct inf_hw *card;
-
-	ret = param_set_uint(val, kp);
-	if (!ret) {
-		read_lock(&card_lock);
-		list_for_each_entry(card, &Cards, list)
-			_set_debug(card);
-		read_unlock(&card_lock);
-	}
-	return ret;
-}
-
-MODULE_AUTHOR("Karsten Keil");
-MODULE_DESCRIPTION("mISDN driver for cards based on Infineon ISDN chipsets");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(INFINEON_REV);
-module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "infineon debug mask");
-module_param(irqloops, uint, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(irqloops, "infineon maximal irqloops (default 4)");
-
-/* Interface functions */
-
-IOFUNC_IO(ISAC, inf_hw, isac.a.io)
-IOFUNC_IO(IPAC, inf_hw, hscx.a.io)
-IOFUNC_IND(ISAC, inf_hw, isac.a.io)
-IOFUNC_IND(IPAC, inf_hw, hscx.a.io)
-IOFUNC_MEMIO(ISAC, inf_hw, u32, isac.a.p)
-IOFUNC_MEMIO(IPAC, inf_hw, u32, hscx.a.p)
-
-static irqreturn_t
-diva_irq(int intno, void *dev_id)
-{
-	struct inf_hw *hw = dev_id;
-	u8 val;
-
-	spin_lock(&hw->lock);
-	val = inb((u32)hw->cfg.start + DIVA_PCI_CTRL);
-	if (!(val & DIVA_IRQ_BIT)) { /* for us or shared ? */
-		spin_unlock(&hw->lock);
-		return IRQ_NONE; /* shared */
-	}
-	hw->irqcnt++;
-	mISDNipac_irq(&hw->ipac, irqloops);
-	spin_unlock(&hw->lock);
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t
-diva20x_irq(int intno, void *dev_id)
-{
-	struct inf_hw *hw = dev_id;
-	u8 val;
-
-	spin_lock(&hw->lock);
-	val = readb(hw->cfg.p);
-	if (!(val & PITA_INT0_STATUS)) { /* for us or shared ? */
-		spin_unlock(&hw->lock);
-		return IRQ_NONE; /* shared */
-	}
-	hw->irqcnt++;
-	mISDNipac_irq(&hw->ipac, irqloops);
-	writeb(PITA_INT0_STATUS, hw->cfg.p); /* ACK PITA INT0 */
-	spin_unlock(&hw->lock);
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t
-tiger_irq(int intno, void *dev_id)
-{
-	struct inf_hw *hw = dev_id;
-	u8 val;
-
-	spin_lock(&hw->lock);
-	val = inb((u32)hw->cfg.start + TIGER_AUX_STATUS);
-	if (val & TIGER_IRQ_BIT) { /* for us or shared ? */
-		spin_unlock(&hw->lock);
-		return IRQ_NONE; /* shared */
-	}
-	hw->irqcnt++;
-	mISDNipac_irq(&hw->ipac, irqloops);
-	spin_unlock(&hw->lock);
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t
-elsa_irq(int intno, void *dev_id)
-{
-	struct inf_hw *hw = dev_id;
-	u8 val;
-
-	spin_lock(&hw->lock);
-	val = inb((u32)hw->cfg.start + ELSA_IRQ_ADDR);
-	if (!(val & ELSA_IRQ_MASK)) {
-		spin_unlock(&hw->lock);
-		return IRQ_NONE; /* shared */
-	}
-	hw->irqcnt++;
-	mISDNipac_irq(&hw->ipac, irqloops);
-	spin_unlock(&hw->lock);
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t
-niccy_irq(int intno, void *dev_id)
-{
-	struct inf_hw *hw = dev_id;
-	u32 val;
-
-	spin_lock(&hw->lock);
-	val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
-	if (!(val & NICCY_IRQ_BIT)) { /* for us or shared ? */
-		spin_unlock(&hw->lock);
-		return IRQ_NONE; /* shared */
-	}
-	outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
-	hw->irqcnt++;
-	mISDNipac_irq(&hw->ipac, irqloops);
-	spin_unlock(&hw->lock);
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t
-gazel_irq(int intno, void *dev_id)
-{
-	struct inf_hw *hw = dev_id;
-	irqreturn_t ret;
-
-	spin_lock(&hw->lock);
-	ret = mISDNipac_irq(&hw->ipac, irqloops);
-	spin_unlock(&hw->lock);
-	return ret;
-}
-
-static irqreturn_t
-ipac_irq(int intno, void *dev_id)
-{
-	struct inf_hw *hw = dev_id;
-	u8 val;
-
-	spin_lock(&hw->lock);
-	val = hw->ipac.read_reg(hw, IPAC_ISTA);
-	if (!(val & 0x3f)) {
-		spin_unlock(&hw->lock);
-		return IRQ_NONE; /* shared */
-	}
-	hw->irqcnt++;
-	mISDNipac_irq(&hw->ipac, irqloops);
-	spin_unlock(&hw->lock);
-	return IRQ_HANDLED;
-}
-
-static void
-enable_hwirq(struct inf_hw *hw)
-{
-	u16 w;
-	u32 val;
-
-	switch (hw->ci->typ) {
-	case INF_DIVA201:
-	case INF_DIVA202:
-		writel(PITA_INT0_ENABLE, hw->cfg.p);
-		break;
-	case INF_SPEEDWIN:
-	case INF_SAPHIR3:
-		outb(TIGER_IRQ_BIT, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
-		break;
-	case INF_QS1000:
-		outb(QS1000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
-		break;
-	case INF_QS3000:
-		outb(QS3000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
-		break;
-	case INF_NICCY:
-		val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
-		val |= NICCY_IRQ_ENABLE;
-		outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
-		break;
-	case INF_SCT_1:
-		w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
-		w |= SCT_PLX_IRQ_ENABLE;
-		outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
-		break;
-	case INF_GAZEL_R685:
-		outb(GAZEL_ISAC_EN + GAZEL_HSCX_EN + GAZEL_PCI_EN,
-		     (u32)hw->cfg.start + GAZEL_INCSR);
-		break;
-	case INF_GAZEL_R753:
-		outb(GAZEL_IPAC_EN + GAZEL_PCI_EN,
-		     (u32)hw->cfg.start + GAZEL_INCSR);
-		break;
-	default:
-		break;
-	}
-}
-
-static void
-disable_hwirq(struct inf_hw *hw)
-{
-	u16 w;
-	u32 val;
-
-	switch (hw->ci->typ) {
-	case INF_DIVA201:
-	case INF_DIVA202:
-		writel(0, hw->cfg.p);
-		break;
-	case INF_SPEEDWIN:
-	case INF_SAPHIR3:
-		outb(0, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
-		break;
-	case INF_QS1000:
-		outb(QS1000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
-		break;
-	case INF_QS3000:
-		outb(QS3000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
-		break;
-	case INF_NICCY:
-		val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
-		val &= NICCY_IRQ_DISABLE;
-		outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
-		break;
-	case INF_SCT_1:
-		w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
-		w &= (~SCT_PLX_IRQ_ENABLE);
-		outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
-		break;
-	case INF_GAZEL_R685:
-	case INF_GAZEL_R753:
-		outb(0, (u32)hw->cfg.start + GAZEL_INCSR);
-		break;
-	default:
-		break;
-	}
-}
-
-static void
-ipac_chip_reset(struct inf_hw *hw)
-{
-	hw->ipac.write_reg(hw, IPAC_POTA2, 0x20);
-	mdelay(5);
-	hw->ipac.write_reg(hw, IPAC_POTA2, 0x00);
-	mdelay(5);
-	hw->ipac.write_reg(hw, IPAC_CONF, hw->ipac.conf);
-	hw->ipac.write_reg(hw, IPAC_MASK, 0xc0);
-}
-
-static void
-reset_inf(struct inf_hw *hw)
-{
-	u16 w;
-	u32 val;
-
-	if (debug & DEBUG_HW)
-		pr_notice("%s: resetting card\n", hw->name);
-	switch (hw->ci->typ) {
-	case INF_DIVA20:
-	case INF_DIVA20U:
-		outb(0, (u32)hw->cfg.start + DIVA_PCI_CTRL);
-		mdelay(10);
-		outb(DIVA_RESET_BIT, (u32)hw->cfg.start + DIVA_PCI_CTRL);
-		mdelay(10);
-		/* Workaround PCI9060 */
-		outb(9, (u32)hw->cfg.start + 0x69);
-		outb(DIVA_RESET_BIT | DIVA_LED_A,
-		     (u32)hw->cfg.start + DIVA_PCI_CTRL);
-		break;
-	case INF_DIVA201:
-		writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
-		       hw->cfg.p + PITA_MISC_REG);
-		mdelay(1);
-		writel(PITA_PARA_MPX_MODE, hw->cfg.p + PITA_MISC_REG);
-		mdelay(10);
-		break;
-	case INF_DIVA202:
-		writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
-		       hw->cfg.p + PITA_MISC_REG);
-		mdelay(1);
-		writel(PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET,
-		       hw->cfg.p + PITA_MISC_REG);
-		mdelay(10);
-		break;
-	case INF_SPEEDWIN:
-	case INF_SAPHIR3:
-		ipac_chip_reset(hw);
-		hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
-		hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
-		hw->ipac.write_reg(hw, IPAC_PCFG, 0x12);
-		break;
-	case INF_QS1000:
-	case INF_QS3000:
-		ipac_chip_reset(hw);
-		hw->ipac.write_reg(hw, IPAC_ACFG, 0x00);
-		hw->ipac.write_reg(hw, IPAC_AOE, 0x3c);
-		hw->ipac.write_reg(hw, IPAC_ATX, 0xff);
-		break;
-	case INF_NICCY:
-		break;
-	case INF_SCT_1:
-		w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
-		w &= (~SCT_PLX_RESET_BIT);
-		outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
-		mdelay(10);
-		w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
-		w |= SCT_PLX_RESET_BIT;
-		outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
-		mdelay(10);
-		break;
-	case INF_GAZEL_R685:
-		val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
-		val |= (GAZEL_RESET_9050 + GAZEL_RESET);
-		outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
-		val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
-		mdelay(4);
-		outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
-		mdelay(10);
-		hw->ipac.isac.adf2 = 0x87;
-		hw->ipac.hscx[0].slot = 0x1f;
-		hw->ipac.hscx[1].slot = 0x23;
-		break;
-	case INF_GAZEL_R753:
-		val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
-		val |= (GAZEL_RESET_9050 + GAZEL_RESET);
-		outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
-		val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
-		mdelay(4);
-		outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
-		mdelay(10);
-		ipac_chip_reset(hw);
-		hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
-		hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
-		hw->ipac.conf = 0x01; /* IOM off */
-		break;
-	default:
-		return;
-	}
-	enable_hwirq(hw);
-}
-
-static int
-inf_ctrl(struct inf_hw *hw, u32 cmd, u_long arg)
-{
-	int ret = 0;
-
-	switch (cmd) {
-	case HW_RESET_REQ:
-		reset_inf(hw);
-		break;
-	default:
-		pr_info("%s: %s unknown command %x %lx\n",
-			hw->name, __func__, cmd, arg);
-		ret = -EINVAL;
-		break;
-	}
-	return ret;
-}
-
-static int
-init_irq(struct inf_hw *hw)
-{
-	int	ret, cnt = 3;
-	u_long	flags;
-
-	if (!hw->ci->irqfunc)
-		return -EINVAL;
-	ret = request_irq(hw->irq, hw->ci->irqfunc, IRQF_SHARED, hw->name, hw);
-	if (ret) {
-		pr_info("%s: couldn't get interrupt %d\n", hw->name, hw->irq);
-		return ret;
-	}
-	while (cnt--) {
-		spin_lock_irqsave(&hw->lock, flags);
-		reset_inf(hw);
-		ret = hw->ipac.init(&hw->ipac);
-		if (ret) {
-			spin_unlock_irqrestore(&hw->lock, flags);
-			pr_info("%s: ISAC init failed with %d\n",
-				hw->name, ret);
-			break;
-		}
-		spin_unlock_irqrestore(&hw->lock, flags);
-		msleep_interruptible(10);
-		if (debug & DEBUG_HW)
-			pr_notice("%s: IRQ %d count %d\n", hw->name,
-				  hw->irq, hw->irqcnt);
-		if (!hw->irqcnt) {
-			pr_info("%s: IRQ(%d) got no requests during init %d\n",
-				hw->name, hw->irq, 3 - cnt);
-		} else
-			return 0;
-	}
-	free_irq(hw->irq, hw);
-	return -EIO;
-}
-
-static void
-release_io(struct inf_hw *hw)
-{
-	if (hw->cfg.mode) {
-		if (hw->cfg.mode == AM_MEMIO) {
-			release_mem_region(hw->cfg.start, hw->cfg.size);
-			if (hw->cfg.p)
-				iounmap(hw->cfg.p);
-		} else
-			release_region(hw->cfg.start, hw->cfg.size);
-		hw->cfg.mode = AM_NONE;
-	}
-	if (hw->addr.mode) {
-		if (hw->addr.mode == AM_MEMIO) {
-			release_mem_region(hw->addr.start, hw->addr.size);
-			if (hw->addr.p)
-				iounmap(hw->addr.p);
-		} else
-			release_region(hw->addr.start, hw->addr.size);
-		hw->addr.mode = AM_NONE;
-	}
-}
-
-static int
-setup_io(struct inf_hw *hw)
-{
-	int err = 0;
-
-	if (hw->ci->cfg_mode) {
-		hw->cfg.start = pci_resource_start(hw->pdev, hw->ci->cfg_bar);
-		hw->cfg.size = pci_resource_len(hw->pdev, hw->ci->cfg_bar);
-		if (hw->ci->cfg_mode == AM_MEMIO) {
-			if (!request_mem_region(hw->cfg.start, hw->cfg.size,
-						hw->name))
-				err = -EBUSY;
-		} else {
-			if (!request_region(hw->cfg.start, hw->cfg.size,
-					    hw->name))
-				err = -EBUSY;
-		}
-		if (err) {
-			pr_info("mISDN: %s config port %lx (%lu bytes)"
-				"already in use\n", hw->name,
-				(ulong)hw->cfg.start, (ulong)hw->cfg.size);
-			return err;
-		}
-		hw->cfg.mode = hw->ci->cfg_mode;
-		if (hw->ci->cfg_mode == AM_MEMIO) {
-			hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size);
-			if (!hw->cfg.p)
-				return -ENOMEM;
-		}
-		if (debug & DEBUG_HW)
-			pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n",
-				  hw->name, (ulong)hw->cfg.start,
-				  (ulong)hw->cfg.size, hw->ci->cfg_mode);
-
-	}
-	if (hw->ci->addr_mode) {
-		hw->addr.start = pci_resource_start(hw->pdev, hw->ci->addr_bar);
-		hw->addr.size = pci_resource_len(hw->pdev, hw->ci->addr_bar);
-		if (hw->ci->addr_mode == AM_MEMIO) {
-			if (!request_mem_region(hw->addr.start, hw->addr.size,
-						hw->name))
-				err = -EBUSY;
-		} else {
-			if (!request_region(hw->addr.start, hw->addr.size,
-					    hw->name))
-				err = -EBUSY;
-		}
-		if (err) {
-			pr_info("mISDN: %s address port %lx (%lu bytes)"
-				"already in use\n", hw->name,
-				(ulong)hw->addr.start, (ulong)hw->addr.size);
-			return err;
-		}
-		hw->addr.mode = hw->ci->addr_mode;
-		if (hw->ci->addr_mode == AM_MEMIO) {
-			hw->addr.p = ioremap(hw->addr.start, hw->addr.size);
-			if (!hw->addr.p)
-				return -ENOMEM;
-		}
-		if (debug & DEBUG_HW)
-			pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n",
-				  hw->name, (ulong)hw->addr.start,
-				  (ulong)hw->addr.size, hw->ci->addr_mode);
-
-	}
-
-	switch (hw->ci->typ) {
-	case INF_DIVA20:
-	case INF_DIVA20U:
-		hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
-		hw->isac.mode = hw->cfg.mode;
-		hw->isac.a.io.ale = (u32)hw->cfg.start + DIVA_ISAC_ALE;
-		hw->isac.a.io.port = (u32)hw->cfg.start + DIVA_ISAC_PORT;
-		hw->hscx.mode = hw->cfg.mode;
-		hw->hscx.a.io.ale = (u32)hw->cfg.start + DIVA_HSCX_ALE;
-		hw->hscx.a.io.port = (u32)hw->cfg.start + DIVA_HSCX_PORT;
-		break;
-	case INF_DIVA201:
-		hw->ipac.type = IPAC_TYPE_IPAC;
-		hw->ipac.isac.off = 0x80;
-		hw->isac.mode = hw->addr.mode;
-		hw->isac.a.p = hw->addr.p;
-		hw->hscx.mode = hw->addr.mode;
-		hw->hscx.a.p = hw->addr.p;
-		break;
-	case INF_DIVA202:
-		hw->ipac.type = IPAC_TYPE_IPACX;
-		hw->isac.mode = hw->addr.mode;
-		hw->isac.a.p = hw->addr.p;
-		hw->hscx.mode = hw->addr.mode;
-		hw->hscx.a.p = hw->addr.p;
-		break;
-	case INF_SPEEDWIN:
-	case INF_SAPHIR3:
-		hw->ipac.type = IPAC_TYPE_IPAC;
-		hw->ipac.isac.off = 0x80;
-		hw->isac.mode = hw->cfg.mode;
-		hw->isac.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
-		hw->isac.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
-		hw->hscx.mode = hw->cfg.mode;
-		hw->hscx.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
-		hw->hscx.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
-		outb(0xff, (ulong)hw->cfg.start);
-		mdelay(1);
-		outb(0x00, (ulong)hw->cfg.start);
-		mdelay(1);
-		outb(TIGER_IOMASK, (ulong)hw->cfg.start + TIGER_AUX_CTRL);
-		break;
-	case INF_QS1000:
-	case INF_QS3000:
-		hw->ipac.type = IPAC_TYPE_IPAC;
-		hw->ipac.isac.off = 0x80;
-		hw->isac.a.io.ale = (u32)hw->addr.start;
-		hw->isac.a.io.port = (u32)hw->addr.start + 1;
-		hw->isac.mode = hw->addr.mode;
-		hw->hscx.a.io.ale = (u32)hw->addr.start;
-		hw->hscx.a.io.port = (u32)hw->addr.start + 1;
-		hw->hscx.mode = hw->addr.mode;
-		break;
-	case INF_NICCY:
-		hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
-		hw->isac.mode = hw->addr.mode;
-		hw->isac.a.io.ale = (u32)hw->addr.start + NICCY_ISAC_ALE;
-		hw->isac.a.io.port = (u32)hw->addr.start + NICCY_ISAC_PORT;
-		hw->hscx.mode = hw->addr.mode;
-		hw->hscx.a.io.ale = (u32)hw->addr.start + NICCY_HSCX_ALE;
-		hw->hscx.a.io.port = (u32)hw->addr.start + NICCY_HSCX_PORT;
-		break;
-	case INF_SCT_1:
-		hw->ipac.type = IPAC_TYPE_IPAC;
-		hw->ipac.isac.off = 0x80;
-		hw->isac.a.io.ale = (u32)hw->addr.start;
-		hw->isac.a.io.port = hw->isac.a.io.ale + 4;
-		hw->isac.mode = hw->addr.mode;
-		hw->hscx.a.io.ale = hw->isac.a.io.ale;
-		hw->hscx.a.io.port = hw->isac.a.io.port;
-		hw->hscx.mode = hw->addr.mode;
-		break;
-	case INF_SCT_2:
-		hw->ipac.type = IPAC_TYPE_IPAC;
-		hw->ipac.isac.off = 0x80;
-		hw->isac.a.io.ale = (u32)hw->addr.start + 0x08;
-		hw->isac.a.io.port = hw->isac.a.io.ale + 4;
-		hw->isac.mode = hw->addr.mode;
-		hw->hscx.a.io.ale = hw->isac.a.io.ale;
-		hw->hscx.a.io.port = hw->isac.a.io.port;
-		hw->hscx.mode = hw->addr.mode;
-		break;
-	case INF_SCT_3:
-		hw->ipac.type = IPAC_TYPE_IPAC;
-		hw->ipac.isac.off = 0x80;
-		hw->isac.a.io.ale = (u32)hw->addr.start + 0x10;
-		hw->isac.a.io.port = hw->isac.a.io.ale + 4;
-		hw->isac.mode = hw->addr.mode;
-		hw->hscx.a.io.ale = hw->isac.a.io.ale;
-		hw->hscx.a.io.port = hw->isac.a.io.port;
-		hw->hscx.mode = hw->addr.mode;
-		break;
-	case INF_SCT_4:
-		hw->ipac.type = IPAC_TYPE_IPAC;
-		hw->ipac.isac.off = 0x80;
-		hw->isac.a.io.ale = (u32)hw->addr.start + 0x20;
-		hw->isac.a.io.port = hw->isac.a.io.ale + 4;
-		hw->isac.mode = hw->addr.mode;
-		hw->hscx.a.io.ale = hw->isac.a.io.ale;
-		hw->hscx.a.io.port = hw->isac.a.io.port;
-		hw->hscx.mode = hw->addr.mode;
-		break;
-	case INF_GAZEL_R685:
-		hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
-		hw->ipac.isac.off = 0x80;
-		hw->isac.mode = hw->addr.mode;
-		hw->isac.a.io.port = (u32)hw->addr.start;
-		hw->hscx.mode = hw->addr.mode;
-		hw->hscx.a.io.port = hw->isac.a.io.port;
-		break;
-	case INF_GAZEL_R753:
-		hw->ipac.type = IPAC_TYPE_IPAC;
-		hw->ipac.isac.off = 0x80;
-		hw->isac.mode = hw->addr.mode;
-		hw->isac.a.io.ale = (u32)hw->addr.start;
-		hw->isac.a.io.port = (u32)hw->addr.start + GAZEL_IPAC_DATA_PORT;
-		hw->hscx.mode = hw->addr.mode;
-		hw->hscx.a.io.ale = hw->isac.a.io.ale;
-		hw->hscx.a.io.port = hw->isac.a.io.port;
-		break;
-	default:
-		return -EINVAL;
-	}
-	switch (hw->isac.mode) {
-	case AM_MEMIO:
-		ASSIGN_FUNC_IPAC(MIO, hw->ipac);
-		break;
-	case AM_IND_IO:
-		ASSIGN_FUNC_IPAC(IND, hw->ipac);
-		break;
-	case AM_IO:
-		ASSIGN_FUNC_IPAC(IO, hw->ipac);
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static void
-release_card(struct inf_hw *card) {
-	ulong	flags;
-	int	i;
-
-	spin_lock_irqsave(&card->lock, flags);
-	disable_hwirq(card);
-	spin_unlock_irqrestore(&card->lock, flags);
-	card->ipac.isac.release(&card->ipac.isac);
-	free_irq(card->irq, card);
-	mISDN_unregister_device(&card->ipac.isac.dch.dev);
-	release_io(card);
-	write_lock_irqsave(&card_lock, flags);
-	list_del(&card->list);
-	write_unlock_irqrestore(&card_lock, flags);
-	switch (card->ci->typ) {
-	case INF_SCT_2:
-	case INF_SCT_3:
-	case INF_SCT_4:
-		break;
-	case INF_SCT_1:
-		for (i = 0; i < 3; i++) {
-			if (card->sc[i])
-				release_card(card->sc[i]);
-			card->sc[i] = NULL;
-		}
-		fallthrough;
-	default:
-		pci_disable_device(card->pdev);
-		pci_set_drvdata(card->pdev, NULL);
-		break;
-	}
-	kfree(card);
-	inf_cnt--;
-}
-
-static int
-setup_instance(struct inf_hw *card)
-{
-	int err;
-	ulong flags;
-
-	snprintf(card->name, MISDN_MAX_IDLEN - 1, "%s.%d", card->ci->name,
-		 inf_cnt + 1);
-	write_lock_irqsave(&card_lock, flags);
-	list_add_tail(&card->list, &Cards);
-	write_unlock_irqrestore(&card_lock, flags);
-
-	_set_debug(card);
-	card->ipac.isac.name = card->name;
-	card->ipac.name = card->name;
-	card->ipac.owner = THIS_MODULE;
-	spin_lock_init(&card->lock);
-	card->ipac.isac.hwlock = &card->lock;
-	card->ipac.hwlock = &card->lock;
-	card->ipac.ctrl = (void *)&inf_ctrl;
-
-	err = setup_io(card);
-	if (err)
-		goto error_setup;
-
-	card->ipac.isac.dch.dev.Bprotocols =
-		mISDNipac_init(&card->ipac, card);
-
-	if (card->ipac.isac.dch.dev.Bprotocols == 0)
-		goto error_setup;
-
-	err = mISDN_register_device(&card->ipac.isac.dch.dev,
-				    &card->pdev->dev, card->name);
-	if (err)
-		goto error;
-
-	err = init_irq(card);
-	if (!err)  {
-		inf_cnt++;
-		pr_notice("Infineon %d cards installed\n", inf_cnt);
-		return 0;
-	}
-	mISDN_unregister_device(&card->ipac.isac.dch.dev);
-error:
-	card->ipac.release(&card->ipac);
-error_setup:
-	release_io(card);
-	write_lock_irqsave(&card_lock, flags);
-	list_del(&card->list);
-	write_unlock_irqrestore(&card_lock, flags);
-	return err;
-}
-
-static const struct inf_cinfo inf_card_info[] = {
-	{
-		INF_DIVA20,
-		"Dialogic Diva 2.0",
-		"diva20",
-		AM_IND_IO, AM_NONE, 2, 0,
-		&diva_irq
-	},
-	{
-		INF_DIVA20U,
-		"Dialogic Diva 2.0U",
-		"diva20U",
-		AM_IND_IO, AM_NONE, 2, 0,
-		&diva_irq
-	},
-	{
-		INF_DIVA201,
-		"Dialogic Diva 2.01",
-		"diva201",
-		AM_MEMIO, AM_MEMIO, 0, 1,
-		&diva20x_irq
-	},
-	{
-		INF_DIVA202,
-		"Dialogic Diva 2.02",
-		"diva202",
-		AM_MEMIO, AM_MEMIO, 0, 1,
-		&diva20x_irq
-	},
-	{
-		INF_SPEEDWIN,
-		"Sedlbauer SpeedWin PCI",
-		"speedwin",
-		AM_IND_IO, AM_NONE, 0, 0,
-		&tiger_irq
-	},
-	{
-		INF_SAPHIR3,
-		"HST Saphir 3",
-		"saphir",
-		AM_IND_IO, AM_NONE, 0, 0,
-		&tiger_irq
-	},
-	{
-		INF_QS1000,
-		"Develo Microlink PCI",
-		"qs1000",
-		AM_IO, AM_IND_IO, 1, 3,
-		&elsa_irq
-	},
-	{
-		INF_QS3000,
-		"Develo QuickStep 3000",
-		"qs3000",
-		AM_IO, AM_IND_IO, 1, 3,
-		&elsa_irq
-	},
-	{
-		INF_NICCY,
-		"Sagem NICCY",
-		"niccy",
-		AM_IO, AM_IND_IO, 0, 1,
-		&niccy_irq
-	},
-	{
-		INF_SCT_1,
-		"SciTel Quadro",
-		"p1_scitel",
-		AM_IO, AM_IND_IO, 1, 5,
-		&ipac_irq
-	},
-	{
-		INF_SCT_2,
-		"SciTel Quadro",
-		"p2_scitel",
-		AM_NONE, AM_IND_IO, 0, 4,
-		&ipac_irq
-	},
-	{
-		INF_SCT_3,
-		"SciTel Quadro",
-		"p3_scitel",
-		AM_NONE, AM_IND_IO, 0, 3,
-		&ipac_irq
-	},
-	{
-		INF_SCT_4,
-		"SciTel Quadro",
-		"p4_scitel",
-		AM_NONE, AM_IND_IO, 0, 2,
-		&ipac_irq
-	},
-	{
-		INF_GAZEL_R685,
-		"Gazel R685",
-		"gazel685",
-		AM_IO, AM_IO, 1, 2,
-		&gazel_irq
-	},
-	{
-		INF_GAZEL_R753,
-		"Gazel R753",
-		"gazel753",
-		AM_IO, AM_IND_IO, 1, 2,
-		&ipac_irq
-	},
-	{
-		INF_NONE,
-	}
-};
-
-static const struct inf_cinfo *
-get_card_info(enum inf_types typ)
-{
-	const struct inf_cinfo *ci = inf_card_info;
-
-	while (ci->typ != INF_NONE) {
-		if (ci->typ == typ)
-			return ci;
-		ci++;
-	}
-	return NULL;
-}
-
-static int
-inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	int err = -ENOMEM;
-	struct inf_hw *card;
-
-	card = kzalloc_obj(struct inf_hw);
-	if (!card) {
-		pr_info("No memory for Infineon ISDN card\n");
-		return err;
-	}
-	card->pdev = pdev;
-	err = pci_enable_device(pdev);
-	if (err) {
-		kfree(card);
-		return err;
-	}
-	card->ci = get_card_info(ent->driver_data);
-	if (!card->ci) {
-		pr_info("mISDN: do not have information about adapter at %s\n",
-			pci_name(pdev));
-		kfree(card);
-		pci_disable_device(pdev);
-		return -EINVAL;
-	} else
-		pr_notice("mISDN: found adapter %s at %s\n",
-			  card->ci->full, pci_name(pdev));
-
-	card->irq = pdev->irq;
-	pci_set_drvdata(pdev, card);
-	err = setup_instance(card);
-	if (err) {
-		pci_disable_device(pdev);
-		kfree(card);
-		pci_set_drvdata(pdev, NULL);
-	} else if (ent->driver_data == INF_SCT_1) {
-		int i;
-		struct inf_hw *sc;
-
-		for (i = 1; i < 4; i++) {
-			sc = kzalloc_obj(struct inf_hw);
-			if (!sc) {
-				release_card(card);
-				pci_disable_device(pdev);
-				return -ENOMEM;
-			}
-			sc->irq = card->irq;
-			sc->pdev = card->pdev;
-			sc->ci = card->ci + i;
-			err = setup_instance(sc);
-			if (err) {
-				pci_disable_device(pdev);
-				kfree(sc);
-				release_card(card);
-				break;
-			} else
-				card->sc[i - 1] = sc;
-		}
-	}
-	return err;
-}
-
-static void
-inf_remove(struct pci_dev *pdev)
-{
-	struct inf_hw	*card = pci_get_drvdata(pdev);
-
-	if (card)
-		release_card(card);
-	else
-		pr_debug("%s: drvdata already removed\n", __func__);
-}
-
-static struct pci_driver infineon_driver = {
-	.name = "ISDN Infineon pci",
-	.probe = inf_probe,
-	.remove = inf_remove,
-	.id_table = infineon_ids,
-};
-
-static int __init
-infineon_init(void)
-{
-	int err;
-
-	pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV);
-	err = pci_register_driver(&infineon_driver);
-	return err;
-}
-
-static void __exit
-infineon_cleanup(void)
-{
-	pci_unregister_driver(&infineon_driver);
-}
-
-module_init(infineon_init);
-module_exit(infineon_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c
deleted file mode 100644
index a34ea6058960..000000000000
--- a/drivers/isdn/hardware/mISDN/mISDNipac.c
+++ /dev/null
@@ -1,1636 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * isac.c   ISAC specific routines
- *
- * Author       Karsten Keil <keil@isdn4linux.de>
- *
- * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
- */
-
-#include <linux/irqreturn.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/mISDNhw.h>
-#include "ipac.h"
-
-
-#define DBUSY_TIMER_VALUE	80
-#define ARCOFI_USE		1
-
-#define ISAC_REV		"2.0"
-
-MODULE_AUTHOR("Karsten Keil");
-MODULE_VERSION(ISAC_REV);
-MODULE_DESCRIPTION("mISDN driver for ISAC specific functions");
-MODULE_LICENSE("GPL v2");
-
-#define ReadISAC(is, o)		(is->read_reg(is->dch.hw, o + is->off))
-#define	WriteISAC(is, o, v)	(is->write_reg(is->dch.hw, o + is->off, v))
-#define ReadHSCX(h, o)		(h->ip->read_reg(h->ip->hw, h->off + o))
-#define WriteHSCX(h, o, v)	(h->ip->write_reg(h->ip->hw, h->off + o, v))
-#define ReadIPAC(ip, o)		(ip->read_reg(ip->hw, o))
-#define WriteIPAC(ip, o, v)	(ip->write_reg(ip->hw, o, v))
-
-static inline void
-ph_command(struct isac_hw *isac, u8 command)
-{
-	pr_debug("%s: ph_command %x\n", isac->name, command);
-	if (isac->type & IPAC_TYPE_ISACX)
-		WriteISAC(isac, ISACX_CIX0, (command << 4) | 0xE);
-	else
-		WriteISAC(isac, ISAC_CIX0, (command << 2) | 3);
-}
-
-static void
-isac_ph_state_change(struct isac_hw *isac)
-{
-	switch (isac->state) {
-	case (ISAC_IND_RS):
-	case (ISAC_IND_EI):
-		ph_command(isac, ISAC_CMD_DUI);
-	}
-	schedule_event(&isac->dch, FLG_PHCHANGE);
-}
-
-static void
-isac_ph_state_bh(struct dchannel *dch)
-{
-	struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
-
-	switch (isac->state) {
-	case ISAC_IND_RS:
-	case ISAC_IND_EI:
-		dch->state = 0;
-		l1_event(dch->l1, HW_RESET_IND);
-		break;
-	case ISAC_IND_DID:
-		dch->state = 3;
-		l1_event(dch->l1, HW_DEACT_CNF);
-		break;
-	case ISAC_IND_DR:
-	case ISAC_IND_DR6:
-		dch->state = 3;
-		l1_event(dch->l1, HW_DEACT_IND);
-		break;
-	case ISAC_IND_PU:
-		dch->state = 4;
-		l1_event(dch->l1, HW_POWERUP_IND);
-		break;
-	case ISAC_IND_RSY:
-		if (dch->state <= 5) {
-			dch->state = 5;
-			l1_event(dch->l1, ANYSIGNAL);
-		} else {
-			dch->state = 8;
-			l1_event(dch->l1, LOSTFRAMING);
-		}
-		break;
-	case ISAC_IND_ARD:
-		dch->state = 6;
-		l1_event(dch->l1, INFO2);
-		break;
-	case ISAC_IND_AI8:
-		dch->state = 7;
-		l1_event(dch->l1, INFO4_P8);
-		break;
-	case ISAC_IND_AI10:
-		dch->state = 7;
-		l1_event(dch->l1, INFO4_P10);
-		break;
-	}
-	pr_debug("%s: TE newstate %x\n", isac->name, dch->state);
-}
-
-static void
-isac_empty_fifo(struct isac_hw *isac, int count)
-{
-	u8 *ptr;
-
-	pr_debug("%s: %s  %d\n", isac->name, __func__, count);
-
-	if (!isac->dch.rx_skb) {
-		isac->dch.rx_skb = mI_alloc_skb(isac->dch.maxlen, GFP_ATOMIC);
-		if (!isac->dch.rx_skb) {
-			pr_info("%s: D receive out of memory\n", isac->name);
-			WriteISAC(isac, ISAC_CMDR, 0x80);
-			return;
-		}
-	}
-	if ((isac->dch.rx_skb->len + count) >= isac->dch.maxlen) {
-		pr_debug("%s: %s overrun %d\n", isac->name, __func__,
-			 isac->dch.rx_skb->len + count);
-		WriteISAC(isac, ISAC_CMDR, 0x80);
-		return;
-	}
-	ptr = skb_put(isac->dch.rx_skb, count);
-	isac->read_fifo(isac->dch.hw, isac->off, ptr, count);
-	WriteISAC(isac, ISAC_CMDR, 0x80);
-	if (isac->dch.debug & DEBUG_HW_DFIFO) {
-		char	pfx[MISDN_MAX_IDLEN + 16];
-
-		snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-recv %s %d ",
-			 isac->name, count);
-		print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
-	}
-}
-
-static void
-isac_fill_fifo(struct isac_hw *isac)
-{
-	int count, more;
-	u8 *ptr;
-
-	if (!isac->dch.tx_skb)
-		return;
-	count = isac->dch.tx_skb->len - isac->dch.tx_idx;
-	if (count <= 0)
-		return;
-
-	more = 0;
-	if (count > 32) {
-		more = !0;
-		count = 32;
-	}
-	pr_debug("%s: %s  %d\n", isac->name, __func__, count);
-	ptr = isac->dch.tx_skb->data + isac->dch.tx_idx;
-	isac->dch.tx_idx += count;
-	isac->write_fifo(isac->dch.hw, isac->off, ptr, count);
-	WriteISAC(isac, ISAC_CMDR, more ? 0x8 : 0xa);
-	if (test_and_set_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
-		pr_debug("%s: %s dbusytimer running\n", isac->name, __func__);
-		timer_delete(&isac->dch.timer);
-	}
-	isac->dch.timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
-	add_timer(&isac->dch.timer);
-	if (isac->dch.debug & DEBUG_HW_DFIFO) {
-		char	pfx[MISDN_MAX_IDLEN + 16];
-
-		snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-send %s %d ",
-			 isac->name, count);
-		print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
-	}
-}
-
-static void
-isac_rme_irq(struct isac_hw *isac)
-{
-	u8 val, count;
-
-	val = ReadISAC(isac, ISAC_RSTA);
-	if ((val & 0x70) != 0x20) {
-		if (val & 0x40) {
-			pr_debug("%s: ISAC RDO\n", isac->name);
-#ifdef ERROR_STATISTIC
-			isac->dch.err_rx++;
-#endif
-		}
-		if (!(val & 0x20)) {
-			pr_debug("%s: ISAC CRC error\n", isac->name);
-#ifdef ERROR_STATISTIC
-			isac->dch.err_crc++;
-#endif
-		}
-		WriteISAC(isac, ISAC_CMDR, 0x80);
-		dev_kfree_skb(isac->dch.rx_skb);
-		isac->dch.rx_skb = NULL;
-	} else {
-		count = ReadISAC(isac, ISAC_RBCL) & 0x1f;
-		if (count == 0)
-			count = 32;
-		isac_empty_fifo(isac, count);
-		recv_Dchannel(&isac->dch);
-	}
-}
-
-static void
-isac_xpr_irq(struct isac_hw *isac)
-{
-	if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
-		timer_delete(&isac->dch.timer);
-	if (isac->dch.tx_skb && isac->dch.tx_idx < isac->dch.tx_skb->len) {
-		isac_fill_fifo(isac);
-	} else {
-		dev_kfree_skb(isac->dch.tx_skb);
-		if (get_next_dframe(&isac->dch))
-			isac_fill_fifo(isac);
-	}
-}
-
-static void
-isac_retransmit(struct isac_hw *isac)
-{
-	if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
-		timer_delete(&isac->dch.timer);
-	if (test_bit(FLG_TX_BUSY, &isac->dch.Flags)) {
-		/* Restart frame */
-		isac->dch.tx_idx = 0;
-		isac_fill_fifo(isac);
-	} else if (isac->dch.tx_skb) { /* should not happen */
-		pr_info("%s: tx_skb exist but not busy\n", isac->name);
-		test_and_set_bit(FLG_TX_BUSY, &isac->dch.Flags);
-		isac->dch.tx_idx = 0;
-		isac_fill_fifo(isac);
-	} else {
-		pr_info("%s: ISAC XDU no TX_BUSY\n", isac->name);
-		if (get_next_dframe(&isac->dch))
-			isac_fill_fifo(isac);
-	}
-}
-
-static void
-isac_mos_irq(struct isac_hw *isac)
-{
-	u8 val;
-	int ret;
-
-	val = ReadISAC(isac, ISAC_MOSR);
-	pr_debug("%s: ISAC MOSR %02x\n", isac->name, val);
-#if ARCOFI_USE
-	if (val & 0x08) {
-		if (!isac->mon_rx) {
-			isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
-			if (!isac->mon_rx) {
-				pr_info("%s: ISAC MON RX out of memory!\n",
-					isac->name);
-				isac->mocr &= 0xf0;
-				isac->mocr |= 0x0a;
-				WriteISAC(isac, ISAC_MOCR, isac->mocr);
-				goto afterMONR0;
-			} else
-				isac->mon_rxp = 0;
-		}
-		if (isac->mon_rxp >= MAX_MON_FRAME) {
-			isac->mocr &= 0xf0;
-			isac->mocr |= 0x0a;
-			WriteISAC(isac, ISAC_MOCR, isac->mocr);
-			isac->mon_rxp = 0;
-			pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
-			goto afterMONR0;
-		}
-		isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR0);
-		pr_debug("%s: ISAC MOR0 %02x\n", isac->name,
-			 isac->mon_rx[isac->mon_rxp - 1]);
-		if (isac->mon_rxp == 1) {
-			isac->mocr |= 0x04;
-			WriteISAC(isac, ISAC_MOCR, isac->mocr);
-		}
-	}
-afterMONR0:
-	if (val & 0x80) {
-		if (!isac->mon_rx) {
-			isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
-			if (!isac->mon_rx) {
-				pr_info("%s: ISAC MON RX out of memory!\n",
-					isac->name);
-				isac->mocr &= 0x0f;
-				isac->mocr |= 0xa0;
-				WriteISAC(isac, ISAC_MOCR, isac->mocr);
-				goto afterMONR1;
-			} else
-				isac->mon_rxp = 0;
-		}
-		if (isac->mon_rxp >= MAX_MON_FRAME) {
-			isac->mocr &= 0x0f;
-			isac->mocr |= 0xa0;
-			WriteISAC(isac, ISAC_MOCR, isac->mocr);
-			isac->mon_rxp = 0;
-			pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
-			goto afterMONR1;
-		}
-		isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR1);
-		pr_debug("%s: ISAC MOR1 %02x\n", isac->name,
-			 isac->mon_rx[isac->mon_rxp - 1]);
-		isac->mocr |= 0x40;
-		WriteISAC(isac, ISAC_MOCR, isac->mocr);
-	}
-afterMONR1:
-	if (val & 0x04) {
-		isac->mocr &= 0xf0;
-		WriteISAC(isac, ISAC_MOCR, isac->mocr);
-		isac->mocr |= 0x0a;
-		WriteISAC(isac, ISAC_MOCR, isac->mocr);
-		if (isac->monitor) {
-			ret = isac->monitor(isac->dch.hw, MONITOR_RX_0,
-					    isac->mon_rx, isac->mon_rxp);
-			if (ret)
-				kfree(isac->mon_rx);
-		} else {
-			pr_info("%s: MONITOR 0 received %d but no user\n",
-				isac->name, isac->mon_rxp);
-			kfree(isac->mon_rx);
-		}
-		isac->mon_rx = NULL;
-		isac->mon_rxp = 0;
-	}
-	if (val & 0x40) {
-		isac->mocr &= 0x0f;
-		WriteISAC(isac, ISAC_MOCR, isac->mocr);
-		isac->mocr |= 0xa0;
-		WriteISAC(isac, ISAC_MOCR, isac->mocr);
-		if (isac->monitor) {
-			ret = isac->monitor(isac->dch.hw, MONITOR_RX_1,
-					    isac->mon_rx, isac->mon_rxp);
-			if (ret)
-				kfree(isac->mon_rx);
-		} else {
-			pr_info("%s: MONITOR 1 received %d but no user\n",
-				isac->name, isac->mon_rxp);
-			kfree(isac->mon_rx);
-		}
-		isac->mon_rx = NULL;
-		isac->mon_rxp = 0;
-	}
-	if (val & 0x02) {
-		if ((!isac->mon_tx) || (isac->mon_txc &&
-					(isac->mon_txp >= isac->mon_txc) && !(val & 0x08))) {
-			isac->mocr &= 0xf0;
-			WriteISAC(isac, ISAC_MOCR, isac->mocr);
-			isac->mocr |= 0x0a;
-			WriteISAC(isac, ISAC_MOCR, isac->mocr);
-			if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
-				if (isac->monitor)
-					isac->monitor(isac->dch.hw,
-						      MONITOR_TX_0, NULL, 0);
-			}
-			kfree(isac->mon_tx);
-			isac->mon_tx = NULL;
-			isac->mon_txc = 0;
-			isac->mon_txp = 0;
-			goto AfterMOX0;
-		}
-		if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
-			if (isac->monitor)
-				isac->monitor(isac->dch.hw,
-					      MONITOR_TX_0, NULL, 0);
-			kfree(isac->mon_tx);
-			isac->mon_tx = NULL;
-			isac->mon_txc = 0;
-			isac->mon_txp = 0;
-			goto AfterMOX0;
-		}
-		WriteISAC(isac, ISAC_MOX0, isac->mon_tx[isac->mon_txp++]);
-		pr_debug("%s: ISAC %02x -> MOX0\n", isac->name,
-			 isac->mon_tx[isac->mon_txp - 1]);
-	}
-AfterMOX0:
-	if (val & 0x20) {
-		if ((!isac->mon_tx) || (isac->mon_txc &&
-					(isac->mon_txp >= isac->mon_txc) && !(val & 0x80))) {
-			isac->mocr &= 0x0f;
-			WriteISAC(isac, ISAC_MOCR, isac->mocr);
-			isac->mocr |= 0xa0;
-			WriteISAC(isac, ISAC_MOCR, isac->mocr);
-			if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
-				if (isac->monitor)
-					isac->monitor(isac->dch.hw,
-						      MONITOR_TX_1, NULL, 0);
-			}
-			kfree(isac->mon_tx);
-			isac->mon_tx = NULL;
-			isac->mon_txc = 0;
-			isac->mon_txp = 0;
-			goto AfterMOX1;
-		}
-		if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
-			if (isac->monitor)
-				isac->monitor(isac->dch.hw,
-					      MONITOR_TX_1, NULL, 0);
-			kfree(isac->mon_tx);
-			isac->mon_tx = NULL;
-			isac->mon_txc = 0;
-			isac->mon_txp = 0;
-			goto AfterMOX1;
-		}
-		WriteISAC(isac, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]);
-		pr_debug("%s: ISAC %02x -> MOX1\n", isac->name,
-			 isac->mon_tx[isac->mon_txp - 1]);
-	}
-AfterMOX1:
-	val = 0; /* dummy to avoid warning */
-#endif
-}
-
-static void
-isac_cisq_irq(struct isac_hw *isac) {
-	u8 val;
-
-	val = ReadISAC(isac, ISAC_CIR0);
-	pr_debug("%s: ISAC CIR0 %02X\n", isac->name, val);
-	if (val & 2) {
-		pr_debug("%s: ph_state change %x->%x\n", isac->name,
-			 isac->state, (val >> 2) & 0xf);
-		isac->state = (val >> 2) & 0xf;
-		isac_ph_state_change(isac);
-	}
-	if (val & 1) {
-		val = ReadISAC(isac, ISAC_CIR1);
-		pr_debug("%s: ISAC CIR1 %02X\n", isac->name, val);
-	}
-}
-
-static void
-isacsx_cic_irq(struct isac_hw *isac)
-{
-	u8 val;
-
-	val = ReadISAC(isac, ISACX_CIR0);
-	pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
-	if (val & ISACX_CIR0_CIC0) {
-		pr_debug("%s: ph_state change %x->%x\n", isac->name,
-			 isac->state, val >> 4);
-		isac->state = val >> 4;
-		isac_ph_state_change(isac);
-	}
-}
-
-static void
-isacsx_rme_irq(struct isac_hw *isac)
-{
-	int count;
-	u8 val;
-
-	val = ReadISAC(isac, ISACX_RSTAD);
-	if ((val & (ISACX_RSTAD_VFR |
-		    ISACX_RSTAD_RDO |
-		    ISACX_RSTAD_CRC |
-		    ISACX_RSTAD_RAB))
-	    != (ISACX_RSTAD_VFR | ISACX_RSTAD_CRC)) {
-		pr_debug("%s: RSTAD %#x, dropped\n", isac->name, val);
-#ifdef ERROR_STATISTIC
-		if (val & ISACX_RSTAD_CRC)
-			isac->dch.err_rx++;
-		else
-			isac->dch.err_crc++;
-#endif
-		WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC);
-		dev_kfree_skb(isac->dch.rx_skb);
-		isac->dch.rx_skb = NULL;
-	} else {
-		count = ReadISAC(isac, ISACX_RBCLD) & 0x1f;
-		if (count == 0)
-			count = 32;
-		isac_empty_fifo(isac, count);
-		if (isac->dch.rx_skb) {
-			skb_trim(isac->dch.rx_skb, isac->dch.rx_skb->len - 1);
-			pr_debug("%s: dchannel received %d\n", isac->name,
-				 isac->dch.rx_skb->len);
-			recv_Dchannel(&isac->dch);
-		}
-	}
-}
-
-irqreturn_t
-mISDNisac_irq(struct isac_hw *isac, u8 val)
-{
-	if (unlikely(!val))
-		return IRQ_NONE;
-	pr_debug("%s: ISAC interrupt %02x\n", isac->name, val);
-	if (isac->type & IPAC_TYPE_ISACX) {
-		if (val & ISACX__CIC)
-			isacsx_cic_irq(isac);
-		if (val & ISACX__ICD) {
-			val = ReadISAC(isac, ISACX_ISTAD);
-			pr_debug("%s: ISTAD %02x\n", isac->name, val);
-			if (val & ISACX_D_XDU) {
-				pr_debug("%s: ISAC XDU\n", isac->name);
-#ifdef ERROR_STATISTIC
-				isac->dch.err_tx++;
-#endif
-				isac_retransmit(isac);
-			}
-			if (val & ISACX_D_XMR) {
-				pr_debug("%s: ISAC XMR\n", isac->name);
-#ifdef ERROR_STATISTIC
-				isac->dch.err_tx++;
-#endif
-				isac_retransmit(isac);
-			}
-			if (val & ISACX_D_XPR)
-				isac_xpr_irq(isac);
-			if (val & ISACX_D_RFO) {
-				pr_debug("%s: ISAC RFO\n", isac->name);
-				WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC);
-			}
-			if (val & ISACX_D_RME)
-				isacsx_rme_irq(isac);
-			if (val & ISACX_D_RPF)
-				isac_empty_fifo(isac, 0x20);
-		}
-	} else {
-		if (val & 0x80)	/* RME */
-			isac_rme_irq(isac);
-		if (val & 0x40)	/* RPF */
-			isac_empty_fifo(isac, 32);
-		if (val & 0x10)	/* XPR */
-			isac_xpr_irq(isac);
-		if (val & 0x04)	/* CISQ */
-			isac_cisq_irq(isac);
-		if (val & 0x20)	/* RSC - never */
-			pr_debug("%s: ISAC RSC interrupt\n", isac->name);
-		if (val & 0x02)	/* SIN - never */
-			pr_debug("%s: ISAC SIN interrupt\n", isac->name);
-		if (val & 0x01) {	/* EXI */
-			val = ReadISAC(isac, ISAC_EXIR);
-			pr_debug("%s: ISAC EXIR %02x\n", isac->name, val);
-			if (val & 0x80)	/* XMR */
-				pr_debug("%s: ISAC XMR\n", isac->name);
-			if (val & 0x40) { /* XDU */
-				pr_debug("%s: ISAC XDU\n", isac->name);
-#ifdef ERROR_STATISTIC
-				isac->dch.err_tx++;
-#endif
-				isac_retransmit(isac);
-			}
-			if (val & 0x04)	/* MOS */
-				isac_mos_irq(isac);
-		}
-	}
-	return IRQ_HANDLED;
-}
-EXPORT_SYMBOL(mISDNisac_irq);
-
-static int
-isac_l1hw(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
-	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
-	struct isac_hw		*isac = container_of(dch, struct isac_hw, dch);
-	int			ret = -EINVAL;
-	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
-	u32			id;
-	u_long			flags;
-
-	switch (hh->prim) {
-	case PH_DATA_REQ:
-		spin_lock_irqsave(isac->hwlock, flags);
-		ret = dchannel_senddata(dch, skb);
-		if (ret > 0) { /* direct TX */
-			id = hh->id; /* skb can be freed */
-			isac_fill_fifo(isac);
-			ret = 0;
-			spin_unlock_irqrestore(isac->hwlock, flags);
-			queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
-		} else
-			spin_unlock_irqrestore(isac->hwlock, flags);
-		return ret;
-	case PH_ACTIVATE_REQ:
-		ret = l1_event(dch->l1, hh->prim);
-		break;
-	case PH_DEACTIVATE_REQ:
-		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
-		ret = l1_event(dch->l1, hh->prim);
-		break;
-	}
-
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-static int
-isac_ctrl(struct isac_hw *isac, u32 cmd, unsigned long para)
-{
-	u8 tl = 0;
-	unsigned long flags;
-	int ret = 0;
-
-	switch (cmd) {
-	case HW_TESTLOOP:
-		spin_lock_irqsave(isac->hwlock, flags);
-		if (!(isac->type & IPAC_TYPE_ISACX)) {
-			/* TODO: implement for IPAC_TYPE_ISACX */
-			if (para & 1) /* B1 */
-				tl |= 0x0c;
-			else if (para & 2) /* B2 */
-				tl |= 0x3;
-			/* we only support IOM2 mode */
-			WriteISAC(isac, ISAC_SPCR, tl);
-			if (tl)
-				WriteISAC(isac, ISAC_ADF1, 0x8);
-			else
-				WriteISAC(isac, ISAC_ADF1, 0x0);
-		}
-		spin_unlock_irqrestore(isac->hwlock, flags);
-		break;
-	case HW_TIMER3_VALUE:
-		ret = l1_event(isac->dch.l1, HW_TIMER3_VALUE | (para & 0xff));
-		break;
-	default:
-		pr_debug("%s: %s unknown command %x %lx\n", isac->name,
-			 __func__, cmd, para);
-		ret = -1;
-	}
-	return ret;
-}
-
-static int
-isac_l1cmd(struct dchannel *dch, u32 cmd)
-{
-	struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
-	u_long flags;
-
-	pr_debug("%s: cmd(%x) state(%02x)\n", isac->name, cmd, isac->state);
-	switch (cmd) {
-	case INFO3_P8:
-		spin_lock_irqsave(isac->hwlock, flags);
-		ph_command(isac, ISAC_CMD_AR8);
-		spin_unlock_irqrestore(isac->hwlock, flags);
-		break;
-	case INFO3_P10:
-		spin_lock_irqsave(isac->hwlock, flags);
-		ph_command(isac, ISAC_CMD_AR10);
-		spin_unlock_irqrestore(isac->hwlock, flags);
-		break;
-	case HW_RESET_REQ:
-		spin_lock_irqsave(isac->hwlock, flags);
-		if ((isac->state == ISAC_IND_EI) ||
-		    (isac->state == ISAC_IND_DR) ||
-		    (isac->state == ISAC_IND_DR6) ||
-		    (isac->state == ISAC_IND_RS))
-			ph_command(isac, ISAC_CMD_TIM);
-		else
-			ph_command(isac, ISAC_CMD_RS);
-		spin_unlock_irqrestore(isac->hwlock, flags);
-		break;
-	case HW_DEACT_REQ:
-		skb_queue_purge(&dch->squeue);
-		if (dch->tx_skb) {
-			dev_kfree_skb(dch->tx_skb);
-			dch->tx_skb = NULL;
-		}
-		dch->tx_idx = 0;
-		if (dch->rx_skb) {
-			dev_kfree_skb(dch->rx_skb);
-			dch->rx_skb = NULL;
-		}
-		test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
-		if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
-			timer_delete(&dch->timer);
-		break;
-	case HW_POWERUP_REQ:
-		spin_lock_irqsave(isac->hwlock, flags);
-		ph_command(isac, ISAC_CMD_TIM);
-		spin_unlock_irqrestore(isac->hwlock, flags);
-		break;
-	case PH_ACTIVATE_IND:
-		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
-		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			    GFP_ATOMIC);
-		break;
-	case PH_DEACTIVATE_IND:
-		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
-		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			    GFP_ATOMIC);
-		break;
-	default:
-		pr_debug("%s: %s unknown command %x\n", isac->name,
-			 __func__, cmd);
-		return -1;
-	}
-	return 0;
-}
-
-static void
-isac_release(struct isac_hw *isac)
-{
-	if (isac->type & IPAC_TYPE_ISACX)
-		WriteISAC(isac, ISACX_MASK, 0xff);
-	else if (isac->type != 0)
-		WriteISAC(isac, ISAC_MASK, 0xff);
-	if (isac->dch.timer.function != NULL) {
-		timer_delete(&isac->dch.timer);
-		isac->dch.timer.function = NULL;
-	}
-	kfree(isac->mon_rx);
-	isac->mon_rx = NULL;
-	kfree(isac->mon_tx);
-	isac->mon_tx = NULL;
-	if (isac->dch.l1)
-		l1_event(isac->dch.l1, CLOSE_CHANNEL);
-	mISDN_freedchannel(&isac->dch);
-}
-
-static void
-dbusy_timer_handler(struct timer_list *t)
-{
-	struct isac_hw *isac = timer_container_of(isac, t, dch.timer);
-	int rbch, star;
-	u_long flags;
-
-	if (test_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
-		spin_lock_irqsave(isac->hwlock, flags);
-		rbch = ReadISAC(isac, ISAC_RBCH);
-		star = ReadISAC(isac, ISAC_STAR);
-		pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n",
-			 isac->name, rbch, star);
-		if (rbch & ISAC_RBCH_XAC) /* D-Channel Busy */
-			test_and_set_bit(FLG_L1_BUSY, &isac->dch.Flags);
-		else {
-			/* discard frame; reset transceiver */
-			test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags);
-			if (isac->dch.tx_idx)
-				isac->dch.tx_idx = 0;
-			else
-				pr_info("%s: ISAC D-Channel Busy no tx_idx\n",
-					isac->name);
-			/* Transmitter reset */
-			WriteISAC(isac, ISAC_CMDR, 0x01);
-		}
-		spin_unlock_irqrestore(isac->hwlock, flags);
-	}
-}
-
-static int
-open_dchannel_caller(struct isac_hw *isac, struct channel_req *rq, void *caller)
-{
-	pr_debug("%s: %s dev(%d) open from %p\n", isac->name, __func__,
-		 isac->dch.dev.id, caller);
-	if (rq->protocol != ISDN_P_TE_S0)
-		return -EINVAL;
-	if (rq->adr.channel == 1)
-		/* E-Channel not supported */
-		return -EINVAL;
-	rq->ch = &isac->dch.dev.D;
-	rq->ch->protocol = rq->protocol;
-	if (isac->dch.state == 7)
-		_queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
-			    0, NULL, GFP_KERNEL);
-	return 0;
-}
-
-static int
-open_dchannel(struct isac_hw *isac, struct channel_req *rq)
-{
-	return open_dchannel_caller(isac, rq, __builtin_return_address(0));
-}
-
-static const char *ISACVer[] =
-{"2086/2186 V1.1", "2085 B1", "2085 B2",
- "2085 V2.3"};
-
-static int
-isac_init(struct isac_hw *isac)
-{
-	u8 val;
-	int err = 0;
-
-	if (!isac->dch.l1) {
-		err = create_l1(&isac->dch, isac_l1cmd);
-		if (err)
-			return err;
-	}
-	isac->mon_tx = NULL;
-	isac->mon_rx = NULL;
-	timer_setup(&isac->dch.timer, dbusy_timer_handler, 0);
-	isac->mocr = 0xaa;
-	if (isac->type & IPAC_TYPE_ISACX) {
-		/* Disable all IRQ */
-		WriteISAC(isac, ISACX_MASK, 0xff);
-		val = ReadISAC(isac, ISACX_STARD);
-		pr_debug("%s: ISACX STARD %x\n", isac->name, val);
-		val = ReadISAC(isac, ISACX_ISTAD);
-		pr_debug("%s: ISACX ISTAD %x\n", isac->name, val);
-		val = ReadISAC(isac, ISACX_ISTA);
-		pr_debug("%s: ISACX ISTA %x\n", isac->name, val);
-		/* clear LDD */
-		WriteISAC(isac, ISACX_TR_CONF0, 0x00);
-		/* enable transmitter */
-		WriteISAC(isac, ISACX_TR_CONF2, 0x00);
-		/* transparent mode 0, RAC, stop/go */
-		WriteISAC(isac, ISACX_MODED, 0xc9);
-		/* all HDLC IRQ unmasked */
-		val = ReadISAC(isac, ISACX_ID);
-		if (isac->dch.debug & DEBUG_HW)
-			pr_notice("%s: ISACX Design ID %x\n",
-				  isac->name, val & 0x3f);
-		val = ReadISAC(isac, ISACX_CIR0);
-		pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
-		isac->state = val >> 4;
-		isac_ph_state_change(isac);
-		ph_command(isac, ISAC_CMD_RS);
-		WriteISAC(isac, ISACX_MASK, IPACX__ON);
-		WriteISAC(isac, ISACX_MASKD, 0x00);
-	} else { /* old isac */
-		WriteISAC(isac, ISAC_MASK, 0xff);
-		val = ReadISAC(isac, ISAC_STAR);
-		pr_debug("%s: ISAC STAR %x\n", isac->name, val);
-		val = ReadISAC(isac, ISAC_MODE);
-		pr_debug("%s: ISAC MODE %x\n", isac->name, val);
-		val = ReadISAC(isac, ISAC_ADF2);
-		pr_debug("%s: ISAC ADF2 %x\n", isac->name, val);
-		val = ReadISAC(isac, ISAC_ISTA);
-		pr_debug("%s: ISAC ISTA %x\n", isac->name, val);
-		if (val & 0x01) {
-			val = ReadISAC(isac, ISAC_EXIR);
-			pr_debug("%s: ISAC EXIR %x\n", isac->name, val);
-		}
-		val = ReadISAC(isac, ISAC_RBCH);
-		if (isac->dch.debug & DEBUG_HW)
-			pr_notice("%s: ISAC version (%x): %s\n", isac->name,
-				  val, ISACVer[(val >> 5) & 3]);
-		isac->type |= ((val >> 5) & 3);
-		if (!isac->adf2)
-			isac->adf2 = 0x80;
-		if (!(isac->adf2 & 0x80)) { /* only IOM 2 Mode */
-			pr_info("%s: only support IOM2 mode but adf2=%02x\n",
-				isac->name, isac->adf2);
-			isac_release(isac);
-			return -EINVAL;
-		}
-		WriteISAC(isac, ISAC_ADF2, isac->adf2);
-		WriteISAC(isac, ISAC_SQXR, 0x2f);
-		WriteISAC(isac, ISAC_SPCR, 0x00);
-		WriteISAC(isac, ISAC_STCR, 0x70);
-		WriteISAC(isac, ISAC_MODE, 0xc9);
-		WriteISAC(isac, ISAC_TIMR, 0x00);
-		WriteISAC(isac, ISAC_ADF1, 0x00);
-		val = ReadISAC(isac, ISAC_CIR0);
-		pr_debug("%s: ISAC CIR0 %x\n", isac->name, val);
-		isac->state = (val >> 2) & 0xf;
-		isac_ph_state_change(isac);
-		ph_command(isac, ISAC_CMD_RS);
-		WriteISAC(isac, ISAC_MASK, 0);
-	}
-	return err;
-}
-
-int
-mISDNisac_init(struct isac_hw *isac, void *hw)
-{
-	mISDN_initdchannel(&isac->dch, MAX_DFRAME_LEN_L1, isac_ph_state_bh);
-	isac->dch.hw = hw;
-	isac->dch.dev.D.send = isac_l1hw;
-	isac->init = isac_init;
-	isac->release = isac_release;
-	isac->ctrl = isac_ctrl;
-	isac->open = open_dchannel;
-	isac->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0);
-	isac->dch.dev.nrbchan = 2;
-	return 0;
-}
-EXPORT_SYMBOL(mISDNisac_init);
-
-static void
-waitforCEC(struct hscx_hw *hx)
-{
-	u8 starb, to = 50;
-
-	while (to) {
-		starb = ReadHSCX(hx, IPAC_STARB);
-		if (!(starb & 0x04))
-			break;
-		udelay(1);
-		to--;
-	}
-	if (to < 50)
-		pr_debug("%s: B%1d CEC %d us\n", hx->ip->name, hx->bch.nr,
-			 50 - to);
-	if (!to)
-		pr_info("%s: B%1d CEC timeout\n", hx->ip->name, hx->bch.nr);
-}
-
-
-static void
-waitforXFW(struct hscx_hw *hx)
-{
-	u8 starb, to = 50;
-
-	while (to) {
-		starb = ReadHSCX(hx, IPAC_STARB);
-		if ((starb & 0x44) == 0x40)
-			break;
-		udelay(1);
-		to--;
-	}
-	if (to < 50)
-		pr_debug("%s: B%1d XFW %d us\n", hx->ip->name, hx->bch.nr,
-			 50 - to);
-	if (!to)
-		pr_info("%s: B%1d XFW timeout\n", hx->ip->name, hx->bch.nr);
-}
-
-static void
-hscx_cmdr(struct hscx_hw *hx, u8 cmd)
-{
-	if (hx->ip->type & IPAC_TYPE_IPACX)
-		WriteHSCX(hx, IPACX_CMDRB, cmd);
-	else {
-		waitforCEC(hx);
-		WriteHSCX(hx, IPAC_CMDRB, cmd);
-	}
-}
-
-static void
-hscx_empty_fifo(struct hscx_hw *hscx, u8 count)
-{
-	u8 *p;
-	int maxlen;
-
-	pr_debug("%s: B%1d %d\n", hscx->ip->name, hscx->bch.nr, count);
-	if (test_bit(FLG_RX_OFF, &hscx->bch.Flags)) {
-		hscx->bch.dropcnt += count;
-		hscx_cmdr(hscx, 0x80); /* RMC */
-		return;
-	}
-	maxlen = bchannel_get_rxbuf(&hscx->bch, count);
-	if (maxlen < 0) {
-		hscx_cmdr(hscx, 0x80); /* RMC */
-		if (hscx->bch.rx_skb)
-			skb_trim(hscx->bch.rx_skb, 0);
-		pr_warn("%s.B%d: No bufferspace for %d bytes\n",
-			hscx->ip->name, hscx->bch.nr, count);
-		return;
-	}
-	p = skb_put(hscx->bch.rx_skb, count);
-
-	if (hscx->ip->type & IPAC_TYPE_IPACX)
-		hscx->ip->read_fifo(hscx->ip->hw,
-				    hscx->off + IPACX_RFIFOB, p, count);
-	else
-		hscx->ip->read_fifo(hscx->ip->hw,
-				    hscx->off, p, count);
-
-	hscx_cmdr(hscx, 0x80); /* RMC */
-
-	if (hscx->bch.debug & DEBUG_HW_BFIFO) {
-		snprintf(hscx->log, 64, "B%1d-recv %s %d ",
-			 hscx->bch.nr, hscx->ip->name, count);
-		print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
-	}
-}
-
-static void
-hscx_fill_fifo(struct hscx_hw *hscx)
-{
-	int count, more;
-	u8 *p;
-
-	if (!hscx->bch.tx_skb) {
-		if (!test_bit(FLG_TX_EMPTY, &hscx->bch.Flags))
-			return;
-		count = hscx->fifo_size;
-		more = 1;
-		p = hscx->log;
-		memset(p, hscx->bch.fill[0], count);
-	} else {
-		count = hscx->bch.tx_skb->len - hscx->bch.tx_idx;
-		if (count <= 0)
-			return;
-		p = hscx->bch.tx_skb->data + hscx->bch.tx_idx;
-
-		more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0;
-		if (count > hscx->fifo_size) {
-			count = hscx->fifo_size;
-			more = 1;
-		}
-		pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr,
-			 count, hscx->bch.tx_idx, hscx->bch.tx_skb->len);
-		hscx->bch.tx_idx += count;
-	}
-	if (hscx->ip->type & IPAC_TYPE_IPACX)
-		hscx->ip->write_fifo(hscx->ip->hw,
-				     hscx->off + IPACX_XFIFOB, p, count);
-	else {
-		waitforXFW(hscx);
-		hscx->ip->write_fifo(hscx->ip->hw,
-				     hscx->off, p, count);
-	}
-	hscx_cmdr(hscx, more ? 0x08 : 0x0a);
-
-	if (hscx->bch.tx_skb && (hscx->bch.debug & DEBUG_HW_BFIFO)) {
-		snprintf(hscx->log, 64, "B%1d-send %s %d ",
-			 hscx->bch.nr, hscx->ip->name, count);
-		print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
-	}
-}
-
-static void
-hscx_xpr(struct hscx_hw *hx)
-{
-	if (hx->bch.tx_skb && hx->bch.tx_idx < hx->bch.tx_skb->len) {
-		hscx_fill_fifo(hx);
-	} else {
-		dev_kfree_skb(hx->bch.tx_skb);
-		if (get_next_bframe(&hx->bch)) {
-			hscx_fill_fifo(hx);
-			test_and_clear_bit(FLG_TX_EMPTY, &hx->bch.Flags);
-		} else if (test_bit(FLG_TX_EMPTY, &hx->bch.Flags)) {
-			hscx_fill_fifo(hx);
-		}
-	}
-}
-
-static void
-ipac_rme(struct hscx_hw *hx)
-{
-	int count;
-	u8 rstab;
-
-	if (hx->ip->type & IPAC_TYPE_IPACX)
-		rstab = ReadHSCX(hx, IPACX_RSTAB);
-	else
-		rstab = ReadHSCX(hx, IPAC_RSTAB);
-	pr_debug("%s: B%1d RSTAB %02x\n", hx->ip->name, hx->bch.nr, rstab);
-	if ((rstab & 0xf0) != 0xa0) {
-		/* !(VFR && !RDO && CRC && !RAB) */
-		if (!(rstab & 0x80)) {
-			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
-				pr_notice("%s: B%1d invalid frame\n",
-					  hx->ip->name, hx->bch.nr);
-		}
-		if (rstab & 0x40) {
-			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
-				pr_notice("%s: B%1d RDO proto=%x\n",
-					  hx->ip->name, hx->bch.nr,
-					  hx->bch.state);
-		}
-		if (!(rstab & 0x20)) {
-			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
-				pr_notice("%s: B%1d CRC error\n",
-					  hx->ip->name, hx->bch.nr);
-		}
-		hscx_cmdr(hx, 0x80); /* Do RMC */
-		return;
-	}
-	if (hx->ip->type & IPAC_TYPE_IPACX)
-		count = ReadHSCX(hx, IPACX_RBCLB);
-	else
-		count = ReadHSCX(hx, IPAC_RBCLB);
-	count &= (hx->fifo_size - 1);
-	if (count == 0)
-		count = hx->fifo_size;
-	hscx_empty_fifo(hx, count);
-	if (!hx->bch.rx_skb)
-		return;
-	if (hx->bch.rx_skb->len < 2) {
-		pr_debug("%s: B%1d frame too short %d\n",
-			 hx->ip->name, hx->bch.nr, hx->bch.rx_skb->len);
-		skb_trim(hx->bch.rx_skb, 0);
-	} else {
-		skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1);
-		recv_Bchannel(&hx->bch, 0, false);
-	}
-}
-
-static void
-ipac_irq(struct hscx_hw *hx, u8 ista)
-{
-	u8 istab, m, exirb = 0;
-
-	if (hx->ip->type & IPAC_TYPE_IPACX)
-		istab = ReadHSCX(hx, IPACX_ISTAB);
-	else if (hx->ip->type & IPAC_TYPE_IPAC) {
-		istab = ReadHSCX(hx, IPAC_ISTAB);
-		m = (hx->bch.nr & 1) ? IPAC__EXA : IPAC__EXB;
-		if (m & ista) {
-			exirb = ReadHSCX(hx, IPAC_EXIRB);
-			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
-				 hx->bch.nr, exirb);
-		}
-	} else if (hx->bch.nr & 2) { /* HSCX B */
-		if (ista & (HSCX__EXA | HSCX__ICA))
-			ipac_irq(&hx->ip->hscx[0], ista);
-		if (ista & HSCX__EXB) {
-			exirb = ReadHSCX(hx, IPAC_EXIRB);
-			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
-				 hx->bch.nr, exirb);
-		}
-		istab = ista & 0xF8;
-	} else { /* HSCX A */
-		istab = ReadHSCX(hx, IPAC_ISTAB);
-		if (ista & HSCX__EXA) {
-			exirb = ReadHSCX(hx, IPAC_EXIRB);
-			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
-				 hx->bch.nr, exirb);
-		}
-		istab = istab & 0xF8;
-	}
-	if (exirb & IPAC_B_XDU)
-		istab |= IPACX_B_XDU;
-	if (exirb & IPAC_B_RFO)
-		istab |= IPACX_B_RFO;
-	pr_debug("%s: B%1d ISTAB %02x\n", hx->ip->name, hx->bch.nr, istab);
-
-	if (!test_bit(FLG_ACTIVE, &hx->bch.Flags))
-		return;
-
-	if (istab & IPACX_B_RME)
-		ipac_rme(hx);
-
-	if (istab & IPACX_B_RPF) {
-		hscx_empty_fifo(hx, hx->fifo_size);
-		if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags))
-			recv_Bchannel(&hx->bch, 0, false);
-	}
-
-	if (istab & IPACX_B_RFO) {
-		pr_debug("%s: B%1d RFO error\n", hx->ip->name, hx->bch.nr);
-		hscx_cmdr(hx, 0x40);	/* RRES */
-	}
-
-	if (istab & IPACX_B_XPR)
-		hscx_xpr(hx);
-
-	if (istab & IPACX_B_XDU) {
-		if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) {
-			if (test_bit(FLG_FILLEMPTY, &hx->bch.Flags))
-				test_and_set_bit(FLG_TX_EMPTY, &hx->bch.Flags);
-			hscx_xpr(hx);
-			return;
-		}
-		pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name,
-			 hx->bch.nr, hx->bch.tx_idx);
-		hx->bch.tx_idx = 0;
-		hscx_cmdr(hx, 0x01);	/* XRES */
-	}
-}
-
-irqreturn_t
-mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
-{
-	int cnt = maxloop + 1;
-	u8 ista, istad;
-	struct isac_hw  *isac = &ipac->isac;
-
-	if (ipac->type & IPAC_TYPE_IPACX) {
-		ista = ReadIPAC(ipac, ISACX_ISTA);
-		while (ista && --cnt) {
-			pr_debug("%s: ISTA %02x\n", ipac->name, ista);
-			if (ista & IPACX__ICA)
-				ipac_irq(&ipac->hscx[0], ista);
-			if (ista & IPACX__ICB)
-				ipac_irq(&ipac->hscx[1], ista);
-			if (ista & (ISACX__ICD | ISACX__CIC))
-				mISDNisac_irq(&ipac->isac, ista);
-			ista = ReadIPAC(ipac, ISACX_ISTA);
-		}
-	} else if (ipac->type & IPAC_TYPE_IPAC) {
-		ista = ReadIPAC(ipac, IPAC_ISTA);
-		while (ista && --cnt) {
-			pr_debug("%s: ISTA %02x\n", ipac->name, ista);
-			if (ista & (IPAC__ICD | IPAC__EXD)) {
-				istad = ReadISAC(isac, ISAC_ISTA);
-				pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
-				if (istad & IPAC_D_TIN2)
-					pr_debug("%s TIN2 irq\n", ipac->name);
-				if (ista & IPAC__EXD)
-					istad |= 1; /* ISAC EXI */
-				mISDNisac_irq(isac, istad);
-			}
-			if (ista & (IPAC__ICA | IPAC__EXA))
-				ipac_irq(&ipac->hscx[0], ista);
-			if (ista & (IPAC__ICB | IPAC__EXB))
-				ipac_irq(&ipac->hscx[1], ista);
-			ista = ReadIPAC(ipac, IPAC_ISTA);
-		}
-	} else if (ipac->type & IPAC_TYPE_HSCX) {
-		while (--cnt) {
-			ista = ReadIPAC(ipac, IPAC_ISTAB + ipac->hscx[1].off);
-			pr_debug("%s: B2 ISTA %02x\n", ipac->name, ista);
-			if (ista)
-				ipac_irq(&ipac->hscx[1], ista);
-			istad = ReadISAC(isac, ISAC_ISTA);
-			pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
-			if (istad)
-				mISDNisac_irq(isac, istad);
-			if (0 == (ista | istad))
-				break;
-		}
-	}
-	if (cnt > maxloop) /* only for ISAC/HSCX without PCI IRQ test */
-		return IRQ_NONE;
-	if (cnt < maxloop)
-		pr_debug("%s: %d irqloops cpu%d\n", ipac->name,
-			 maxloop - cnt, smp_processor_id());
-	if (maxloop && !cnt)
-		pr_notice("%s: %d IRQ LOOP cpu%d\n", ipac->name,
-			  maxloop, smp_processor_id());
-	return IRQ_HANDLED;
-}
-EXPORT_SYMBOL(mISDNipac_irq);
-
-static int
-hscx_mode(struct hscx_hw *hscx, u32 bprotocol)
-{
-	pr_debug("%s: HSCX %c protocol %x-->%x ch %d\n", hscx->ip->name,
-		 '@' + hscx->bch.nr, hscx->bch.state, bprotocol, hscx->bch.nr);
-	if (hscx->ip->type & IPAC_TYPE_IPACX) {
-		if (hscx->bch.nr & 1) { /* B1 and ICA */
-			WriteIPAC(hscx->ip, ISACX_BCHA_TSDP_BC1, 0x80);
-			WriteIPAC(hscx->ip, ISACX_BCHA_CR, 0x88);
-		} else { /* B2 and ICB */
-			WriteIPAC(hscx->ip, ISACX_BCHB_TSDP_BC1, 0x81);
-			WriteIPAC(hscx->ip, ISACX_BCHB_CR, 0x88);
-		}
-		switch (bprotocol) {
-		case ISDN_P_NONE: /* init */
-			WriteHSCX(hscx, IPACX_MODEB, 0xC0);	/* rec off */
-			WriteHSCX(hscx, IPACX_EXMB,  0x30);	/* std adj. */
-			WriteHSCX(hscx, IPACX_MASKB, 0xFF);	/* ints off */
-			hscx_cmdr(hscx, 0x41);
-			test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
-			test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
-			break;
-		case ISDN_P_B_RAW:
-			WriteHSCX(hscx, IPACX_MODEB, 0x88);	/* ex trans */
-			WriteHSCX(hscx, IPACX_EXMB,  0x00);	/* trans */
-			hscx_cmdr(hscx, 0x41);
-			WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
-			test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
-			break;
-		case ISDN_P_B_HDLC:
-			WriteHSCX(hscx, IPACX_MODEB, 0xC0);	/* trans */
-			WriteHSCX(hscx, IPACX_EXMB,  0x00);	/* hdlc,crc */
-			hscx_cmdr(hscx, 0x41);
-			WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
-			test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
-			break;
-		default:
-			pr_info("%s: protocol not known %x\n", hscx->ip->name,
-				bprotocol);
-			return -ENOPROTOOPT;
-		}
-	} else if (hscx->ip->type & IPAC_TYPE_IPAC) { /* IPAC */
-		WriteHSCX(hscx, IPAC_CCR1, 0x82);
-		WriteHSCX(hscx, IPAC_CCR2, 0x30);
-		WriteHSCX(hscx, IPAC_XCCR, 0x07);
-		WriteHSCX(hscx, IPAC_RCCR, 0x07);
-		WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
-		WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
-		switch (bprotocol) {
-		case ISDN_P_NONE:
-			WriteHSCX(hscx, IPAC_TSAX, 0x1F);
-			WriteHSCX(hscx, IPAC_TSAR, 0x1F);
-			WriteHSCX(hscx, IPAC_MODEB, 0x84);
-			WriteHSCX(hscx, IPAC_CCR1, 0x82);
-			WriteHSCX(hscx, IPAC_MASKB, 0xFF);	/* ints off */
-			test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
-			test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
-			break;
-		case ISDN_P_B_RAW:
-			WriteHSCX(hscx, IPAC_MODEB, 0xe4);	/* ex trans */
-			WriteHSCX(hscx, IPAC_CCR1, 0x82);
-			hscx_cmdr(hscx, 0x41);
-			WriteHSCX(hscx, IPAC_MASKB, 0);
-			test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
-			break;
-		case ISDN_P_B_HDLC:
-			WriteHSCX(hscx, IPAC_MODEB, 0x8c);
-			WriteHSCX(hscx, IPAC_CCR1, 0x8a);
-			hscx_cmdr(hscx, 0x41);
-			WriteHSCX(hscx, IPAC_MASKB, 0);
-			test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
-			break;
-		default:
-			pr_info("%s: protocol not known %x\n", hscx->ip->name,
-				bprotocol);
-			return -ENOPROTOOPT;
-		}
-	} else if (hscx->ip->type & IPAC_TYPE_HSCX) { /* HSCX */
-		WriteHSCX(hscx, IPAC_CCR1, 0x85);
-		WriteHSCX(hscx, IPAC_CCR2, 0x30);
-		WriteHSCX(hscx, IPAC_XCCR, 0x07);
-		WriteHSCX(hscx, IPAC_RCCR, 0x07);
-		WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
-		WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
-		switch (bprotocol) {
-		case ISDN_P_NONE:
-			WriteHSCX(hscx, IPAC_TSAX, 0x1F);
-			WriteHSCX(hscx, IPAC_TSAR, 0x1F);
-			WriteHSCX(hscx, IPAC_MODEB, 0x84);
-			WriteHSCX(hscx, IPAC_CCR1, 0x85);
-			WriteHSCX(hscx, IPAC_MASKB, 0xFF);	/* ints off */
-			test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
-			test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
-			break;
-		case ISDN_P_B_RAW:
-			WriteHSCX(hscx, IPAC_MODEB, 0xe4);	/* ex trans */
-			WriteHSCX(hscx, IPAC_CCR1, 0x85);
-			hscx_cmdr(hscx, 0x41);
-			WriteHSCX(hscx, IPAC_MASKB, 0);
-			test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
-			break;
-		case ISDN_P_B_HDLC:
-			WriteHSCX(hscx, IPAC_MODEB, 0x8c);
-			WriteHSCX(hscx, IPAC_CCR1, 0x8d);
-			hscx_cmdr(hscx, 0x41);
-			WriteHSCX(hscx, IPAC_MASKB, 0);
-			test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
-			break;
-		default:
-			pr_info("%s: protocol not known %x\n", hscx->ip->name,
-				bprotocol);
-			return -ENOPROTOOPT;
-		}
-	} else
-		return -EINVAL;
-	hscx->bch.state = bprotocol;
-	return 0;
-}
-
-static int
-hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct bchannel *bch = container_of(ch, struct bchannel, ch);
-	struct hscx_hw	*hx = container_of(bch, struct hscx_hw, bch);
-	int ret = -EINVAL;
-	struct mISDNhead *hh = mISDN_HEAD_P(skb);
-	unsigned long flags;
-
-	switch (hh->prim) {
-	case PH_DATA_REQ:
-		spin_lock_irqsave(hx->ip->hwlock, flags);
-		ret = bchannel_senddata(bch, skb);
-		if (ret > 0) { /* direct TX */
-			ret = 0;
-			hscx_fill_fifo(hx);
-		}
-		spin_unlock_irqrestore(hx->ip->hwlock, flags);
-		return ret;
-	case PH_ACTIVATE_REQ:
-		spin_lock_irqsave(hx->ip->hwlock, flags);
-		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
-			ret = hscx_mode(hx, ch->protocol);
-		else
-			ret = 0;
-		spin_unlock_irqrestore(hx->ip->hwlock, flags);
-		if (!ret)
-			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-				    NULL, GFP_KERNEL);
-		break;
-	case PH_DEACTIVATE_REQ:
-		spin_lock_irqsave(hx->ip->hwlock, flags);
-		mISDN_clear_bchannel(bch);
-		hscx_mode(hx, ISDN_P_NONE);
-		spin_unlock_irqrestore(hx->ip->hwlock, flags);
-		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			    NULL, GFP_KERNEL);
-		ret = 0;
-		break;
-	default:
-		pr_info("%s: %s unknown prim(%x,%x)\n",
-			hx->ip->name, __func__, hh->prim, hh->id);
-		ret = -EINVAL;
-	}
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-static int
-channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
-{
-	return mISDN_ctrl_bchannel(bch, cq);
-}
-
-static int
-hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
-{
-	struct bchannel *bch = container_of(ch, struct bchannel, ch);
-	struct hscx_hw	*hx = container_of(bch, struct hscx_hw, bch);
-	int ret = -EINVAL;
-	u_long flags;
-
-	pr_debug("%s: %s cmd:%x %p\n", hx->ip->name, __func__, cmd, arg);
-	switch (cmd) {
-	case CLOSE_CHANNEL:
-		test_and_clear_bit(FLG_OPEN, &bch->Flags);
-		cancel_work_sync(&bch->workq);
-		spin_lock_irqsave(hx->ip->hwlock, flags);
-		mISDN_clear_bchannel(bch);
-		hscx_mode(hx, ISDN_P_NONE);
-		spin_unlock_irqrestore(hx->ip->hwlock, flags);
-		ch->protocol = ISDN_P_NONE;
-		ch->peer = NULL;
-		module_put(hx->ip->owner);
-		ret = 0;
-		break;
-	case CONTROL_CHANNEL:
-		ret = channel_bctrl(bch, arg);
-		break;
-	default:
-		pr_info("%s: %s unknown prim(%x)\n",
-			hx->ip->name, __func__, cmd);
-	}
-	return ret;
-}
-
-static void
-free_ipac(struct ipac_hw *ipac)
-{
-	isac_release(&ipac->isac);
-}
-
-static const char *HSCXVer[] =
-{"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
- "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
-
-
-
-static void
-hscx_init(struct hscx_hw *hx)
-{
-	u8 val;
-
-	WriteHSCX(hx, IPAC_RAH2, 0xFF);
-	WriteHSCX(hx, IPAC_XBCH, 0x00);
-	WriteHSCX(hx, IPAC_RLCR, 0x00);
-
-	if (hx->ip->type & IPAC_TYPE_HSCX) {
-		WriteHSCX(hx, IPAC_CCR1, 0x85);
-		val = ReadHSCX(hx, HSCX_VSTR);
-		pr_debug("%s: HSCX VSTR %02x\n", hx->ip->name, val);
-		if (hx->bch.debug & DEBUG_HW)
-			pr_notice("%s: HSCX version %s\n", hx->ip->name,
-				  HSCXVer[val & 0x0f]);
-	} else
-		WriteHSCX(hx, IPAC_CCR1, 0x82);
-	WriteHSCX(hx, IPAC_CCR2, 0x30);
-	WriteHSCX(hx, IPAC_XCCR, 0x07);
-	WriteHSCX(hx, IPAC_RCCR, 0x07);
-}
-
-static int
-ipac_init(struct ipac_hw *ipac)
-{
-	u8 val;
-
-	if (ipac->type & IPAC_TYPE_HSCX) {
-		hscx_init(&ipac->hscx[0]);
-		hscx_init(&ipac->hscx[1]);
-		val = ReadIPAC(ipac, IPAC_ID);
-	} else if (ipac->type & IPAC_TYPE_IPAC) {
-		hscx_init(&ipac->hscx[0]);
-		hscx_init(&ipac->hscx[1]);
-		WriteIPAC(ipac, IPAC_MASK, IPAC__ON);
-		val = ReadIPAC(ipac, IPAC_CONF);
-		/* conf is default 0, but can be overwritten by card setup */
-		pr_debug("%s: IPAC CONF %02x/%02x\n", ipac->name,
-			 val, ipac->conf);
-		WriteIPAC(ipac, IPAC_CONF, ipac->conf);
-		val = ReadIPAC(ipac, IPAC_ID);
-		if (ipac->hscx[0].bch.debug & DEBUG_HW)
-			pr_notice("%s: IPAC Design ID %02x\n", ipac->name, val);
-	}
-	/* nothing special for IPACX to do here */
-	return isac_init(&ipac->isac);
-}
-
-static int
-open_bchannel(struct ipac_hw *ipac, struct channel_req *rq)
-{
-	struct bchannel		*bch;
-
-	if (rq->adr.channel == 0 || rq->adr.channel > 2)
-		return -EINVAL;
-	if (rq->protocol == ISDN_P_NONE)
-		return -EINVAL;
-	bch = &ipac->hscx[rq->adr.channel - 1].bch;
-	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
-		return -EBUSY; /* b-channel can be only open once */
-	test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
-	bch->ch.protocol = rq->protocol;
-	rq->ch = &bch->ch;
-	return 0;
-}
-
-static int
-channel_ctrl(struct ipac_hw *ipac, struct mISDN_ctrl_req *cq)
-{
-	int	ret = 0;
-
-	switch (cq->op) {
-	case MISDN_CTRL_GETOP:
-		cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
-		break;
-	case MISDN_CTRL_LOOP:
-		/* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
-		if (cq->channel < 0 || cq->channel > 3) {
-			ret = -EINVAL;
-			break;
-		}
-		ret = ipac->ctrl(ipac, HW_TESTLOOP, cq->channel);
-		break;
-	case MISDN_CTRL_L1_TIMER3:
-		ret = ipac->isac.ctrl(&ipac->isac, HW_TIMER3_VALUE, cq->p1);
-		break;
-	default:
-		pr_info("%s: unknown CTRL OP %x\n", ipac->name, cq->op);
-		ret = -EINVAL;
-		break;
-	}
-	return ret;
-}
-
-static int
-ipac_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
-{
-	struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
-	struct dchannel *dch = container_of(dev, struct dchannel, dev);
-	struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
-	struct ipac_hw *ipac = container_of(isac, struct ipac_hw, isac);
-	struct channel_req *rq;
-	int err = 0;
-
-	pr_debug("%s: DCTRL: %x %p\n", ipac->name, cmd, arg);
-	switch (cmd) {
-	case OPEN_CHANNEL:
-		rq = arg;
-		if (rq->protocol == ISDN_P_TE_S0)
-			err = open_dchannel_caller(isac, rq, __builtin_return_address(0));
-		else
-			err = open_bchannel(ipac, rq);
-		if (err)
-			break;
-		if (!try_module_get(ipac->owner))
-			pr_info("%s: cannot get module\n", ipac->name);
-		break;
-	case CLOSE_CHANNEL:
-		pr_debug("%s: dev(%d) close from %p\n", ipac->name,
-			 dch->dev.id, __builtin_return_address(0));
-		module_put(ipac->owner);
-		break;
-	case CONTROL_CHANNEL:
-		err = channel_ctrl(ipac, arg);
-		break;
-	default:
-		pr_debug("%s: unknown DCTRL command %x\n", ipac->name, cmd);
-		return -EINVAL;
-	}
-	return err;
-}
-
-u32
-mISDNipac_init(struct ipac_hw *ipac, void *hw)
-{
-	u32 ret;
-	u8 i;
-
-	ipac->hw = hw;
-	if (ipac->isac.dch.debug & DEBUG_HW)
-		pr_notice("%s: ipac type %x\n", ipac->name, ipac->type);
-	if (ipac->type & IPAC_TYPE_HSCX) {
-		ipac->isac.type = IPAC_TYPE_ISAC;
-		ipac->hscx[0].off = 0;
-		ipac->hscx[1].off = 0x40;
-		ipac->hscx[0].fifo_size = 32;
-		ipac->hscx[1].fifo_size = 32;
-	} else if (ipac->type & IPAC_TYPE_IPAC) {
-		ipac->isac.type = IPAC_TYPE_IPAC | IPAC_TYPE_ISAC;
-		ipac->hscx[0].off = 0;
-		ipac->hscx[1].off = 0x40;
-		ipac->hscx[0].fifo_size = 64;
-		ipac->hscx[1].fifo_size = 64;
-	} else if (ipac->type & IPAC_TYPE_IPACX) {
-		ipac->isac.type = IPAC_TYPE_IPACX | IPAC_TYPE_ISACX;
-		ipac->hscx[0].off = IPACX_OFF_ICA;
-		ipac->hscx[1].off = IPACX_OFF_ICB;
-		ipac->hscx[0].fifo_size = 64;
-		ipac->hscx[1].fifo_size = 64;
-	} else
-		return 0;
-
-	mISDNisac_init(&ipac->isac, hw);
-
-	ipac->isac.dch.dev.D.ctrl = ipac_dctrl;
-
-	for (i = 0; i < 2; i++) {
-		ipac->hscx[i].bch.nr = i + 1;
-		set_channelmap(i + 1, ipac->isac.dch.dev.channelmap);
-		list_add(&ipac->hscx[i].bch.ch.list,
-			 &ipac->isac.dch.dev.bchannels);
-		mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM,
-				   ipac->hscx[i].fifo_size);
-		ipac->hscx[i].bch.ch.nr = i + 1;
-		ipac->hscx[i].bch.ch.send = &hscx_l2l1;
-		ipac->hscx[i].bch.ch.ctrl = hscx_bctrl;
-		ipac->hscx[i].bch.hw = hw;
-		ipac->hscx[i].ip = ipac;
-		/* default values for IOM time slots
-		 * can be overwritten by card */
-		ipac->hscx[i].slot = (i == 0) ? 0x2f : 0x03;
-	}
-
-	ipac->init = ipac_init;
-	ipac->release = free_ipac;
-
-	ret =	(1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
-	return ret;
-}
-EXPORT_SYMBOL(mISDNipac_init);
-
-static int __init
-isac_mod_init(void)
-{
-	pr_notice("mISDNipac module version %s\n", ISAC_REV);
-	return 0;
-}
-
-static void __exit
-isac_mod_cleanup(void)
-{
-	pr_notice("mISDNipac module unloaded\n");
-}
-module_init(isac_mod_init);
-module_exit(isac_mod_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c
deleted file mode 100644
index dace91ba412b..000000000000
--- a/drivers/isdn/hardware/mISDN/mISDNisar.c
+++ /dev/null
@@ -1,1694 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * mISDNisar.c   ISAR (Siemens PSB 7110) specific functions
- *
- * Author Karsten Keil (keil@isdn4linux.de)
- *
- * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
- */
-
-/* define this to enable static debug messages, if you kernel supports
- * dynamic debugging, you should use debugfs for this
- */
-/* #define DEBUG */
-
-#include <linux/gfp.h>
-#include <linux/delay.h>
-#include <linux/vmalloc.h>
-#include <linux/mISDNhw.h>
-#include <linux/module.h>
-#include "isar.h"
-
-#define ISAR_REV	"2.1"
-
-MODULE_AUTHOR("Karsten Keil");
-MODULE_DESCRIPTION("mISDN driver for ISAR (Siemens PSB 7110) specific functions");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(ISAR_REV);
-
-#define DEBUG_HW_FIRMWARE_FIFO	0x10000
-
-static const u8 faxmodulation[] = {3, 24, 48, 72, 73, 74, 96, 97, 98, 121,
-				   122, 145, 146};
-#define FAXMODCNT 13
-
-static void isar_setup(struct isar_hw *);
-
-static inline int
-waitforHIA(struct isar_hw *isar, int timeout)
-{
-	int t = timeout;
-	u8 val = isar->read_reg(isar->hw, ISAR_HIA);
-
-	while ((val & 1) && t) {
-		udelay(1);
-		t--;
-		val = isar->read_reg(isar->hw, ISAR_HIA);
-	}
-	pr_debug("%s: HIA after %dus\n", isar->name, timeout - t);
-	return timeout;
-}
-
-/*
- * send msg to ISAR mailbox
- * if msg is NULL use isar->buf
- */
-static int
-send_mbox(struct isar_hw *isar, u8 his, u8 creg, u8 len, u8 *msg)
-{
-	if (!waitforHIA(isar, 1000))
-		return 0;
-	pr_debug("send_mbox(%02x,%02x,%d)\n", his, creg, len);
-	isar->write_reg(isar->hw, ISAR_CTRL_H, creg);
-	isar->write_reg(isar->hw, ISAR_CTRL_L, len);
-	isar->write_reg(isar->hw, ISAR_WADR, 0);
-	if (!msg)
-		msg = isar->buf;
-	if (msg && len) {
-		isar->write_fifo(isar->hw, ISAR_MBOX, msg, len);
-		if (isar->ch[0].bch.debug & DEBUG_HW_BFIFO) {
-			int l = 0;
-
-			while (l < (int)len) {
-				hex_dump_to_buffer(msg + l, len - l, 32, 1,
-						   isar->log, 256, 1);
-				pr_debug("%s: %s %02x: %s\n", isar->name,
-					 __func__, l, isar->log);
-				l += 32;
-			}
-		}
-	}
-	isar->write_reg(isar->hw, ISAR_HIS, his);
-	waitforHIA(isar, 1000);
-	return 1;
-}
-
-/*
- * receive message from ISAR mailbox
- * if msg is NULL use isar->buf
- */
-static void
-rcv_mbox(struct isar_hw *isar, u8 *msg)
-{
-	if (!msg)
-		msg = isar->buf;
-	isar->write_reg(isar->hw, ISAR_RADR, 0);
-	if (msg && isar->clsb) {
-		isar->read_fifo(isar->hw, ISAR_MBOX, msg, isar->clsb);
-		if (isar->ch[0].bch.debug & DEBUG_HW_BFIFO) {
-			int l = 0;
-
-			while (l < (int)isar->clsb) {
-				hex_dump_to_buffer(msg + l, isar->clsb - l, 32,
-						   1, isar->log, 256, 1);
-				pr_debug("%s: %s %02x: %s\n", isar->name,
-					 __func__, l, isar->log);
-				l += 32;
-			}
-		}
-	}
-	isar->write_reg(isar->hw, ISAR_IIA, 0);
-}
-
-static inline void
-get_irq_infos(struct isar_hw *isar)
-{
-	isar->iis = isar->read_reg(isar->hw, ISAR_IIS);
-	isar->cmsb = isar->read_reg(isar->hw, ISAR_CTRL_H);
-	isar->clsb = isar->read_reg(isar->hw, ISAR_CTRL_L);
-	pr_debug("%s: rcv_mbox(%02x,%02x,%d)\n", isar->name,
-		 isar->iis, isar->cmsb, isar->clsb);
-}
-
-/*
- * poll answer message from ISAR mailbox
- * should be used only with ISAR IRQs disabled before DSP was started
- *
- */
-static int
-poll_mbox(struct isar_hw *isar, int maxdelay)
-{
-	int t = maxdelay;
-	u8 irq;
-
-	irq = isar->read_reg(isar->hw, ISAR_IRQBIT);
-	while (t && !(irq & ISAR_IRQSTA)) {
-		udelay(1);
-		t--;
-	}
-	if (t)	{
-		get_irq_infos(isar);
-		rcv_mbox(isar, NULL);
-	}
-	pr_debug("%s: pulled %d bytes after %d us\n",
-		 isar->name, isar->clsb, maxdelay - t);
-	return t;
-}
-
-static int
-ISARVersion(struct isar_hw *isar)
-{
-	int ver;
-
-	/* disable ISAR IRQ */
-	isar->write_reg(isar->hw, ISAR_IRQBIT, 0);
-	isar->buf[0] = ISAR_MSG_HWVER;
-	isar->buf[1] = 0;
-	isar->buf[2] = 1;
-	if (!send_mbox(isar, ISAR_HIS_VNR, 0, 3, NULL))
-		return -1;
-	if (!poll_mbox(isar, 1000))
-		return -2;
-	if (isar->iis == ISAR_IIS_VNR) {
-		if (isar->clsb == 1) {
-			ver = isar->buf[0] & 0xf;
-			return ver;
-		}
-		return -3;
-	}
-	return -4;
-}
-
-static int
-load_firmware(struct isar_hw *isar, const u8 *buf, int size)
-{
-	u32	saved_debug = isar->ch[0].bch.debug;
-	int	ret, cnt;
-	u8	nom, noc;
-	u16	left, val, *sp = (u16 *)buf;
-	u8	*mp;
-	u_long	flags;
-
-	struct {
-		u16 sadr;
-		u16 len;
-		u16 d_key;
-	} blk_head;
-
-	if (1 != isar->version) {
-		pr_err("%s: ISAR wrong version %d firmware download aborted\n",
-		       isar->name, isar->version);
-		return -EINVAL;
-	}
-	if (!(saved_debug & DEBUG_HW_FIRMWARE_FIFO))
-		isar->ch[0].bch.debug &= ~DEBUG_HW_BFIFO;
-	pr_debug("%s: load firmware %d words (%d bytes)\n",
-		 isar->name, size / 2, size);
-	cnt = 0;
-	size /= 2;
-	/* disable ISAR IRQ */
-	spin_lock_irqsave(isar->hwlock, flags);
-	isar->write_reg(isar->hw, ISAR_IRQBIT, 0);
-	spin_unlock_irqrestore(isar->hwlock, flags);
-	while (cnt < size) {
-		blk_head.sadr = le16_to_cpu(*sp++);
-		blk_head.len = le16_to_cpu(*sp++);
-		blk_head.d_key = le16_to_cpu(*sp++);
-		cnt += 3;
-		pr_debug("ISAR firmware block (%#x,%d,%#x)\n",
-			 blk_head.sadr, blk_head.len, blk_head.d_key & 0xff);
-		left = blk_head.len;
-		if (cnt + left > size) {
-			pr_info("%s: firmware error have %d need %d words\n",
-				isar->name, size, cnt + left);
-			ret = -EINVAL;
-			goto reterrflg;
-		}
-		spin_lock_irqsave(isar->hwlock, flags);
-		if (!send_mbox(isar, ISAR_HIS_DKEY, blk_head.d_key & 0xff,
-			       0, NULL)) {
-			pr_info("ISAR send_mbox dkey failed\n");
-			ret = -ETIME;
-			goto reterror;
-		}
-		if (!poll_mbox(isar, 1000)) {
-			pr_warn("ISAR poll_mbox dkey failed\n");
-			ret = -ETIME;
-			goto reterror;
-		}
-		spin_unlock_irqrestore(isar->hwlock, flags);
-		if ((isar->iis != ISAR_IIS_DKEY) || isar->cmsb || isar->clsb) {
-			pr_info("ISAR wrong dkey response (%x,%x,%x)\n",
-				isar->iis, isar->cmsb, isar->clsb);
-			ret = 1;
-			goto reterrflg;
-		}
-		while (left > 0) {
-			if (left > 126)
-				noc = 126;
-			else
-				noc = left;
-			nom = (2 * noc) + 3;
-			mp  = isar->buf;
-			/* the ISAR is big endian */
-			*mp++ = blk_head.sadr >> 8;
-			*mp++ = blk_head.sadr & 0xFF;
-			left -= noc;
-			cnt += noc;
-			*mp++ = noc;
-			pr_debug("%s: load %3d words at %04x\n", isar->name,
-				 noc, blk_head.sadr);
-			blk_head.sadr += noc;
-			while (noc) {
-				val = le16_to_cpu(*sp++);
-				*mp++ = val >> 8;
-				*mp++ = val & 0xFF;
-				noc--;
-			}
-			spin_lock_irqsave(isar->hwlock, flags);
-			if (!send_mbox(isar, ISAR_HIS_FIRM, 0, nom, NULL)) {
-				pr_info("ISAR send_mbox prog failed\n");
-				ret = -ETIME;
-				goto reterror;
-			}
-			if (!poll_mbox(isar, 1000)) {
-				pr_info("ISAR poll_mbox prog failed\n");
-				ret = -ETIME;
-				goto reterror;
-			}
-			spin_unlock_irqrestore(isar->hwlock, flags);
-			if ((isar->iis != ISAR_IIS_FIRM) ||
-			    isar->cmsb || isar->clsb) {
-				pr_info("ISAR wrong prog response (%x,%x,%x)\n",
-					isar->iis, isar->cmsb, isar->clsb);
-				ret = -EIO;
-				goto reterrflg;
-			}
-		}
-		pr_debug("%s: ISAR firmware block %d words loaded\n",
-			 isar->name, blk_head.len);
-	}
-	isar->ch[0].bch.debug = saved_debug;
-	/* 10ms delay */
-	cnt = 10;
-	while (cnt--)
-		mdelay(1);
-	isar->buf[0] = 0xff;
-	isar->buf[1] = 0xfe;
-	isar->bstat = 0;
-	spin_lock_irqsave(isar->hwlock, flags);
-	if (!send_mbox(isar, ISAR_HIS_STDSP, 0, 2, NULL)) {
-		pr_info("ISAR send_mbox start dsp failed\n");
-		ret = -ETIME;
-		goto reterror;
-	}
-	if (!poll_mbox(isar, 1000)) {
-		pr_info("ISAR poll_mbox start dsp failed\n");
-		ret = -ETIME;
-		goto reterror;
-	}
-	if ((isar->iis != ISAR_IIS_STDSP) || isar->cmsb || isar->clsb) {
-		pr_info("ISAR wrong start dsp response (%x,%x,%x)\n",
-			isar->iis, isar->cmsb, isar->clsb);
-		ret = -EIO;
-		goto reterror;
-	} else
-		pr_debug("%s: ISAR start dsp success\n", isar->name);
-
-	/* NORMAL mode entered */
-	/* Enable IRQs of ISAR */
-	isar->write_reg(isar->hw, ISAR_IRQBIT, ISAR_IRQSTA);
-	spin_unlock_irqrestore(isar->hwlock, flags);
-	cnt = 1000; /* max 1s */
-	while ((!isar->bstat) && cnt) {
-		mdelay(1);
-		cnt--;
-	}
-	if (!cnt) {
-		pr_info("ISAR no general status event received\n");
-		ret = -ETIME;
-		goto reterrflg;
-	} else
-		pr_debug("%s: ISAR general status event %x\n",
-			 isar->name, isar->bstat);
-	/* 10ms delay */
-	cnt = 10;
-	while (cnt--)
-		mdelay(1);
-	isar->iis = 0;
-	spin_lock_irqsave(isar->hwlock, flags);
-	if (!send_mbox(isar, ISAR_HIS_DIAG, ISAR_CTRL_STST, 0, NULL)) {
-		pr_info("ISAR send_mbox self tst failed\n");
-		ret = -ETIME;
-		goto reterror;
-	}
-	spin_unlock_irqrestore(isar->hwlock, flags);
-	cnt = 10000; /* max 100 ms */
-	while ((isar->iis != ISAR_IIS_DIAG) && cnt) {
-		udelay(10);
-		cnt--;
-	}
-	mdelay(1);
-	if (!cnt) {
-		pr_info("ISAR no self tst response\n");
-		ret = -ETIME;
-		goto reterrflg;
-	}
-	if ((isar->cmsb == ISAR_CTRL_STST) && (isar->clsb == 1)
-	    && (isar->buf[0] == 0))
-		pr_debug("%s: ISAR selftest OK\n", isar->name);
-	else {
-		pr_info("ISAR selftest not OK %x/%x/%x\n",
-			isar->cmsb, isar->clsb, isar->buf[0]);
-		ret = -EIO;
-		goto reterrflg;
-	}
-	spin_lock_irqsave(isar->hwlock, flags);
-	isar->iis = 0;
-	if (!send_mbox(isar, ISAR_HIS_DIAG, ISAR_CTRL_SWVER, 0, NULL)) {
-		pr_info("ISAR RQST SVN failed\n");
-		ret = -ETIME;
-		goto reterror;
-	}
-	spin_unlock_irqrestore(isar->hwlock, flags);
-	cnt = 30000; /* max 300 ms */
-	while ((isar->iis != ISAR_IIS_DIAG) && cnt) {
-		udelay(10);
-		cnt--;
-	}
-	mdelay(1);
-	if (!cnt) {
-		pr_info("ISAR no SVN response\n");
-		ret = -ETIME;
-		goto reterrflg;
-	} else {
-		if ((isar->cmsb == ISAR_CTRL_SWVER) && (isar->clsb == 1)) {
-			pr_notice("%s: ISAR software version %#x\n",
-				  isar->name, isar->buf[0]);
-		} else {
-			pr_info("%s: ISAR wrong swver response (%x,%x)"
-				" cnt(%d)\n", isar->name, isar->cmsb,
-				isar->clsb, cnt);
-			ret = -EIO;
-			goto reterrflg;
-		}
-	}
-	spin_lock_irqsave(isar->hwlock, flags);
-	isar_setup(isar);
-	spin_unlock_irqrestore(isar->hwlock, flags);
-	ret = 0;
-reterrflg:
-	spin_lock_irqsave(isar->hwlock, flags);
-reterror:
-	isar->ch[0].bch.debug = saved_debug;
-	if (ret)
-		/* disable ISAR IRQ */
-		isar->write_reg(isar->hw, ISAR_IRQBIT, 0);
-	spin_unlock_irqrestore(isar->hwlock, flags);
-	return ret;
-}
-
-static inline void
-deliver_status(struct isar_ch *ch, int status)
-{
-	pr_debug("%s: HL->LL FAXIND %x\n", ch->is->name, status);
-	_queue_data(&ch->bch.ch, PH_CONTROL_IND, status, 0, NULL, GFP_ATOMIC);
-}
-
-static inline void
-isar_rcv_frame(struct isar_ch *ch)
-{
-	u8	*ptr;
-	int	maxlen;
-
-	if (!ch->is->clsb) {
-		pr_debug("%s; ISAR zero len frame\n", ch->is->name);
-		ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
-		return;
-	}
-	if (test_bit(FLG_RX_OFF, &ch->bch.Flags)) {
-		ch->bch.dropcnt += ch->is->clsb;
-		ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
-		return;
-	}
-	switch (ch->bch.state) {
-	case ISDN_P_NONE:
-		pr_debug("%s: ISAR protocol 0 spurious IIS_RDATA %x/%x/%x\n",
-			 ch->is->name, ch->is->iis, ch->is->cmsb, ch->is->clsb);
-		ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
-		break;
-	case ISDN_P_B_RAW:
-	case ISDN_P_B_L2DTMF:
-	case ISDN_P_B_MODEM_ASYNC:
-		maxlen = bchannel_get_rxbuf(&ch->bch, ch->is->clsb);
-		if (maxlen < 0) {
-			pr_warn("%s.B%d: No bufferspace for %d bytes\n",
-				ch->is->name, ch->bch.nr, ch->is->clsb);
-			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
-			break;
-		}
-		rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb));
-		recv_Bchannel(&ch->bch, 0, false);
-		break;
-	case ISDN_P_B_HDLC:
-		maxlen = bchannel_get_rxbuf(&ch->bch, ch->is->clsb);
-		if (maxlen < 0) {
-			pr_warn("%s.B%d: No bufferspace for %d bytes\n",
-				ch->is->name, ch->bch.nr, ch->is->clsb);
-			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
-			break;
-		}
-		if (ch->is->cmsb & HDLC_ERROR) {
-			pr_debug("%s: ISAR frame error %x len %d\n",
-				 ch->is->name, ch->is->cmsb, ch->is->clsb);
-#ifdef ERROR_STATISTIC
-			if (ch->is->cmsb & HDLC_ERR_RER)
-				ch->bch.err_inv++;
-			if (ch->is->cmsb & HDLC_ERR_CER)
-				ch->bch.err_crc++;
-#endif
-			skb_trim(ch->bch.rx_skb, 0);
-			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
-			break;
-		}
-		if (ch->is->cmsb & HDLC_FSD)
-			skb_trim(ch->bch.rx_skb, 0);
-		ptr = skb_put(ch->bch.rx_skb, ch->is->clsb);
-		rcv_mbox(ch->is, ptr);
-		if (ch->is->cmsb & HDLC_FED) {
-			if (ch->bch.rx_skb->len < 3) { /* last 2 are the FCS */
-				pr_debug("%s: ISAR frame too short %d\n",
-					 ch->is->name, ch->bch.rx_skb->len);
-				skb_trim(ch->bch.rx_skb, 0);
-				break;
-			}
-			skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2);
-			recv_Bchannel(&ch->bch, 0, false);
-		}
-		break;
-	case ISDN_P_B_T30_FAX:
-		if (ch->state != STFAX_ACTIV) {
-			pr_debug("%s: isar_rcv_frame: not ACTIV\n",
-				 ch->is->name);
-			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
-			if (ch->bch.rx_skb)
-				skb_trim(ch->bch.rx_skb, 0);
-			break;
-		}
-		if (!ch->bch.rx_skb) {
-			ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen,
-						      GFP_ATOMIC);
-			if (unlikely(!ch->bch.rx_skb)) {
-				pr_info("%s: B receive out of memory\n",
-					__func__);
-				ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
-				break;
-			}
-		}
-		if (ch->cmd == PCTRL_CMD_FRM) {
-			rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb));
-			pr_debug("%s: isar_rcv_frame: %d\n",
-				 ch->is->name, ch->bch.rx_skb->len);
-			if (ch->is->cmsb & SART_NMD) { /* ABORT */
-				pr_debug("%s: isar_rcv_frame: no more data\n",
-					 ch->is->name);
-				ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
-				send_mbox(ch->is, SET_DPS(ch->dpath) |
-					  ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC,
-					  0, NULL);
-				ch->state = STFAX_ESCAPE;
-				/* set_skb_flag(skb, DF_NOMOREDATA); */
-			}
-			recv_Bchannel(&ch->bch, 0, false);
-			if (ch->is->cmsb & SART_NMD)
-				deliver_status(ch, HW_MOD_NOCARR);
-			break;
-		}
-		if (ch->cmd != PCTRL_CMD_FRH) {
-			pr_debug("%s: isar_rcv_frame: unknown fax mode %x\n",
-				 ch->is->name, ch->cmd);
-			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
-			if (ch->bch.rx_skb)
-				skb_trim(ch->bch.rx_skb, 0);
-			break;
-		}
-		/* PCTRL_CMD_FRH */
-		if ((ch->bch.rx_skb->len + ch->is->clsb) >
-		    (ch->bch.maxlen + 2)) {
-			pr_info("%s: %s incoming packet too large\n",
-				ch->is->name, __func__);
-			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
-			skb_trim(ch->bch.rx_skb, 0);
-			break;
-		}  else if (ch->is->cmsb & HDLC_ERROR) {
-			pr_info("%s: ISAR frame error %x len %d\n",
-				ch->is->name, ch->is->cmsb, ch->is->clsb);
-			skb_trim(ch->bch.rx_skb, 0);
-			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
-			break;
-		}
-		if (ch->is->cmsb & HDLC_FSD)
-			skb_trim(ch->bch.rx_skb, 0);
-		ptr = skb_put(ch->bch.rx_skb, ch->is->clsb);
-		rcv_mbox(ch->is, ptr);
-		if (ch->is->cmsb & HDLC_FED) {
-			if (ch->bch.rx_skb->len < 3) { /* last 2 are the FCS */
-				pr_info("%s: ISAR frame too short %d\n",
-					ch->is->name, ch->bch.rx_skb->len);
-				skb_trim(ch->bch.rx_skb, 0);
-				break;
-			}
-			skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2);
-			recv_Bchannel(&ch->bch, 0, false);
-		}
-		if (ch->is->cmsb & SART_NMD) { /* ABORT */
-			pr_debug("%s: isar_rcv_frame: no more data\n",
-				 ch->is->name);
-			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
-			if (ch->bch.rx_skb)
-				skb_trim(ch->bch.rx_skb, 0);
-			send_mbox(ch->is, SET_DPS(ch->dpath) |
-				  ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL);
-			ch->state = STFAX_ESCAPE;
-			deliver_status(ch, HW_MOD_NOCARR);
-		}
-		break;
-	default:
-		pr_info("isar_rcv_frame protocol (%x)error\n", ch->bch.state);
-		ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
-		break;
-	}
-}
-
-static void
-isar_fill_fifo(struct isar_ch *ch)
-{
-	int count;
-	u8 msb;
-	u8 *ptr;
-
-	pr_debug("%s: ch%d  tx_skb %d tx_idx %d\n", ch->is->name, ch->bch.nr,
-		 ch->bch.tx_skb ? ch->bch.tx_skb->len : -1, ch->bch.tx_idx);
-	if (!(ch->is->bstat &
-	      (ch->dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2)))
-		return;
-	if (!ch->bch.tx_skb) {
-		if (!test_bit(FLG_TX_EMPTY, &ch->bch.Flags) ||
-		    (ch->bch.state != ISDN_P_B_RAW))
-			return;
-		count = ch->mml;
-		/* use the card buffer */
-		memset(ch->is->buf, ch->bch.fill[0], count);
-		send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
-			  0, count, ch->is->buf);
-		return;
-	}
-	count = ch->bch.tx_skb->len - ch->bch.tx_idx;
-	if (count <= 0)
-		return;
-	if (count > ch->mml) {
-		msb = 0;
-		count = ch->mml;
-	} else {
-		msb = HDLC_FED;
-	}
-	ptr = ch->bch.tx_skb->data + ch->bch.tx_idx;
-	if (!ch->bch.tx_idx) {
-		pr_debug("%s: frame start\n", ch->is->name);
-		if ((ch->bch.state == ISDN_P_B_T30_FAX) &&
-		    (ch->cmd == PCTRL_CMD_FTH)) {
-			if (count > 1) {
-				if ((ptr[0] == 0xff) && (ptr[1] == 0x13)) {
-					/* last frame */
-					test_and_set_bit(FLG_LASTDATA,
-							 &ch->bch.Flags);
-					pr_debug("%s: set LASTDATA\n",
-						 ch->is->name);
-					if (msb == HDLC_FED)
-						test_and_set_bit(FLG_DLEETX,
-								 &ch->bch.Flags);
-				}
-			}
-		}
-		msb |= HDLC_FST;
-	}
-	ch->bch.tx_idx += count;
-	switch (ch->bch.state) {
-	case ISDN_P_NONE:
-		pr_info("%s: wrong protocol 0\n", __func__);
-		break;
-	case ISDN_P_B_RAW:
-	case ISDN_P_B_L2DTMF:
-	case ISDN_P_B_MODEM_ASYNC:
-		send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
-			  0, count, ptr);
-		break;
-	case ISDN_P_B_HDLC:
-		send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
-			  msb, count, ptr);
-		break;
-	case ISDN_P_B_T30_FAX:
-		if (ch->state != STFAX_ACTIV)
-			pr_debug("%s: not ACTIV\n", ch->is->name);
-		else if (ch->cmd == PCTRL_CMD_FTH)
-			send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
-				  msb, count, ptr);
-		else if (ch->cmd == PCTRL_CMD_FTM)
-			send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
-				  0, count, ptr);
-		else
-			pr_debug("%s: not FTH/FTM\n", ch->is->name);
-		break;
-	default:
-		pr_info("%s: protocol(%x) error\n",
-			__func__, ch->bch.state);
-		break;
-	}
-}
-
-static inline struct isar_ch *
-sel_bch_isar(struct isar_hw *isar, u8 dpath)
-{
-	struct isar_ch	*base = &isar->ch[0];
-
-	if ((!dpath) || (dpath > 2))
-		return NULL;
-	if (base->dpath == dpath)
-		return base;
-	base++;
-	if (base->dpath == dpath)
-		return base;
-	return NULL;
-}
-
-static void
-send_next(struct isar_ch *ch)
-{
-	pr_debug("%s: %s ch%d tx_skb %d tx_idx %d\n", ch->is->name, __func__,
-		 ch->bch.nr, ch->bch.tx_skb ? ch->bch.tx_skb->len : -1,
-		 ch->bch.tx_idx);
-	if (ch->bch.state == ISDN_P_B_T30_FAX) {
-		if (ch->cmd == PCTRL_CMD_FTH) {
-			if (test_bit(FLG_LASTDATA, &ch->bch.Flags)) {
-				pr_debug("set NMD_DATA\n");
-				test_and_set_bit(FLG_NMD_DATA, &ch->bch.Flags);
-			}
-		} else if (ch->cmd == PCTRL_CMD_FTM) {
-			if (test_bit(FLG_DLEETX, &ch->bch.Flags)) {
-				test_and_set_bit(FLG_LASTDATA, &ch->bch.Flags);
-				test_and_set_bit(FLG_NMD_DATA, &ch->bch.Flags);
-			}
-		}
-	}
-	dev_kfree_skb(ch->bch.tx_skb);
-	if (get_next_bframe(&ch->bch)) {
-		isar_fill_fifo(ch);
-		test_and_clear_bit(FLG_TX_EMPTY, &ch->bch.Flags);
-	} else if (test_bit(FLG_TX_EMPTY, &ch->bch.Flags)) {
-		isar_fill_fifo(ch);
-	} else {
-		if (test_and_clear_bit(FLG_DLEETX, &ch->bch.Flags)) {
-			if (test_and_clear_bit(FLG_LASTDATA,
-					       &ch->bch.Flags)) {
-				if (test_and_clear_bit(FLG_NMD_DATA,
-						       &ch->bch.Flags)) {
-					u8 zd = 0;
-					send_mbox(ch->is, SET_DPS(ch->dpath) |
-						  ISAR_HIS_SDATA, 0x01, 1, &zd);
-				}
-				test_and_set_bit(FLG_LL_OK, &ch->bch.Flags);
-			} else {
-				deliver_status(ch, HW_MOD_CONNECT);
-			}
-		} else if (test_bit(FLG_FILLEMPTY, &ch->bch.Flags)) {
-			test_and_set_bit(FLG_TX_EMPTY, &ch->bch.Flags);
-		}
-	}
-}
-
-static void
-check_send(struct isar_hw *isar, u8 rdm)
-{
-	struct isar_ch	*ch;
-
-	pr_debug("%s: rdm %x\n", isar->name, rdm);
-	if (rdm & BSTAT_RDM1) {
-		ch = sel_bch_isar(isar, 1);
-		if (ch && test_bit(FLG_ACTIVE, &ch->bch.Flags)) {
-			if (ch->bch.tx_skb && (ch->bch.tx_skb->len >
-					       ch->bch.tx_idx))
-				isar_fill_fifo(ch);
-			else
-				send_next(ch);
-		}
-	}
-	if (rdm & BSTAT_RDM2) {
-		ch = sel_bch_isar(isar, 2);
-		if (ch && test_bit(FLG_ACTIVE, &ch->bch.Flags)) {
-			if (ch->bch.tx_skb && (ch->bch.tx_skb->len >
-					       ch->bch.tx_idx))
-				isar_fill_fifo(ch);
-			else
-				send_next(ch);
-		}
-	}
-}
-
-static const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", "NODEF4",
-		       "300", "600", "1200", "2400", "4800", "7200",
-		       "9600nt", "9600t", "12000", "14400", "WRONG"};
-static const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21",
-		       "Bell103", "V23", "Bell202", "V17", "V29", "V27ter"};
-
-static void
-isar_pump_status_rsp(struct isar_ch *ch) {
-	u8 ril = ch->is->buf[0];
-	u8 rim;
-
-	if (!test_and_clear_bit(ISAR_RATE_REQ, &ch->is->Flags))
-		return;
-	if (ril > 14) {
-		pr_info("%s: wrong pstrsp ril=%d\n", ch->is->name, ril);
-		ril = 15;
-	}
-	switch (ch->is->buf[1]) {
-	case 0:
-		rim = 0;
-		break;
-	case 0x20:
-		rim = 2;
-		break;
-	case 0x40:
-		rim = 3;
-		break;
-	case 0x41:
-		rim = 4;
-		break;
-	case 0x51:
-		rim = 5;
-		break;
-	case 0x61:
-		rim = 6;
-		break;
-	case 0x71:
-		rim = 7;
-		break;
-	case 0x82:
-		rim = 8;
-		break;
-	case 0x92:
-		rim = 9;
-		break;
-	case 0xa2:
-		rim = 10;
-		break;
-	default:
-		rim = 1;
-		break;
-	}
-	sprintf(ch->conmsg, "%s %s", dmril[ril], dmrim[rim]);
-	pr_debug("%s: pump strsp %s\n", ch->is->name, ch->conmsg);
-}
-
-static void
-isar_pump_statev_modem(struct isar_ch *ch, u8 devt) {
-	u8 dps = SET_DPS(ch->dpath);
-
-	switch (devt) {
-	case PSEV_10MS_TIMER:
-		pr_debug("%s: pump stev TIMER\n", ch->is->name);
-		break;
-	case PSEV_CON_ON:
-		pr_debug("%s: pump stev CONNECT\n", ch->is->name);
-		deliver_status(ch, HW_MOD_CONNECT);
-		break;
-	case PSEV_CON_OFF:
-		pr_debug("%s: pump stev NO CONNECT\n", ch->is->name);
-		send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
-		deliver_status(ch, HW_MOD_NOCARR);
-		break;
-	case PSEV_V24_OFF:
-		pr_debug("%s: pump stev V24 OFF\n", ch->is->name);
-		break;
-	case PSEV_CTS_ON:
-		pr_debug("%s: pump stev CTS ON\n", ch->is->name);
-		break;
-	case PSEV_CTS_OFF:
-		pr_debug("%s pump stev CTS OFF\n", ch->is->name);
-		break;
-	case PSEV_DCD_ON:
-		pr_debug("%s: pump stev CARRIER ON\n", ch->is->name);
-		test_and_set_bit(ISAR_RATE_REQ, &ch->is->Flags);
-		send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
-		break;
-	case PSEV_DCD_OFF:
-		pr_debug("%s: pump stev CARRIER OFF\n", ch->is->name);
-		break;
-	case PSEV_DSR_ON:
-		pr_debug("%s: pump stev DSR ON\n", ch->is->name);
-		break;
-	case PSEV_DSR_OFF:
-		pr_debug("%s: pump stev DSR_OFF\n", ch->is->name);
-		break;
-	case PSEV_REM_RET:
-		pr_debug("%s: pump stev REMOTE RETRAIN\n", ch->is->name);
-		break;
-	case PSEV_REM_REN:
-		pr_debug("%s: pump stev REMOTE RENEGOTIATE\n", ch->is->name);
-		break;
-	case PSEV_GSTN_CLR:
-		pr_debug("%s: pump stev GSTN CLEAR\n", ch->is->name);
-		break;
-	default:
-		pr_info("u%s: unknown pump stev %x\n", ch->is->name, devt);
-		break;
-	}
-}
-
-static void
-isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
-	u8 dps = SET_DPS(ch->dpath);
-	u8 p1;
-
-	switch (devt) {
-	case PSEV_10MS_TIMER:
-		pr_debug("%s: pump stev TIMER\n", ch->is->name);
-		break;
-	case PSEV_RSP_READY:
-		pr_debug("%s: pump stev RSP_READY\n", ch->is->name);
-		ch->state = STFAX_READY;
-		deliver_status(ch, HW_MOD_READY);
-#ifdef AUTOCON
-		if (test_bit(BC_FLG_ORIG, &ch->bch.Flags))
-			isar_pump_cmd(bch, HW_MOD_FRH, 3);
-		else
-			isar_pump_cmd(bch, HW_MOD_FTH, 3);
-#endif
-		break;
-	case PSEV_LINE_TX_H:
-		if (ch->state == STFAX_LINE) {
-			pr_debug("%s: pump stev LINE_TX_H\n", ch->is->name);
-			ch->state = STFAX_CONT;
-			send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-				  PCTRL_CMD_CONT, 0, NULL);
-		} else {
-			pr_debug("%s: pump stev LINE_TX_H wrong st %x\n",
-				 ch->is->name, ch->state);
-		}
-		break;
-	case PSEV_LINE_RX_H:
-		if (ch->state == STFAX_LINE) {
-			pr_debug("%s: pump stev LINE_RX_H\n", ch->is->name);
-			ch->state = STFAX_CONT;
-			send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-				  PCTRL_CMD_CONT, 0, NULL);
-		} else {
-			pr_debug("%s: pump stev LINE_RX_H wrong st %x\n",
-				 ch->is->name, ch->state);
-		}
-		break;
-	case PSEV_LINE_TX_B:
-		if (ch->state == STFAX_LINE) {
-			pr_debug("%s: pump stev LINE_TX_B\n", ch->is->name);
-			ch->state = STFAX_CONT;
-			send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-				  PCTRL_CMD_CONT, 0, NULL);
-		} else {
-			pr_debug("%s: pump stev LINE_TX_B wrong st %x\n",
-				 ch->is->name, ch->state);
-		}
-		break;
-	case PSEV_LINE_RX_B:
-		if (ch->state == STFAX_LINE) {
-			pr_debug("%s: pump stev LINE_RX_B\n", ch->is->name);
-			ch->state = STFAX_CONT;
-			send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-				  PCTRL_CMD_CONT, 0, NULL);
-		} else {
-			pr_debug("%s: pump stev LINE_RX_B wrong st %x\n",
-				 ch->is->name, ch->state);
-		}
-		break;
-	case PSEV_RSP_CONN:
-		if (ch->state == STFAX_CONT) {
-			pr_debug("%s: pump stev RSP_CONN\n", ch->is->name);
-			ch->state = STFAX_ACTIV;
-			test_and_set_bit(ISAR_RATE_REQ, &ch->is->Flags);
-			send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
-			if (ch->cmd == PCTRL_CMD_FTH) {
-				int delay = (ch->mod == 3) ? 1000 : 200;
-				/* 1s (200 ms) Flags before data */
-				if (test_and_set_bit(FLG_FTI_RUN,
-						     &ch->bch.Flags))
-					timer_delete(&ch->ftimer);
-				ch->ftimer.expires =
-					jiffies + ((delay * HZ) / 1000);
-				test_and_set_bit(FLG_LL_CONN,
-						 &ch->bch.Flags);
-				add_timer(&ch->ftimer);
-			} else {
-				deliver_status(ch, HW_MOD_CONNECT);
-			}
-		} else {
-			pr_debug("%s: pump stev RSP_CONN wrong st %x\n",
-				 ch->is->name, ch->state);
-		}
-		break;
-	case PSEV_FLAGS_DET:
-		pr_debug("%s: pump stev FLAGS_DET\n", ch->is->name);
-		break;
-	case PSEV_RSP_DISC:
-		pr_debug("%s: pump stev RSP_DISC state(%d)\n",
-			 ch->is->name, ch->state);
-		if (ch->state == STFAX_ESCAPE) {
-			p1 = 5;
-			switch (ch->newcmd) {
-			case 0:
-				ch->state = STFAX_READY;
-				break;
-			case PCTRL_CMD_FTM:
-				p1 = 2;
-				fallthrough;
-			case PCTRL_CMD_FTH:
-				send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-					  PCTRL_CMD_SILON, 1, &p1);
-				ch->state = STFAX_SILDET;
-				break;
-			case PCTRL_CMD_FRH:
-			case PCTRL_CMD_FRM:
-				ch->mod = ch->newmod;
-				p1 = ch->newmod;
-				ch->newmod = 0;
-				ch->cmd = ch->newcmd;
-				ch->newcmd = 0;
-				send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-					  ch->cmd, 1, &p1);
-				ch->state = STFAX_LINE;
-				ch->try_mod = 3;
-				break;
-			default:
-				pr_debug("%s: RSP_DISC unknown newcmd %x\n",
-					 ch->is->name, ch->newcmd);
-				break;
-			}
-		} else if (ch->state == STFAX_ACTIV) {
-			if (test_and_clear_bit(FLG_LL_OK, &ch->bch.Flags))
-				deliver_status(ch, HW_MOD_OK);
-			else if (ch->cmd == PCTRL_CMD_FRM)
-				deliver_status(ch, HW_MOD_NOCARR);
-			else
-				deliver_status(ch, HW_MOD_FCERROR);
-			ch->state = STFAX_READY;
-		} else if (ch->state != STFAX_SILDET) {
-			/* ignore in STFAX_SILDET */
-			ch->state = STFAX_READY;
-			deliver_status(ch, HW_MOD_FCERROR);
-		}
-		break;
-	case PSEV_RSP_SILDET:
-		pr_debug("%s: pump stev RSP_SILDET\n", ch->is->name);
-		if (ch->state == STFAX_SILDET) {
-			ch->mod = ch->newmod;
-			p1 = ch->newmod;
-			ch->newmod = 0;
-			ch->cmd = ch->newcmd;
-			ch->newcmd = 0;
-			send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-				  ch->cmd, 1, &p1);
-			ch->state = STFAX_LINE;
-			ch->try_mod = 3;
-		}
-		break;
-	case PSEV_RSP_SILOFF:
-		pr_debug("%s: pump stev RSP_SILOFF\n", ch->is->name);
-		break;
-	case PSEV_RSP_FCERR:
-		if (ch->state == STFAX_LINE) {
-			pr_debug("%s: pump stev RSP_FCERR try %d\n",
-				 ch->is->name, ch->try_mod);
-			if (ch->try_mod--) {
-				send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-					  ch->cmd, 1, &ch->mod);
-				break;
-			}
-		}
-		pr_debug("%s: pump stev RSP_FCERR\n", ch->is->name);
-		ch->state = STFAX_ESCAPE;
-		send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC,
-			  0, NULL);
-		deliver_status(ch, HW_MOD_FCERROR);
-		break;
-	default:
-		break;
-	}
-}
-
-void
-mISDNisar_irq(struct isar_hw *isar)
-{
-	struct isar_ch *ch;
-
-	get_irq_infos(isar);
-	switch (isar->iis & ISAR_IIS_MSCMSD) {
-	case ISAR_IIS_RDATA:
-		ch = sel_bch_isar(isar, isar->iis >> 6);
-		if (ch)
-			isar_rcv_frame(ch);
-		else {
-			pr_debug("%s: ISAR spurious IIS_RDATA %x/%x/%x\n",
-				 isar->name, isar->iis, isar->cmsb,
-				 isar->clsb);
-			isar->write_reg(isar->hw, ISAR_IIA, 0);
-		}
-		break;
-	case ISAR_IIS_GSTEV:
-		isar->write_reg(isar->hw, ISAR_IIA, 0);
-		isar->bstat |= isar->cmsb;
-		check_send(isar, isar->cmsb);
-		break;
-	case ISAR_IIS_BSTEV:
-#ifdef ERROR_STATISTIC
-		ch = sel_bch_isar(isar, isar->iis >> 6);
-		if (ch) {
-			if (isar->cmsb == BSTEV_TBO)
-				ch->bch.err_tx++;
-			if (isar->cmsb == BSTEV_RBO)
-				ch->bch.err_rdo++;
-		}
-#endif
-		pr_debug("%s: Buffer STEV dpath%d msb(%x)\n",
-			 isar->name, isar->iis >> 6, isar->cmsb);
-		isar->write_reg(isar->hw, ISAR_IIA, 0);
-		break;
-	case ISAR_IIS_PSTEV:
-		ch = sel_bch_isar(isar, isar->iis >> 6);
-		if (ch) {
-			rcv_mbox(isar, NULL);
-			if (ch->bch.state == ISDN_P_B_MODEM_ASYNC)
-				isar_pump_statev_modem(ch, isar->cmsb);
-			else if (ch->bch.state == ISDN_P_B_T30_FAX)
-				isar_pump_statev_fax(ch, isar->cmsb);
-			else if (ch->bch.state == ISDN_P_B_RAW) {
-				int	tt;
-				tt = isar->cmsb | 0x30;
-				if (tt == 0x3e)
-					tt = '*';
-				else if (tt == 0x3f)
-					tt = '#';
-				else if (tt > '9')
-					tt += 7;
-				tt |= DTMF_TONE_VAL;
-				_queue_data(&ch->bch.ch, PH_CONTROL_IND,
-					    MISDN_ID_ANY, sizeof(tt), &tt,
-					    GFP_ATOMIC);
-			} else
-				pr_debug("%s: ISAR IIS_PSTEV pm %d sta %x\n",
-					 isar->name, ch->bch.state,
-					 isar->cmsb);
-		} else {
-			pr_debug("%s: ISAR spurious IIS_PSTEV %x/%x/%x\n",
-				 isar->name, isar->iis, isar->cmsb,
-				 isar->clsb);
-			isar->write_reg(isar->hw, ISAR_IIA, 0);
-		}
-		break;
-	case ISAR_IIS_PSTRSP:
-		ch = sel_bch_isar(isar, isar->iis >> 6);
-		if (ch) {
-			rcv_mbox(isar, NULL);
-			isar_pump_status_rsp(ch);
-		} else {
-			pr_debug("%s: ISAR spurious IIS_PSTRSP %x/%x/%x\n",
-				 isar->name, isar->iis, isar->cmsb,
-				 isar->clsb);
-			isar->write_reg(isar->hw, ISAR_IIA, 0);
-		}
-		break;
-	case ISAR_IIS_DIAG:
-	case ISAR_IIS_BSTRSP:
-	case ISAR_IIS_IOM2RSP:
-		rcv_mbox(isar, NULL);
-		break;
-	case ISAR_IIS_INVMSG:
-		rcv_mbox(isar, NULL);
-		pr_debug("%s: invalid msg his:%x\n", isar->name, isar->cmsb);
-		break;
-	default:
-		rcv_mbox(isar, NULL);
-		pr_debug("%s: unhandled msg iis(%x) ctrl(%x/%x)\n",
-			 isar->name, isar->iis, isar->cmsb, isar->clsb);
-		break;
-	}
-}
-EXPORT_SYMBOL(mISDNisar_irq);
-
-static void
-ftimer_handler(struct timer_list *t)
-{
-	struct isar_ch *ch = timer_container_of(ch, t, ftimer);
-
-	pr_debug("%s: ftimer flags %lx\n", ch->is->name, ch->bch.Flags);
-	test_and_clear_bit(FLG_FTI_RUN, &ch->bch.Flags);
-	if (test_and_clear_bit(FLG_LL_CONN, &ch->bch.Flags))
-		deliver_status(ch, HW_MOD_CONNECT);
-}
-
-static void
-setup_pump(struct isar_ch *ch) {
-	u8 dps = SET_DPS(ch->dpath);
-	u8 ctrl, param[6];
-
-	switch (ch->bch.state) {
-	case ISDN_P_NONE:
-	case ISDN_P_B_RAW:
-	case ISDN_P_B_HDLC:
-		send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, PMOD_BYPASS, 0, NULL);
-		break;
-	case ISDN_P_B_L2DTMF:
-		if (test_bit(FLG_DTMFSEND, &ch->bch.Flags)) {
-			param[0] = 5; /* TOA 5 db */
-			send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG,
-				  PMOD_DTMF_TRANS, 1, param);
-		} else {
-			param[0] = 40; /* REL -46 dbm */
-			send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG,
-				  PMOD_DTMF, 1, param);
-		}
-		fallthrough;
-	case ISDN_P_B_MODEM_ASYNC:
-		ctrl = PMOD_DATAMODEM;
-		if (test_bit(FLG_ORIGIN, &ch->bch.Flags)) {
-			ctrl |= PCTRL_ORIG;
-			param[5] = PV32P6_CTN;
-		} else {
-			param[5] = PV32P6_ATN;
-		}
-		param[0] = 6; /* 6 db */
-		param[1] = PV32P2_V23R | PV32P2_V22A | PV32P2_V22B |
-			PV32P2_V22C | PV32P2_V21 | PV32P2_BEL;
-		param[2] = PV32P3_AMOD | PV32P3_V32B | PV32P3_V23B;
-		param[3] = PV32P4_UT144;
-		param[4] = PV32P5_UT144;
-		send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, ctrl, 6, param);
-		break;
-	case ISDN_P_B_T30_FAX:
-		ctrl = PMOD_FAX;
-		if (test_bit(FLG_ORIGIN, &ch->bch.Flags)) {
-			ctrl |= PCTRL_ORIG;
-			param[1] = PFAXP2_CTN;
-		} else {
-			param[1] = PFAXP2_ATN;
-		}
-		param[0] = 6; /* 6 db */
-		send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, ctrl, 2, param);
-		ch->state = STFAX_NULL;
-		ch->newcmd = 0;
-		ch->newmod = 0;
-		test_and_set_bit(FLG_FTI_RUN, &ch->bch.Flags);
-		break;
-	}
-	udelay(1000);
-	send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
-	udelay(1000);
-}
-
-static void
-setup_sart(struct isar_ch *ch) {
-	u8 dps = SET_DPS(ch->dpath);
-	u8 ctrl, param[2] = {0, 0};
-
-	switch (ch->bch.state) {
-	case ISDN_P_NONE:
-		send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_DISABLE,
-			  0, NULL);
-		break;
-	case ISDN_P_B_RAW:
-	case ISDN_P_B_L2DTMF:
-		send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_BINARY,
-			  2, param);
-		break;
-	case ISDN_P_B_HDLC:
-	case ISDN_P_B_T30_FAX:
-		send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_HDLC,
-			  1, param);
-		break;
-	case ISDN_P_B_MODEM_ASYNC:
-		ctrl = SMODE_V14 | SCTRL_HDMC_BOTH;
-		param[0] = S_P1_CHS_8;
-		param[1] = S_P2_BFT_DEF;
-		send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, ctrl, 2, param);
-		break;
-	}
-	udelay(1000);
-	send_mbox(ch->is, dps | ISAR_HIS_BSTREQ, 0, 0, NULL);
-	udelay(1000);
-}
-
-static void
-setup_iom2(struct isar_ch *ch) {
-	u8 dps = SET_DPS(ch->dpath);
-	u8 cmsb = IOM_CTRL_ENA, msg[5] = {IOM_P1_TXD, 0, 0, 0, 0};
-
-	if (ch->bch.nr == 2) {
-		msg[1] = 1;
-		msg[3] = 1;
-	}
-	switch (ch->bch.state) {
-	case ISDN_P_NONE:
-		cmsb = 0;
-		/* dummy slot */
-		msg[1] = ch->dpath + 2;
-		msg[3] = ch->dpath + 2;
-		break;
-	case ISDN_P_B_RAW:
-	case ISDN_P_B_HDLC:
-		break;
-	case ISDN_P_B_MODEM_ASYNC:
-	case ISDN_P_B_T30_FAX:
-		cmsb |= IOM_CTRL_RCV;
-		fallthrough;
-	case ISDN_P_B_L2DTMF:
-		if (test_bit(FLG_DTMFSEND, &ch->bch.Flags))
-			cmsb |= IOM_CTRL_RCV;
-		cmsb |= IOM_CTRL_ALAW;
-		break;
-	}
-	send_mbox(ch->is, dps | ISAR_HIS_IOM2CFG, cmsb, 5, msg);
-	udelay(1000);
-	send_mbox(ch->is, dps | ISAR_HIS_IOM2REQ, 0, 0, NULL);
-	udelay(1000);
-}
-
-static int
-modeisar(struct isar_ch *ch, u32 bprotocol)
-{
-	/* Here we are selecting the best datapath for requested protocol */
-	if (ch->bch.state == ISDN_P_NONE) { /* New Setup */
-		switch (bprotocol) {
-		case ISDN_P_NONE: /* init */
-			if (!ch->dpath)
-				/* no init for dpath 0 */
-				return 0;
-			test_and_clear_bit(FLG_HDLC, &ch->bch.Flags);
-			test_and_clear_bit(FLG_TRANSPARENT, &ch->bch.Flags);
-			break;
-		case ISDN_P_B_RAW:
-		case ISDN_P_B_HDLC:
-			/* best is datapath 2 */
-			if (!test_and_set_bit(ISAR_DP2_USE, &ch->is->Flags))
-				ch->dpath = 2;
-			else if (!test_and_set_bit(ISAR_DP1_USE,
-						   &ch->is->Flags))
-				ch->dpath = 1;
-			else {
-				pr_info("modeisar both paths in use\n");
-				return -EBUSY;
-			}
-			if (bprotocol == ISDN_P_B_HDLC)
-				test_and_set_bit(FLG_HDLC, &ch->bch.Flags);
-			else
-				test_and_set_bit(FLG_TRANSPARENT,
-						 &ch->bch.Flags);
-			break;
-		case ISDN_P_B_MODEM_ASYNC:
-		case ISDN_P_B_T30_FAX:
-		case ISDN_P_B_L2DTMF:
-			/* only datapath 1 */
-			if (!test_and_set_bit(ISAR_DP1_USE, &ch->is->Flags))
-				ch->dpath = 1;
-			else {
-				pr_info("%s: ISAR modeisar analog functions"
-					"only with DP1\n", ch->is->name);
-				return -EBUSY;
-			}
-			break;
-		default:
-			pr_info("%s: protocol not known %x\n", ch->is->name,
-				bprotocol);
-			return -ENOPROTOOPT;
-		}
-	}
-	pr_debug("%s: ISAR ch%d dp%d protocol %x->%x\n", ch->is->name,
-		 ch->bch.nr, ch->dpath, ch->bch.state, bprotocol);
-	ch->bch.state = bprotocol;
-	setup_pump(ch);
-	setup_iom2(ch);
-	setup_sart(ch);
-	if (ch->bch.state == ISDN_P_NONE) {
-		/* Clear resources */
-		if (ch->dpath == 1)
-			test_and_clear_bit(ISAR_DP1_USE, &ch->is->Flags);
-		else if (ch->dpath == 2)
-			test_and_clear_bit(ISAR_DP2_USE, &ch->is->Flags);
-		ch->dpath = 0;
-		ch->is->ctrl(ch->is->hw, HW_DEACT_IND, ch->bch.nr);
-	} else
-		ch->is->ctrl(ch->is->hw, HW_ACTIVATE_IND, ch->bch.nr);
-	return 0;
-}
-
-static void
-isar_pump_cmd(struct isar_ch *ch, u32 cmd, u8 para)
-{
-	u8 dps = SET_DPS(ch->dpath);
-	u8 ctrl = 0, nom = 0, p1 = 0;
-
-	pr_debug("%s: isar_pump_cmd %x/%x state(%x)\n",
-		 ch->is->name, cmd, para, ch->bch.state);
-	switch (cmd) {
-	case HW_MOD_FTM:
-		if (ch->state == STFAX_READY) {
-			p1 = para;
-			ctrl = PCTRL_CMD_FTM;
-			nom = 1;
-			ch->state = STFAX_LINE;
-			ch->cmd = ctrl;
-			ch->mod = para;
-			ch->newmod = 0;
-			ch->newcmd = 0;
-			ch->try_mod = 3;
-		} else if ((ch->state == STFAX_ACTIV) &&
-			   (ch->cmd == PCTRL_CMD_FTM) && (ch->mod == para))
-			deliver_status(ch, HW_MOD_CONNECT);
-		else {
-			ch->newmod = para;
-			ch->newcmd = PCTRL_CMD_FTM;
-			nom = 0;
-			ctrl = PCTRL_CMD_ESC;
-			ch->state = STFAX_ESCAPE;
-		}
-		break;
-	case HW_MOD_FTH:
-		if (ch->state == STFAX_READY) {
-			p1 = para;
-			ctrl = PCTRL_CMD_FTH;
-			nom = 1;
-			ch->state = STFAX_LINE;
-			ch->cmd = ctrl;
-			ch->mod = para;
-			ch->newmod = 0;
-			ch->newcmd = 0;
-			ch->try_mod = 3;
-		} else if ((ch->state == STFAX_ACTIV) &&
-			   (ch->cmd == PCTRL_CMD_FTH) && (ch->mod == para))
-			deliver_status(ch, HW_MOD_CONNECT);
-		else {
-			ch->newmod = para;
-			ch->newcmd = PCTRL_CMD_FTH;
-			nom = 0;
-			ctrl = PCTRL_CMD_ESC;
-			ch->state = STFAX_ESCAPE;
-		}
-		break;
-	case HW_MOD_FRM:
-		if (ch->state == STFAX_READY) {
-			p1 = para;
-			ctrl = PCTRL_CMD_FRM;
-			nom = 1;
-			ch->state = STFAX_LINE;
-			ch->cmd = ctrl;
-			ch->mod = para;
-			ch->newmod = 0;
-			ch->newcmd = 0;
-			ch->try_mod = 3;
-		} else if ((ch->state == STFAX_ACTIV) &&
-			   (ch->cmd == PCTRL_CMD_FRM) && (ch->mod == para))
-			deliver_status(ch, HW_MOD_CONNECT);
-		else {
-			ch->newmod = para;
-			ch->newcmd = PCTRL_CMD_FRM;
-			nom = 0;
-			ctrl = PCTRL_CMD_ESC;
-			ch->state = STFAX_ESCAPE;
-		}
-		break;
-	case HW_MOD_FRH:
-		if (ch->state == STFAX_READY) {
-			p1 = para;
-			ctrl = PCTRL_CMD_FRH;
-			nom = 1;
-			ch->state = STFAX_LINE;
-			ch->cmd = ctrl;
-			ch->mod = para;
-			ch->newmod = 0;
-			ch->newcmd = 0;
-			ch->try_mod = 3;
-		} else if ((ch->state == STFAX_ACTIV) &&
-			   (ch->cmd == PCTRL_CMD_FRH) && (ch->mod == para))
-			deliver_status(ch, HW_MOD_CONNECT);
-		else {
-			ch->newmod = para;
-			ch->newcmd = PCTRL_CMD_FRH;
-			nom = 0;
-			ctrl = PCTRL_CMD_ESC;
-			ch->state = STFAX_ESCAPE;
-		}
-		break;
-	case PCTRL_CMD_TDTMF:
-		p1 = para;
-		nom = 1;
-		ctrl = PCTRL_CMD_TDTMF;
-		break;
-	}
-	if (ctrl)
-		send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, ctrl, nom, &p1);
-}
-
-static void
-isar_setup(struct isar_hw *isar)
-{
-	u8 msg;
-	int i;
-
-	/* Dpath 1, 2 */
-	msg = 61;
-	for (i = 0; i < 2; i++) {
-		/* Buffer Config */
-		send_mbox(isar, (i ? ISAR_HIS_DPS2 : ISAR_HIS_DPS1) |
-			  ISAR_HIS_P12CFG, 4, 1, &msg);
-		isar->ch[i].mml = msg;
-		isar->ch[i].bch.state = 0;
-		isar->ch[i].dpath = i + 1;
-		modeisar(&isar->ch[i], ISDN_P_NONE);
-	}
-}
-
-static int
-isar_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct bchannel *bch = container_of(ch, struct bchannel, ch);
-	struct isar_ch *ich = container_of(bch, struct isar_ch, bch);
-	int ret = -EINVAL;
-	struct mISDNhead *hh = mISDN_HEAD_P(skb);
-	u32 id, *val;
-	u_long flags;
-
-	switch (hh->prim) {
-	case PH_DATA_REQ:
-		spin_lock_irqsave(ich->is->hwlock, flags);
-		ret = bchannel_senddata(bch, skb);
-		if (ret > 0) { /* direct TX */
-			ret = 0;
-			isar_fill_fifo(ich);
-		}
-		spin_unlock_irqrestore(ich->is->hwlock, flags);
-		return ret;
-	case PH_ACTIVATE_REQ:
-		spin_lock_irqsave(ich->is->hwlock, flags);
-		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
-			ret = modeisar(ich, ch->protocol);
-		else
-			ret = 0;
-		spin_unlock_irqrestore(ich->is->hwlock, flags);
-		if (!ret)
-			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-				    NULL, GFP_KERNEL);
-		break;
-	case PH_DEACTIVATE_REQ:
-		spin_lock_irqsave(ich->is->hwlock, flags);
-		mISDN_clear_bchannel(bch);
-		modeisar(ich, ISDN_P_NONE);
-		spin_unlock_irqrestore(ich->is->hwlock, flags);
-		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			    NULL, GFP_KERNEL);
-		ret = 0;
-		break;
-	case PH_CONTROL_REQ:
-		val = (u32 *)skb->data;
-		pr_debug("%s: PH_CONTROL | REQUEST %x/%x\n", ich->is->name,
-			 hh->id, *val);
-		if ((hh->id == 0) && ((*val & ~DTMF_TONE_MASK) ==
-				      DTMF_TONE_VAL)) {
-			if (bch->state == ISDN_P_B_L2DTMF) {
-				char tt = *val & DTMF_TONE_MASK;
-
-				if (tt == '*')
-					tt = 0x1e;
-				else if (tt == '#')
-					tt = 0x1f;
-				else if (tt > '9')
-					tt -= 7;
-				tt &= 0x1f;
-				spin_lock_irqsave(ich->is->hwlock, flags);
-				isar_pump_cmd(ich, PCTRL_CMD_TDTMF, tt);
-				spin_unlock_irqrestore(ich->is->hwlock, flags);
-			} else {
-				pr_info("%s: DTMF send wrong protocol %x\n",
-					__func__, bch->state);
-				return -EINVAL;
-			}
-		} else if ((hh->id == HW_MOD_FRM) || (hh->id == HW_MOD_FRH) ||
-			   (hh->id == HW_MOD_FTM) || (hh->id == HW_MOD_FTH)) {
-			for (id = 0; id < FAXMODCNT; id++)
-				if (faxmodulation[id] == *val)
-					break;
-			if ((FAXMODCNT > id) &&
-			    test_bit(FLG_INITIALIZED, &bch->Flags)) {
-				pr_debug("%s: isar: new mod\n", ich->is->name);
-				isar_pump_cmd(ich, hh->id, *val);
-				ret = 0;
-			} else {
-				pr_info("%s: wrong modulation\n",
-					ich->is->name);
-				ret = -EINVAL;
-			}
-		} else if (hh->id == HW_MOD_LASTDATA)
-			test_and_set_bit(FLG_DLEETX, &bch->Flags);
-		else {
-			pr_info("%s: unknown PH_CONTROL_REQ %x\n",
-				ich->is->name, hh->id);
-			ret = -EINVAL;
-		}
-		fallthrough;
-	default:
-		pr_info("%s: %s unknown prim(%x,%x)\n",
-			ich->is->name, __func__, hh->prim, hh->id);
-		ret = -EINVAL;
-	}
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-static int
-channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
-{
-	return mISDN_ctrl_bchannel(bch, cq);
-}
-
-static int
-isar_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
-{
-	struct bchannel *bch = container_of(ch, struct bchannel, ch);
-	struct isar_ch *ich = container_of(bch, struct isar_ch, bch);
-	int ret = -EINVAL;
-	u_long flags;
-
-	pr_debug("%s: %s cmd:%x %p\n", ich->is->name, __func__, cmd, arg);
-	switch (cmd) {
-	case CLOSE_CHANNEL:
-		test_and_clear_bit(FLG_OPEN, &bch->Flags);
-		cancel_work_sync(&bch->workq);
-		spin_lock_irqsave(ich->is->hwlock, flags);
-		mISDN_clear_bchannel(bch);
-		modeisar(ich, ISDN_P_NONE);
-		spin_unlock_irqrestore(ich->is->hwlock, flags);
-		ch->protocol = ISDN_P_NONE;
-		ch->peer = NULL;
-		module_put(ich->is->owner);
-		ret = 0;
-		break;
-	case CONTROL_CHANNEL:
-		ret = channel_bctrl(bch, arg);
-		break;
-	default:
-		pr_info("%s: %s unknown prim(%x)\n",
-			ich->is->name, __func__, cmd);
-	}
-	return ret;
-}
-
-static void
-free_isar(struct isar_hw *isar)
-{
-	modeisar(&isar->ch[0], ISDN_P_NONE);
-	modeisar(&isar->ch[1], ISDN_P_NONE);
-	timer_delete(&isar->ch[0].ftimer);
-	timer_delete(&isar->ch[1].ftimer);
-	test_and_clear_bit(FLG_INITIALIZED, &isar->ch[0].bch.Flags);
-	test_and_clear_bit(FLG_INITIALIZED, &isar->ch[1].bch.Flags);
-}
-
-static int
-init_isar(struct isar_hw *isar)
-{
-	int	cnt = 3;
-
-	while (cnt--) {
-		isar->version = ISARVersion(isar);
-		if (isar->ch[0].bch.debug & DEBUG_HW)
-			pr_notice("%s: Testing version %d (%d time)\n",
-				  isar->name, isar->version, 3 - cnt);
-		if (isar->version == 1)
-			break;
-		isar->ctrl(isar->hw, HW_RESET_REQ, 0);
-	}
-	if (isar->version != 1)
-		return -EINVAL;
-	timer_setup(&isar->ch[0].ftimer, ftimer_handler, 0);
-	test_and_set_bit(FLG_INITIALIZED, &isar->ch[0].bch.Flags);
-	timer_setup(&isar->ch[1].ftimer, ftimer_handler, 0);
-	test_and_set_bit(FLG_INITIALIZED, &isar->ch[1].bch.Flags);
-	return 0;
-}
-
-static int
-isar_open(struct isar_hw *isar, struct channel_req *rq)
-{
-	struct bchannel		*bch;
-
-	if (rq->adr.channel == 0 || rq->adr.channel > 2)
-		return -EINVAL;
-	if (rq->protocol == ISDN_P_NONE)
-		return -EINVAL;
-	bch = &isar->ch[rq->adr.channel - 1].bch;
-	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
-		return -EBUSY; /* b-channel can be only open once */
-	bch->ch.protocol = rq->protocol;
-	rq->ch = &bch->ch;
-	return 0;
-}
-
-u32
-mISDNisar_init(struct isar_hw *isar, void *hw)
-{
-	u32 ret, i;
-
-	isar->hw = hw;
-	for (i = 0; i < 2; i++) {
-		isar->ch[i].bch.nr = i + 1;
-		mISDN_initbchannel(&isar->ch[i].bch, MAX_DATA_MEM, 32);
-		isar->ch[i].bch.ch.nr = i + 1;
-		isar->ch[i].bch.ch.send = &isar_l2l1;
-		isar->ch[i].bch.ch.ctrl = isar_bctrl;
-		isar->ch[i].bch.hw = hw;
-		isar->ch[i].is = isar;
-	}
-
-	isar->init = &init_isar;
-	isar->release = &free_isar;
-	isar->firmware = &load_firmware;
-	isar->open = &isar_open;
-
-	ret =	(1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)) |
-		(1 << (ISDN_P_B_L2DTMF & ISDN_P_B_MASK)) |
-		(1 << (ISDN_P_B_MODEM_ASYNC & ISDN_P_B_MASK)) |
-		(1 << (ISDN_P_B_T30_FAX & ISDN_P_B_MASK));
-
-	return ret;
-}
-EXPORT_SYMBOL(mISDNisar_init);
-
-static int __init isar_mod_init(void)
-{
-	pr_notice("mISDN: ISAR driver Rev. %s\n", ISAR_REV);
-	return 0;
-}
-
-static void __exit isar_mod_cleanup(void)
-{
-	pr_notice("mISDN: ISAR module unloaded\n");
-}
-module_init(isar_mod_init);
-module_exit(isar_mod_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c
deleted file mode 100644
index 8d740d8eacec..000000000000
--- a/drivers/isdn/hardware/mISDN/netjet.c
+++ /dev/null
@@ -1,1154 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * NETJet mISDN driver
- *
- * Author       Karsten Keil <keil@isdn4linux.de>
- *
- * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
- */
-
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/mISDNhw.h>
-#include <linux/slab.h>
-#include "ipac.h"
-#include "iohelper.h"
-#include "netjet.h"
-#include "isdnhdlc.h"
-
-#define NETJET_REV	"2.0"
-
-enum nj_types {
-	NETJET_S_TJ300,
-	NETJET_S_TJ320,
-	ENTERNOW__TJ320,
-};
-
-struct tiger_dma {
-	size_t		size;
-	u32		*start;
-	int		idx;
-	u32		dmastart;
-	u32		dmairq;
-	u32		dmaend;
-	u32		dmacur;
-};
-
-struct tiger_hw;
-
-struct tiger_ch {
-	struct bchannel		bch;
-	struct tiger_hw		*nj;
-	int			idx;
-	int			free;
-	int			lastrx;
-	u16			rxstate;
-	u16			txstate;
-	struct isdnhdlc_vars	hsend;
-	struct isdnhdlc_vars	hrecv;
-	u8			*hsbuf;
-	u8			*hrbuf;
-};
-
-#define TX_INIT		0x0001
-#define TX_IDLE		0x0002
-#define TX_RUN		0x0004
-#define TX_UNDERRUN	0x0100
-#define RX_OVERRUN	0x0100
-
-#define LOG_SIZE	64
-
-struct tiger_hw {
-	struct list_head	list;
-	struct pci_dev		*pdev;
-	char			name[MISDN_MAX_IDLEN];
-	enum nj_types		typ;
-	int			irq;
-	u32			irqcnt;
-	u32			base;
-	size_t			base_s;
-	dma_addr_t		dma;
-	void			*dma_p;
-	spinlock_t		lock;	/* lock HW */
-	struct isac_hw		isac;
-	struct tiger_dma	send;
-	struct tiger_dma	recv;
-	struct tiger_ch		bc[2];
-	u8			ctrlreg;
-	u8			dmactrl;
-	u8			auxd;
-	u8			last_is0;
-	u8			irqmask0;
-	char			log[LOG_SIZE];
-};
-
-static LIST_HEAD(Cards);
-static DEFINE_RWLOCK(card_lock); /* protect Cards */
-static u32 debug;
-static int nj_cnt;
-
-static void
-_set_debug(struct tiger_hw *card)
-{
-	card->isac.dch.debug = debug;
-	card->bc[0].bch.debug = debug;
-	card->bc[1].bch.debug = debug;
-}
-
-static int
-set_debug(const char *val, const struct kernel_param *kp)
-{
-	int ret;
-	struct tiger_hw *card;
-
-	ret = param_set_uint(val, kp);
-	if (!ret) {
-		read_lock(&card_lock);
-		list_for_each_entry(card, &Cards, list)
-			_set_debug(card);
-		read_unlock(&card_lock);
-	}
-	return ret;
-}
-
-MODULE_AUTHOR("Karsten Keil");
-MODULE_DESCRIPTION("mISDN driver for NETJet cards");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(NETJET_REV);
-module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Netjet debug mask");
-
-static void
-nj_disable_hwirq(struct tiger_hw *card)
-{
-	outb(0, card->base + NJ_IRQMASK0);
-	outb(0, card->base + NJ_IRQMASK1);
-}
-
-
-static u8
-ReadISAC_nj(void *p, u8 offset)
-{
-	struct tiger_hw *card = p;
-	u8 ret;
-
-	card->auxd &= 0xfc;
-	card->auxd |= (offset >> 4) & 3;
-	outb(card->auxd, card->base + NJ_AUXDATA);
-	ret = inb(card->base + NJ_ISAC_OFF + ((offset & 0x0f) << 2));
-	return ret;
-}
-
-static void
-WriteISAC_nj(void *p, u8 offset, u8 value)
-{
-	struct tiger_hw *card = p;
-
-	card->auxd &= 0xfc;
-	card->auxd |= (offset >> 4) & 3;
-	outb(card->auxd, card->base + NJ_AUXDATA);
-	outb(value, card->base + NJ_ISAC_OFF + ((offset & 0x0f) << 2));
-}
-
-static void
-ReadFiFoISAC_nj(void *p, u8 offset, u8 *data, int size)
-{
-	struct tiger_hw *card = p;
-
-	card->auxd &= 0xfc;
-	outb(card->auxd, card->base + NJ_AUXDATA);
-	insb(card->base + NJ_ISAC_OFF, data, size);
-}
-
-static void
-WriteFiFoISAC_nj(void *p, u8 offset, u8 *data, int size)
-{
-	struct tiger_hw *card = p;
-
-	card->auxd &= 0xfc;
-	outb(card->auxd, card->base + NJ_AUXDATA);
-	outsb(card->base + NJ_ISAC_OFF, data, size);
-}
-
-static void
-fill_mem(struct tiger_ch *bc, u32 idx, u32 cnt, u32 fill)
-{
-	struct tiger_hw *card = bc->bch.hw;
-	u32 mask = 0xff, val;
-
-	pr_debug("%s: B%1d fill %02x len %d idx %d/%d\n", card->name,
-		 bc->bch.nr, fill, cnt, idx, card->send.idx);
-	if (bc->bch.nr & 2) {
-		fill  <<= 8;
-		mask <<= 8;
-	}
-	mask ^= 0xffffffff;
-	while (cnt--) {
-		val = card->send.start[idx];
-		val &= mask;
-		val |= fill;
-		card->send.start[idx++] = val;
-		if (idx >= card->send.size)
-			idx = 0;
-	}
-}
-
-static int
-mode_tiger(struct tiger_ch *bc, u32 protocol)
-{
-	struct tiger_hw *card = bc->bch.hw;
-
-	pr_debug("%s: B%1d protocol %x-->%x\n", card->name,
-		 bc->bch.nr, bc->bch.state, protocol);
-	switch (protocol) {
-	case ISDN_P_NONE:
-		if (bc->bch.state == ISDN_P_NONE)
-			break;
-		fill_mem(bc, 0, card->send.size, 0xff);
-		bc->bch.state = protocol;
-		/* only stop dma and interrupts if both channels NULL */
-		if ((card->bc[0].bch.state == ISDN_P_NONE) &&
-		    (card->bc[1].bch.state == ISDN_P_NONE)) {
-			card->dmactrl = 0;
-			outb(card->dmactrl, card->base + NJ_DMACTRL);
-			outb(0, card->base + NJ_IRQMASK0);
-		}
-		test_and_clear_bit(FLG_HDLC, &bc->bch.Flags);
-		test_and_clear_bit(FLG_TRANSPARENT, &bc->bch.Flags);
-		bc->txstate = 0;
-		bc->rxstate = 0;
-		bc->lastrx = -1;
-		break;
-	case ISDN_P_B_RAW:
-		test_and_set_bit(FLG_TRANSPARENT, &bc->bch.Flags);
-		bc->bch.state = protocol;
-		bc->idx = 0;
-		bc->free = card->send.size / 2;
-		bc->rxstate = 0;
-		bc->txstate = TX_INIT | TX_IDLE;
-		bc->lastrx = -1;
-		if (!card->dmactrl) {
-			card->dmactrl = 1;
-			outb(card->dmactrl, card->base + NJ_DMACTRL);
-			outb(0x0f, card->base + NJ_IRQMASK0);
-		}
-		break;
-	case ISDN_P_B_HDLC:
-		test_and_set_bit(FLG_HDLC, &bc->bch.Flags);
-		bc->bch.state = protocol;
-		bc->idx = 0;
-		bc->free = card->send.size / 2;
-		bc->rxstate = 0;
-		bc->txstate = TX_INIT | TX_IDLE;
-		isdnhdlc_rcv_init(&bc->hrecv, 0);
-		isdnhdlc_out_init(&bc->hsend, 0);
-		bc->lastrx = -1;
-		if (!card->dmactrl) {
-			card->dmactrl = 1;
-			outb(card->dmactrl, card->base + NJ_DMACTRL);
-			outb(0x0f, card->base + NJ_IRQMASK0);
-		}
-		break;
-	default:
-		pr_info("%s: %s protocol %x not handled\n", card->name,
-			__func__, protocol);
-		return -ENOPROTOOPT;
-	}
-	card->send.dmacur = inl(card->base + NJ_DMA_READ_ADR);
-	card->recv.dmacur = inl(card->base + NJ_DMA_WRITE_ADR);
-	card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2;
-	card->recv.idx = (card->recv.dmacur - card->recv.dmastart) >> 2;
-	pr_debug("%s: %s ctrl %x irq  %02x/%02x idx %d/%d\n",
-		 card->name, __func__,
-		 inb(card->base + NJ_DMACTRL),
-		 inb(card->base + NJ_IRQMASK0),
-		 inb(card->base + NJ_IRQSTAT0),
-		 card->send.idx,
-		 card->recv.idx);
-	return 0;
-}
-
-static void
-nj_reset(struct tiger_hw *card)
-{
-	outb(0xff, card->base + NJ_CTRL); /* Reset On */
-	mdelay(1);
-
-	/* now edge triggered for TJ320 GE 13/07/00 */
-	/* see comment in IRQ function */
-	if (card->typ == NETJET_S_TJ320) /* TJ320 */
-		card->ctrlreg = 0x40;  /* Reset Off and status read clear */
-	else
-		card->ctrlreg = 0x00;  /* Reset Off and status read clear */
-	outb(card->ctrlreg, card->base + NJ_CTRL);
-	mdelay(10);
-
-	/* configure AUX pins (all output except ISAC IRQ pin) */
-	card->auxd = 0;
-	card->dmactrl = 0;
-	outb(~NJ_ISACIRQ, card->base + NJ_AUXCTRL);
-	outb(NJ_ISACIRQ,  card->base + NJ_IRQMASK1);
-	outb(card->auxd, card->base + NJ_AUXDATA);
-}
-
-static int
-inittiger(struct tiger_hw *card)
-{
-	int i;
-
-	card->dma_p = dma_alloc_coherent(&card->pdev->dev, NJ_DMA_SIZE,
-					 &card->dma, GFP_ATOMIC);
-	if (!card->dma_p) {
-		pr_info("%s: No DMA memory\n", card->name);
-		return -ENOMEM;
-	}
-	if ((u64)card->dma > 0xffffffff) {
-		pr_info("%s: DMA outside 32 bit\n", card->name);
-		return -ENOMEM;
-	}
-	for (i = 0; i < 2; i++) {
-		card->bc[i].hsbuf = kmalloc(NJ_DMA_TXSIZE, GFP_ATOMIC);
-		if (!card->bc[i].hsbuf) {
-			pr_info("%s: no B%d send buffer\n", card->name, i + 1);
-			return -ENOMEM;
-		}
-		card->bc[i].hrbuf = kmalloc(NJ_DMA_RXSIZE, GFP_ATOMIC);
-		if (!card->bc[i].hrbuf) {
-			pr_info("%s: no B%d recv buffer\n", card->name, i + 1);
-			return -ENOMEM;
-		}
-	}
-	memset(card->dma_p, 0xff, NJ_DMA_SIZE);
-
-	card->send.start = card->dma_p;
-	card->send.dmastart = (u32)card->dma;
-	card->send.dmaend = card->send.dmastart +
-		(4 * (NJ_DMA_TXSIZE - 1));
-	card->send.dmairq = card->send.dmastart +
-		(4 * ((NJ_DMA_TXSIZE / 2) - 1));
-	card->send.size = NJ_DMA_TXSIZE;
-
-	if (debug & DEBUG_HW)
-		pr_notice("%s: send buffer phy %#x - %#x - %#x  virt %p"
-			  " size %zu u32\n", card->name,
-			  card->send.dmastart, card->send.dmairq,
-			  card->send.dmaend, card->send.start, card->send.size);
-
-	outl(card->send.dmastart, card->base + NJ_DMA_READ_START);
-	outl(card->send.dmairq, card->base + NJ_DMA_READ_IRQ);
-	outl(card->send.dmaend, card->base + NJ_DMA_READ_END);
-
-	card->recv.start = card->dma_p + (NJ_DMA_SIZE / 2);
-	card->recv.dmastart = (u32)card->dma  + (NJ_DMA_SIZE / 2);
-	card->recv.dmaend = card->recv.dmastart +
-		(4 * (NJ_DMA_RXSIZE - 1));
-	card->recv.dmairq = card->recv.dmastart +
-		(4 * ((NJ_DMA_RXSIZE / 2) - 1));
-	card->recv.size = NJ_DMA_RXSIZE;
-
-	if (debug & DEBUG_HW)
-		pr_notice("%s: recv buffer phy %#x - %#x - %#x  virt %p"
-			  " size %zu u32\n", card->name,
-			  card->recv.dmastart, card->recv.dmairq,
-			  card->recv.dmaend, card->recv.start, card->recv.size);
-
-	outl(card->recv.dmastart, card->base + NJ_DMA_WRITE_START);
-	outl(card->recv.dmairq, card->base + NJ_DMA_WRITE_IRQ);
-	outl(card->recv.dmaend, card->base + NJ_DMA_WRITE_END);
-	return 0;
-}
-
-static void
-read_dma(struct tiger_ch *bc, u32 idx, int cnt)
-{
-	struct tiger_hw *card = bc->bch.hw;
-	int i, stat;
-	u32 val;
-	u8 *p, *pn;
-
-	if (bc->lastrx == idx) {
-		bc->rxstate |= RX_OVERRUN;
-		pr_info("%s: B%1d overrun at idx %d\n", card->name,
-			bc->bch.nr, idx);
-	}
-	bc->lastrx = idx;
-	if (test_bit(FLG_RX_OFF, &bc->bch.Flags)) {
-		bc->bch.dropcnt += cnt;
-		return;
-	}
-	stat = bchannel_get_rxbuf(&bc->bch, cnt);
-	/* only transparent use the count here, HDLC overun is detected later */
-	if (stat == -ENOMEM) {
-		pr_warn("%s.B%d: No memory for %d bytes\n",
-			card->name, bc->bch.nr, cnt);
-		return;
-	}
-	if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags))
-		p = skb_put(bc->bch.rx_skb, cnt);
-	else
-		p = bc->hrbuf;
-
-	for (i = 0; i < cnt; i++) {
-		val = card->recv.start[idx++];
-		if (bc->bch.nr & 2)
-			val >>= 8;
-		if (idx >= card->recv.size)
-			idx = 0;
-		p[i] = val & 0xff;
-	}
-
-	if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) {
-		recv_Bchannel(&bc->bch, 0, false);
-		return;
-	}
-
-	pn = bc->hrbuf;
-	while (cnt > 0) {
-		stat = isdnhdlc_decode(&bc->hrecv, pn, cnt, &i,
-				       bc->bch.rx_skb->data, bc->bch.maxlen);
-		if (stat > 0) { /* valid frame received */
-			p = skb_put(bc->bch.rx_skb, stat);
-			if (debug & DEBUG_HW_BFIFO) {
-				snprintf(card->log, LOG_SIZE,
-					 "B%1d-recv %s %d ", bc->bch.nr,
-					 card->name, stat);
-				print_hex_dump_bytes(card->log,
-						     DUMP_PREFIX_OFFSET, p,
-						     stat);
-			}
-			recv_Bchannel(&bc->bch, 0, false);
-			stat = bchannel_get_rxbuf(&bc->bch, bc->bch.maxlen);
-			if (stat < 0) {
-				pr_warn("%s.B%d: No memory for %d bytes\n",
-					card->name, bc->bch.nr, cnt);
-				return;
-			}
-		} else if (stat == -HDLC_CRC_ERROR) {
-			pr_info("%s: B%1d receive frame CRC error\n",
-				card->name, bc->bch.nr);
-		} else if (stat == -HDLC_FRAMING_ERROR) {
-			pr_info("%s: B%1d receive framing error\n",
-				card->name, bc->bch.nr);
-		} else if (stat == -HDLC_LENGTH_ERROR) {
-			pr_info("%s: B%1d receive frame too long (> %d)\n",
-				card->name, bc->bch.nr, bc->bch.maxlen);
-		}
-		pn += i;
-		cnt -= i;
-	}
-}
-
-static void
-recv_tiger(struct tiger_hw *card, u8 irq_stat)
-{
-	u32 idx;
-	int cnt = card->recv.size / 2;
-
-	/* Note receive is via the WRITE DMA channel */
-	card->last_is0 &= ~NJ_IRQM0_WR_MASK;
-	card->last_is0 |= (irq_stat & NJ_IRQM0_WR_MASK);
-
-	if (irq_stat & NJ_IRQM0_WR_END)
-		idx = cnt - 1;
-	else
-		idx = card->recv.size - 1;
-
-	if (test_bit(FLG_ACTIVE, &card->bc[0].bch.Flags))
-		read_dma(&card->bc[0], idx, cnt);
-	if (test_bit(FLG_ACTIVE, &card->bc[1].bch.Flags))
-		read_dma(&card->bc[1], idx, cnt);
-}
-
-/* sync with current DMA address at start or after exception */
-static void
-resync(struct tiger_ch *bc, struct tiger_hw *card)
-{
-	card->send.dmacur = inl(card->base | NJ_DMA_READ_ADR);
-	card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2;
-	if (bc->free > card->send.size / 2)
-		bc->free = card->send.size / 2;
-	/* currently we simple sync to the next complete free area
-	 * this hast the advantage that we have always maximum time to
-	 * handle TX irq
-	 */
-	if (card->send.idx < ((card->send.size / 2) - 1))
-		bc->idx = (card->recv.size / 2) - 1;
-	else
-		bc->idx = card->recv.size - 1;
-	bc->txstate = TX_RUN;
-	pr_debug("%s: %s B%1d free %d idx %d/%d\n", card->name,
-		 __func__, bc->bch.nr, bc->free, bc->idx, card->send.idx);
-}
-
-static int bc_next_frame(struct tiger_ch *);
-
-static void
-fill_hdlc_flag(struct tiger_ch *bc)
-{
-	struct tiger_hw *card = bc->bch.hw;
-	int count, i;
-	u32 m, v;
-	u8  *p;
-
-	if (bc->free == 0)
-		return;
-	pr_debug("%s: %s B%1d %d state %x idx %d/%d\n", card->name,
-		 __func__, bc->bch.nr, bc->free, bc->txstate,
-		 bc->idx, card->send.idx);
-	if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN))
-		resync(bc, card);
-	count = isdnhdlc_encode(&bc->hsend, NULL, 0, &i,
-				bc->hsbuf, bc->free);
-	pr_debug("%s: B%1d hdlc encoded %d flags\n", card->name,
-		 bc->bch.nr, count);
-	bc->free -= count;
-	p = bc->hsbuf;
-	m = (bc->bch.nr & 1) ? 0xffffff00 : 0xffff00ff;
-	for (i = 0; i < count; i++) {
-		if (bc->idx >= card->send.size)
-			bc->idx = 0;
-		v = card->send.start[bc->idx];
-		v &= m;
-		v |= (bc->bch.nr & 1) ? (u32)(p[i]) : ((u32)(p[i])) << 8;
-		card->send.start[bc->idx++] = v;
-	}
-	if (debug & DEBUG_HW_BFIFO) {
-		snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ",
-			 bc->bch.nr, card->name, count);
-		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, p, count);
-	}
-}
-
-static void
-fill_dma(struct tiger_ch *bc)
-{
-	struct tiger_hw *card = bc->bch.hw;
-	int count, i, fillempty = 0;
-	u32 m, v, n = 0;
-	u8  *p;
-
-	if (bc->free == 0)
-		return;
-	if (!bc->bch.tx_skb) {
-		if (!test_bit(FLG_TX_EMPTY, &bc->bch.Flags))
-			return;
-		fillempty = 1;
-		count = card->send.size >> 1;
-		p = bc->bch.fill;
-	} else {
-		count = bc->bch.tx_skb->len - bc->bch.tx_idx;
-		if (count <= 0)
-			return;
-		pr_debug("%s: %s B%1d %d/%d/%d/%d state %x idx %d/%d\n",
-			 card->name, __func__, bc->bch.nr, count, bc->free,
-			 bc->bch.tx_idx, bc->bch.tx_skb->len, bc->txstate,
-			 bc->idx, card->send.idx);
-		p = bc->bch.tx_skb->data + bc->bch.tx_idx;
-	}
-	if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN))
-		resync(bc, card);
-	if (test_bit(FLG_HDLC, &bc->bch.Flags) && !fillempty) {
-		count = isdnhdlc_encode(&bc->hsend, p, count, &i,
-					bc->hsbuf, bc->free);
-		pr_debug("%s: B%1d hdlc encoded %d in %d\n", card->name,
-			 bc->bch.nr, i, count);
-		bc->bch.tx_idx += i;
-		bc->free -= count;
-		p = bc->hsbuf;
-	} else {
-		if (count > bc->free)
-			count = bc->free;
-		if (!fillempty)
-			bc->bch.tx_idx += count;
-		bc->free -= count;
-	}
-	m = (bc->bch.nr & 1) ? 0xffffff00 : 0xffff00ff;
-	if (fillempty) {
-		n = p[0];
-		if (!(bc->bch.nr & 1))
-			n <<= 8;
-		for (i = 0; i < count; i++) {
-			if (bc->idx >= card->send.size)
-				bc->idx = 0;
-			v = card->send.start[bc->idx];
-			v &= m;
-			v |= n;
-			card->send.start[bc->idx++] = v;
-		}
-	} else {
-		for (i = 0; i < count; i++) {
-			if (bc->idx >= card->send.size)
-				bc->idx = 0;
-			v = card->send.start[bc->idx];
-			v &= m;
-			n = p[i];
-			v |= (bc->bch.nr & 1) ? n : n << 8;
-			card->send.start[bc->idx++] = v;
-		}
-	}
-	if (debug & DEBUG_HW_BFIFO) {
-		snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ",
-			 bc->bch.nr, card->name, count);
-		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, p, count);
-	}
-	if (bc->free)
-		bc_next_frame(bc);
-}
-
-
-static int
-bc_next_frame(struct tiger_ch *bc)
-{
-	int ret = 1;
-
-	if (bc->bch.tx_skb && bc->bch.tx_idx < bc->bch.tx_skb->len) {
-		fill_dma(bc);
-	} else {
-		dev_kfree_skb(bc->bch.tx_skb);
-		if (get_next_bframe(&bc->bch)) {
-			fill_dma(bc);
-			test_and_clear_bit(FLG_TX_EMPTY, &bc->bch.Flags);
-		} else if (test_bit(FLG_TX_EMPTY, &bc->bch.Flags)) {
-			fill_dma(bc);
-		} else if (test_bit(FLG_FILLEMPTY, &bc->bch.Flags)) {
-			test_and_set_bit(FLG_TX_EMPTY, &bc->bch.Flags);
-			ret = 0;
-		} else {
-			ret = 0;
-		}
-	}
-	return ret;
-}
-
-static void
-send_tiger_bc(struct tiger_hw *card, struct tiger_ch *bc)
-{
-	int ret;
-
-	bc->free += card->send.size / 2;
-	if (bc->free >= card->send.size) {
-		if (!(bc->txstate & (TX_UNDERRUN | TX_INIT))) {
-			pr_info("%s: B%1d TX underrun state %x\n", card->name,
-				bc->bch.nr, bc->txstate);
-			bc->txstate |= TX_UNDERRUN;
-		}
-		bc->free = card->send.size;
-	}
-	ret = bc_next_frame(bc);
-	if (!ret) {
-		if (test_bit(FLG_HDLC, &bc->bch.Flags)) {
-			fill_hdlc_flag(bc);
-			return;
-		}
-		pr_debug("%s: B%1d TX no data free %d idx %d/%d\n", card->name,
-			 bc->bch.nr, bc->free, bc->idx, card->send.idx);
-		if (!(bc->txstate & (TX_IDLE | TX_INIT))) {
-			fill_mem(bc, bc->idx, bc->free, 0xff);
-			if (bc->free == card->send.size)
-				bc->txstate |= TX_IDLE;
-		}
-	}
-}
-
-static void
-send_tiger(struct tiger_hw *card, u8 irq_stat)
-{
-	int i;
-
-	/* Note send is via the READ DMA channel */
-	if ((irq_stat & card->last_is0) & NJ_IRQM0_RD_MASK) {
-		pr_info("%s: tiger warn write double dma %x/%x\n",
-			card->name, irq_stat, card->last_is0);
-		return;
-	} else {
-		card->last_is0 &= ~NJ_IRQM0_RD_MASK;
-		card->last_is0 |= (irq_stat & NJ_IRQM0_RD_MASK);
-	}
-	for (i = 0; i < 2; i++) {
-		if (test_bit(FLG_ACTIVE, &card->bc[i].bch.Flags))
-			send_tiger_bc(card, &card->bc[i]);
-	}
-}
-
-static irqreturn_t
-nj_irq(int intno, void *dev_id)
-{
-	struct tiger_hw *card = dev_id;
-	u8 val, s1val, s0val;
-
-	spin_lock(&card->lock);
-	s0val = inb(card->base | NJ_IRQSTAT0);
-	s1val = inb(card->base | NJ_IRQSTAT1);
-	if ((s1val & NJ_ISACIRQ) && (s0val == 0)) {
-		/* shared IRQ */
-		spin_unlock(&card->lock);
-		return IRQ_NONE;
-	}
-	pr_debug("%s: IRQSTAT0 %02x IRQSTAT1 %02x\n", card->name, s0val, s1val);
-	card->irqcnt++;
-	if (!(s1val & NJ_ISACIRQ)) {
-		val = ReadISAC_nj(card, ISAC_ISTA);
-		if (val)
-			mISDNisac_irq(&card->isac, val);
-	}
-
-	if (s0val)
-		/* write to clear */
-		outb(s0val, card->base | NJ_IRQSTAT0);
-	else
-		goto end;
-	s1val = s0val;
-	/* set bits in sval to indicate which page is free */
-	card->recv.dmacur = inl(card->base | NJ_DMA_WRITE_ADR);
-	card->recv.idx = (card->recv.dmacur - card->recv.dmastart) >> 2;
-	if (card->recv.dmacur < card->recv.dmairq)
-		s0val = 0x08;	/* the 2nd write area is free */
-	else
-		s0val = 0x04;	/* the 1st write area is free */
-
-	card->send.dmacur = inl(card->base | NJ_DMA_READ_ADR);
-	card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2;
-	if (card->send.dmacur < card->send.dmairq)
-		s0val |= 0x02;	/* the 2nd read area is free */
-	else
-		s0val |= 0x01;	/* the 1st read area is free */
-
-	pr_debug("%s: DMA Status %02x/%02x/%02x %d/%d\n", card->name,
-		 s1val, s0val, card->last_is0,
-		 card->recv.idx, card->send.idx);
-	/* test if we have a DMA interrupt */
-	if (s0val != card->last_is0) {
-		if ((s0val & NJ_IRQM0_RD_MASK) !=
-		    (card->last_is0 & NJ_IRQM0_RD_MASK))
-			/* got a write dma int */
-			send_tiger(card, s0val);
-		if ((s0val & NJ_IRQM0_WR_MASK) !=
-		    (card->last_is0 & NJ_IRQM0_WR_MASK))
-			/* got a read dma int */
-			recv_tiger(card, s0val);
-	}
-end:
-	spin_unlock(&card->lock);
-	return IRQ_HANDLED;
-}
-
-static int
-nj_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	int ret = -EINVAL;
-	struct bchannel *bch = container_of(ch, struct bchannel, ch);
-	struct tiger_ch *bc = container_of(bch, struct tiger_ch, bch);
-	struct tiger_hw *card = bch->hw;
-	struct mISDNhead *hh = mISDN_HEAD_P(skb);
-	unsigned long flags;
-
-	switch (hh->prim) {
-	case PH_DATA_REQ:
-		spin_lock_irqsave(&card->lock, flags);
-		ret = bchannel_senddata(bch, skb);
-		if (ret > 0) { /* direct TX */
-			fill_dma(bc);
-			ret = 0;
-		}
-		spin_unlock_irqrestore(&card->lock, flags);
-		return ret;
-	case PH_ACTIVATE_REQ:
-		spin_lock_irqsave(&card->lock, flags);
-		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
-			ret = mode_tiger(bc, ch->protocol);
-		else
-			ret = 0;
-		spin_unlock_irqrestore(&card->lock, flags);
-		if (!ret)
-			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-				    NULL, GFP_KERNEL);
-		break;
-	case PH_DEACTIVATE_REQ:
-		spin_lock_irqsave(&card->lock, flags);
-		mISDN_clear_bchannel(bch);
-		mode_tiger(bc, ISDN_P_NONE);
-		spin_unlock_irqrestore(&card->lock, flags);
-		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			    NULL, GFP_KERNEL);
-		ret = 0;
-		break;
-	}
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-static int
-channel_bctrl(struct tiger_ch *bc, struct mISDN_ctrl_req *cq)
-{
-	return mISDN_ctrl_bchannel(&bc->bch, cq);
-}
-
-static int
-nj_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
-{
-	struct bchannel *bch = container_of(ch, struct bchannel, ch);
-	struct tiger_ch *bc = container_of(bch, struct tiger_ch, bch);
-	struct tiger_hw *card  = bch->hw;
-	int ret = -EINVAL;
-	u_long flags;
-
-	pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg);
-	switch (cmd) {
-	case CLOSE_CHANNEL:
-		test_and_clear_bit(FLG_OPEN, &bch->Flags);
-		cancel_work_sync(&bch->workq);
-		spin_lock_irqsave(&card->lock, flags);
-		mISDN_clear_bchannel(bch);
-		mode_tiger(bc, ISDN_P_NONE);
-		spin_unlock_irqrestore(&card->lock, flags);
-		ch->protocol = ISDN_P_NONE;
-		ch->peer = NULL;
-		module_put(THIS_MODULE);
-		ret = 0;
-		break;
-	case CONTROL_CHANNEL:
-		ret = channel_bctrl(bc, arg);
-		break;
-	default:
-		pr_info("%s: %s unknown prim(%x)\n", card->name, __func__, cmd);
-	}
-	return ret;
-}
-
-static int
-channel_ctrl(struct tiger_hw *card, struct mISDN_ctrl_req *cq)
-{
-	int	ret = 0;
-
-	switch (cq->op) {
-	case MISDN_CTRL_GETOP:
-		cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
-		break;
-	case MISDN_CTRL_LOOP:
-		/* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
-		if (cq->channel < 0 || cq->channel > 3) {
-			ret = -EINVAL;
-			break;
-		}
-		ret = card->isac.ctrl(&card->isac, HW_TESTLOOP, cq->channel);
-		break;
-	case MISDN_CTRL_L1_TIMER3:
-		ret = card->isac.ctrl(&card->isac, HW_TIMER3_VALUE, cq->p1);
-		break;
-	default:
-		pr_info("%s: %s unknown Op %x\n", card->name, __func__, cq->op);
-		ret = -EINVAL;
-		break;
-	}
-	return ret;
-}
-
-static int
-open_bchannel(struct tiger_hw *card, struct channel_req *rq)
-{
-	struct bchannel *bch;
-
-	if (rq->adr.channel == 0 || rq->adr.channel > 2)
-		return -EINVAL;
-	if (rq->protocol == ISDN_P_NONE)
-		return -EINVAL;
-	bch = &card->bc[rq->adr.channel - 1].bch;
-	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
-		return -EBUSY; /* b-channel can be only open once */
-	test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
-	bch->ch.protocol = rq->protocol;
-	rq->ch = &bch->ch;
-	return 0;
-}
-
-/*
- * device control function
- */
-static int
-nj_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
-{
-	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
-	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
-	struct tiger_hw	*card = dch->hw;
-	struct channel_req	*rq;
-	int			err = 0;
-
-	pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg);
-	switch (cmd) {
-	case OPEN_CHANNEL:
-		rq = arg;
-		if (rq->protocol == ISDN_P_TE_S0)
-			err = card->isac.open(&card->isac, rq);
-		else
-			err = open_bchannel(card, rq);
-		if (err)
-			break;
-		if (!try_module_get(THIS_MODULE))
-			pr_info("%s: cannot get module\n", card->name);
-		break;
-	case CLOSE_CHANNEL:
-		pr_debug("%s: dev(%d) close from %p\n", card->name, dch->dev.id,
-			 __builtin_return_address(0));
-		module_put(THIS_MODULE);
-		break;
-	case CONTROL_CHANNEL:
-		err = channel_ctrl(card, arg);
-		break;
-	default:
-		pr_debug("%s: %s unknown command %x\n",
-			 card->name, __func__, cmd);
-		return -EINVAL;
-	}
-	return err;
-}
-
-static int
-nj_init_card(struct tiger_hw *card)
-{
-	u_long flags;
-	int ret;
-
-	spin_lock_irqsave(&card->lock, flags);
-	nj_disable_hwirq(card);
-	spin_unlock_irqrestore(&card->lock, flags);
-
-	card->irq = card->pdev->irq;
-	if (request_irq(card->irq, nj_irq, IRQF_SHARED, card->name, card)) {
-		pr_info("%s: couldn't get interrupt %d\n",
-			card->name, card->irq);
-		card->irq = -1;
-		return -EIO;
-	}
-
-	spin_lock_irqsave(&card->lock, flags);
-	nj_reset(card);
-	ret = card->isac.init(&card->isac);
-	if (ret)
-		goto error;
-	ret = inittiger(card);
-	if (ret)
-		goto error;
-	mode_tiger(&card->bc[0], ISDN_P_NONE);
-	mode_tiger(&card->bc[1], ISDN_P_NONE);
-error:
-	spin_unlock_irqrestore(&card->lock, flags);
-	return ret;
-}
-
-
-static void
-nj_release(struct tiger_hw *card)
-{
-	u_long flags;
-	int i;
-
-	if (card->base_s) {
-		spin_lock_irqsave(&card->lock, flags);
-		nj_disable_hwirq(card);
-		mode_tiger(&card->bc[0], ISDN_P_NONE);
-		mode_tiger(&card->bc[1], ISDN_P_NONE);
-		spin_unlock_irqrestore(&card->lock, flags);
-		card->isac.release(&card->isac);
-		release_region(card->base, card->base_s);
-		card->base_s = 0;
-	}
-	if (card->irq > 0)
-		free_irq(card->irq, card);
-	if (device_is_registered(&card->isac.dch.dev.dev))
-		mISDN_unregister_device(&card->isac.dch.dev);
-
-	for (i = 0; i < 2; i++) {
-		mISDN_freebchannel(&card->bc[i].bch);
-		kfree(card->bc[i].hsbuf);
-		kfree(card->bc[i].hrbuf);
-	}
-	if (card->dma_p)
-		dma_free_coherent(&card->pdev->dev, NJ_DMA_SIZE, card->dma_p,
-				  card->dma);
-	write_lock_irqsave(&card_lock, flags);
-	list_del(&card->list);
-	write_unlock_irqrestore(&card_lock, flags);
-	pci_disable_device(card->pdev);
-	pci_set_drvdata(card->pdev, NULL);
-	kfree(card);
-}
-
-
-static int
-nj_setup(struct tiger_hw *card)
-{
-	card->base = pci_resource_start(card->pdev, 0);
-	card->base_s = pci_resource_len(card->pdev, 0);
-	if (!request_region(card->base, card->base_s, card->name)) {
-		pr_info("%s: NETjet config port %#x-%#x already in use\n",
-			card->name, card->base,
-			(u32)(card->base + card->base_s - 1));
-		card->base_s = 0;
-		return -EIO;
-	}
-	ASSIGN_FUNC(nj, ISAC, card->isac);
-	return 0;
-}
-
-
-static int
-setup_instance(struct tiger_hw *card)
-{
-	int i, err;
-	u_long flags;
-
-	snprintf(card->name, MISDN_MAX_IDLEN - 1, "netjet.%d", nj_cnt + 1);
-	write_lock_irqsave(&card_lock, flags);
-	list_add_tail(&card->list, &Cards);
-	write_unlock_irqrestore(&card_lock, flags);
-
-	_set_debug(card);
-	card->isac.name = card->name;
-	spin_lock_init(&card->lock);
-	card->isac.hwlock = &card->lock;
-	mISDNisac_init(&card->isac, card);
-
-	card->isac.dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
-	card->isac.dch.dev.D.ctrl = nj_dctrl;
-	for (i = 0; i < 2; i++) {
-		card->bc[i].bch.nr = i + 1;
-		set_channelmap(i + 1, card->isac.dch.dev.channelmap);
-		mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM,
-				   NJ_DMA_RXSIZE >> 1);
-		card->bc[i].bch.hw = card;
-		card->bc[i].bch.ch.send = nj_l2l1B;
-		card->bc[i].bch.ch.ctrl = nj_bctrl;
-		card->bc[i].bch.ch.nr = i + 1;
-		list_add(&card->bc[i].bch.ch.list,
-			 &card->isac.dch.dev.bchannels);
-		card->bc[i].bch.hw = card;
-	}
-	err = nj_setup(card);
-	if (err)
-		goto error;
-	err = mISDN_register_device(&card->isac.dch.dev, &card->pdev->dev,
-				    card->name);
-	if (err)
-		goto error;
-	err = nj_init_card(card);
-	if (!err)  {
-		nj_cnt++;
-		pr_notice("Netjet %d cards installed\n", nj_cnt);
-		return 0;
-	}
-error:
-	nj_release(card);
-	return err;
-}
-
-static int
-nj_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	int err = -ENOMEM;
-	int cfg;
-	struct tiger_hw *card;
-
-	if (pdev->subsystem_vendor == 0x8086 &&
-	    pdev->subsystem_device == 0x0003) {
-		pr_notice("Netjet: Digium X100P/X101P not handled\n");
-		return -ENODEV;
-	}
-
-	if (pdev->subsystem_vendor == 0x55 &&
-	    pdev->subsystem_device == 0x02) {
-		pr_notice("Netjet: Enter!Now not handled yet\n");
-		return -ENODEV;
-	}
-
-	if (pdev->subsystem_vendor == 0xb100 &&
-	    pdev->subsystem_device == 0x0003) {
-		pr_notice("Netjet: Digium TDM400P not handled yet\n");
-		return -ENODEV;
-	}
-
-	card = kzalloc_obj(struct tiger_hw);
-	if (!card) {
-		pr_info("No kmem for Netjet\n");
-		return err;
-	}
-
-	card->pdev = pdev;
-
-	err = pci_enable_device(pdev);
-	if (err) {
-		kfree(card);
-		return err;
-	}
-
-	printk(KERN_INFO "nj_probe(mISDN): found adapter at %s\n",
-	       pci_name(pdev));
-
-	pci_set_master(pdev);
-
-	/* the TJ300 and TJ320 must be detected, the IRQ handling is different
-	 * unfortunately the chips use the same device ID, but the TJ320 has
-	 * the bit20 in status PCI cfg register set
-	 */
-	pci_read_config_dword(pdev, 0x04, &cfg);
-	if (cfg & 0x00100000)
-		card->typ = NETJET_S_TJ320;
-	else
-		card->typ = NETJET_S_TJ300;
-
-	card->base = pci_resource_start(pdev, 0);
-	pci_set_drvdata(pdev, card);
-	err = setup_instance(card);
-	if (err)
-		pci_set_drvdata(pdev, NULL);
-
-	return err;
-}
-
-
-static void nj_remove(struct pci_dev *pdev)
-{
-	struct tiger_hw *card = pci_get_drvdata(pdev);
-
-	if (card)
-		nj_release(card);
-	else
-		pr_info("%s drvdata already removed\n", __func__);
-}
-
-/* We cannot select cards with PCI_SUB... IDs, since here are cards with
- * SUB IDs set to PCI_ANY_ID, so we need to match all and reject
- * known other cards which not work with this driver - see probe function */
-static const struct pci_device_id nj_pci_ids[] = {
-	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_300,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ }
-};
-MODULE_DEVICE_TABLE(pci, nj_pci_ids);
-
-static struct pci_driver nj_driver = {
-	.name = "netjet",
-	.probe = nj_probe,
-	.remove = nj_remove,
-	.id_table = nj_pci_ids,
-};
-
-static int __init nj_init(void)
-{
-	int err;
-
-	pr_notice("Netjet PCI driver Rev. %s\n", NETJET_REV);
-	err = pci_register_driver(&nj_driver);
-	return err;
-}
-
-static void __exit nj_cleanup(void)
-{
-	pci_unregister_driver(&nj_driver);
-}
-
-module_init(nj_init);
-module_exit(nj_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/speedfax.c b/drivers/isdn/hardware/mISDN/speedfax.c
deleted file mode 100644
index ab24c3c460e6..000000000000
--- a/drivers/isdn/hardware/mISDN/speedfax.c
+++ /dev/null
@@ -1,520 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * speedfax.c	low level stuff for Sedlbauer Speedfax+ cards
- *		based on the ISAR DSP
- *		Thanks to Sedlbauer AG for informations and HW
- *
- * Author       Karsten Keil <keil@isdn4linux.de>
- *
- * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
- */
-
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/mISDNhw.h>
-#include <linux/firmware.h>
-#include "ipac.h"
-#include "isar.h"
-
-#define SPEEDFAX_REV	"2.0"
-
-#define PCI_SUBVENDOR_SPEEDFAX_PYRAMID	0x51
-#define PCI_SUBVENDOR_SPEEDFAX_PCI	0x54
-#define PCI_SUB_ID_SEDLBAUER		0x01
-
-#define SFAX_PCI_ADDR		0xc8
-#define SFAX_PCI_ISAC		0xd0
-#define SFAX_PCI_ISAR		0xe0
-
-/* TIGER 100 Registers */
-
-#define TIGER_RESET_ADDR	0x00
-#define TIGER_EXTERN_RESET_ON	0x01
-#define TIGER_EXTERN_RESET_OFF	0x00
-#define TIGER_AUX_CTRL		0x02
-#define TIGER_AUX_DATA		0x03
-#define TIGER_AUX_IRQMASK	0x05
-#define TIGER_AUX_STATUS	0x07
-
-/* Tiger AUX BITs */
-#define SFAX_AUX_IOMASK		0xdd	/* 1 and 5 are inputs */
-#define SFAX_ISAR_RESET_BIT_OFF 0x00
-#define SFAX_ISAR_RESET_BIT_ON	0x01
-#define SFAX_TIGER_IRQ_BIT	0x02
-#define SFAX_LED1_BIT		0x08
-#define SFAX_LED2_BIT		0x10
-
-#define SFAX_PCI_RESET_ON	(SFAX_ISAR_RESET_BIT_ON)
-#define SFAX_PCI_RESET_OFF	(SFAX_LED1_BIT | SFAX_LED2_BIT)
-
-static int sfax_cnt;
-static u32 debug;
-static u32 irqloops = 4;
-
-struct sfax_hw {
-	struct list_head	list;
-	struct pci_dev		*pdev;
-	char			name[MISDN_MAX_IDLEN];
-	u32			irq;
-	u32			irqcnt;
-	u32			cfg;
-	struct _ioport		p_isac;
-	struct _ioport		p_isar;
-	u8			aux_data;
-	spinlock_t		lock;	/* HW access lock */
-	struct isac_hw		isac;
-	struct isar_hw		isar;
-};
-
-static LIST_HEAD(Cards);
-static DEFINE_RWLOCK(card_lock); /* protect Cards */
-
-static void
-_set_debug(struct sfax_hw *card)
-{
-	card->isac.dch.debug = debug;
-	card->isar.ch[0].bch.debug = debug;
-	card->isar.ch[1].bch.debug = debug;
-}
-
-static int
-set_debug(const char *val, const struct kernel_param *kp)
-{
-	int ret;
-	struct sfax_hw *card;
-
-	ret = param_set_uint(val, kp);
-	if (!ret) {
-		read_lock(&card_lock);
-		list_for_each_entry(card, &Cards, list)
-			_set_debug(card);
-		read_unlock(&card_lock);
-	}
-	return ret;
-}
-
-MODULE_AUTHOR("Karsten Keil");
-MODULE_DESCRIPTION("mISDN driver for Sedlbauer Speedfax+ cards");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(SPEEDFAX_REV);
-MODULE_FIRMWARE("isdn/ISAR.BIN");
-module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Speedfax debug mask");
-module_param(irqloops, uint, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(irqloops, "Speedfax maximal irqloops (default 4)");
-
-IOFUNC_IND(ISAC, sfax_hw, p_isac)
-IOFUNC_IND(ISAR, sfax_hw, p_isar)
-
-static irqreturn_t
-speedfax_irq(int intno, void *dev_id)
-{
-	struct sfax_hw	*sf = dev_id;
-	u8 val;
-	int cnt = irqloops;
-
-	spin_lock(&sf->lock);
-	val = inb(sf->cfg + TIGER_AUX_STATUS);
-	if (val & SFAX_TIGER_IRQ_BIT) { /* for us or shared ? */
-		spin_unlock(&sf->lock);
-		return IRQ_NONE; /* shared */
-	}
-	sf->irqcnt++;
-	val = ReadISAR_IND(sf, ISAR_IRQBIT);
-Start_ISAR:
-	if (val & ISAR_IRQSTA)
-		mISDNisar_irq(&sf->isar);
-	val = ReadISAC_IND(sf, ISAC_ISTA);
-	if (val)
-		mISDNisac_irq(&sf->isac, val);
-	val = ReadISAR_IND(sf, ISAR_IRQBIT);
-	if ((val & ISAR_IRQSTA) && cnt--)
-		goto Start_ISAR;
-	if (cnt < irqloops)
-		pr_debug("%s: %d irqloops cpu%d\n", sf->name,
-			 irqloops - cnt, smp_processor_id());
-	if (irqloops && !cnt)
-		pr_notice("%s: %d IRQ LOOP cpu%d\n", sf->name,
-			  irqloops, smp_processor_id());
-	spin_unlock(&sf->lock);
-	return IRQ_HANDLED;
-}
-
-static void
-enable_hwirq(struct sfax_hw *sf)
-{
-	WriteISAC_IND(sf, ISAC_MASK, 0);
-	WriteISAR_IND(sf, ISAR_IRQBIT, ISAR_IRQMSK);
-	outb(SFAX_TIGER_IRQ_BIT, sf->cfg + TIGER_AUX_IRQMASK);
-}
-
-static void
-disable_hwirq(struct sfax_hw *sf)
-{
-	WriteISAC_IND(sf, ISAC_MASK, 0xFF);
-	WriteISAR_IND(sf, ISAR_IRQBIT, 0);
-	outb(0, sf->cfg + TIGER_AUX_IRQMASK);
-}
-
-static void
-reset_speedfax(struct sfax_hw *sf)
-{
-
-	pr_debug("%s: resetting card\n", sf->name);
-	outb(TIGER_EXTERN_RESET_ON, sf->cfg + TIGER_RESET_ADDR);
-	outb(SFAX_PCI_RESET_ON, sf->cfg + TIGER_AUX_DATA);
-	mdelay(1);
-	outb(TIGER_EXTERN_RESET_OFF, sf->cfg + TIGER_RESET_ADDR);
-	sf->aux_data = SFAX_PCI_RESET_OFF;
-	outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
-	mdelay(1);
-}
-
-static int
-sfax_ctrl(struct sfax_hw  *sf, u32 cmd, u_long arg)
-{
-	int ret = 0;
-
-	switch (cmd) {
-	case HW_RESET_REQ:
-		reset_speedfax(sf);
-		break;
-	case HW_ACTIVATE_IND:
-		if (arg & 1)
-			sf->aux_data &= ~SFAX_LED1_BIT;
-		if (arg & 2)
-			sf->aux_data &= ~SFAX_LED2_BIT;
-		outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
-		break;
-	case HW_DEACT_IND:
-		if (arg & 1)
-			sf->aux_data |= SFAX_LED1_BIT;
-		if (arg & 2)
-			sf->aux_data |= SFAX_LED2_BIT;
-		outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
-		break;
-	default:
-		pr_info("%s: %s unknown command %x %lx\n",
-			sf->name, __func__, cmd, arg);
-		ret = -EINVAL;
-		break;
-	}
-	return ret;
-}
-
-static int
-channel_ctrl(struct sfax_hw  *sf, struct mISDN_ctrl_req *cq)
-{
-	int	ret = 0;
-
-	switch (cq->op) {
-	case MISDN_CTRL_GETOP:
-		cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
-		break;
-	case MISDN_CTRL_LOOP:
-		/* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
-		if (cq->channel < 0 || cq->channel > 3) {
-			ret = -EINVAL;
-			break;
-		}
-		ret = sf->isac.ctrl(&sf->isac, HW_TESTLOOP, cq->channel);
-		break;
-	case MISDN_CTRL_L1_TIMER3:
-		ret = sf->isac.ctrl(&sf->isac, HW_TIMER3_VALUE, cq->p1);
-		break;
-	default:
-		pr_info("%s: unknown Op %x\n", sf->name, cq->op);
-		ret = -EINVAL;
-		break;
-	}
-	return ret;
-}
-
-static int
-sfax_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
-{
-	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
-	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
-	struct sfax_hw		*sf = dch->hw;
-	struct channel_req	*rq;
-	int			err = 0;
-
-	pr_debug("%s: cmd:%x %p\n", sf->name, cmd, arg);
-	switch (cmd) {
-	case OPEN_CHANNEL:
-		rq = arg;
-		if (rq->protocol == ISDN_P_TE_S0)
-			err = sf->isac.open(&sf->isac, rq);
-		else
-			err = sf->isar.open(&sf->isar, rq);
-		if (err)
-			break;
-		if (!try_module_get(THIS_MODULE))
-			pr_info("%s: cannot get module\n", sf->name);
-		break;
-	case CLOSE_CHANNEL:
-		pr_debug("%s: dev(%d) close from %p\n", sf->name,
-			 dch->dev.id, __builtin_return_address(0));
-		module_put(THIS_MODULE);
-		break;
-	case CONTROL_CHANNEL:
-		err = channel_ctrl(sf, arg);
-		break;
-	default:
-		pr_debug("%s: unknown command %x\n", sf->name, cmd);
-		return -EINVAL;
-	}
-	return err;
-}
-
-static int
-init_card(struct sfax_hw *sf)
-{
-	int	ret, cnt = 3;
-	u_long	flags;
-
-	ret = request_irq(sf->irq, speedfax_irq, IRQF_SHARED, sf->name, sf);
-	if (ret) {
-		pr_info("%s: couldn't get interrupt %d\n", sf->name, sf->irq);
-		return ret;
-	}
-	while (cnt--) {
-		spin_lock_irqsave(&sf->lock, flags);
-		ret = sf->isac.init(&sf->isac);
-		if (ret) {
-			spin_unlock_irqrestore(&sf->lock, flags);
-			pr_info("%s: ISAC init failed with %d\n",
-				sf->name, ret);
-			break;
-		}
-		enable_hwirq(sf);
-		/* RESET Receiver and Transmitter */
-		WriteISAC_IND(sf, ISAC_CMDR, 0x41);
-		spin_unlock_irqrestore(&sf->lock, flags);
-		msleep_interruptible(10);
-		if (debug & DEBUG_HW)
-			pr_notice("%s: IRQ %d count %d\n", sf->name,
-				  sf->irq, sf->irqcnt);
-		if (!sf->irqcnt) {
-			pr_info("%s: IRQ(%d) got no requests during init %d\n",
-				sf->name, sf->irq, 3 - cnt);
-		} else
-			return 0;
-	}
-	free_irq(sf->irq, sf);
-	return -EIO;
-}
-
-
-static int
-setup_speedfax(struct sfax_hw *sf)
-{
-	u_long flags;
-
-	if (!request_region(sf->cfg, 256, sf->name)) {
-		pr_info("mISDN: %s config port %x-%x already in use\n",
-			sf->name, sf->cfg, sf->cfg + 255);
-		return -EIO;
-	}
-	outb(0xff, sf->cfg);
-	outb(0, sf->cfg);
-	outb(0xdd, sf->cfg + TIGER_AUX_CTRL);
-	outb(0, sf->cfg + TIGER_AUX_IRQMASK);
-
-	sf->isac.type = IPAC_TYPE_ISAC;
-	sf->p_isac.ale = sf->cfg + SFAX_PCI_ADDR;
-	sf->p_isac.port = sf->cfg + SFAX_PCI_ISAC;
-	sf->p_isar.ale = sf->cfg + SFAX_PCI_ADDR;
-	sf->p_isar.port = sf->cfg + SFAX_PCI_ISAR;
-	ASSIGN_FUNC(IND, ISAC, sf->isac);
-	ASSIGN_FUNC(IND, ISAR, sf->isar);
-	spin_lock_irqsave(&sf->lock, flags);
-	reset_speedfax(sf);
-	disable_hwirq(sf);
-	spin_unlock_irqrestore(&sf->lock, flags);
-	return 0;
-}
-
-static void
-release_card(struct sfax_hw *card) {
-	u_long	flags;
-
-	spin_lock_irqsave(&card->lock, flags);
-	disable_hwirq(card);
-	spin_unlock_irqrestore(&card->lock, flags);
-	card->isac.release(&card->isac);
-	free_irq(card->irq, card);
-	card->isar.release(&card->isar);
-	mISDN_unregister_device(&card->isac.dch.dev);
-	release_region(card->cfg, 256);
-	pci_disable_device(card->pdev);
-	pci_set_drvdata(card->pdev, NULL);
-	write_lock_irqsave(&card_lock, flags);
-	list_del(&card->list);
-	write_unlock_irqrestore(&card_lock, flags);
-	kfree(card);
-	sfax_cnt--;
-}
-
-static int
-setup_instance(struct sfax_hw *card)
-{
-	const struct firmware *firmware;
-	int i, err;
-	u_long flags;
-
-	snprintf(card->name, MISDN_MAX_IDLEN - 1, "Speedfax.%d", sfax_cnt + 1);
-	write_lock_irqsave(&card_lock, flags);
-	list_add_tail(&card->list, &Cards);
-	write_unlock_irqrestore(&card_lock, flags);
-	_set_debug(card);
-	spin_lock_init(&card->lock);
-	card->isac.hwlock = &card->lock;
-	card->isar.hwlock = &card->lock;
-	card->isar.ctrl = (void *)&sfax_ctrl;
-	card->isac.name = card->name;
-	card->isar.name = card->name;
-	card->isar.owner = THIS_MODULE;
-
-	err = request_firmware(&firmware, "isdn/ISAR.BIN", &card->pdev->dev);
-	if (err < 0) {
-		pr_info("%s: firmware request failed %d\n",
-			card->name, err);
-		goto error_fw;
-	}
-	if (debug & DEBUG_HW)
-		pr_notice("%s: got firmware %zu bytes\n",
-			  card->name, firmware->size);
-
-	mISDNisac_init(&card->isac, card);
-
-	card->isac.dch.dev.D.ctrl = sfax_dctrl;
-	card->isac.dch.dev.Bprotocols =
-		mISDNisar_init(&card->isar, card);
-	for (i = 0; i < 2; i++) {
-		set_channelmap(i + 1, card->isac.dch.dev.channelmap);
-		list_add(&card->isar.ch[i].bch.ch.list,
-			 &card->isac.dch.dev.bchannels);
-	}
-
-	err = setup_speedfax(card);
-	if (err)
-		goto error_setup;
-	err = card->isar.init(&card->isar);
-	if (err)
-		goto error;
-	err = mISDN_register_device(&card->isac.dch.dev,
-				    &card->pdev->dev, card->name);
-	if (err)
-		goto error;
-	err = init_card(card);
-	if (err)
-		goto error_init;
-	err = card->isar.firmware(&card->isar, firmware->data, firmware->size);
-	if (!err)  {
-		release_firmware(firmware);
-		sfax_cnt++;
-		pr_notice("SpeedFax %d cards installed\n", sfax_cnt);
-		return 0;
-	}
-	disable_hwirq(card);
-	free_irq(card->irq, card);
-error_init:
-	mISDN_unregister_device(&card->isac.dch.dev);
-error:
-	release_region(card->cfg, 256);
-error_setup:
-	card->isac.release(&card->isac);
-	card->isar.release(&card->isar);
-	release_firmware(firmware);
-error_fw:
-	pci_disable_device(card->pdev);
-	write_lock_irqsave(&card_lock, flags);
-	list_del(&card->list);
-	write_unlock_irqrestore(&card_lock, flags);
-	kfree(card);
-	return err;
-}
-
-static int
-sfaxpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	int err = -ENOMEM;
-	struct sfax_hw *card = kzalloc_obj(struct sfax_hw);
-
-	if (!card) {
-		pr_info("No memory for Speedfax+ PCI\n");
-		return err;
-	}
-	card->pdev = pdev;
-	err = pci_enable_device(pdev);
-	if (err) {
-		kfree(card);
-		return err;
-	}
-
-	pr_notice("mISDN: Speedfax found adapter %s at %s\n",
-		  (char *)ent->driver_data, pci_name(pdev));
-
-	card->cfg = pci_resource_start(pdev, 0);
-	card->irq = pdev->irq;
-	pci_set_drvdata(pdev, card);
-	err = setup_instance(card);
-	if (err)
-		pci_set_drvdata(pdev, NULL);
-	return err;
-}
-
-static void
-sfax_remove_pci(struct pci_dev *pdev)
-{
-	struct sfax_hw	*card = pci_get_drvdata(pdev);
-
-	if (card)
-		release_card(card);
-	else
-		pr_debug("%s: drvdata already removed\n", __func__);
-}
-
-static struct pci_device_id sfaxpci_ids[] = {
-	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
-	  PCI_SUBVENDOR_SPEEDFAX_PYRAMID, PCI_SUB_ID_SEDLBAUER,
-	  0, 0, (unsigned long) "Pyramid Speedfax + PCI"
-	},
-	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
-	  PCI_SUBVENDOR_SPEEDFAX_PCI, PCI_SUB_ID_SEDLBAUER,
-	  0, 0, (unsigned long) "Sedlbauer Speedfax + PCI"
-	},
-	{ }
-};
-MODULE_DEVICE_TABLE(pci, sfaxpci_ids);
-
-static struct pci_driver sfaxpci_driver = {
-	.name = "speedfax+ pci",
-	.probe = sfaxpci_probe,
-	.remove = sfax_remove_pci,
-	.id_table = sfaxpci_ids,
-};
-
-static int __init
-Speedfax_init(void)
-{
-	int err;
-
-	pr_notice("Sedlbauer Speedfax+ Driver Rev. %s\n",
-		  SPEEDFAX_REV);
-	err = pci_register_driver(&sfaxpci_driver);
-	return err;
-}
-
-static void __exit
-Speedfax_cleanup(void)
-{
-	pci_unregister_driver(&sfaxpci_driver);
-}
-
-module_init(Speedfax_init);
-module_exit(Speedfax_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c
deleted file mode 100644
index a341470c042f..000000000000
--- a/drivers/isdn/hardware/mISDN/w6692.c
+++ /dev/null
@@ -1,1417 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * w6692.c     mISDN driver for Winbond w6692 based cards
- *
- * Author      Karsten Keil <kkeil@suse.de>
- *             based on the w6692 I4L driver from Petr Novak <petr.novak@i.cz>
- *
- * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
- */
-
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/mISDNhw.h>
-#include <linux/slab.h>
-#include "w6692.h"
-
-#define W6692_REV	"2.0"
-
-#define DBUSY_TIMER_VALUE	80
-
-enum {
-	W6692_ASUS,
-	W6692_WINBOND,
-	W6692_USR
-};
-
-/* private data in the PCI devices list */
-struct w6692map {
-	u_int	subtype;
-	char	*name;
-};
-
-static const struct w6692map  w6692_map[] =
-{
-	{W6692_ASUS, "Dynalink/AsusCom IS64PH"},
-	{W6692_WINBOND, "Winbond W6692"},
-	{W6692_USR, "USR W6692"}
-};
-
-#define PCI_DEVICE_ID_USR_6692	0x3409
-
-struct w6692_ch {
-	struct bchannel		bch;
-	u32			addr;
-	struct timer_list	timer;
-	u8			b_mode;
-};
-
-struct w6692_hw {
-	struct list_head	list;
-	struct pci_dev		*pdev;
-	char			name[MISDN_MAX_IDLEN];
-	u32			irq;
-	u32			irqcnt;
-	u32			addr;
-	u32			fmask;	/* feature mask - bit set per card nr */
-	int			subtype;
-	spinlock_t		lock;	/* hw lock */
-	u8			imask;
-	u8			pctl;
-	u8			xaddr;
-	u8			xdata;
-	u8			state;
-	struct w6692_ch		bc[2];
-	struct dchannel		dch;
-	char			log[64];
-};
-
-static LIST_HEAD(Cards);
-static DEFINE_RWLOCK(card_lock); /* protect Cards */
-
-static int w6692_cnt;
-static int debug;
-static u32 led;
-static u32 pots;
-
-static void
-_set_debug(struct w6692_hw *card)
-{
-	card->dch.debug = debug;
-	card->bc[0].bch.debug = debug;
-	card->bc[1].bch.debug = debug;
-}
-
-static int
-set_debug(const char *val, const struct kernel_param *kp)
-{
-	int ret;
-	struct w6692_hw *card;
-
-	ret = param_set_uint(val, kp);
-	if (!ret) {
-		read_lock(&card_lock);
-		list_for_each_entry(card, &Cards, list)
-			_set_debug(card);
-		read_unlock(&card_lock);
-	}
-	return ret;
-}
-
-MODULE_AUTHOR("Karsten Keil");
-MODULE_DESCRIPTION("mISDN driver for Winbond w6692 based cards");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(W6692_REV);
-module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "W6692 debug mask");
-module_param(led, uint, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(led, "W6692 LED support bitmask (one bit per card)");
-module_param(pots, uint, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(pots, "W6692 POTS support bitmask (one bit per card)");
-
-static inline u8
-ReadW6692(struct w6692_hw *card, u8 offset)
-{
-	return inb(card->addr + offset);
-}
-
-static inline void
-WriteW6692(struct w6692_hw *card, u8 offset, u8 value)
-{
-	outb(value, card->addr + offset);
-}
-
-static inline u8
-ReadW6692B(struct w6692_ch *bc, u8 offset)
-{
-	return inb(bc->addr + offset);
-}
-
-static inline void
-WriteW6692B(struct w6692_ch *bc, u8 offset, u8 value)
-{
-	outb(value, bc->addr + offset);
-}
-
-static void
-enable_hwirq(struct w6692_hw *card)
-{
-	WriteW6692(card, W_IMASK, card->imask);
-}
-
-static void
-disable_hwirq(struct w6692_hw *card)
-{
-	WriteW6692(card, W_IMASK, 0xff);
-}
-
-static const char *W6692Ver[] = {"V00", "V01", "V10", "V11"};
-
-static void
-W6692Version(struct w6692_hw *card)
-{
-	int val;
-
-	val = ReadW6692(card, W_D_RBCH);
-	pr_notice("%s: Winbond W6692 version: %s\n", card->name,
-		  W6692Ver[(val >> 6) & 3]);
-}
-
-static void
-w6692_led_handler(struct w6692_hw *card, int on)
-{
-	if ((!(card->fmask & led)) || card->subtype == W6692_USR)
-		return;
-	if (on) {
-		card->xdata &= 0xfb;	/*  LED ON */
-		WriteW6692(card, W_XDATA, card->xdata);
-	} else {
-		card->xdata |= 0x04;	/*  LED OFF */
-		WriteW6692(card, W_XDATA, card->xdata);
-	}
-}
-
-static void
-ph_command(struct w6692_hw *card, u8 cmd)
-{
-	pr_debug("%s: ph_command %x\n", card->name, cmd);
-	WriteW6692(card, W_CIX, cmd);
-}
-
-static void
-W6692_new_ph(struct w6692_hw *card)
-{
-	if (card->state == W_L1CMD_RST)
-		ph_command(card, W_L1CMD_DRC);
-	schedule_event(&card->dch, FLG_PHCHANGE);
-}
-
-static void
-W6692_ph_bh(struct dchannel *dch)
-{
-	struct w6692_hw *card = dch->hw;
-
-	switch (card->state) {
-	case W_L1CMD_RST:
-		dch->state = 0;
-		l1_event(dch->l1, HW_RESET_IND);
-		break;
-	case W_L1IND_CD:
-		dch->state = 3;
-		l1_event(dch->l1, HW_DEACT_CNF);
-		break;
-	case W_L1IND_DRD:
-		dch->state = 3;
-		l1_event(dch->l1, HW_DEACT_IND);
-		break;
-	case W_L1IND_CE:
-		dch->state = 4;
-		l1_event(dch->l1, HW_POWERUP_IND);
-		break;
-	case W_L1IND_LD:
-		if (dch->state <= 5) {
-			dch->state = 5;
-			l1_event(dch->l1, ANYSIGNAL);
-		} else {
-			dch->state = 8;
-			l1_event(dch->l1, LOSTFRAMING);
-		}
-		break;
-	case W_L1IND_ARD:
-		dch->state = 6;
-		l1_event(dch->l1, INFO2);
-		break;
-	case W_L1IND_AI8:
-		dch->state = 7;
-		l1_event(dch->l1, INFO4_P8);
-		break;
-	case W_L1IND_AI10:
-		dch->state = 7;
-		l1_event(dch->l1, INFO4_P10);
-		break;
-	default:
-		pr_debug("%s: TE unknown state %02x dch state %02x\n",
-			 card->name, card->state, dch->state);
-		break;
-	}
-	pr_debug("%s: TE newstate %02x\n", card->name, dch->state);
-}
-
-static void
-W6692_empty_Dfifo(struct w6692_hw *card, int count)
-{
-	struct dchannel *dch = &card->dch;
-	u8 *ptr;
-
-	pr_debug("%s: empty_Dfifo %d\n", card->name, count);
-	if (!dch->rx_skb) {
-		dch->rx_skb = mI_alloc_skb(card->dch.maxlen, GFP_ATOMIC);
-		if (!dch->rx_skb) {
-			pr_info("%s: D receive out of memory\n", card->name);
-			WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
-			return;
-		}
-	}
-	if ((dch->rx_skb->len + count) >= dch->maxlen) {
-		pr_debug("%s: empty_Dfifo overrun %d\n", card->name,
-			 dch->rx_skb->len + count);
-		WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
-		return;
-	}
-	ptr = skb_put(dch->rx_skb, count);
-	insb(card->addr + W_D_RFIFO, ptr, count);
-	WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
-	if (debug & DEBUG_HW_DFIFO) {
-		snprintf(card->log, 63, "D-recv %s %d ",
-			 card->name, count);
-		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
-	}
-}
-
-static void
-W6692_fill_Dfifo(struct w6692_hw *card)
-{
-	struct dchannel *dch = &card->dch;
-	int count;
-	u8 *ptr;
-	u8 cmd = W_D_CMDR_XMS;
-
-	pr_debug("%s: fill_Dfifo\n", card->name);
-	if (!dch->tx_skb)
-		return;
-	count = dch->tx_skb->len - dch->tx_idx;
-	if (count <= 0)
-		return;
-	if (count > W_D_FIFO_THRESH)
-		count = W_D_FIFO_THRESH;
-	else
-		cmd |= W_D_CMDR_XME;
-	ptr = dch->tx_skb->data + dch->tx_idx;
-	dch->tx_idx += count;
-	outsb(card->addr + W_D_XFIFO, ptr, count);
-	WriteW6692(card, W_D_CMDR, cmd);
-	if (test_and_set_bit(FLG_BUSY_TIMER, &dch->Flags)) {
-		pr_debug("%s: fill_Dfifo dbusytimer running\n", card->name);
-		timer_delete(&dch->timer);
-	}
-	dch->timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000);
-	add_timer(&dch->timer);
-	if (debug & DEBUG_HW_DFIFO) {
-		snprintf(card->log, 63, "D-send %s %d ",
-			 card->name, count);
-		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
-	}
-}
-
-static void
-d_retransmit(struct w6692_hw *card)
-{
-	struct dchannel *dch = &card->dch;
-
-	if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
-		timer_delete(&dch->timer);
-#ifdef FIXME
-	if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
-		dchannel_sched_event(dch, D_CLEARBUSY);
-#endif
-	if (test_bit(FLG_TX_BUSY, &dch->Flags)) {
-		/* Restart frame */
-		dch->tx_idx = 0;
-		W6692_fill_Dfifo(card);
-	} else if (dch->tx_skb) { /* should not happen */
-		pr_info("%s: %s without TX_BUSY\n", card->name, __func__);
-		test_and_set_bit(FLG_TX_BUSY, &dch->Flags);
-		dch->tx_idx = 0;
-		W6692_fill_Dfifo(card);
-	} else {
-		pr_info("%s: XDU no TX_BUSY\n", card->name);
-		if (get_next_dframe(dch))
-			W6692_fill_Dfifo(card);
-	}
-}
-
-static void
-handle_rxD(struct w6692_hw *card) {
-	u8	stat;
-	int	count;
-
-	stat = ReadW6692(card, W_D_RSTA);
-	if (stat & (W_D_RSTA_RDOV | W_D_RSTA_CRCE | W_D_RSTA_RMB)) {
-		if (stat & W_D_RSTA_RDOV) {
-			pr_debug("%s: D-channel RDOV\n", card->name);
-#ifdef ERROR_STATISTIC
-			card->dch.err_rx++;
-#endif
-		}
-		if (stat & W_D_RSTA_CRCE) {
-			pr_debug("%s: D-channel CRC error\n", card->name);
-#ifdef ERROR_STATISTIC
-			card->dch.err_crc++;
-#endif
-		}
-		if (stat & W_D_RSTA_RMB) {
-			pr_debug("%s: D-channel ABORT\n", card->name);
-#ifdef ERROR_STATISTIC
-			card->dch.err_rx++;
-#endif
-		}
-		dev_kfree_skb(card->dch.rx_skb);
-		card->dch.rx_skb = NULL;
-		WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK | W_D_CMDR_RRST);
-	} else {
-		count = ReadW6692(card, W_D_RBCL) & (W_D_FIFO_THRESH - 1);
-		if (count == 0)
-			count = W_D_FIFO_THRESH;
-		W6692_empty_Dfifo(card, count);
-		recv_Dchannel(&card->dch);
-	}
-}
-
-static void
-handle_txD(struct w6692_hw *card) {
-	if (test_and_clear_bit(FLG_BUSY_TIMER, &card->dch.Flags))
-		timer_delete(&card->dch.timer);
-	if (card->dch.tx_skb && card->dch.tx_idx < card->dch.tx_skb->len) {
-		W6692_fill_Dfifo(card);
-	} else {
-		dev_kfree_skb(card->dch.tx_skb);
-		if (get_next_dframe(&card->dch))
-			W6692_fill_Dfifo(card);
-	}
-}
-
-static void
-handle_statusD(struct w6692_hw *card)
-{
-	struct dchannel *dch = &card->dch;
-	u8 exval, v1, cir;
-
-	exval = ReadW6692(card, W_D_EXIR);
-
-	pr_debug("%s: D_EXIR %02x\n", card->name, exval);
-	if (exval & (W_D_EXI_XDUN | W_D_EXI_XCOL)) {
-		/* Transmit underrun/collision */
-		pr_debug("%s: D-channel underrun/collision\n", card->name);
-#ifdef ERROR_STATISTIC
-		dch->err_tx++;
-#endif
-		d_retransmit(card);
-	}
-	if (exval & W_D_EXI_RDOV) {	/* RDOV */
-		pr_debug("%s: D-channel RDOV\n", card->name);
-		WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST);
-	}
-	if (exval & W_D_EXI_TIN2)	/* TIN2 - never */
-		pr_debug("%s: spurious TIN2 interrupt\n", card->name);
-	if (exval & W_D_EXI_MOC) {	/* MOC - not supported */
-		v1 = ReadW6692(card, W_MOSR);
-		pr_debug("%s: spurious MOC interrupt MOSR %02x\n",
-			 card->name, v1);
-	}
-	if (exval & W_D_EXI_ISC) {	/* ISC - Level1 change */
-		cir = ReadW6692(card, W_CIR);
-		pr_debug("%s: ISC CIR %02X\n", card->name, cir);
-		if (cir & W_CIR_ICC) {
-			v1 = cir & W_CIR_COD_MASK;
-			pr_debug("%s: ph_state_change %x -> %x\n", card->name,
-				 dch->state, v1);
-			card->state = v1;
-			if (card->fmask & led) {
-				switch (v1) {
-				case W_L1IND_AI8:
-				case W_L1IND_AI10:
-					w6692_led_handler(card, 1);
-					break;
-				default:
-					w6692_led_handler(card, 0);
-					break;
-				}
-			}
-			W6692_new_ph(card);
-		}
-		if (cir & W_CIR_SCC) {
-			v1 = ReadW6692(card, W_SQR);
-			pr_debug("%s: SCC SQR %02X\n", card->name, v1);
-		}
-	}
-	if (exval & W_D_EXI_WEXP)
-		pr_debug("%s: spurious WEXP interrupt!\n", card->name);
-	if (exval & W_D_EXI_TEXP)
-		pr_debug("%s: spurious TEXP interrupt!\n", card->name);
-}
-
-static void
-W6692_empty_Bfifo(struct w6692_ch *wch, int count)
-{
-	struct w6692_hw *card = wch->bch.hw;
-	u8 *ptr;
-	int maxlen;
-
-	pr_debug("%s: empty_Bfifo %d\n", card->name, count);
-	if (unlikely(wch->bch.state == ISDN_P_NONE)) {
-		pr_debug("%s: empty_Bfifo ISDN_P_NONE\n", card->name);
-		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
-		if (wch->bch.rx_skb)
-			skb_trim(wch->bch.rx_skb, 0);
-		return;
-	}
-	if (test_bit(FLG_RX_OFF, &wch->bch.Flags)) {
-		wch->bch.dropcnt += count;
-		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
-		return;
-	}
-	maxlen = bchannel_get_rxbuf(&wch->bch, count);
-	if (maxlen < 0) {
-		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
-		if (wch->bch.rx_skb)
-			skb_trim(wch->bch.rx_skb, 0);
-		pr_warn("%s.B%d: No bufferspace for %d bytes\n",
-			card->name, wch->bch.nr, count);
-		return;
-	}
-	ptr = skb_put(wch->bch.rx_skb, count);
-	insb(wch->addr + W_B_RFIFO, ptr, count);
-	WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
-	if (debug & DEBUG_HW_DFIFO) {
-		snprintf(card->log, 63, "B%1d-recv %s %d ",
-			 wch->bch.nr, card->name, count);
-		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
-	}
-}
-
-static void
-W6692_fill_Bfifo(struct w6692_ch *wch)
-{
-	struct w6692_hw *card = wch->bch.hw;
-	int count, fillempty = 0;
-	u8 *ptr, cmd = W_B_CMDR_RACT | W_B_CMDR_XMS;
-
-	pr_debug("%s: fill Bfifo\n", card->name);
-	if (!wch->bch.tx_skb) {
-		if (!test_bit(FLG_TX_EMPTY, &wch->bch.Flags))
-			return;
-		ptr = wch->bch.fill;
-		count = W_B_FIFO_THRESH;
-		fillempty = 1;
-	} else {
-		count = wch->bch.tx_skb->len - wch->bch.tx_idx;
-		if (count <= 0)
-			return;
-		ptr = wch->bch.tx_skb->data + wch->bch.tx_idx;
-	}
-	if (count > W_B_FIFO_THRESH)
-		count = W_B_FIFO_THRESH;
-	else if (test_bit(FLG_HDLC, &wch->bch.Flags))
-		cmd |= W_B_CMDR_XME;
-
-	pr_debug("%s: fill Bfifo%d/%d\n", card->name,
-		 count, wch->bch.tx_idx);
-	wch->bch.tx_idx += count;
-	if (fillempty) {
-		while (count > 0) {
-			outsb(wch->addr + W_B_XFIFO, ptr, MISDN_BCH_FILL_SIZE);
-			count -= MISDN_BCH_FILL_SIZE;
-		}
-	} else {
-		outsb(wch->addr + W_B_XFIFO, ptr, count);
-	}
-	WriteW6692B(wch, W_B_CMDR, cmd);
-	if ((debug & DEBUG_HW_BFIFO) && !fillempty) {
-		snprintf(card->log, 63, "B%1d-send %s %d ",
-			 wch->bch.nr, card->name, count);
-		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
-	}
-}
-
-#if 0
-static int
-setvolume(struct w6692_ch *wch, int mic, struct sk_buff *skb)
-{
-	struct w6692_hw *card = wch->bch.hw;
-	u16 *vol = (u16 *)skb->data;
-	u8 val;
-
-	if ((!(card->fmask & pots)) ||
-	    !test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
-		return -ENODEV;
-	if (skb->len < 2)
-		return -EINVAL;
-	if (*vol > 7)
-		return -EINVAL;
-	val = *vol & 7;
-	val = 7 - val;
-	if (mic) {
-		val <<= 3;
-		card->xaddr &= 0xc7;
-	} else {
-		card->xaddr &= 0xf8;
-	}
-	card->xaddr |= val;
-	WriteW6692(card, W_XADDR, card->xaddr);
-	return 0;
-}
-
-static int
-enable_pots(struct w6692_ch *wch)
-{
-	struct w6692_hw *card = wch->bch.hw;
-
-	if ((!(card->fmask & pots)) ||
-	    !test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
-		return -ENODEV;
-	wch->b_mode |= W_B_MODE_EPCM | W_B_MODE_BSW0;
-	WriteW6692B(wch, W_B_MODE, wch->b_mode);
-	WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
-	card->pctl |= ((wch->bch.nr & 2) ? W_PCTL_PCX : 0);
-	WriteW6692(card, W_PCTL, card->pctl);
-	return 0;
-}
-#endif
-
-static int
-disable_pots(struct w6692_ch *wch)
-{
-	struct w6692_hw *card = wch->bch.hw;
-
-	if (!(card->fmask & pots))
-		return -ENODEV;
-	wch->b_mode &= ~(W_B_MODE_EPCM | W_B_MODE_BSW0);
-	WriteW6692B(wch, W_B_MODE, wch->b_mode);
-	WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
-		    W_B_CMDR_XRST);
-	return 0;
-}
-
-static int
-w6692_mode(struct w6692_ch *wch, u32 pr)
-{
-	struct w6692_hw	*card;
-
-	card = wch->bch.hw;
-	pr_debug("%s: B%d protocol %x-->%x\n", card->name,
-		 wch->bch.nr, wch->bch.state, pr);
-	switch (pr) {
-	case ISDN_P_NONE:
-		if ((card->fmask & pots) && (wch->b_mode & W_B_MODE_EPCM))
-			disable_pots(wch);
-		wch->b_mode = 0;
-		mISDN_clear_bchannel(&wch->bch);
-		WriteW6692B(wch, W_B_MODE, wch->b_mode);
-		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
-		test_and_clear_bit(FLG_HDLC, &wch->bch.Flags);
-		test_and_clear_bit(FLG_TRANSPARENT, &wch->bch.Flags);
-		break;
-	case ISDN_P_B_RAW:
-		wch->b_mode = W_B_MODE_MMS;
-		WriteW6692B(wch, W_B_MODE, wch->b_mode);
-		WriteW6692B(wch, W_B_EXIM, 0);
-		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
-			    W_B_CMDR_XRST);
-		test_and_set_bit(FLG_TRANSPARENT, &wch->bch.Flags);
-		break;
-	case ISDN_P_B_HDLC:
-		wch->b_mode = W_B_MODE_ITF;
-		WriteW6692B(wch, W_B_MODE, wch->b_mode);
-		WriteW6692B(wch, W_B_ADM1, 0xff);
-		WriteW6692B(wch, W_B_ADM2, 0xff);
-		WriteW6692B(wch, W_B_EXIM, 0);
-		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
-			    W_B_CMDR_XRST);
-		test_and_set_bit(FLG_HDLC, &wch->bch.Flags);
-		break;
-	default:
-		pr_info("%s: protocol %x not known\n", card->name, pr);
-		return -ENOPROTOOPT;
-	}
-	wch->bch.state = pr;
-	return 0;
-}
-
-static void
-send_next(struct w6692_ch *wch)
-{
-	if (wch->bch.tx_skb && wch->bch.tx_idx < wch->bch.tx_skb->len) {
-		W6692_fill_Bfifo(wch);
-	} else {
-		dev_kfree_skb(wch->bch.tx_skb);
-		if (get_next_bframe(&wch->bch)) {
-			W6692_fill_Bfifo(wch);
-			test_and_clear_bit(FLG_TX_EMPTY, &wch->bch.Flags);
-		} else if (test_bit(FLG_TX_EMPTY, &wch->bch.Flags)) {
-			W6692_fill_Bfifo(wch);
-		}
-	}
-}
-
-static void
-W6692B_interrupt(struct w6692_hw *card, int ch)
-{
-	struct w6692_ch	*wch = &card->bc[ch];
-	int		count;
-	u8		stat, star = 0;
-
-	stat = ReadW6692B(wch, W_B_EXIR);
-	pr_debug("%s: B%d EXIR %02x\n", card->name, wch->bch.nr, stat);
-	if (stat & W_B_EXI_RME) {
-		star = ReadW6692B(wch, W_B_STAR);
-		if (star & (W_B_STAR_RDOV | W_B_STAR_CRCE | W_B_STAR_RMB)) {
-			if ((star & W_B_STAR_RDOV) &&
-			    test_bit(FLG_ACTIVE, &wch->bch.Flags)) {
-				pr_debug("%s: B%d RDOV proto=%x\n", card->name,
-					 wch->bch.nr, wch->bch.state);
-#ifdef ERROR_STATISTIC
-				wch->bch.err_rdo++;
-#endif
-			}
-			if (test_bit(FLG_HDLC, &wch->bch.Flags)) {
-				if (star & W_B_STAR_CRCE) {
-					pr_debug("%s: B%d CRC error\n",
-						 card->name, wch->bch.nr);
-#ifdef ERROR_STATISTIC
-					wch->bch.err_crc++;
-#endif
-				}
-				if (star & W_B_STAR_RMB) {
-					pr_debug("%s: B%d message abort\n",
-						 card->name, wch->bch.nr);
-#ifdef ERROR_STATISTIC
-					wch->bch.err_inv++;
-#endif
-				}
-			}
-			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
-				    W_B_CMDR_RRST | W_B_CMDR_RACT);
-			if (wch->bch.rx_skb)
-				skb_trim(wch->bch.rx_skb, 0);
-		} else {
-			count = ReadW6692B(wch, W_B_RBCL) &
-				(W_B_FIFO_THRESH - 1);
-			if (count == 0)
-				count = W_B_FIFO_THRESH;
-			W6692_empty_Bfifo(wch, count);
-			recv_Bchannel(&wch->bch, 0, false);
-		}
-	}
-	if (stat & W_B_EXI_RMR) {
-		if (!(stat & W_B_EXI_RME))
-			star = ReadW6692B(wch, W_B_STAR);
-		if (star & W_B_STAR_RDOV) {
-			pr_debug("%s: B%d RDOV proto=%x\n", card->name,
-				 wch->bch.nr, wch->bch.state);
-#ifdef ERROR_STATISTIC
-			wch->bch.err_rdo++;
-#endif
-			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
-				    W_B_CMDR_RRST | W_B_CMDR_RACT);
-		} else {
-			W6692_empty_Bfifo(wch, W_B_FIFO_THRESH);
-			if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
-				recv_Bchannel(&wch->bch, 0, false);
-		}
-	}
-	if (stat & W_B_EXI_RDOV) {
-		/* only if it is not handled yet */
-		if (!(star & W_B_STAR_RDOV)) {
-			pr_debug("%s: B%d RDOV IRQ proto=%x\n", card->name,
-				 wch->bch.nr, wch->bch.state);
-#ifdef ERROR_STATISTIC
-			wch->bch.err_rdo++;
-#endif
-			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
-				    W_B_CMDR_RRST | W_B_CMDR_RACT);
-		}
-	}
-	if (stat & W_B_EXI_XFR) {
-		if (!(stat & (W_B_EXI_RME | W_B_EXI_RMR))) {
-			star = ReadW6692B(wch, W_B_STAR);
-			pr_debug("%s: B%d star %02x\n", card->name,
-				 wch->bch.nr, star);
-		}
-		if (star & W_B_STAR_XDOW) {
-			pr_warn("%s: B%d XDOW proto=%x\n", card->name,
-				wch->bch.nr, wch->bch.state);
-#ifdef ERROR_STATISTIC
-			wch->bch.err_xdu++;
-#endif
-			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_XRST |
-				    W_B_CMDR_RACT);
-			/* resend */
-			if (wch->bch.tx_skb) {
-				if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
-					wch->bch.tx_idx = 0;
-			}
-		}
-		send_next(wch);
-		if (star & W_B_STAR_XDOW)
-			return; /* handle XDOW only once */
-	}
-	if (stat & W_B_EXI_XDUN) {
-		pr_warn("%s: B%d XDUN proto=%x\n", card->name,
-			wch->bch.nr, wch->bch.state);
-#ifdef ERROR_STATISTIC
-		wch->bch.err_xdu++;
-#endif
-		/* resend - no XRST needed */
-		if (wch->bch.tx_skb) {
-			if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
-				wch->bch.tx_idx = 0;
-		} else if (test_bit(FLG_FILLEMPTY, &wch->bch.Flags)) {
-			test_and_set_bit(FLG_TX_EMPTY, &wch->bch.Flags);
-		}
-		send_next(wch);
-	}
-}
-
-static irqreturn_t
-w6692_irq(int intno, void *dev_id)
-{
-	struct w6692_hw	*card = dev_id;
-	u8		ista;
-
-	spin_lock(&card->lock);
-	ista = ReadW6692(card, W_ISTA);
-	if ((ista | card->imask) == card->imask) {
-		/* possible a shared  IRQ reqest */
-		spin_unlock(&card->lock);
-		return IRQ_NONE;
-	}
-	card->irqcnt++;
-	pr_debug("%s: ista %02x\n", card->name, ista);
-	ista &= ~card->imask;
-	if (ista & W_INT_B1_EXI)
-		W6692B_interrupt(card, 0);
-	if (ista & W_INT_B2_EXI)
-		W6692B_interrupt(card, 1);
-	if (ista & W_INT_D_RME)
-		handle_rxD(card);
-	if (ista & W_INT_D_RMR)
-		W6692_empty_Dfifo(card, W_D_FIFO_THRESH);
-	if (ista & W_INT_D_XFR)
-		handle_txD(card);
-	if (ista & W_INT_D_EXI)
-		handle_statusD(card);
-	if (ista & (W_INT_XINT0 | W_INT_XINT1)) /* XINT0/1 - never */
-		pr_debug("%s: W6692 spurious XINT!\n", card->name);
-/* End IRQ Handler */
-	spin_unlock(&card->lock);
-	return IRQ_HANDLED;
-}
-
-static void
-dbusy_timer_handler(struct timer_list *t)
-{
-	struct dchannel *dch = timer_container_of(dch, t, timer);
-	struct w6692_hw	*card = dch->hw;
-	int		rbch, star;
-	u_long		flags;
-
-	if (test_bit(FLG_BUSY_TIMER, &dch->Flags)) {
-		spin_lock_irqsave(&card->lock, flags);
-		rbch = ReadW6692(card, W_D_RBCH);
-		star = ReadW6692(card, W_D_STAR);
-		pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n",
-			 card->name, rbch, star);
-		if (star & W_D_STAR_XBZ)	/* D-Channel Busy */
-			test_and_set_bit(FLG_L1_BUSY, &dch->Flags);
-		else {
-			/* discard frame; reset transceiver */
-			test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags);
-			if (dch->tx_idx)
-				dch->tx_idx = 0;
-			else
-				pr_info("%s: W6692 D-Channel Busy no tx_idx\n",
-					card->name);
-			/* Transmitter reset */
-			WriteW6692(card, W_D_CMDR, W_D_CMDR_XRST);
-		}
-		spin_unlock_irqrestore(&card->lock, flags);
-	}
-}
-
-static void initW6692(struct w6692_hw *card)
-{
-	u8	val;
-
-	timer_setup(&card->dch.timer, dbusy_timer_handler, 0);
-	w6692_mode(&card->bc[0], ISDN_P_NONE);
-	w6692_mode(&card->bc[1], ISDN_P_NONE);
-	WriteW6692(card, W_D_CTL, 0x00);
-	disable_hwirq(card);
-	WriteW6692(card, W_D_SAM, 0xff);
-	WriteW6692(card, W_D_TAM, 0xff);
-	WriteW6692(card, W_D_MODE, W_D_MODE_RACT);
-	card->state = W_L1CMD_RST;
-	ph_command(card, W_L1CMD_RST);
-	ph_command(card, W_L1CMD_ECK);
-	/* enable all IRQ but extern */
-	card->imask = 0x18;
-	WriteW6692(card, W_D_EXIM, 0x00);
-	WriteW6692B(&card->bc[0], W_B_EXIM, 0);
-	WriteW6692B(&card->bc[1], W_B_EXIM, 0);
-	/* Reset D-chan receiver and transmitter */
-	WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST);
-	/* Reset B-chan receiver and transmitter */
-	WriteW6692B(&card->bc[0], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
-	WriteW6692B(&card->bc[1], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
-	/* enable peripheral */
-	if (card->subtype == W6692_USR) {
-		/* seems that USR implemented some power control features
-		 * Pin 79 is connected to the oscilator circuit so we
-		 * have to handle it here
-		 */
-		card->pctl = 0x80;
-		card->xdata = 0;
-		WriteW6692(card, W_PCTL, card->pctl);
-		WriteW6692(card, W_XDATA, card->xdata);
-	} else {
-		card->pctl = W_PCTL_OE5 | W_PCTL_OE4 | W_PCTL_OE2 |
-			W_PCTL_OE1 | W_PCTL_OE0;
-		card->xaddr = 0x00;/* all sw off */
-		if (card->fmask & pots)
-			card->xdata |= 0x06;	/*  POWER UP/ LED OFF / ALAW */
-		if (card->fmask & led)
-			card->xdata |= 0x04;	/* LED OFF */
-		if ((card->fmask & pots) || (card->fmask & led)) {
-			WriteW6692(card, W_PCTL, card->pctl);
-			WriteW6692(card, W_XADDR, card->xaddr);
-			WriteW6692(card, W_XDATA, card->xdata);
-			val = ReadW6692(card, W_XADDR);
-			if (debug & DEBUG_HW)
-				pr_notice("%s: W_XADDR=%02x\n",
-					  card->name, val);
-		}
-	}
-}
-
-static void
-reset_w6692(struct w6692_hw *card)
-{
-	WriteW6692(card, W_D_CTL, W_D_CTL_SRST);
-	mdelay(10);
-	WriteW6692(card, W_D_CTL, 0);
-}
-
-static int
-init_card(struct w6692_hw *card)
-{
-	int	cnt = 3;
-	u_long	flags;
-
-	spin_lock_irqsave(&card->lock, flags);
-	disable_hwirq(card);
-	spin_unlock_irqrestore(&card->lock, flags);
-	if (request_irq(card->irq, w6692_irq, IRQF_SHARED, card->name, card)) {
-		pr_info("%s: couldn't get interrupt %d\n", card->name,
-			card->irq);
-		return -EIO;
-	}
-	while (cnt--) {
-		spin_lock_irqsave(&card->lock, flags);
-		initW6692(card);
-		enable_hwirq(card);
-		spin_unlock_irqrestore(&card->lock, flags);
-		/* Timeout 10ms */
-		msleep_interruptible(10);
-		if (debug & DEBUG_HW)
-			pr_notice("%s: IRQ %d count %d\n", card->name,
-				  card->irq, card->irqcnt);
-		if (!card->irqcnt) {
-			pr_info("%s: IRQ(%d) getting no IRQs during init %d\n",
-				card->name, card->irq, 3 - cnt);
-			reset_w6692(card);
-		} else
-			return 0;
-	}
-	free_irq(card->irq, card);
-	return -EIO;
-}
-
-static int
-w6692_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct bchannel *bch = container_of(ch, struct bchannel, ch);
-	struct w6692_ch	*bc = container_of(bch, struct w6692_ch, bch);
-	struct w6692_hw *card = bch->hw;
-	int ret = -EINVAL;
-	struct mISDNhead *hh = mISDN_HEAD_P(skb);
-	unsigned long flags;
-
-	switch (hh->prim) {
-	case PH_DATA_REQ:
-		spin_lock_irqsave(&card->lock, flags);
-		ret = bchannel_senddata(bch, skb);
-		if (ret > 0) { /* direct TX */
-			ret = 0;
-			W6692_fill_Bfifo(bc);
-		}
-		spin_unlock_irqrestore(&card->lock, flags);
-		return ret;
-	case PH_ACTIVATE_REQ:
-		spin_lock_irqsave(&card->lock, flags);
-		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
-			ret = w6692_mode(bc, ch->protocol);
-		else
-			ret = 0;
-		spin_unlock_irqrestore(&card->lock, flags);
-		if (!ret)
-			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-				    NULL, GFP_KERNEL);
-		break;
-	case PH_DEACTIVATE_REQ:
-		spin_lock_irqsave(&card->lock, flags);
-		mISDN_clear_bchannel(bch);
-		w6692_mode(bc, ISDN_P_NONE);
-		spin_unlock_irqrestore(&card->lock, flags);
-		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			    NULL, GFP_KERNEL);
-		ret = 0;
-		break;
-	default:
-		pr_info("%s: %s unknown prim(%x,%x)\n",
-			card->name, __func__, hh->prim, hh->id);
-		ret = -EINVAL;
-	}
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-static int
-channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
-{
-	return mISDN_ctrl_bchannel(bch, cq);
-}
-
-static int
-open_bchannel(struct w6692_hw *card, struct channel_req *rq)
-{
-	struct bchannel *bch;
-
-	if (rq->adr.channel == 0 || rq->adr.channel > 2)
-		return -EINVAL;
-	if (rq->protocol == ISDN_P_NONE)
-		return -EINVAL;
-	bch = &card->bc[rq->adr.channel - 1].bch;
-	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
-		return -EBUSY; /* b-channel can be only open once */
-	bch->ch.protocol = rq->protocol;
-	rq->ch = &bch->ch;
-	return 0;
-}
-
-static int
-channel_ctrl(struct w6692_hw *card, struct mISDN_ctrl_req *cq)
-{
-	int	ret = 0;
-
-	switch (cq->op) {
-	case MISDN_CTRL_GETOP:
-		cq->op = MISDN_CTRL_L1_TIMER3;
-		break;
-	case MISDN_CTRL_L1_TIMER3:
-		ret = l1_event(card->dch.l1, HW_TIMER3_VALUE | (cq->p1 & 0xff));
-		break;
-	default:
-		pr_info("%s: unknown CTRL OP %x\n", card->name, cq->op);
-		ret = -EINVAL;
-		break;
-	}
-	return ret;
-}
-
-static int
-w6692_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
-{
-	struct bchannel *bch = container_of(ch, struct bchannel, ch);
-	struct w6692_ch *bc = container_of(bch, struct w6692_ch, bch);
-	struct w6692_hw *card = bch->hw;
-	int ret = -EINVAL;
-	u_long flags;
-
-	pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg);
-	switch (cmd) {
-	case CLOSE_CHANNEL:
-		test_and_clear_bit(FLG_OPEN, &bch->Flags);
-		cancel_work_sync(&bch->workq);
-		spin_lock_irqsave(&card->lock, flags);
-		mISDN_clear_bchannel(bch);
-		w6692_mode(bc, ISDN_P_NONE);
-		spin_unlock_irqrestore(&card->lock, flags);
-		ch->protocol = ISDN_P_NONE;
-		ch->peer = NULL;
-		module_put(THIS_MODULE);
-		ret = 0;
-		break;
-	case CONTROL_CHANNEL:
-		ret = channel_bctrl(bch, arg);
-		break;
-	default:
-		pr_info("%s: %s unknown prim(%x)\n",
-			card->name, __func__, cmd);
-	}
-	return ret;
-}
-
-static int
-w6692_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
-	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
-	struct w6692_hw		*card = container_of(dch, struct w6692_hw, dch);
-	int			ret = -EINVAL;
-	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
-	u32			id;
-	u_long			flags;
-
-	switch (hh->prim) {
-	case PH_DATA_REQ:
-		spin_lock_irqsave(&card->lock, flags);
-		ret = dchannel_senddata(dch, skb);
-		if (ret > 0) { /* direct TX */
-			id = hh->id; /* skb can be freed */
-			W6692_fill_Dfifo(card);
-			ret = 0;
-			spin_unlock_irqrestore(&card->lock, flags);
-			queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
-		} else
-			spin_unlock_irqrestore(&card->lock, flags);
-		return ret;
-	case PH_ACTIVATE_REQ:
-		ret = l1_event(dch->l1, hh->prim);
-		break;
-	case PH_DEACTIVATE_REQ:
-		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
-		ret = l1_event(dch->l1, hh->prim);
-		break;
-	}
-
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-static int
-w6692_l1callback(struct dchannel *dch, u32 cmd)
-{
-	struct w6692_hw *card = container_of(dch, struct w6692_hw, dch);
-	u_long flags;
-
-	pr_debug("%s: cmd(%x) state(%02x)\n", card->name, cmd, card->state);
-	switch (cmd) {
-	case INFO3_P8:
-		spin_lock_irqsave(&card->lock, flags);
-		ph_command(card, W_L1CMD_AR8);
-		spin_unlock_irqrestore(&card->lock, flags);
-		break;
-	case INFO3_P10:
-		spin_lock_irqsave(&card->lock, flags);
-		ph_command(card, W_L1CMD_AR10);
-		spin_unlock_irqrestore(&card->lock, flags);
-		break;
-	case HW_RESET_REQ:
-		spin_lock_irqsave(&card->lock, flags);
-		if (card->state != W_L1IND_DRD)
-			ph_command(card, W_L1CMD_RST);
-		ph_command(card, W_L1CMD_ECK);
-		spin_unlock_irqrestore(&card->lock, flags);
-		break;
-	case HW_DEACT_REQ:
-		skb_queue_purge(&dch->squeue);
-		if (dch->tx_skb) {
-			dev_kfree_skb(dch->tx_skb);
-			dch->tx_skb = NULL;
-		}
-		dch->tx_idx = 0;
-		if (dch->rx_skb) {
-			dev_kfree_skb(dch->rx_skb);
-			dch->rx_skb = NULL;
-		}
-		test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
-		if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
-			timer_delete(&dch->timer);
-		break;
-	case HW_POWERUP_REQ:
-		spin_lock_irqsave(&card->lock, flags);
-		ph_command(card, W_L1CMD_ECK);
-		spin_unlock_irqrestore(&card->lock, flags);
-		break;
-	case PH_ACTIVATE_IND:
-		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
-		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			    GFP_ATOMIC);
-		break;
-	case PH_DEACTIVATE_IND:
-		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
-		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			    GFP_ATOMIC);
-		break;
-	default:
-		pr_debug("%s: %s unknown command %x\n", card->name,
-			 __func__, cmd);
-		return -1;
-	}
-	return 0;
-}
-
-static int
-open_dchannel(struct w6692_hw *card, struct channel_req *rq, void *caller)
-{
-	pr_debug("%s: %s dev(%d) open from %p\n", card->name, __func__,
-		 card->dch.dev.id, caller);
-	if (rq->protocol != ISDN_P_TE_S0)
-		return -EINVAL;
-	if (rq->adr.channel == 1)
-		/* E-Channel not supported */
-		return -EINVAL;
-	rq->ch = &card->dch.dev.D;
-	rq->ch->protocol = rq->protocol;
-	if (card->dch.state == 7)
-		_queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
-			    0, NULL, GFP_KERNEL);
-	return 0;
-}
-
-static int
-w6692_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
-{
-	struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
-	struct dchannel *dch = container_of(dev, struct dchannel, dev);
-	struct w6692_hw *card = container_of(dch, struct w6692_hw, dch);
-	struct channel_req *rq;
-	int err = 0;
-
-	pr_debug("%s: DCTRL: %x %p\n", card->name, cmd, arg);
-	switch (cmd) {
-	case OPEN_CHANNEL:
-		rq = arg;
-		if (rq->protocol == ISDN_P_TE_S0)
-			err = open_dchannel(card, rq, __builtin_return_address(0));
-		else
-			err = open_bchannel(card, rq);
-		if (err)
-			break;
-		if (!try_module_get(THIS_MODULE))
-			pr_info("%s: cannot get module\n", card->name);
-		break;
-	case CLOSE_CHANNEL:
-		pr_debug("%s: dev(%d) close from %p\n", card->name,
-			 dch->dev.id, __builtin_return_address(0));
-		module_put(THIS_MODULE);
-		break;
-	case CONTROL_CHANNEL:
-		err = channel_ctrl(card, arg);
-		break;
-	default:
-		pr_debug("%s: unknown DCTRL command %x\n", card->name, cmd);
-		return -EINVAL;
-	}
-	return err;
-}
-
-static int
-setup_w6692(struct w6692_hw *card)
-{
-	u32	val;
-
-	if (!request_region(card->addr, 256, card->name)) {
-		pr_info("%s: config port %x-%x already in use\n", card->name,
-			card->addr, card->addr + 255);
-		return -EIO;
-	}
-	W6692Version(card);
-	card->bc[0].addr = card->addr;
-	card->bc[1].addr = card->addr + 0x40;
-	val = ReadW6692(card, W_ISTA);
-	if (debug & DEBUG_HW)
-		pr_notice("%s ISTA=%02x\n", card->name, val);
-	val = ReadW6692(card, W_IMASK);
-	if (debug & DEBUG_HW)
-		pr_notice("%s IMASK=%02x\n", card->name, val);
-	val = ReadW6692(card, W_D_EXIR);
-	if (debug & DEBUG_HW)
-		pr_notice("%s D_EXIR=%02x\n", card->name, val);
-	val = ReadW6692(card, W_D_EXIM);
-	if (debug & DEBUG_HW)
-		pr_notice("%s D_EXIM=%02x\n", card->name, val);
-	val = ReadW6692(card, W_D_RSTA);
-	if (debug & DEBUG_HW)
-		pr_notice("%s D_RSTA=%02x\n", card->name, val);
-	return 0;
-}
-
-static void
-release_card(struct w6692_hw *card)
-{
-	u_long	flags;
-
-	spin_lock_irqsave(&card->lock, flags);
-	disable_hwirq(card);
-	w6692_mode(&card->bc[0], ISDN_P_NONE);
-	w6692_mode(&card->bc[1], ISDN_P_NONE);
-	if ((card->fmask & led) || card->subtype == W6692_USR) {
-		card->xdata |= 0x04;	/*  LED OFF */
-		WriteW6692(card, W_XDATA, card->xdata);
-	}
-	spin_unlock_irqrestore(&card->lock, flags);
-	free_irq(card->irq, card);
-	l1_event(card->dch.l1, CLOSE_CHANNEL);
-	mISDN_unregister_device(&card->dch.dev);
-	release_region(card->addr, 256);
-	mISDN_freebchannel(&card->bc[1].bch);
-	mISDN_freebchannel(&card->bc[0].bch);
-	mISDN_freedchannel(&card->dch);
-	write_lock_irqsave(&card_lock, flags);
-	list_del(&card->list);
-	write_unlock_irqrestore(&card_lock, flags);
-	pci_disable_device(card->pdev);
-	pci_set_drvdata(card->pdev, NULL);
-	kfree(card);
-}
-
-static int
-setup_instance(struct w6692_hw *card)
-{
-	int		i, err;
-	u_long		flags;
-
-	snprintf(card->name, MISDN_MAX_IDLEN - 1, "w6692.%d", w6692_cnt + 1);
-	write_lock_irqsave(&card_lock, flags);
-	list_add_tail(&card->list, &Cards);
-	write_unlock_irqrestore(&card_lock, flags);
-	card->fmask = (1 << w6692_cnt);
-	_set_debug(card);
-	spin_lock_init(&card->lock);
-	mISDN_initdchannel(&card->dch, MAX_DFRAME_LEN_L1, W6692_ph_bh);
-	card->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0);
-	card->dch.dev.D.send = w6692_l2l1D;
-	card->dch.dev.D.ctrl = w6692_dctrl;
-	card->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
-	card->dch.hw = card;
-	card->dch.dev.nrbchan = 2;
-	for (i = 0; i < 2; i++) {
-		mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM,
-				   W_B_FIFO_THRESH);
-		card->bc[i].bch.hw = card;
-		card->bc[i].bch.nr = i + 1;
-		card->bc[i].bch.ch.nr = i + 1;
-		card->bc[i].bch.ch.send = w6692_l2l1B;
-		card->bc[i].bch.ch.ctrl = w6692_bctrl;
-		set_channelmap(i + 1, card->dch.dev.channelmap);
-		list_add(&card->bc[i].bch.ch.list, &card->dch.dev.bchannels);
-	}
-	err = setup_w6692(card);
-	if (err)
-		goto error_setup;
-	err = mISDN_register_device(&card->dch.dev, &card->pdev->dev,
-				    card->name);
-	if (err)
-		goto error_reg;
-	err = init_card(card);
-	if (err)
-		goto error_init;
-	err = create_l1(&card->dch, w6692_l1callback);
-	if (!err) {
-		w6692_cnt++;
-		pr_notice("W6692 %d cards installed\n", w6692_cnt);
-		return 0;
-	}
-
-	free_irq(card->irq, card);
-error_init:
-	mISDN_unregister_device(&card->dch.dev);
-error_reg:
-	release_region(card->addr, 256);
-error_setup:
-	mISDN_freebchannel(&card->bc[1].bch);
-	mISDN_freebchannel(&card->bc[0].bch);
-	mISDN_freedchannel(&card->dch);
-	write_lock_irqsave(&card_lock, flags);
-	list_del(&card->list);
-	write_unlock_irqrestore(&card_lock, flags);
-	kfree(card);
-	return err;
-}
-
-static int
-w6692_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	int		err = -ENOMEM;
-	struct w6692_hw	*card;
-	struct w6692map	*m = (struct w6692map *)ent->driver_data;
-
-	card = kzalloc_obj(struct w6692_hw);
-	if (!card) {
-		pr_info("No kmem for w6692 card\n");
-		return err;
-	}
-	card->pdev = pdev;
-	card->subtype = m->subtype;
-	err = pci_enable_device(pdev);
-	if (err) {
-		kfree(card);
-		return err;
-	}
-
-	printk(KERN_INFO "mISDN_w6692: found adapter %s at %s\n",
-	       m->name, pci_name(pdev));
-
-	card->addr = pci_resource_start(pdev, 1);
-	card->irq = pdev->irq;
-	pci_set_drvdata(pdev, card);
-	err = setup_instance(card);
-	if (err)
-		pci_set_drvdata(pdev, NULL);
-	return err;
-}
-
-static void
-w6692_remove_pci(struct pci_dev *pdev)
-{
-	struct w6692_hw	*card = pci_get_drvdata(pdev);
-
-	if (card)
-		release_card(card);
-	else
-		if (debug)
-			pr_notice("%s: drvdata already removed\n", __func__);
-}
-
-static const struct pci_device_id w6692_ids[] = {
-	{ PCI_VENDOR_ID_DYNALINK, PCI_DEVICE_ID_DYNALINK_IS64PH,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, (ulong)&w6692_map[0]},
-	{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692,
-	  PCI_VENDOR_ID_USR, PCI_DEVICE_ID_USR_6692, 0, 0,
-	  (ulong)&w6692_map[2]},
-	{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, (ulong)&w6692_map[1]},
-	{ }
-};
-MODULE_DEVICE_TABLE(pci, w6692_ids);
-
-static struct pci_driver w6692_driver = {
-	.name =  "w6692",
-	.probe = w6692_probe,
-	.remove = w6692_remove_pci,
-	.id_table = w6692_ids,
-};
-
-static int __init w6692_init(void)
-{
-	int err;
-
-	pr_notice("Winbond W6692 PCI driver Rev. %s\n", W6692_REV);
-
-	err = pci_register_driver(&w6692_driver);
-	return err;
-}
-
-static void __exit w6692_cleanup(void)
-{
-	pci_unregister_driver(&w6692_driver);
-}
-
-module_init(w6692_init);
-module_exit(w6692_cleanup);
diff --git a/drivers/isdn/mISDN/clock.c b/drivers/isdn/mISDN/clock.c
deleted file mode 100644
index 2668be9de20a..000000000000
--- a/drivers/isdn/mISDN/clock.c
+++ /dev/null
@@ -1,197 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright 2008  by Andreas Eversberg <andreas@eversberg.eu>
- *
- * Quick API description:
- *
- * A clock source registers using mISDN_register_clock:
- *	name = text string to name clock source
- *	priority = value to priorize clock sources (0 = default)
- *	ctl = callback function to enable/disable clock source
- *	priv = private pointer of clock source
- *	return = pointer to clock source structure;
- *
- * Note: Callback 'ctl' can be called before mISDN_register_clock returns!
- *       Also it can be called during mISDN_unregister_clock.
- *
- * A clock source calls mISDN_clock_update with given samples elapsed, if
- * enabled. If function call is delayed, tv must be set with the timestamp
- * of the actual event.
- *
- * A clock source unregisters using mISDN_unregister_clock.
- *
- * To get current clock, call mISDN_clock_get. The signed short value
- * counts the number of samples since. Time since last clock event is added.
- */
-
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/stddef.h>
-#include <linux/spinlock.h>
-#include <linux/ktime.h>
-#include <linux/mISDNif.h>
-#include <linux/export.h>
-#include "core.h"
-
-static u_int *debug;
-static LIST_HEAD(iclock_list);
-static DEFINE_RWLOCK(iclock_lock);
-static u16 iclock_count;		/* counter of last clock */
-static ktime_t iclock_timestamp;	/* time stamp of last clock */
-static int iclock_timestamp_valid;	/* already received one timestamp */
-static struct mISDNclock *iclock_current;
-
-void
-mISDN_init_clock(u_int *dp)
-{
-	debug = dp;
-	iclock_timestamp = ktime_get();
-}
-
-static void
-select_iclock(void)
-{
-	struct mISDNclock *iclock, *bestclock = NULL, *lastclock = NULL;
-	int pri = -128;
-
-	list_for_each_entry(iclock, &iclock_list, list) {
-		if (iclock->pri > pri) {
-			pri = iclock->pri;
-			bestclock = iclock;
-		}
-		if (iclock_current == iclock)
-			lastclock = iclock;
-	}
-	if (lastclock && bestclock != lastclock) {
-		/* last used clock source still exists but changes, disable */
-		if (*debug & DEBUG_CLOCK)
-			printk(KERN_DEBUG "Old clock source '%s' disable.\n",
-			       lastclock->name);
-		lastclock->ctl(lastclock->priv, 0);
-	}
-	if (bestclock && bestclock != iclock_current) {
-		/* new clock source selected, enable */
-		if (*debug & DEBUG_CLOCK)
-			printk(KERN_DEBUG "New clock source '%s' enable.\n",
-			       bestclock->name);
-		bestclock->ctl(bestclock->priv, 1);
-	}
-	if (bestclock != iclock_current) {
-		/* no clock received yet */
-		iclock_timestamp_valid = 0;
-	}
-	iclock_current = bestclock;
-}
-
-struct mISDNclock
-*mISDN_register_clock(char *name, int pri, clockctl_func_t *ctl, void *priv)
-{
-	u_long			flags;
-	struct mISDNclock	*iclock;
-
-	if (*debug & (DEBUG_CORE | DEBUG_CLOCK))
-		printk(KERN_DEBUG "%s: %s %d\n", __func__, name, pri);
-	iclock = kzalloc_obj(struct mISDNclock, GFP_ATOMIC);
-	if (!iclock) {
-		printk(KERN_ERR "%s: No memory for clock entry.\n", __func__);
-		return NULL;
-	}
-	strscpy(iclock->name, name, sizeof(iclock->name));
-	iclock->pri = pri;
-	iclock->priv = priv;
-	iclock->ctl = ctl;
-	write_lock_irqsave(&iclock_lock, flags);
-	list_add_tail(&iclock->list, &iclock_list);
-	select_iclock();
-	write_unlock_irqrestore(&iclock_lock, flags);
-	return iclock;
-}
-EXPORT_SYMBOL(mISDN_register_clock);
-
-void
-mISDN_unregister_clock(struct mISDNclock *iclock)
-{
-	u_long	flags;
-
-	if (*debug & (DEBUG_CORE | DEBUG_CLOCK))
-		printk(KERN_DEBUG "%s: %s %d\n", __func__, iclock->name,
-		       iclock->pri);
-	write_lock_irqsave(&iclock_lock, flags);
-	if (iclock_current == iclock) {
-		if (*debug & DEBUG_CLOCK)
-			printk(KERN_DEBUG
-			       "Current clock source '%s' unregisters.\n",
-			       iclock->name);
-		iclock->ctl(iclock->priv, 0);
-	}
-	list_del(&iclock->list);
-	select_iclock();
-	write_unlock_irqrestore(&iclock_lock, flags);
-}
-EXPORT_SYMBOL(mISDN_unregister_clock);
-
-void
-mISDN_clock_update(struct mISDNclock *iclock, int samples, ktime_t *timestamp)
-{
-	u_long		flags;
-	ktime_t		timestamp_now;
-	u16		delta;
-
-	write_lock_irqsave(&iclock_lock, flags);
-	if (iclock_current != iclock) {
-		printk(KERN_ERR "%s: '%s' sends us clock updates, but we do "
-		       "listen to '%s'. This is a bug!\n", __func__,
-		       iclock->name,
-		       iclock_current ? iclock_current->name : "nothing");
-		iclock->ctl(iclock->priv, 0);
-		write_unlock_irqrestore(&iclock_lock, flags);
-		return;
-	}
-	if (iclock_timestamp_valid) {
-		/* increment sample counter by given samples */
-		iclock_count += samples;
-		if (timestamp) { /* timestamp must be set, if function call is delayed */
-			iclock_timestamp = *timestamp;
-		} else	{
-			iclock_timestamp = ktime_get();
-		}
-	} else {
-		/* calc elapsed time by system clock */
-		if (timestamp) { /* timestamp must be set, if function call is delayed */
-			timestamp_now = *timestamp;
-		} else {
-			timestamp_now = ktime_get();
-		}
-		delta = ktime_divns(ktime_sub(timestamp_now, iclock_timestamp),
-				(NSEC_PER_SEC / 8000));
-		/* add elapsed time to counter and set new timestamp */
-		iclock_count += delta;
-		iclock_timestamp = timestamp_now;
-		iclock_timestamp_valid = 1;
-		if (*debug & DEBUG_CLOCK)
-			printk("Received first clock from source '%s'.\n",
-			       iclock_current ? iclock_current->name : "nothing");
-	}
-	write_unlock_irqrestore(&iclock_lock, flags);
-}
-EXPORT_SYMBOL(mISDN_clock_update);
-
-unsigned short
-mISDN_clock_get(void)
-{
-	u_long		flags;
-	ktime_t		timestamp_now;
-	u16		delta;
-	u16		count;
-
-	read_lock_irqsave(&iclock_lock, flags);
-	/* calc elapsed time by system clock */
-	timestamp_now = ktime_get();
-	delta = ktime_divns(ktime_sub(timestamp_now, iclock_timestamp),
-			(NSEC_PER_SEC / 8000));
-	/* add elapsed time to counter */
-	count =	iclock_count + delta;
-	read_unlock_irqrestore(&iclock_lock, flags);
-	return count;
-}
-EXPORT_SYMBOL(mISDN_clock_get);
diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c
deleted file mode 100644
index 8ec2d4d4f135..000000000000
--- a/drivers/isdn/mISDN/core.c
+++ /dev/null
@@ -1,400 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- */
-
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/stddef.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/mISDNif.h>
-#include "core.h"
-
-static u_int debug;
-
-MODULE_AUTHOR("Karsten Keil");
-MODULE_DESCRIPTION("Modular ISDN core driver");
-MODULE_LICENSE("GPL");
-module_param(debug, uint, S_IRUGO | S_IWUSR);
-
-static u64		device_ids;
-#define MAX_DEVICE_ID	63
-
-static LIST_HEAD(Bprotocols);
-static DEFINE_RWLOCK(bp_lock);
-
-static void mISDN_dev_release(struct device *dev)
-{
-	/* nothing to do: the device is part of its parent's data structure */
-}
-
-static ssize_t id_show(struct device *dev,
-		       struct device_attribute *attr, char *buf)
-{
-	struct mISDNdevice *mdev = dev_to_mISDN(dev);
-
-	if (!mdev)
-		return -ENODEV;
-	return sprintf(buf, "%d\n", mdev->id);
-}
-static DEVICE_ATTR_RO(id);
-
-static ssize_t nrbchan_show(struct device *dev,
-			    struct device_attribute *attr, char *buf)
-{
-	struct mISDNdevice *mdev = dev_to_mISDN(dev);
-
-	if (!mdev)
-		return -ENODEV;
-	return sprintf(buf, "%d\n", mdev->nrbchan);
-}
-static DEVICE_ATTR_RO(nrbchan);
-
-static ssize_t d_protocols_show(struct device *dev,
-				struct device_attribute *attr, char *buf)
-{
-	struct mISDNdevice *mdev = dev_to_mISDN(dev);
-
-	if (!mdev)
-		return -ENODEV;
-	return sprintf(buf, "%d\n", mdev->Dprotocols);
-}
-static DEVICE_ATTR_RO(d_protocols);
-
-static ssize_t b_protocols_show(struct device *dev,
-				struct device_attribute *attr, char *buf)
-{
-	struct mISDNdevice *mdev = dev_to_mISDN(dev);
-
-	if (!mdev)
-		return -ENODEV;
-	return sprintf(buf, "%d\n", mdev->Bprotocols | get_all_Bprotocols());
-}
-static DEVICE_ATTR_RO(b_protocols);
-
-static ssize_t protocol_show(struct device *dev,
-			     struct device_attribute *attr, char *buf)
-{
-	struct mISDNdevice *mdev = dev_to_mISDN(dev);
-
-	if (!mdev)
-		return -ENODEV;
-	return sprintf(buf, "%d\n", mdev->D.protocol);
-}
-static DEVICE_ATTR_RO(protocol);
-
-static ssize_t name_show(struct device *dev,
-			 struct device_attribute *attr, char *buf)
-{
-	strcpy(buf, dev_name(dev));
-	return strlen(buf);
-}
-static DEVICE_ATTR_RO(name);
-
-#if 0 /* hangs */
-static ssize_t name_set(struct device *dev, struct device_attribute *attr,
-			const char *buf, size_t count)
-{
-	int err = 0;
-	char *out = kmalloc(count + 1, GFP_KERNEL);
-
-	if (!out)
-		return -ENOMEM;
-
-	memcpy(out, buf, count);
-	if (count && out[count - 1] == '\n')
-		out[--count] = 0;
-	if (count)
-		err = device_rename(dev, out);
-	kfree(out);
-
-	return (err < 0) ? err : count;
-}
-static DEVICE_ATTR_RW(name);
-#endif
-
-static ssize_t channelmap_show(struct device *dev,
-			       struct device_attribute *attr, char *buf)
-{
-	struct mISDNdevice *mdev = dev_to_mISDN(dev);
-	char *bp = buf;
-	int i;
-
-	for (i = 0; i <= mdev->nrbchan; i++)
-		*bp++ = test_channelmap(i, mdev->channelmap) ? '1' : '0';
-
-	return bp - buf;
-}
-static DEVICE_ATTR_RO(channelmap);
-
-static struct attribute *mISDN_attrs[] = {
-	&dev_attr_id.attr,
-	&dev_attr_d_protocols.attr,
-	&dev_attr_b_protocols.attr,
-	&dev_attr_protocol.attr,
-	&dev_attr_channelmap.attr,
-	&dev_attr_nrbchan.attr,
-	&dev_attr_name.attr,
-	NULL,
-};
-ATTRIBUTE_GROUPS(mISDN);
-
-static int mISDN_uevent(const struct device *dev, struct kobj_uevent_env *env)
-{
-	const struct mISDNdevice *mdev = dev_to_mISDN(dev);
-
-	if (!mdev)
-		return 0;
-
-	if (add_uevent_var(env, "nchans=%d", mdev->nrbchan))
-		return -ENOMEM;
-
-	return 0;
-}
-
-static struct class mISDN_class = {
-	.name = "mISDN",
-	.dev_uevent = mISDN_uevent,
-	.dev_groups = mISDN_groups,
-	.dev_release = mISDN_dev_release,
-};
-
-static int
-_get_mdevice(struct device *dev, const void *id)
-{
-	struct mISDNdevice *mdev = dev_to_mISDN(dev);
-
-	if (!mdev)
-		return 0;
-	if (mdev->id != *(const u_int *)id)
-		return 0;
-	return 1;
-}
-
-struct mISDNdevice
-*get_mdevice(u_int id)
-{
-	return dev_to_mISDN(class_find_device(&mISDN_class, NULL, &id,
-					      _get_mdevice));
-}
-
-static int
-_get_mdevice_count(struct device *dev, void *cnt)
-{
-	*(int *)cnt += 1;
-	return 0;
-}
-
-int
-get_mdevice_count(void)
-{
-	int cnt = 0;
-
-	class_for_each_device(&mISDN_class, NULL, &cnt, _get_mdevice_count);
-	return cnt;
-}
-
-static int
-get_free_devid(void)
-{
-	u_int	i;
-
-	for (i = 0; i <= MAX_DEVICE_ID; i++)
-		if (!test_and_set_bit(i, (u_long *)&device_ids))
-			break;
-	if (i > MAX_DEVICE_ID)
-		return -EBUSY;
-	return i;
-}
-
-int
-mISDN_register_device(struct mISDNdevice *dev,
-		      struct device *parent, char *name)
-{
-	int	err;
-
-	err = get_free_devid();
-	if (err < 0)
-		return err;
-	dev->id = err;
-
-	device_initialize(&dev->dev);
-	if (name && name[0])
-		dev_set_name(&dev->dev, "%s", name);
-	else
-		dev_set_name(&dev->dev, "mISDN%d", dev->id);
-	if (debug & DEBUG_CORE)
-		printk(KERN_DEBUG "mISDN_register %s %d\n",
-		       dev_name(&dev->dev), dev->id);
-	dev->dev.class = &mISDN_class;
-
-	err = create_stack(dev);
-	if (err)
-		goto error1;
-
-	dev->dev.platform_data = dev;
-	dev->dev.parent = parent;
-	dev_set_drvdata(&dev->dev, dev);
-
-	err = device_add(&dev->dev);
-	if (err)
-		goto error3;
-	return 0;
-
-error3:
-	delete_stack(dev);
-error1:
-	put_device(&dev->dev);
-	return err;
-
-}
-EXPORT_SYMBOL(mISDN_register_device);
-
-void
-mISDN_unregister_device(struct mISDNdevice *dev) {
-	if (debug & DEBUG_CORE)
-		printk(KERN_DEBUG "mISDN_unregister %s %d\n",
-		       dev_name(&dev->dev), dev->id);
-	/* sysfs_remove_link(&dev->dev.kobj, "device"); */
-	device_del(&dev->dev);
-	dev_set_drvdata(&dev->dev, NULL);
-
-	test_and_clear_bit(dev->id, (u_long *)&device_ids);
-	delete_stack(dev);
-	put_device(&dev->dev);
-}
-EXPORT_SYMBOL(mISDN_unregister_device);
-
-u_int
-get_all_Bprotocols(void)
-{
-	struct Bprotocol	*bp;
-	u_int	m = 0;
-
-	read_lock(&bp_lock);
-	list_for_each_entry(bp, &Bprotocols, list)
-		m |= bp->Bprotocols;
-	read_unlock(&bp_lock);
-	return m;
-}
-
-struct Bprotocol *
-get_Bprotocol4mask(u_int m)
-{
-	struct Bprotocol	*bp;
-
-	read_lock(&bp_lock);
-	list_for_each_entry(bp, &Bprotocols, list)
-		if (bp->Bprotocols & m) {
-			read_unlock(&bp_lock);
-			return bp;
-		}
-	read_unlock(&bp_lock);
-	return NULL;
-}
-
-int
-mISDN_register_Bprotocol(struct Bprotocol *bp)
-{
-	u_long			flags;
-	struct Bprotocol	*old;
-
-	if (debug & DEBUG_CORE)
-		printk(KERN_DEBUG "%s: %s/%x\n", __func__,
-		       bp->name, bp->Bprotocols);
-	old = get_Bprotocol4mask(bp->Bprotocols);
-	if (old) {
-		printk(KERN_WARNING
-		       "register duplicate protocol old %s/%x new %s/%x\n",
-		       old->name, old->Bprotocols, bp->name, bp->Bprotocols);
-		return -EBUSY;
-	}
-	write_lock_irqsave(&bp_lock, flags);
-	list_add_tail(&bp->list, &Bprotocols);
-	write_unlock_irqrestore(&bp_lock, flags);
-	return 0;
-}
-EXPORT_SYMBOL(mISDN_register_Bprotocol);
-
-void
-mISDN_unregister_Bprotocol(struct Bprotocol *bp)
-{
-	u_long	flags;
-
-	if (debug & DEBUG_CORE)
-		printk(KERN_DEBUG "%s: %s/%x\n", __func__, bp->name,
-		       bp->Bprotocols);
-	write_lock_irqsave(&bp_lock, flags);
-	list_del(&bp->list);
-	write_unlock_irqrestore(&bp_lock, flags);
-}
-EXPORT_SYMBOL(mISDN_unregister_Bprotocol);
-
-static const char *msg_no_channel = "<no channel>";
-static const char *msg_no_stack = "<no stack>";
-static const char *msg_no_stackdev = "<no stack device>";
-
-const char *mISDNDevName4ch(struct mISDNchannel *ch)
-{
-	if (!ch)
-		return msg_no_channel;
-	if (!ch->st)
-		return msg_no_stack;
-	if (!ch->st->dev)
-		return msg_no_stackdev;
-	return dev_name(&ch->st->dev->dev);
-};
-EXPORT_SYMBOL(mISDNDevName4ch);
-
-static int
-mISDNInit(void)
-{
-	int	err;
-
-	printk(KERN_INFO "Modular ISDN core version %d.%d.%d\n",
-	       MISDN_MAJOR_VERSION, MISDN_MINOR_VERSION, MISDN_RELEASE);
-	mISDN_init_clock(&debug);
-	mISDN_initstack(&debug);
-	err = class_register(&mISDN_class);
-	if (err)
-		goto error1;
-	err = mISDN_inittimer(&debug);
-	if (err)
-		goto error2;
-	err = Isdnl1_Init(&debug);
-	if (err)
-		goto error3;
-	err = Isdnl2_Init(&debug);
-	if (err)
-		goto error4;
-	err = misdn_sock_init(&debug);
-	if (err)
-		goto error5;
-	return 0;
-
-error5:
-	Isdnl2_cleanup();
-error4:
-	Isdnl1_cleanup();
-error3:
-	mISDN_timer_cleanup();
-error2:
-	class_unregister(&mISDN_class);
-error1:
-	return err;
-}
-
-static void mISDN_cleanup(void)
-{
-	misdn_sock_cleanup();
-	Isdnl2_cleanup();
-	Isdnl1_cleanup();
-	mISDN_timer_cleanup();
-	class_unregister(&mISDN_class);
-
-	printk(KERN_DEBUG "mISDNcore unloaded\n");
-}
-
-module_init(mISDNInit);
-module_exit(mISDN_cleanup);
diff --git a/drivers/isdn/mISDN/dsp_audio.c b/drivers/isdn/mISDN/dsp_audio.c
deleted file mode 100644
index bbef98e7a16e..000000000000
--- a/drivers/isdn/mISDN/dsp_audio.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * Audio support data for mISDN_dsp.
- *
- * Copyright 2002/2003 by Andreas Eversberg (jolly@eversberg.eu)
- * Rewritten by Peter
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/delay.h>
-#include <linux/mISDNif.h>
-#include <linux/mISDNdsp.h>
-#include <linux/export.h>
-#include <linux/bitrev.h>
-#include "core.h"
-#include "dsp.h"
-
-/* ulaw[unsigned char] -> signed 16-bit */
-s32 dsp_audio_ulaw_to_s32[256];
-/* alaw[unsigned char] -> signed 16-bit */
-s32 dsp_audio_alaw_to_s32[256];
-
-s32 *dsp_audio_law_to_s32;
-EXPORT_SYMBOL(dsp_audio_law_to_s32);
-
-/* signed 16-bit -> law */
-u8 dsp_audio_s16_to_law[65536];
-EXPORT_SYMBOL(dsp_audio_s16_to_law);
-
-/* alaw -> ulaw */
-u8 dsp_audio_alaw_to_ulaw[256];
-/* ulaw -> alaw */
-static u8 dsp_audio_ulaw_to_alaw[256];
-u8 dsp_silence;
-
-
-/*****************************************************
- * generate table for conversion of s16 to alaw/ulaw *
- *****************************************************/
-
-#define AMI_MASK 0x55
-
-static inline unsigned char linear2alaw(short int linear)
-{
-	int mask;
-	int seg;
-	int pcm_val;
-	static int seg_end[8] = {
-		0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
-	};
-
-	pcm_val = linear;
-	if (pcm_val >= 0) {
-		/* Sign (7th) bit = 1 */
-		mask = AMI_MASK | 0x80;
-	} else {
-		/* Sign bit = 0 */
-		mask = AMI_MASK;
-		pcm_val = -pcm_val;
-	}
-
-	/* Convert the scaled magnitude to segment number. */
-	for (seg = 0; seg < 8; seg++) {
-		if (pcm_val <= seg_end[seg])
-			break;
-	}
-	/* Combine the sign, segment, and quantization bits. */
-	return  ((seg << 4) |
-		 ((pcm_val >> ((seg)  ?  (seg + 3)  :  4)) & 0x0F)) ^ mask;
-}
-
-
-static inline short int alaw2linear(unsigned char alaw)
-{
-	int i;
-	int seg;
-
-	alaw ^= AMI_MASK;
-	i = ((alaw & 0x0F) << 4) + 8 /* rounding error */;
-	seg = (((int) alaw & 0x70) >> 4);
-	if (seg)
-		i = (i + 0x100) << (seg - 1);
-	return (short int) ((alaw & 0x80)  ?  i  :  -i);
-}
-
-static inline short int ulaw2linear(unsigned char ulaw)
-{
-	short mu, e, f, y;
-	static short etab[] = {0, 132, 396, 924, 1980, 4092, 8316, 16764};
-
-	mu = 255 - ulaw;
-	e = (mu & 0x70) / 16;
-	f = mu & 0x0f;
-	y = f * (1 << (e + 3));
-	y += etab[e];
-	if (mu & 0x80)
-		y = -y;
-	return y;
-}
-
-#define BIAS 0x84   /*!< define the add-in bias for 16 bit samples */
-
-static unsigned char linear2ulaw(short sample)
-{
-	static int exp_lut[256] = {
-		0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
-		4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-		5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-		5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
-	int sign, exponent, mantissa;
-	unsigned char ulawbyte;
-
-	/* Get the sample into sign-magnitude. */
-	sign = (sample >> 8) & 0x80;	  /* set aside the sign */
-	if (sign != 0)
-		sample = -sample;	      /* get magnitude */
-
-	/* Convert from 16 bit linear to ulaw. */
-	sample = sample + BIAS;
-	exponent = exp_lut[(sample >> 7) & 0xFF];
-	mantissa = (sample >> (exponent + 3)) & 0x0F;
-	ulawbyte = ~(sign | (exponent << 4) | mantissa);
-
-	return ulawbyte;
-}
-
-void dsp_audio_generate_law_tables(void)
-{
-	int i;
-	for (i = 0; i < 256; i++)
-		dsp_audio_alaw_to_s32[i] = alaw2linear(bitrev8((u8)i));
-
-	for (i = 0; i < 256; i++)
-		dsp_audio_ulaw_to_s32[i] = ulaw2linear(bitrev8((u8)i));
-
-	for (i = 0; i < 256; i++) {
-		dsp_audio_alaw_to_ulaw[i] =
-			linear2ulaw(dsp_audio_alaw_to_s32[i]);
-		dsp_audio_ulaw_to_alaw[i] =
-			linear2alaw(dsp_audio_ulaw_to_s32[i]);
-	}
-}
-
-void
-dsp_audio_generate_s2law_table(void)
-{
-	int i;
-
-	if (dsp_options & DSP_OPT_ULAW) {
-		/* generating ulaw-table */
-		for (i = -32768; i < 32768; i++) {
-			dsp_audio_s16_to_law[i & 0xffff] =
-				bitrev8(linear2ulaw(i));
-		}
-	} else {
-		/* generating alaw-table */
-		for (i = -32768; i < 32768; i++) {
-			dsp_audio_s16_to_law[i & 0xffff] =
-				bitrev8(linear2alaw(i));
-		}
-	}
-}
-
-
-/*
- * the seven bit sample is the number of every second alaw-sample ordered by
- * aplitude. 0x00 is negative, 0x7f is positive amplitude.
- */
-u8 dsp_audio_seven2law[128];
-u8 dsp_audio_law2seven[256];
-
-/********************************************************************
- * generate table for conversion law from/to 7-bit alaw-like sample *
- ********************************************************************/
-
-void
-dsp_audio_generate_seven(void)
-{
-	int i, j, k;
-	u8 spl;
-	u8 sorted_alaw[256];
-
-	/* generate alaw table, sorted by the linear value */
-	for (i = 0; i < 256; i++) {
-		j = 0;
-		for (k = 0; k < 256; k++) {
-			if (dsp_audio_alaw_to_s32[k]
-			    < dsp_audio_alaw_to_s32[i])
-				j++;
-		}
-		sorted_alaw[j] = i;
-	}
-
-	/* generate tabels */
-	for (i = 0; i < 256; i++) {
-		/* spl is the source: the law-sample (converted to alaw) */
-		spl = i;
-		if (dsp_options & DSP_OPT_ULAW)
-			spl = dsp_audio_ulaw_to_alaw[i];
-		/* find the 7-bit-sample */
-		for (j = 0; j < 256; j++) {
-			if (sorted_alaw[j] == spl)
-				break;
-		}
-		/* write 7-bit audio value */
-		dsp_audio_law2seven[i] = j >> 1;
-	}
-	for (i = 0; i < 128; i++) {
-		spl = sorted_alaw[i << 1];
-		if (dsp_options & DSP_OPT_ULAW)
-			spl = dsp_audio_alaw_to_ulaw[spl];
-		dsp_audio_seven2law[i] = spl;
-	}
-}
-
-
-/* mix 2*law -> law */
-u8 dsp_audio_mix_law[65536];
-
-/******************************************************
- * generate mix table to mix two law samples into one *
- ******************************************************/
-
-void
-dsp_audio_generate_mix_table(void)
-{
-	int i, j;
-	s32 sample;
-
-	i = 0;
-	while (i < 256) {
-		j = 0;
-		while (j < 256) {
-			sample = dsp_audio_law_to_s32[i];
-			sample += dsp_audio_law_to_s32[j];
-			if (sample > 32767)
-				sample = 32767;
-			if (sample < -32768)
-				sample = -32768;
-			dsp_audio_mix_law[(i << 8) | j] =
-				dsp_audio_s16_to_law[sample & 0xffff];
-			j++;
-		}
-		i++;
-	}
-}
-
-
-/*************************************
- * generate different volume changes *
- *************************************/
-
-static u8 dsp_audio_reduce8[256];
-static u8 dsp_audio_reduce7[256];
-static u8 dsp_audio_reduce6[256];
-static u8 dsp_audio_reduce5[256];
-static u8 dsp_audio_reduce4[256];
-static u8 dsp_audio_reduce3[256];
-static u8 dsp_audio_reduce2[256];
-static u8 dsp_audio_reduce1[256];
-static u8 dsp_audio_increase1[256];
-static u8 dsp_audio_increase2[256];
-static u8 dsp_audio_increase3[256];
-static u8 dsp_audio_increase4[256];
-static u8 dsp_audio_increase5[256];
-static u8 dsp_audio_increase6[256];
-static u8 dsp_audio_increase7[256];
-static u8 dsp_audio_increase8[256];
-
-static u8 *dsp_audio_volume_change[16] = {
-	dsp_audio_reduce8,
-	dsp_audio_reduce7,
-	dsp_audio_reduce6,
-	dsp_audio_reduce5,
-	dsp_audio_reduce4,
-	dsp_audio_reduce3,
-	dsp_audio_reduce2,
-	dsp_audio_reduce1,
-	dsp_audio_increase1,
-	dsp_audio_increase2,
-	dsp_audio_increase3,
-	dsp_audio_increase4,
-	dsp_audio_increase5,
-	dsp_audio_increase6,
-	dsp_audio_increase7,
-	dsp_audio_increase8,
-};
-
-void
-dsp_audio_generate_volume_changes(void)
-{
-	register s32 sample;
-	int i;
-	int num[]   = { 110, 125, 150, 175, 200, 300, 400, 500 };
-	int denum[] = { 100, 100, 100, 100, 100, 100, 100, 100 };
-
-	i = 0;
-	while (i < 256) {
-		dsp_audio_reduce8[i] = dsp_audio_s16_to_law[
-			(dsp_audio_law_to_s32[i] * denum[7] / num[7]) & 0xffff];
-		dsp_audio_reduce7[i] = dsp_audio_s16_to_law[
-			(dsp_audio_law_to_s32[i] * denum[6] / num[6]) & 0xffff];
-		dsp_audio_reduce6[i] = dsp_audio_s16_to_law[
-			(dsp_audio_law_to_s32[i] * denum[5] / num[5]) & 0xffff];
-		dsp_audio_reduce5[i] = dsp_audio_s16_to_law[
-			(dsp_audio_law_to_s32[i] * denum[4] / num[4]) & 0xffff];
-		dsp_audio_reduce4[i] = dsp_audio_s16_to_law[
-			(dsp_audio_law_to_s32[i] * denum[3] / num[3]) & 0xffff];
-		dsp_audio_reduce3[i] = dsp_audio_s16_to_law[
-			(dsp_audio_law_to_s32[i] * denum[2] / num[2]) & 0xffff];
-		dsp_audio_reduce2[i] = dsp_audio_s16_to_law[
-			(dsp_audio_law_to_s32[i] * denum[1] / num[1]) & 0xffff];
-		dsp_audio_reduce1[i] = dsp_audio_s16_to_law[
-			(dsp_audio_law_to_s32[i] * denum[0] / num[0]) & 0xffff];
-		sample = dsp_audio_law_to_s32[i] * num[0] / denum[0];
-		if (sample < -32768)
-			sample = -32768;
-		else if (sample > 32767)
-			sample = 32767;
-		dsp_audio_increase1[i] = dsp_audio_s16_to_law[sample & 0xffff];
-		sample = dsp_audio_law_to_s32[i] * num[1] / denum[1];
-		if (sample < -32768)
-			sample = -32768;
-		else if (sample > 32767)
-			sample = 32767;
-		dsp_audio_increase2[i] = dsp_audio_s16_to_law[sample & 0xffff];
-		sample = dsp_audio_law_to_s32[i] * num[2] / denum[2];
-		if (sample < -32768)
-			sample = -32768;
-		else if (sample > 32767)
-			sample = 32767;
-		dsp_audio_increase3[i] = dsp_audio_s16_to_law[sample & 0xffff];
-		sample = dsp_audio_law_to_s32[i] * num[3] / denum[3];
-		if (sample < -32768)
-			sample = -32768;
-		else if (sample > 32767)
-			sample = 32767;
-		dsp_audio_increase4[i] = dsp_audio_s16_to_law[sample & 0xffff];
-		sample = dsp_audio_law_to_s32[i] * num[4] / denum[4];
-		if (sample < -32768)
-			sample = -32768;
-		else if (sample > 32767)
-			sample = 32767;
-		dsp_audio_increase5[i] = dsp_audio_s16_to_law[sample & 0xffff];
-		sample = dsp_audio_law_to_s32[i] * num[5] / denum[5];
-		if (sample < -32768)
-			sample = -32768;
-		else if (sample > 32767)
-			sample = 32767;
-		dsp_audio_increase6[i] = dsp_audio_s16_to_law[sample & 0xffff];
-		sample = dsp_audio_law_to_s32[i] * num[6] / denum[6];
-		if (sample < -32768)
-			sample = -32768;
-		else if (sample > 32767)
-			sample = 32767;
-		dsp_audio_increase7[i] = dsp_audio_s16_to_law[sample & 0xffff];
-		sample = dsp_audio_law_to_s32[i] * num[7] / denum[7];
-		if (sample < -32768)
-			sample = -32768;
-		else if (sample > 32767)
-			sample = 32767;
-		dsp_audio_increase8[i] = dsp_audio_s16_to_law[sample & 0xffff];
-
-		i++;
-	}
-}
-
-
-/**************************************
- * change the volume of the given skb *
- **************************************/
-
-/* this is a helper function for changing volume of skb. the range may be
- * -8 to 8, which is a shift to the power of 2. 0 == no volume, 3 == volume*8
- */
-void
-dsp_change_volume(struct sk_buff *skb, int volume)
-{
-	u8 *volume_change;
-	int i, ii;
-	u8 *p;
-	int shift;
-
-	if (volume == 0)
-		return;
-
-	/* get correct conversion table */
-	if (volume < 0) {
-		shift = volume + 8;
-		if (shift < 0)
-			shift = 0;
-	} else {
-		shift = volume + 7;
-		if (shift > 15)
-			shift = 15;
-	}
-	volume_change = dsp_audio_volume_change[shift];
-	i = 0;
-	ii = skb->len;
-	p = skb->data;
-	/* change volume */
-	while (i < ii) {
-		*p = volume_change[*p];
-		p++;
-		i++;
-	}
-}
diff --git a/drivers/isdn/mISDN/dsp_blowfish.c b/drivers/isdn/mISDN/dsp_blowfish.c
deleted file mode 100644
index 0e77c282c862..000000000000
--- a/drivers/isdn/mISDN/dsp_blowfish.c
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- * Blowfish encryption/decryption for mISDN_dsp.
- *
- * Copyright Andreas Eversberg (jolly@eversberg.eu)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/mISDNif.h>
-#include <linux/mISDNdsp.h>
-#include "core.h"
-#include "dsp.h"
-
-/*
- * how to encode a sample stream to 64-bit blocks that will be encryped
- *
- * first of all, data is collected until a block of 9 samples are received.
- * of course, a packet may have much more than 9 sample, but is may have
- * not excacly the multiple of 9 samples. if there is a rest, the next
- * received data will complete the block.
- *
- * the block is then converted to 9 uLAW samples without the least sigificant
- * bit. the result is a 7-bit encoded sample.
- *
- * the samples will be reoganised to form 8 bytes of data:
- * (5(6) means: encoded sample no. 5, bit 6)
- *
- * 0(6) 0(5) 0(4) 0(3) 0(2) 0(1) 0(0) 1(6)
- * 1(5) 1(4) 1(3) 1(2) 1(1) 1(0) 2(6) 2(5)
- * 2(4) 2(3) 2(2) 2(1) 2(0) 3(6) 3(5) 3(4)
- * 3(3) 3(2) 3(1) 3(0) 4(6) 4(5) 4(4) 4(3)
- * 4(2) 4(1) 4(0) 5(6) 5(5) 5(4) 5(3) 5(2)
- * 5(1) 5(0) 6(6) 6(5) 6(4) 6(3) 6(2) 6(1)
- * 6(0) 7(6) 7(5) 7(4) 7(3) 7(2) 7(1) 7(0)
- * 8(6) 8(5) 8(4) 8(3) 8(2) 8(1) 8(0)
- *
- * the missing bit 0 of the last byte is filled with some
- * random noise, to fill all 8 bytes.
- *
- * the 8 bytes will be encrypted using blowfish.
- *
- * the result will be converted into 9 bytes. the bit 7 is used for
- * checksumme (CS) for sync (0, 1) and for the last bit:
- * (5(6) means: crypted byte 5, bit 6)
- *
- * 1    0(7) 0(6) 0(5) 0(4) 0(3) 0(2) 0(1)
- * 0    0(0) 1(7) 1(6) 1(5) 1(4) 1(3) 1(2)
- * 0    1(1) 1(0) 2(7) 2(6) 2(5) 2(4) 2(3)
- * 0    2(2) 2(1) 2(0) 3(7) 3(6) 3(5) 3(4)
- * 0    3(3) 3(2) 3(1) 3(0) 4(7) 4(6) 4(5)
- * CS   4(4) 4(3) 4(2) 4(1) 4(0) 5(7) 5(6)
- * CS   5(5) 5(4) 5(3) 5(2) 5(1) 5(0) 6(7)
- * CS   6(6) 6(5) 6(4) 6(3) 6(2) 6(1) 6(0)
- * 7(0) 7(6) 7(5) 7(4) 7(3) 7(2) 7(1) 7(0)
- *
- * the checksum is used to detect transmission errors and frame drops.
- *
- * synchronisation of received block is done by shifting the upper bit of each
- * byte (bit 7) to a shift register. if the rigister has the first five bits
- * (10000), this is used to find the sync. only if sync has been found, the
- * current block of 9 received bytes are decrypted. before that the check
- * sum is calculated. if it is incorrect the block is dropped.
- * this will avoid loud noise due to corrupt encrypted data.
- *
- * if the last block is corrupt, the current decoded block is repeated
- * until a valid block has been received.
- */
-
-/*
- *  some blowfish parts are taken from the
- * crypto-api for faster implementation
- */
-
-static const u32 bf_pbox[16 + 2] = {
-	0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
-	0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
-	0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
-	0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
-	0x9216d5d9, 0x8979fb1b,
-};
-
-static const u32 bf_sbox[256 * 4] = {
-	0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
-	0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
-	0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
-	0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
-	0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
-	0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
-	0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
-	0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
-	0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
-	0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
-	0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
-	0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
-	0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
-	0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
-	0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
-	0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
-	0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
-	0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
-	0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
-	0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
-	0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
-	0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
-	0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
-	0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
-	0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
-	0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
-	0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
-	0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
-	0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
-	0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
-	0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
-	0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
-	0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
-	0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
-	0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
-	0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
-	0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
-	0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
-	0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
-	0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
-	0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
-	0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
-	0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
-	0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
-	0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
-	0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
-	0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
-	0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
-	0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
-	0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
-	0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
-	0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
-	0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
-	0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
-	0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
-	0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
-	0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
-	0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
-	0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
-	0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
-	0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
-	0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
-	0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
-	0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
-	0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
-	0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
-	0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
-	0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
-	0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
-	0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
-	0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
-	0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
-	0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
-	0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
-	0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
-	0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
-	0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
-	0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
-	0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
-	0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
-	0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
-	0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
-	0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
-	0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
-	0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
-	0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
-	0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
-	0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
-	0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
-	0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
-	0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
-	0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
-	0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
-	0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
-	0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
-	0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
-	0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
-	0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
-	0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
-	0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
-	0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
-	0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
-	0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
-	0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
-	0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
-	0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
-	0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
-	0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
-	0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
-	0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
-	0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
-	0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
-	0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
-	0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
-	0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
-	0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
-	0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
-	0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
-	0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
-	0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
-	0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
-	0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
-	0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
-	0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
-	0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
-	0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
-	0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
-	0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
-	0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
-	0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
-	0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
-	0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
-	0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
-	0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
-	0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
-	0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
-	0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
-	0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
-	0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
-	0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
-	0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
-	0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
-	0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
-	0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
-	0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
-	0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
-	0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
-	0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
-	0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
-	0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
-	0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
-	0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
-	0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
-	0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
-	0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
-	0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
-	0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
-	0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
-	0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
-	0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
-	0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
-	0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
-	0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
-	0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
-	0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
-	0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
-	0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
-	0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
-	0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
-	0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
-	0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
-	0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
-	0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
-	0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
-	0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
-	0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
-	0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
-	0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
-	0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
-	0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
-	0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
-	0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
-	0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
-	0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
-	0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
-	0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
-	0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
-	0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
-	0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
-	0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
-	0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
-	0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
-	0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
-	0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
-	0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
-	0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
-	0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
-	0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
-	0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
-	0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
-	0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
-	0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
-	0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
-	0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
-	0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
-	0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
-	0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
-	0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
-	0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
-	0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
-	0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
-	0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
-	0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
-	0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
-	0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
-	0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
-	0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
-	0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
-	0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
-	0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
-	0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
-	0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
-	0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
-	0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
-	0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
-	0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
-	0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
-	0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
-	0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
-	0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
-	0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
-	0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
-	0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
-	0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
-	0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
-	0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
-	0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
-	0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
-	0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
-	0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
-	0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
-	0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
-	0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
-	0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
-	0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
-	0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
-	0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
-	0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
-	0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
-	0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
-	0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
-	0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
-	0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
-	0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
-	0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
-	0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
-};
-
-/*
- * Round loop unrolling macros, S is a pointer to a S-Box array
- * organized in 4 unsigned longs at a row.
- */
-#define GET32_3(x) (((x) & 0xff))
-#define GET32_2(x) (((x) >> (8)) & (0xff))
-#define GET32_1(x) (((x) >> (16)) & (0xff))
-#define GET32_0(x) (((x) >> (24)) & (0xff))
-
-#define bf_F(x) (((S[GET32_0(x)] + S[256 + GET32_1(x)]) ^	\
-		  S[512 + GET32_2(x)]) + S[768 + GET32_3(x)])
-
-#define EROUND(a, b, n)  do { b ^= P[n]; a ^= bf_F(b); } while (0)
-#define DROUND(a, b, n)  do { a ^= bf_F(b); b ^= P[n]; } while (0)
-
-
-/*
- * encrypt isdn data frame
- * every block with 9 samples is encrypted
- */
-void
-dsp_bf_encrypt(struct dsp *dsp, u8 *data, int len)
-{
-	int i = 0, j = dsp->bf_crypt_pos;
-	u8 *bf_data_in = dsp->bf_data_in;
-	u8 *bf_crypt_out = dsp->bf_crypt_out;
-	u32 *P = dsp->bf_p;
-	u32 *S = dsp->bf_s;
-	u32 yl, yr;
-	u32 cs;
-	u8 nibble;
-
-	while (i < len) {
-		/* collect a block of 9 samples */
-		if (j < 9) {
-			bf_data_in[j] = *data;
-			*data++ = bf_crypt_out[j++];
-			i++;
-			continue;
-		}
-		j = 0;
-		/* transcode 9 samples xlaw to 8 bytes */
-		yl = dsp_audio_law2seven[bf_data_in[0]];
-		yl = (yl << 7) | dsp_audio_law2seven[bf_data_in[1]];
-		yl = (yl << 7) | dsp_audio_law2seven[bf_data_in[2]];
-		yl = (yl << 7) | dsp_audio_law2seven[bf_data_in[3]];
-		nibble = dsp_audio_law2seven[bf_data_in[4]];
-		yr = nibble;
-		yl = (yl << 4) | (nibble >> 3);
-		yr = (yr << 7) | dsp_audio_law2seven[bf_data_in[5]];
-		yr = (yr << 7) | dsp_audio_law2seven[bf_data_in[6]];
-		yr = (yr << 7) | dsp_audio_law2seven[bf_data_in[7]];
-		yr = (yr << 7) | dsp_audio_law2seven[bf_data_in[8]];
-		yr = (yr << 1) | (bf_data_in[0] & 1);
-
-		/* fill unused bit with random noise of audio input */
-		/* encrypt */
-
-		EROUND(yr, yl, 0);
-		EROUND(yl, yr, 1);
-		EROUND(yr, yl, 2);
-		EROUND(yl, yr, 3);
-		EROUND(yr, yl, 4);
-		EROUND(yl, yr, 5);
-		EROUND(yr, yl, 6);
-		EROUND(yl, yr, 7);
-		EROUND(yr, yl, 8);
-		EROUND(yl, yr, 9);
-		EROUND(yr, yl, 10);
-		EROUND(yl, yr, 11);
-		EROUND(yr, yl, 12);
-		EROUND(yl, yr, 13);
-		EROUND(yr, yl, 14);
-		EROUND(yl, yr, 15);
-		yl ^= P[16];
-		yr ^= P[17];
-
-		/* calculate 3-bit checksumme */
-		cs = yl ^ (yl >> 3) ^ (yl >> 6) ^ (yl >> 9) ^ (yl >> 12) ^ (yl >> 15)
-			^ (yl >> 18) ^ (yl >> 21) ^ (yl >> 24) ^ (yl >> 27) ^ (yl >> 30)
-			^ (yr << 2) ^ (yr >> 1) ^ (yr >> 4) ^ (yr >> 7) ^ (yr >> 10)
-			^ (yr >> 13) ^ (yr >> 16) ^ (yr >> 19) ^ (yr >> 22) ^ (yr >> 25)
-			^ (yr >> 28) ^ (yr >> 31);
-
-		/*
-		 * transcode 8 crypted bytes to 9 data bytes with sync
-		 * and checksum information
-		 */
-		bf_crypt_out[0] = (yl >> 25) | 0x80;
-		bf_crypt_out[1] = (yl >> 18) & 0x7f;
-		bf_crypt_out[2] = (yl >> 11) & 0x7f;
-		bf_crypt_out[3] = (yl >> 4) & 0x7f;
-		bf_crypt_out[4] = ((yl << 3) & 0x78) | ((yr >> 29) & 0x07);
-		bf_crypt_out[5] = ((yr >> 22) & 0x7f) | ((cs << 5) & 0x80);
-		bf_crypt_out[6] = ((yr >> 15) & 0x7f) | ((cs << 6) & 0x80);
-		bf_crypt_out[7] = ((yr >> 8) & 0x7f) | (cs << 7);
-		bf_crypt_out[8] = yr;
-	}
-
-	/* write current count */
-	dsp->bf_crypt_pos = j;
-
-}
-
-
-/*
- * decrypt isdn data frame
- * every block with 9 bytes is decrypted
- */
-void
-dsp_bf_decrypt(struct dsp *dsp, u8 *data, int len)
-{
-	int i = 0;
-	u8 j = dsp->bf_decrypt_in_pos;
-	u8 k = dsp->bf_decrypt_out_pos;
-	u8 *bf_crypt_inring = dsp->bf_crypt_inring;
-	u8 *bf_data_out = dsp->bf_data_out;
-	u16 sync = dsp->bf_sync;
-	u32 *P = dsp->bf_p;
-	u32 *S = dsp->bf_s;
-	u32 yl, yr;
-	u8 nibble;
-	u8 cs, cs0, cs1, cs2;
-
-	while (i < len) {
-		/*
-		 * shift upper bit and rotate data to buffer ring
-		 * send current decrypted data
-		 */
-		sync = (sync << 1) | ((*data) >> 7);
-		bf_crypt_inring[j++ & 15] = *data;
-		*data++ = bf_data_out[k++];
-		i++;
-		if (k == 9)
-			k = 0; /* repeat if no sync has been found */
-		/* check if not in sync */
-		if ((sync & 0x1f0) != 0x100)
-			continue;
-		j -= 9;
-		/* transcode receive data to 64 bit block of encrypted data */
-		yl = bf_crypt_inring[j++ & 15];
-		yl = (yl << 7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
-		yl = (yl << 7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
-		yl = (yl << 7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
-		nibble = bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
-		yr = nibble;
-		yl = (yl << 4) | (nibble >> 3);
-		cs2 = bf_crypt_inring[j++ & 15];
-		yr = (yr << 7) | (cs2 & 0x7f);
-		cs1 = bf_crypt_inring[j++ & 15];
-		yr = (yr << 7) | (cs1 & 0x7f);
-		cs0 = bf_crypt_inring[j++ & 15];
-		yr = (yr << 7) | (cs0 & 0x7f);
-		yr = (yr << 8) | bf_crypt_inring[j++ & 15];
-
-		/* calculate 3-bit checksumme */
-		cs = yl ^ (yl >> 3) ^ (yl >> 6) ^ (yl >> 9) ^ (yl >> 12) ^ (yl >> 15)
-			^ (yl >> 18) ^ (yl >> 21) ^ (yl >> 24) ^ (yl >> 27) ^ (yl >> 30)
-			^ (yr << 2) ^ (yr >> 1) ^ (yr >> 4) ^ (yr >> 7) ^ (yr >> 10)
-			^ (yr >> 13) ^ (yr >> 16) ^ (yr >> 19) ^ (yr >> 22) ^ (yr >> 25)
-			^ (yr >> 28) ^ (yr >> 31);
-
-		/* check if frame is valid */
-		if ((cs & 0x7) != (((cs2 >> 5) & 4) | ((cs1 >> 6) & 2) | (cs0 >> 7))) {
-			if (dsp_debug & DEBUG_DSP_BLOWFISH)
-				printk(KERN_DEBUG
-				       "DSP BLOWFISH: received corrupt frame, "
-				       "checksumme is not correct\n");
-			continue;
-		}
-
-		/* decrypt */
-		yr ^= P[17];
-		yl ^= P[16];
-		DROUND(yl, yr, 15);
-		DROUND(yr, yl, 14);
-		DROUND(yl, yr, 13);
-		DROUND(yr, yl, 12);
-		DROUND(yl, yr, 11);
-		DROUND(yr, yl, 10);
-		DROUND(yl, yr, 9);
-		DROUND(yr, yl, 8);
-		DROUND(yl, yr, 7);
-		DROUND(yr, yl, 6);
-		DROUND(yl, yr, 5);
-		DROUND(yr, yl, 4);
-		DROUND(yl, yr, 3);
-		DROUND(yr, yl, 2);
-		DROUND(yl, yr, 1);
-		DROUND(yr, yl, 0);
-
-		/* transcode 8 crypted bytes to 9 sample bytes */
-		bf_data_out[0] = dsp_audio_seven2law[(yl >> 25) & 0x7f];
-		bf_data_out[1] = dsp_audio_seven2law[(yl >> 18) & 0x7f];
-		bf_data_out[2] = dsp_audio_seven2law[(yl >> 11) & 0x7f];
-		bf_data_out[3] = dsp_audio_seven2law[(yl >> 4) & 0x7f];
-		bf_data_out[4] = dsp_audio_seven2law[((yl << 3) & 0x78) |
-						     ((yr >> 29) & 0x07)];
-
-		bf_data_out[5] = dsp_audio_seven2law[(yr >> 22) & 0x7f];
-		bf_data_out[6] = dsp_audio_seven2law[(yr >> 15) & 0x7f];
-		bf_data_out[7] = dsp_audio_seven2law[(yr >> 8) & 0x7f];
-		bf_data_out[8] = dsp_audio_seven2law[(yr >> 1) & 0x7f];
-		k = 0; /* start with new decoded frame */
-	}
-
-	/* write current count and sync */
-	dsp->bf_decrypt_in_pos = j;
-	dsp->bf_decrypt_out_pos = k;
-	dsp->bf_sync = sync;
-}
-
-
-/* used to encrypt S and P boxes */
-static inline void
-encrypt_block(const u32 *P, const u32 *S, u32 *dst, u32 *src)
-{
-	u32 yl = src[0];
-	u32 yr = src[1];
-
-	EROUND(yr, yl, 0);
-	EROUND(yl, yr, 1);
-	EROUND(yr, yl, 2);
-	EROUND(yl, yr, 3);
-	EROUND(yr, yl, 4);
-	EROUND(yl, yr, 5);
-	EROUND(yr, yl, 6);
-	EROUND(yl, yr, 7);
-	EROUND(yr, yl, 8);
-	EROUND(yl, yr, 9);
-	EROUND(yr, yl, 10);
-	EROUND(yl, yr, 11);
-	EROUND(yr, yl, 12);
-	EROUND(yl, yr, 13);
-	EROUND(yr, yl, 14);
-	EROUND(yl, yr, 15);
-
-	yl ^= P[16];
-	yr ^= P[17];
-
-	dst[0] = yr;
-	dst[1] = yl;
-}
-
-/*
- * initialize the dsp for encryption and decryption using the same key
- * Calculates the blowfish S and P boxes for encryption and decryption.
- * The margin of keylen must be 4-56 bytes.
- * returns 0 if ok.
- */
-int
-dsp_bf_init(struct dsp *dsp, const u8 *key, uint keylen)
-{
-	short i, j, count;
-	u32 data[2], temp;
-	u32 *P = (u32 *)dsp->bf_p;
-	u32 *S = (u32 *)dsp->bf_s;
-
-	if (keylen < 4 || keylen > 56)
-		return 1;
-
-	/* Set dsp states */
-	i = 0;
-	while (i < 9) {
-		dsp->bf_crypt_out[i] = 0xff;
-		dsp->bf_data_out[i] = dsp_silence;
-		i++;
-	}
-	dsp->bf_crypt_pos = 0;
-	dsp->bf_decrypt_in_pos = 0;
-	dsp->bf_decrypt_out_pos = 0;
-	dsp->bf_sync = 0x1ff;
-	dsp->bf_enable = 1;
-
-	/* Copy the initialization s-boxes */
-	for (i = 0, count = 0; i < 256; i++)
-		for (j = 0; j < 4; j++, count++)
-			S[count] = bf_sbox[count];
-
-	/* Set the p-boxes */
-	for (i = 0; i < 16 + 2; i++)
-		P[i] = bf_pbox[i];
-
-	/* Actual subkey generation */
-	for (j = 0, i = 0; i < 16 + 2; i++) {
-		temp = (((u32)key[j] << 24) |
-			((u32)key[(j + 1) % keylen] << 16) |
-			((u32)key[(j + 2) % keylen] << 8) |
-			((u32)key[(j + 3) % keylen]));
-
-		P[i] = P[i] ^ temp;
-		j = (j + 4) % keylen;
-	}
-
-	data[0] = 0x00000000;
-	data[1] = 0x00000000;
-
-	for (i = 0; i < 16 + 2; i += 2) {
-		encrypt_block(P, S, data, data);
-
-		P[i] = data[0];
-		P[i + 1] = data[1];
-	}
-
-	for (i = 0; i < 4; i++) {
-		for (j = 0, count = i * 256; j < 256; j += 2, count += 2) {
-			encrypt_block(P, S, data, data);
-
-			S[count] = data[0];
-			S[count + 1] = data[1];
-		}
-	}
-
-	return 0;
-}
-
-
-/*
- * turn encryption off
- */
-void
-dsp_bf_cleanup(struct dsp *dsp)
-{
-	dsp->bf_enable = 0;
-}
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c
deleted file mode 100644
index d5eb2349c414..000000000000
--- a/drivers/isdn/mISDN/dsp_cmx.c
+++ /dev/null
@@ -1,1949 +0,0 @@
-/*
- * Audio crossconnecting/conferrencing (hardware level).
- *
- * Copyright 2002 by Andreas Eversberg (jolly@eversberg.eu)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-/*
- * The process of adding and removing parties to/from a conference:
- *
- * There is a chain of struct dsp_conf which has one or more members in a chain
- * of struct dsp_conf_member.
- *
- * After a party is added, the conference is checked for hardware capability.
- * Also if a party is removed, the conference is checked again.
- *
- * There are 3 different solutions: -1 = software, 0 = hardware-crossconnect
- * 1-n = hardware-conference. The n will give the conference number.
- *
- * Depending on the change after removal or insertion of a party, hardware
- * commands are given.
- *
- * The current solution is stored within the struct dsp_conf entry.
- */
-
-/*
- * HOW THE CMX WORKS:
- *
- * There are 3 types of interaction: One member is alone, in this case only
- * data flow from upper to lower layer is done.
- * Two members will also exchange their data so they are crossconnected.
- * Three or more members will be added in a conference and will hear each
- * other but will not receive their own speech (echo) if not enabled.
- *
- * Features of CMX are:
- *  - Crossconnecting or even conference, if more than two members are together.
- *  - Force mixing of transmit data with other crossconnect/conference members.
- *  - Echo generation to benchmark the delay of audio processing.
- *  - Use hardware to minimize cpu load, disable FIFO load and minimize delay.
- *  - Dejittering and clock generation.
- *
- * There are 2 buffers:
- *
- *
- * RX-Buffer
- *                 R             W
- *                 |             |
- * ----------------+-------------+-------------------
- *
- * The rx-buffer is a ring buffer used to store the received data for each
- * individual member. This is only the case if data needs to be dejittered
- * or in case of a conference where different clocks require reclocking.
- * The transmit-clock (R) will read the buffer.
- * If the clock overruns the write-pointer, we will have a buffer underrun.
- * If the write pointer always has a certain distance from the transmit-
- * clock, we will have a delay. The delay will dynamically be increased and
- * reduced.
- *
- *
- * TX-Buffer
- *                  R        W
- *                  |        |
- * -----------------+--------+-----------------------
- *
- * The tx-buffer is a ring buffer to queue the transmit data from user space
- * until it will be mixed or sent. There are two pointers, R and W. If the write
- * pointer W would reach or overrun R, the buffer would overrun. In this case
- * (some) data is dropped so that it will not overrun.
- * Additionally a dynamic dejittering can be enabled. this allows data from
- * user space that have jitter and different clock source.
- *
- *
- * Clock:
- *
- * A Clock is not required, if the data source has exactly one clock. In this
- * case the data source is forwarded to the destination.
- *
- * A Clock is required, because the data source
- *  - has multiple clocks.
- *  - has no usable clock due to jitter or packet loss (VoIP).
- * In this case the system's clock is used. The clock resolution depends on
- * the jiffy resolution.
- *
- * If a member joins a conference:
- *
- * - If a member joins, its rx_buff is set to silence and change read pointer
- *   to transmit clock.
- *
- * The procedure of received data from card is explained in cmx_receive.
- * The procedure of received data from user space is explained in cmx_transmit.
- * The procedure of transmit data to card is cmx_send.
- *
- *
- * Interaction with other features:
- *
- * DTMF:
- * DTMF decoding is done before the data is crossconnected.
- *
- * Volume change:
- * Changing rx-volume is done before the data is crossconnected. The tx-volume
- * must be changed whenever data is transmitted to the card by the cmx.
- *
- * Tones:
- * If a tone is enabled, it will be processed whenever data is transmitted to
- * the card. It will replace the tx-data from the user space.
- * If tones are generated by hardware, this conference member is removed for
- * this time.
- *
- * Disable rx-data:
- * If cmx is realized in hardware, rx data will be disabled if requested by
- * the upper layer. If dtmf decoding is done by software and enabled, rx data
- * will not be disabled but blocked to the upper layer.
- *
- * HFC conference engine:
- * If it is possible to realize all features using hardware, hardware will be
- * used if not forbidden by control command. Disabling rx-data provides
- * absolutely traffic free audio processing. (except for the quick 1-frame
- * upload of a tone loop, only once for a new tone)
- *
- */
-
-/* delay.h is required for hw_lock.h */
-
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/mISDNif.h>
-#include <linux/mISDNdsp.h>
-#include "core.h"
-#include "dsp.h"
-/*
- * debugging of multi party conference,
- * by using conference even with two members
- */
-
-/* #define CMX_CONF_DEBUG */
-
-/*#define CMX_DEBUG * massive read/write pointer output */
-/*#define CMX_DELAY_DEBUG * gives rx-buffer delay overview */
-/*#define CMX_TX_DEBUG * massive read/write on tx-buffer with content */
-
-/*
- * debug cmx memory structure
- */
-void
-dsp_cmx_debug(struct dsp *dsp)
-{
-	struct dsp_conf	*conf;
-	struct dsp_conf_member	*member;
-	struct dsp		*odsp;
-
-	printk(KERN_DEBUG "-----Current DSP\n");
-	list_for_each_entry(odsp, &dsp_ilist, list) {
-		printk(KERN_DEBUG "* %s hardecho=%d softecho=%d txmix=%d",
-		       odsp->name, odsp->echo.hardware, odsp->echo.software,
-		       odsp->tx_mix);
-		if (odsp->conf)
-			printk(" (Conf %d)", odsp->conf->id);
-		if (dsp == odsp)
-			printk(" *this*");
-		printk("\n");
-	}
-	printk(KERN_DEBUG "-----Current Conf:\n");
-	list_for_each_entry(conf, &conf_ilist, list) {
-		printk(KERN_DEBUG "* Conf %d (%p)\n", conf->id, conf);
-		list_for_each_entry(member, &conf->mlist, list) {
-			printk(KERN_DEBUG
-			       "  - member = %s (slot_tx %d, bank_tx %d, "
-			       "slot_rx %d, bank_rx %d hfc_conf %d "
-			       "tx_data %d rx_is_off %d)%s\n",
-			       member->dsp->name, member->dsp->pcm_slot_tx,
-			       member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx,
-			       member->dsp->pcm_bank_rx, member->dsp->hfc_conf,
-			       member->dsp->tx_data, member->dsp->rx_is_off,
-			       (member->dsp == dsp) ? " *this*" : "");
-		}
-	}
-	printk(KERN_DEBUG "-----end\n");
-}
-
-/*
- * search conference
- */
-static struct dsp_conf *
-dsp_cmx_search_conf(u32 id)
-{
-	struct dsp_conf *conf;
-
-	if (!id) {
-		printk(KERN_WARNING "%s: conference ID is 0.\n", __func__);
-		return NULL;
-	}
-
-	/* search conference */
-	list_for_each_entry(conf, &conf_ilist, list)
-		if (conf->id == id)
-			return conf;
-
-	return NULL;
-}
-
-
-/*
- * add member to conference
- */
-static int
-dsp_cmx_add_conf_member(struct dsp *dsp, struct dsp_conf *conf)
-{
-	struct dsp_conf_member *member;
-
-	if (!conf || !dsp) {
-		printk(KERN_WARNING "%s: conf or dsp is 0.\n", __func__);
-		return -EINVAL;
-	}
-	if (dsp->member) {
-		printk(KERN_WARNING "%s: dsp is already member in a conf.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (dsp->conf) {
-		printk(KERN_WARNING "%s: dsp is already in a conf.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	member = kzalloc_obj(struct dsp_conf_member, GFP_ATOMIC);
-	if (!member) {
-		printk(KERN_ERR "kzalloc struct dsp_conf_member failed\n");
-		return -ENOMEM;
-	}
-	member->dsp = dsp;
-	/* clear rx buffer */
-	memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
-	dsp->rx_init = 1; /* rx_W and rx_R will be adjusted on first frame */
-	dsp->rx_W = 0;
-	dsp->rx_R = 0;
-
-	list_add_tail(&member->list, &conf->mlist);
-
-	dsp->conf = conf;
-	dsp->member = member;
-
-	return 0;
-}
-
-
-/*
- * del member from conference
- */
-int
-dsp_cmx_del_conf_member(struct dsp *dsp)
-{
-	struct dsp_conf_member *member;
-
-	if (!dsp) {
-		printk(KERN_WARNING "%s: dsp is 0.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!dsp->conf) {
-		printk(KERN_WARNING "%s: dsp is not in a conf.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (list_empty(&dsp->conf->mlist)) {
-		printk(KERN_WARNING "%s: dsp has linked an empty conf.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	/* find us in conf */
-	list_for_each_entry(member, &dsp->conf->mlist, list) {
-		if (member->dsp == dsp) {
-			list_del(&member->list);
-			dsp->conf = NULL;
-			dsp->member = NULL;
-			kfree(member);
-			return 0;
-		}
-	}
-	printk(KERN_WARNING
-	       "%s: dsp is not present in its own conf_member list.\n",
-	       __func__);
-
-	return -EINVAL;
-}
-
-
-/*
- * new conference
- */
-static struct dsp_conf
-*dsp_cmx_new_conf(u32 id)
-{
-	struct dsp_conf *conf;
-
-	if (!id) {
-		printk(KERN_WARNING "%s: id is 0.\n",
-		       __func__);
-		return NULL;
-	}
-
-	conf = kzalloc_obj(struct dsp_conf, GFP_ATOMIC);
-	if (!conf) {
-		printk(KERN_ERR "kzalloc struct dsp_conf failed\n");
-		return NULL;
-	}
-	INIT_LIST_HEAD(&conf->mlist);
-	conf->id = id;
-
-	list_add_tail(&conf->list, &conf_ilist);
-
-	return conf;
-}
-
-
-/*
- * del conference
- */
-int
-dsp_cmx_del_conf(struct dsp_conf *conf)
-{
-	if (!conf) {
-		printk(KERN_WARNING "%s: conf is null.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!list_empty(&conf->mlist)) {
-		printk(KERN_WARNING "%s: conf not empty.\n",
-		       __func__);
-		return -EINVAL;
-	}
-	list_del(&conf->list);
-	kfree(conf);
-
-	return 0;
-}
-
-
-/*
- * send HW message to hfc card
- */
-static void
-dsp_cmx_hw_message(struct dsp *dsp, u32 message, u32 param1, u32 param2,
-		   u32 param3, u32 param4)
-{
-	struct mISDN_ctrl_req cq;
-
-	memset(&cq, 0, sizeof(cq));
-	cq.op = message;
-	cq.p1 = param1 | (param2 << 8);
-	cq.p2 = param3 | (param4 << 8);
-	if (dsp->ch.peer)
-		dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq);
-}
-
-
-/*
- * do hardware update and set the software/hardware flag
- *
- * either a conference or a dsp instance can be given
- * if only dsp instance is given, the instance is not associated with a conf
- * and therefore removed. if a conference is given, the dsp is expected to
- * be member of that conference.
- */
-void
-dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
-{
-	struct dsp_conf_member	*member, *nextm;
-	struct dsp		*finddsp;
-	int		memb = 0, i, ii, i1, i2;
-	int		freeunits[8];
-	u_char		freeslots[256];
-	int		same_hfc = -1, same_pcm = -1, current_conf = -1,
-		all_conf = 1, tx_data = 0;
-
-	/* dsp gets updated (no conf) */
-	if (!conf) {
-		if (!dsp)
-			return;
-		if (dsp_debug & DEBUG_DSP_CMX)
-			printk(KERN_DEBUG "%s checking dsp %s\n",
-			       __func__, dsp->name);
-	one_member:
-		/* remove HFC conference if enabled */
-		if (dsp->hfc_conf >= 0) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s removing %s from HFC conf %d "
-				       "because dsp is split\n", __func__,
-				       dsp->name, dsp->hfc_conf);
-			dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_CONF_SPLIT,
-					   0, 0, 0, 0);
-			dsp->hfc_conf = -1;
-		}
-		/* process hw echo */
-		if (dsp->features.pcm_banks < 1)
-			return;
-		if (!dsp->echo.software && !dsp->echo.hardware) {
-			/* NO ECHO: remove PCM slot if assigned */
-			if (dsp->pcm_slot_tx >= 0 || dsp->pcm_slot_rx >= 0) {
-				if (dsp_debug & DEBUG_DSP_CMX)
-					printk(KERN_DEBUG "%s removing %s from"
-					       " PCM slot %d (TX) %d (RX) because"
-					       " dsp is split (no echo)\n",
-					       __func__, dsp->name,
-					       dsp->pcm_slot_tx, dsp->pcm_slot_rx);
-				dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_DISC,
-						   0, 0, 0, 0);
-				dsp->pcm_slot_tx = -1;
-				dsp->pcm_bank_tx = -1;
-				dsp->pcm_slot_rx = -1;
-				dsp->pcm_bank_rx = -1;
-			}
-			return;
-		}
-		/* echo is enabled, find out if we use soft or hardware */
-		dsp->echo.software = dsp->tx_data;
-		dsp->echo.hardware = 0;
-		/* ECHO: already echo */
-		if (dsp->pcm_slot_tx >= 0 && dsp->pcm_slot_rx < 0 &&
-		    dsp->pcm_bank_tx == 2 && dsp->pcm_bank_rx == 2) {
-			dsp->echo.hardware = 1;
-			return;
-		}
-		/* ECHO: if slot already assigned */
-		if (dsp->pcm_slot_tx >= 0) {
-			dsp->pcm_slot_rx = dsp->pcm_slot_tx;
-			dsp->pcm_bank_tx = 2; /* 2 means loop */
-			dsp->pcm_bank_rx = 2;
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s refresh %s for echo using slot %d\n",
-				       __func__, dsp->name,
-				       dsp->pcm_slot_tx);
-			dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
-					   dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
-			dsp->echo.hardware = 1;
-			return;
-		}
-		/* ECHO: find slot */
-		dsp->pcm_slot_tx = -1;
-		dsp->pcm_slot_rx = -1;
-		memset(freeslots, 1, sizeof(freeslots));
-		list_for_each_entry(finddsp, &dsp_ilist, list) {
-			if (finddsp->features.pcm_id == dsp->features.pcm_id) {
-				if (finddsp->pcm_slot_rx >= 0 &&
-				    finddsp->pcm_slot_rx < sizeof(freeslots))
-					freeslots[finddsp->pcm_slot_rx] = 0;
-				if (finddsp->pcm_slot_tx >= 0 &&
-				    finddsp->pcm_slot_tx < sizeof(freeslots))
-					freeslots[finddsp->pcm_slot_tx] = 0;
-			}
-		}
-		i = 0;
-		ii = dsp->features.pcm_slots;
-		while (i < ii) {
-			if (freeslots[i])
-				break;
-			i++;
-		}
-		if (i == ii) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s no slot available for echo\n",
-				       __func__);
-			/* no more slots available */
-			dsp->echo.software = 1;
-			return;
-		}
-		/* assign free slot */
-		dsp->pcm_slot_tx = i;
-		dsp->pcm_slot_rx = i;
-		dsp->pcm_bank_tx = 2; /* loop */
-		dsp->pcm_bank_rx = 2;
-		if (dsp_debug & DEBUG_DSP_CMX)
-			printk(KERN_DEBUG
-			       "%s assign echo for %s using slot %d\n",
-			       __func__, dsp->name, dsp->pcm_slot_tx);
-		dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
-				   dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
-		dsp->echo.hardware = 1;
-		return;
-	}
-
-	/* conf gets updated (all members) */
-	if (dsp_debug & DEBUG_DSP_CMX)
-		printk(KERN_DEBUG "%s checking conference %d\n",
-		       __func__, conf->id);
-
-	if (list_empty(&conf->mlist)) {
-		printk(KERN_ERR "%s: conference without members\n",
-		       __func__);
-		return;
-	}
-	member = list_entry(conf->mlist.next, struct dsp_conf_member, list);
-	same_hfc = member->dsp->features.hfc_id;
-	same_pcm = member->dsp->features.pcm_id;
-	/* check all members in our conference */
-	list_for_each_entry(member, &conf->mlist, list) {
-		/* check if member uses mixing */
-		if (member->dsp->tx_mix) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s dsp %s cannot form a conf, because "
-				       "tx_mix is turned on\n", __func__,
-				       member->dsp->name);
-		conf_software:
-			list_for_each_entry(member, &conf->mlist, list) {
-				dsp = member->dsp;
-				/* remove HFC conference if enabled */
-				if (dsp->hfc_conf >= 0) {
-					if (dsp_debug & DEBUG_DSP_CMX)
-						printk(KERN_DEBUG
-						       "%s removing %s from HFC "
-						       "conf %d because not "
-						       "possible with hardware\n",
-						       __func__,
-						       dsp->name,
-						       dsp->hfc_conf);
-					dsp_cmx_hw_message(dsp,
-							   MISDN_CTRL_HFC_CONF_SPLIT,
-							   0, 0, 0, 0);
-					dsp->hfc_conf = -1;
-				}
-				/* remove PCM slot if assigned */
-				if (dsp->pcm_slot_tx >= 0 ||
-				    dsp->pcm_slot_rx >= 0) {
-					if (dsp_debug & DEBUG_DSP_CMX)
-						printk(KERN_DEBUG "%s removing "
-						       "%s from PCM slot %d (TX)"
-						       " slot %d (RX) because not"
-						       " possible with hardware\n",
-						       __func__,
-						       dsp->name,
-						       dsp->pcm_slot_tx,
-						       dsp->pcm_slot_rx);
-					dsp_cmx_hw_message(dsp,
-							   MISDN_CTRL_HFC_PCM_DISC,
-							   0, 0, 0, 0);
-					dsp->pcm_slot_tx = -1;
-					dsp->pcm_bank_tx = -1;
-					dsp->pcm_slot_rx = -1;
-					dsp->pcm_bank_rx = -1;
-				}
-			}
-			conf->hardware = 0;
-			conf->software = 1;
-			return;
-		}
-		/* check if member has echo turned on */
-		if (member->dsp->echo.hardware || member->dsp->echo.software) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s dsp %s cannot form a conf, because "
-				       "echo is turned on\n", __func__,
-				       member->dsp->name);
-			goto conf_software;
-		}
-		/* check if member has tx_mix turned on */
-		if (member->dsp->tx_mix) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s dsp %s cannot form a conf, because "
-				       "tx_mix is turned on\n",
-				       __func__, member->dsp->name);
-			goto conf_software;
-		}
-		/* check if member changes volume at an not suppoted level */
-		if (member->dsp->tx_volume) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s dsp %s cannot form a conf, because "
-				       "tx_volume is changed\n",
-				       __func__, member->dsp->name);
-			goto conf_software;
-		}
-		if (member->dsp->rx_volume) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s dsp %s cannot form a conf, because "
-				       "rx_volume is changed\n",
-				       __func__, member->dsp->name);
-			goto conf_software;
-		}
-		/* check if tx-data turned on */
-		if (member->dsp->tx_data) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s dsp %s tx_data is turned on\n",
-				       __func__, member->dsp->name);
-			tx_data = 1;
-		}
-		/* check if pipeline exists */
-		if (member->dsp->pipeline.inuse) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s dsp %s cannot form a conf, because "
-				       "pipeline exists\n", __func__,
-				       member->dsp->name);
-			goto conf_software;
-		}
-		/* check if encryption is enabled */
-		if (member->dsp->bf_enable) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG "%s dsp %s cannot form a "
-				       "conf, because encryption is enabled\n",
-				       __func__, member->dsp->name);
-			goto conf_software;
-		}
-		/* check if member is on a card with PCM support */
-		if (member->dsp->features.pcm_id < 0) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s dsp %s cannot form a conf, because "
-				       "dsp has no PCM bus\n",
-				       __func__, member->dsp->name);
-			goto conf_software;
-		}
-		/* check if relations are on the same PCM bus */
-		if (member->dsp->features.pcm_id != same_pcm) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s dsp %s cannot form a conf, because "
-				       "dsp is on a different PCM bus than the "
-				       "first dsp\n",
-				       __func__, member->dsp->name);
-			goto conf_software;
-		}
-		/* determine if members are on the same hfc chip */
-		if (same_hfc != member->dsp->features.hfc_id)
-			same_hfc = -1;
-		/* if there are members already in a conference */
-		if (current_conf < 0 && member->dsp->hfc_conf >= 0)
-			current_conf = member->dsp->hfc_conf;
-		/* if any member is not in a conference */
-		if (member->dsp->hfc_conf < 0)
-			all_conf = 0;
-
-		memb++;
-	}
-
-	/* if no member, this is an error */
-	if (memb < 1)
-		return;
-
-	/* one member */
-	if (memb == 1) {
-		if (dsp_debug & DEBUG_DSP_CMX)
-			printk(KERN_DEBUG
-			       "%s conf %d cannot form a HW conference, "
-			       "because dsp is alone\n", __func__, conf->id);
-		conf->hardware = 0;
-		conf->software = 0;
-		member = list_entry(conf->mlist.next, struct dsp_conf_member,
-				    list);
-		dsp = member->dsp;
-		goto one_member;
-	}
-
-	/*
-	 * ok, now we are sure that all members are on the same pcm.
-	 * now we will see if we have only two members, so we can do
-	 * crossconnections, which don't have any limitations.
-	 */
-
-	/* if we have only two members */
-	if (memb == 2) {
-		member = list_entry(conf->mlist.next, struct dsp_conf_member,
-				    list);
-		nextm = list_entry(member->list.next, struct dsp_conf_member,
-				   list);
-		/* remove HFC conference if enabled */
-		if (member->dsp->hfc_conf >= 0) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s removing %s from HFC conf %d because "
-				       "two parties require only a PCM slot\n",
-				       __func__, member->dsp->name,
-				       member->dsp->hfc_conf);
-			dsp_cmx_hw_message(member->dsp,
-					   MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0);
-			member->dsp->hfc_conf = -1;
-		}
-		if (nextm->dsp->hfc_conf >= 0) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s removing %s from HFC conf %d because "
-				       "two parties require only a PCM slot\n",
-				       __func__, nextm->dsp->name,
-				       nextm->dsp->hfc_conf);
-			dsp_cmx_hw_message(nextm->dsp,
-					   MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0);
-			nextm->dsp->hfc_conf = -1;
-		}
-		/* if members have two banks (and not on the same chip) */
-		if (member->dsp->features.pcm_banks > 1 &&
-		    nextm->dsp->features.pcm_banks > 1 &&
-		    member->dsp->features.hfc_id !=
-		    nextm->dsp->features.hfc_id) {
-			/* if both members have same slots with crossed banks */
-			if (member->dsp->pcm_slot_tx >= 0 &&
-			    member->dsp->pcm_slot_rx >= 0 &&
-			    nextm->dsp->pcm_slot_tx >= 0 &&
-			    nextm->dsp->pcm_slot_rx >= 0 &&
-			    nextm->dsp->pcm_slot_tx ==
-			    member->dsp->pcm_slot_rx &&
-			    nextm->dsp->pcm_slot_rx ==
-			    member->dsp->pcm_slot_tx &&
-			    nextm->dsp->pcm_slot_tx ==
-			    member->dsp->pcm_slot_tx &&
-			    member->dsp->pcm_bank_tx !=
-			    member->dsp->pcm_bank_rx &&
-			    nextm->dsp->pcm_bank_tx !=
-			    nextm->dsp->pcm_bank_rx) {
-				/* all members have same slot */
-				if (dsp_debug & DEBUG_DSP_CMX)
-					printk(KERN_DEBUG
-					       "%s dsp %s & %s stay joined on "
-					       "PCM slot %d bank %d (TX) bank %d "
-					       "(RX) (on different chips)\n",
-					       __func__,
-					       member->dsp->name,
-					       nextm->dsp->name,
-					       member->dsp->pcm_slot_tx,
-					       member->dsp->pcm_bank_tx,
-					       member->dsp->pcm_bank_rx);
-				conf->hardware = 1;
-				conf->software = tx_data;
-				return;
-			}
-			/* find a new slot */
-			memset(freeslots, 1, sizeof(freeslots));
-			list_for_each_entry(dsp, &dsp_ilist, list) {
-				if (dsp != member->dsp &&
-				    dsp != nextm->dsp &&
-				    member->dsp->features.pcm_id ==
-				    dsp->features.pcm_id) {
-					if (dsp->pcm_slot_rx >= 0 &&
-					    dsp->pcm_slot_rx <
-					    sizeof(freeslots))
-						freeslots[dsp->pcm_slot_rx] = 0;
-					if (dsp->pcm_slot_tx >= 0 &&
-					    dsp->pcm_slot_tx <
-					    sizeof(freeslots))
-						freeslots[dsp->pcm_slot_tx] = 0;
-				}
-			}
-			i = 0;
-			ii = member->dsp->features.pcm_slots;
-			while (i < ii) {
-				if (freeslots[i])
-					break;
-				i++;
-			}
-			if (i == ii) {
-				if (dsp_debug & DEBUG_DSP_CMX)
-					printk(KERN_DEBUG
-					       "%s no slot available for "
-					       "%s & %s\n", __func__,
-					       member->dsp->name,
-					       nextm->dsp->name);
-				/* no more slots available */
-				goto conf_software;
-			}
-			/* assign free slot */
-			member->dsp->pcm_slot_tx = i;
-			member->dsp->pcm_slot_rx = i;
-			nextm->dsp->pcm_slot_tx = i;
-			nextm->dsp->pcm_slot_rx = i;
-			member->dsp->pcm_bank_rx = 0;
-			member->dsp->pcm_bank_tx = 1;
-			nextm->dsp->pcm_bank_rx = 1;
-			nextm->dsp->pcm_bank_tx = 0;
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s adding %s & %s to new PCM slot %d "
-				       "(TX and RX on different chips) because "
-				       "both members have not same slots\n",
-				       __func__,
-				       member->dsp->name,
-				       nextm->dsp->name,
-				       member->dsp->pcm_slot_tx);
-			dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
-					   member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx,
-					   member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx);
-			dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN,
-					   nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
-					   nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
-			conf->hardware = 1;
-			conf->software = tx_data;
-			return;
-			/* if members have one bank (or on the same chip) */
-		} else {
-			/* if both members have different crossed slots */
-			if (member->dsp->pcm_slot_tx >= 0 &&
-			    member->dsp->pcm_slot_rx >= 0 &&
-			    nextm->dsp->pcm_slot_tx >= 0 &&
-			    nextm->dsp->pcm_slot_rx >= 0 &&
-			    nextm->dsp->pcm_slot_tx ==
-			    member->dsp->pcm_slot_rx &&
-			    nextm->dsp->pcm_slot_rx ==
-			    member->dsp->pcm_slot_tx &&
-			    member->dsp->pcm_slot_tx !=
-			    member->dsp->pcm_slot_rx &&
-			    member->dsp->pcm_bank_tx == 0 &&
-			    member->dsp->pcm_bank_rx == 0 &&
-			    nextm->dsp->pcm_bank_tx == 0 &&
-			    nextm->dsp->pcm_bank_rx == 0) {
-				/* all members have same slot */
-				if (dsp_debug & DEBUG_DSP_CMX)
-					printk(KERN_DEBUG
-					       "%s dsp %s & %s stay joined on PCM "
-					       "slot %d (TX) %d (RX) on same chip "
-					       "or one bank PCM)\n", __func__,
-					       member->dsp->name,
-					       nextm->dsp->name,
-					       member->dsp->pcm_slot_tx,
-					       member->dsp->pcm_slot_rx);
-				conf->hardware = 1;
-				conf->software = tx_data;
-				return;
-			}
-			/* find two new slot */
-			memset(freeslots, 1, sizeof(freeslots));
-			list_for_each_entry(dsp, &dsp_ilist, list) {
-				if (dsp != member->dsp &&
-				    dsp != nextm->dsp &&
-				    member->dsp->features.pcm_id ==
-				    dsp->features.pcm_id) {
-					if (dsp->pcm_slot_rx >= 0 &&
-					    dsp->pcm_slot_rx <
-					    sizeof(freeslots))
-						freeslots[dsp->pcm_slot_rx] = 0;
-					if (dsp->pcm_slot_tx >= 0 &&
-					    dsp->pcm_slot_tx <
-					    sizeof(freeslots))
-						freeslots[dsp->pcm_slot_tx] = 0;
-				}
-			}
-			i1 = 0;
-			ii = member->dsp->features.pcm_slots;
-			while (i1 < ii) {
-				if (freeslots[i1])
-					break;
-				i1++;
-			}
-			if (i1 == ii) {
-				if (dsp_debug & DEBUG_DSP_CMX)
-					printk(KERN_DEBUG
-					       "%s no slot available "
-					       "for %s & %s\n", __func__,
-					       member->dsp->name,
-					       nextm->dsp->name);
-				/* no more slots available */
-				goto conf_software;
-			}
-			i2 = i1 + 1;
-			while (i2 < ii) {
-				if (freeslots[i2])
-					break;
-				i2++;
-			}
-			if (i2 == ii) {
-				if (dsp_debug & DEBUG_DSP_CMX)
-					printk(KERN_DEBUG
-					       "%s no slot available "
-					       "for %s & %s\n",
-					       __func__,
-					       member->dsp->name,
-					       nextm->dsp->name);
-				/* no more slots available */
-				goto conf_software;
-			}
-			/* assign free slots */
-			member->dsp->pcm_slot_tx = i1;
-			member->dsp->pcm_slot_rx = i2;
-			nextm->dsp->pcm_slot_tx = i2;
-			nextm->dsp->pcm_slot_rx = i1;
-			member->dsp->pcm_bank_rx = 0;
-			member->dsp->pcm_bank_tx = 0;
-			nextm->dsp->pcm_bank_rx = 0;
-			nextm->dsp->pcm_bank_tx = 0;
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s adding %s & %s to new PCM slot %d "
-				       "(TX) %d (RX) on same chip or one bank "
-				       "PCM, because both members have not "
-				       "crossed slots\n", __func__,
-				       member->dsp->name,
-				       nextm->dsp->name,
-				       member->dsp->pcm_slot_tx,
-				       member->dsp->pcm_slot_rx);
-			dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
-					   member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx,
-					   member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx);
-			dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN,
-					   nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
-					   nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
-			conf->hardware = 1;
-			conf->software = tx_data;
-			return;
-		}
-	}
-
-	/*
-	 * if we have more than two, we may check if we have a conference
-	 * unit available on the chip. also all members must be on the same
-	 */
-
-	/* if not the same HFC chip */
-	if (same_hfc < 0) {
-		if (dsp_debug & DEBUG_DSP_CMX)
-			printk(KERN_DEBUG
-			       "%s conference %d cannot be formed, because "
-			       "members are on different chips or not "
-			       "on HFC chip\n",
-			       __func__, conf->id);
-		goto conf_software;
-	}
-
-	/* for more than two members.. */
-
-	/* if all members already have the same conference */
-	if (all_conf) {
-		conf->hardware = 1;
-		conf->software = tx_data;
-		return;
-	}
-
-	/*
-	 * if there is an existing conference, but not all members have joined
-	 */
-	if (current_conf >= 0) {
-	join_members:
-		list_for_each_entry(member, &conf->mlist, list) {
-			/* if no conference engine on our chip, change to
-			 * software */
-			if (!member->dsp->features.hfc_conf)
-				goto conf_software;
-			/* in case of hdlc, change to software */
-			if (member->dsp->hdlc)
-				goto conf_software;
-			/* join to current conference */
-			if (member->dsp->hfc_conf == current_conf)
-				continue;
-			/* get a free timeslot first */
-			memset(freeslots, 1, sizeof(freeslots));
-			list_for_each_entry(dsp, &dsp_ilist, list) {
-				/*
-				 * not checking current member, because
-				 * slot will be overwritten.
-				 */
-				if (
-					dsp != member->dsp &&
-					/* dsp must be on the same PCM */
-					member->dsp->features.pcm_id ==
-					dsp->features.pcm_id) {
-					/* dsp must be on a slot */
-					if (dsp->pcm_slot_tx >= 0 &&
-					    dsp->pcm_slot_tx <
-					    sizeof(freeslots))
-						freeslots[dsp->pcm_slot_tx] = 0;
-					if (dsp->pcm_slot_rx >= 0 &&
-					    dsp->pcm_slot_rx <
-					    sizeof(freeslots))
-						freeslots[dsp->pcm_slot_rx] = 0;
-				}
-			}
-			i = 0;
-			ii = member->dsp->features.pcm_slots;
-			while (i < ii) {
-				if (freeslots[i])
-					break;
-				i++;
-			}
-			if (i == ii) {
-				/* no more slots available */
-				if (dsp_debug & DEBUG_DSP_CMX)
-					printk(KERN_DEBUG
-					       "%s conference %d cannot be formed,"
-					       " because no slot free\n",
-					       __func__, conf->id);
-				goto conf_software;
-			}
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "%s changing dsp %s to HW conference "
-				       "%d slot %d\n", __func__,
-				       member->dsp->name, current_conf, i);
-			/* assign free slot & set PCM & join conf */
-			member->dsp->pcm_slot_tx = i;
-			member->dsp->pcm_slot_rx = i;
-			member->dsp->pcm_bank_tx = 2; /* loop */
-			member->dsp->pcm_bank_rx = 2;
-			member->dsp->hfc_conf = current_conf;
-			dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
-					   i, 2, i, 2);
-			dsp_cmx_hw_message(member->dsp,
-					   MISDN_CTRL_HFC_CONF_JOIN, current_conf, 0, 0, 0);
-		}
-		conf->hardware = 1;
-		conf->software = tx_data;
-		return;
-	}
-
-	/*
-	 * no member is in a conference yet, so we find a free one
-	 */
-	memset(freeunits, 1, sizeof(freeunits));
-	list_for_each_entry(dsp, &dsp_ilist, list) {
-		/* dsp must be on the same chip */
-		if (dsp->features.hfc_id == same_hfc &&
-		    /* dsp must have joined a HW conference */
-		    dsp->hfc_conf >= 0 &&
-		    /* slot must be within range */
-		    dsp->hfc_conf < 8)
-			freeunits[dsp->hfc_conf] = 0;
-	}
-	i = 0;
-	ii = 8;
-	while (i < ii) {
-		if (freeunits[i])
-			break;
-		i++;
-	}
-	if (i == ii) {
-		/* no more conferences available */
-		if (dsp_debug & DEBUG_DSP_CMX)
-			printk(KERN_DEBUG
-			       "%s conference %d cannot be formed, because "
-			       "no conference number free\n",
-			       __func__, conf->id);
-		goto conf_software;
-	}
-	/* join all members */
-	current_conf = i;
-	goto join_members;
-}
-
-
-/*
- * conf_id != 0: join or change conference
- * conf_id == 0: split from conference if not already
- */
-int
-dsp_cmx_conf(struct dsp *dsp, u32 conf_id)
-{
-	int err;
-	struct dsp_conf *conf;
-	struct dsp_conf_member	*member;
-
-	/* if conference doesn't change */
-	if (dsp->conf_id == conf_id)
-		return 0;
-
-	/* first remove us from current conf */
-	if (dsp->conf_id) {
-		if (dsp_debug & DEBUG_DSP_CMX)
-			printk(KERN_DEBUG "removing us from conference %d\n",
-			       dsp->conf->id);
-		/* remove us from conf */
-		conf = dsp->conf;
-		err = dsp_cmx_del_conf_member(dsp);
-		if (err)
-			return err;
-		dsp->conf_id = 0;
-
-		/* update hardware */
-		dsp_cmx_hardware(NULL, dsp);
-
-		/* conf now empty? */
-		if (list_empty(&conf->mlist)) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "conference is empty, so we remove it.\n");
-			err = dsp_cmx_del_conf(conf);
-			if (err)
-				return err;
-		} else {
-			/* update members left on conf */
-			dsp_cmx_hardware(conf, NULL);
-		}
-	}
-
-	/* if split */
-	if (!conf_id)
-		return 0;
-
-	/* now add us to conf */
-	if (dsp_debug & DEBUG_DSP_CMX)
-		printk(KERN_DEBUG "searching conference %d\n",
-		       conf_id);
-	conf = dsp_cmx_search_conf(conf_id);
-	if (!conf) {
-		if (dsp_debug & DEBUG_DSP_CMX)
-			printk(KERN_DEBUG
-			       "conference doesn't exist yet, creating.\n");
-		/* the conference doesn't exist, so we create */
-		conf = dsp_cmx_new_conf(conf_id);
-		if (!conf)
-			return -EINVAL;
-	} else if (!list_empty(&conf->mlist)) {
-		member = list_entry(conf->mlist.next, struct dsp_conf_member,
-				    list);
-		if (dsp->hdlc && !member->dsp->hdlc) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "cannot join transparent conference.\n");
-			return -EINVAL;
-		}
-		if (!dsp->hdlc && member->dsp->hdlc) {
-			if (dsp_debug & DEBUG_DSP_CMX)
-				printk(KERN_DEBUG
-				       "cannot join hdlc conference.\n");
-			return -EINVAL;
-		}
-	}
-	/* add conference member */
-	err = dsp_cmx_add_conf_member(dsp, conf);
-	if (err)
-		return err;
-	dsp->conf_id = conf_id;
-
-	/* if we are alone, we do nothing! */
-	if (list_empty(&conf->mlist)) {
-		if (dsp_debug & DEBUG_DSP_CMX)
-			printk(KERN_DEBUG
-			       "we are alone in this conference, so exit.\n");
-		/* update hardware */
-		dsp_cmx_hardware(NULL, dsp);
-		return 0;
-	}
-
-	/* update members on conf */
-	dsp_cmx_hardware(conf, NULL);
-
-	return 0;
-}
-
-#ifdef CMX_DELAY_DEBUG
-int delaycount;
-static void
-showdelay(struct dsp *dsp, int samples, int delay)
-{
-	char bar[] = "--------------------------------------------------|";
-	int sdelay;
-
-	delaycount += samples;
-	if (delaycount < 8000)
-		return;
-	delaycount = 0;
-
-	sdelay = delay * 50 / (dsp_poll << 2);
-
-	printk(KERN_DEBUG "DELAY (%s) %3d >%s\n", dsp->name, delay,
-	       sdelay > 50 ? "..." : bar + 50 - sdelay);
-}
-#endif
-
-/*
- * audio data is received from card
- */
-void
-dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
-{
-	u8 *d, *p;
-	int len = skb->len;
-	struct mISDNhead *hh = mISDN_HEAD_P(skb);
-	int w, i, ii;
-
-	/* check if we have sompen */
-	if (len < 1)
-		return;
-
-	/* half of the buffer should be larger than maximum packet size */
-	if (len >= CMX_BUFF_HALF) {
-		printk(KERN_ERR
-		       "%s line %d: packet from card is too large (%d bytes). "
-		       "please make card send smaller packets OR increase "
-		       "CMX_BUFF_SIZE\n", __FILE__, __LINE__, len);
-		return;
-	}
-
-	/*
-	 * initialize pointers if not already -
-	 * also add delay if requested by PH_SIGNAL
-	 */
-	if (dsp->rx_init) {
-		dsp->rx_init = 0;
-		if (dsp->features.unordered) {
-			dsp->rx_R = (hh->id & CMX_BUFF_MASK);
-			if (dsp->cmx_delay)
-				dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
-					& CMX_BUFF_MASK;
-			else
-				dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1))
-					& CMX_BUFF_MASK;
-		} else {
-			dsp->rx_R = 0;
-			if (dsp->cmx_delay)
-				dsp->rx_W = dsp->cmx_delay;
-			else
-				dsp->rx_W = dsp_poll >> 1;
-		}
-	}
-	/* if frame contains time code, write directly */
-	if (dsp->features.unordered) {
-		dsp->rx_W = (hh->id & CMX_BUFF_MASK);
-		/* printk(KERN_DEBUG "%s %08x\n", dsp->name, hh->id); */
-	}
-	/*
-	 * if we underrun (or maybe overrun),
-	 * we set our new read pointer, and write silence to buffer
-	 */
-	if (((dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK) >= CMX_BUFF_HALF) {
-		if (dsp_debug & DEBUG_DSP_CLOCK)
-			printk(KERN_DEBUG
-			       "cmx_receive(dsp=%lx): UNDERRUN (or overrun the "
-			       "maximum delay), adjusting read pointer! "
-			       "(inst %s)\n", (u_long)dsp, dsp->name);
-		/* flush rx buffer and set delay to dsp_poll / 2 */
-		if (dsp->features.unordered) {
-			dsp->rx_R = (hh->id & CMX_BUFF_MASK);
-			if (dsp->cmx_delay)
-				dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
-					& CMX_BUFF_MASK;
-			else
-				dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1))
-					& CMX_BUFF_MASK;
-		} else {
-			dsp->rx_R = 0;
-			if (dsp->cmx_delay)
-				dsp->rx_W = dsp->cmx_delay;
-			else
-				dsp->rx_W = dsp_poll >> 1;
-		}
-		memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
-	}
-	/* if we have reached double delay, jump back to middle */
-	if (dsp->cmx_delay)
-		if (((dsp->rx_W - dsp->rx_R) & CMX_BUFF_MASK) >=
-		    (dsp->cmx_delay << 1)) {
-			if (dsp_debug & DEBUG_DSP_CLOCK)
-				printk(KERN_DEBUG
-				       "cmx_receive(dsp=%lx): OVERRUN (because "
-				       "twice the delay is reached), adjusting "
-				       "read pointer! (inst %s)\n",
-				       (u_long)dsp, dsp->name);
-			/* flush buffer */
-			if (dsp->features.unordered) {
-				dsp->rx_R = (hh->id & CMX_BUFF_MASK);
-				dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
-					& CMX_BUFF_MASK;
-			} else {
-				dsp->rx_R = 0;
-				dsp->rx_W = dsp->cmx_delay;
-			}
-			memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
-		}
-
-	/* show where to write */
-#ifdef CMX_DEBUG
-	printk(KERN_DEBUG
-	       "cmx_receive(dsp=%lx): rx_R(dsp)=%05x rx_W(dsp)=%05x len=%d %s\n",
-	       (u_long)dsp, dsp->rx_R, dsp->rx_W, len, dsp->name);
-#endif
-
-	/* write data into rx_buffer */
-	p = skb->data;
-	d = dsp->rx_buff;
-	w = dsp->rx_W;
-	i = 0;
-	ii = len;
-	while (i < ii) {
-		d[w++ & CMX_BUFF_MASK] = *p++;
-		i++;
-	}
-
-	/* increase write-pointer */
-	dsp->rx_W = ((dsp->rx_W + len) & CMX_BUFF_MASK);
-#ifdef CMX_DELAY_DEBUG
-	showdelay(dsp, len, (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK);
-#endif
-}
-
-
-/*
- * send (mixed) audio data to card and control jitter
- */
-static void
-dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
-{
-	struct dsp_conf *conf = dsp->conf;
-	struct dsp *member, *other;
-	register s32 sample;
-	u8 *d, *p, *q, *o_q;
-	struct sk_buff *nskb, *txskb;
-	int r, rr, t, tt, o_r, o_rr;
-	int preload = 0;
-	struct mISDNhead *hh, *thh;
-	int tx_data_only = 0;
-
-	/* don't process if: */
-	if (!dsp->b_active) { /* if not active */
-		dsp->last_tx = 0;
-		return;
-	}
-	if (((dsp->conf && dsp->conf->hardware) || /* hardware conf */
-	     dsp->echo.hardware) && /* OR hardware echo */
-	    dsp->tx_R == dsp->tx_W && /* AND no tx-data */
-	    !(dsp->tone.tone && dsp->tone.software)) { /* AND not soft tones */
-		if (!dsp->tx_data) { /* no tx_data for user space required */
-			dsp->last_tx = 0;
-			return;
-		}
-		if (dsp->conf && dsp->conf->software && dsp->conf->hardware)
-			tx_data_only = 1;
-		if (dsp->echo.software && dsp->echo.hardware)
-			tx_data_only = 1;
-	}
-
-#ifdef CMX_DEBUG
-	printk(KERN_DEBUG
-	       "SEND members=%d dsp=%s, conf=%p, rx_R=%05x rx_W=%05x\n",
-	       members, dsp->name, conf, dsp->rx_R, dsp->rx_W);
-#endif
-
-	/* preload if we have delay set */
-	if (dsp->cmx_delay && !dsp->last_tx) {
-		preload = len;
-		if (preload < 128)
-			preload = 128;
-	}
-
-	/* PREPARE RESULT */
-	nskb = mI_alloc_skb(len + preload, GFP_ATOMIC);
-	if (!nskb) {
-		printk(KERN_ERR
-		       "FATAL ERROR in mISDN_dsp.o: cannot alloc %d bytes\n",
-		       len + preload);
-		return;
-	}
-	hh = mISDN_HEAD_P(nskb);
-	hh->prim = PH_DATA_REQ;
-	hh->id = 0;
-	dsp->last_tx = 1;
-
-	/* set pointers, indexes and stuff */
-	member = dsp;
-	p = dsp->tx_buff; /* transmit data */
-	q = dsp->rx_buff; /* received data */
-	d = skb_put(nskb, preload + len); /* result */
-	t = dsp->tx_R; /* tx-pointers */
-	tt = dsp->tx_W;
-	r = dsp->rx_R; /* rx-pointers */
-	rr = (r + len) & CMX_BUFF_MASK;
-
-	/* preload with silence, if required */
-	if (preload) {
-		memset(d, dsp_silence, preload);
-		d += preload;
-	}
-
-	/* PROCESS TONES/TX-DATA ONLY */
-	if (dsp->tone.tone && dsp->tone.software) {
-		/* -> copy tone */
-		dsp_tone_copy(dsp, d, len);
-		dsp->tx_R = 0; /* clear tx buffer */
-		dsp->tx_W = 0;
-		goto send_packet;
-	}
-	/* if we have tx-data but do not use mixing */
-	if (!dsp->tx_mix && t != tt) {
-		/* -> send tx-data and continue when not enough */
-#ifdef CMX_TX_DEBUG
-		sprintf(debugbuf, "TX sending (%04x-%04x)%p: ", t, tt, p);
-#endif
-		while (r != rr && t != tt) {
-#ifdef CMX_TX_DEBUG
-			if (strlen(debugbuf) < 48)
-				sprintf(debugbuf + strlen(debugbuf), " %02x",
-					p[t]);
-#endif
-			*d++ = p[t]; /* write tx_buff */
-			t = (t + 1) & CMX_BUFF_MASK;
-			r = (r + 1) & CMX_BUFF_MASK;
-		}
-		if (r == rr) {
-			dsp->tx_R = t;
-#ifdef CMX_TX_DEBUG
-			printk(KERN_DEBUG "%s\n", debugbuf);
-#endif
-			goto send_packet;
-		}
-	}
-#ifdef CMX_TX_DEBUG
-	printk(KERN_DEBUG "%s\n", debugbuf);
-#endif
-
-	/* PROCESS DATA (one member / no conf) */
-	if (!conf || members <= 1) {
-		/* -> if echo is NOT enabled */
-		if (!dsp->echo.software) {
-			/* -> send tx-data if available or use 0-volume */
-			while (r != rr && t != tt) {
-				*d++ = p[t]; /* write tx_buff */
-				t = (t + 1) & CMX_BUFF_MASK;
-				r = (r + 1) & CMX_BUFF_MASK;
-			}
-			if (r != rr) {
-				if (dsp_debug & DEBUG_DSP_CLOCK)
-					printk(KERN_DEBUG "%s: RX empty\n",
-					       __func__);
-				memset(d, dsp_silence, (rr - r) & CMX_BUFF_MASK);
-			}
-			/* -> if echo is enabled */
-		} else {
-			/*
-			 * -> mix tx-data with echo if available,
-			 * or use echo only
-			 */
-			while (r != rr && t != tt) {
-				*d++ = dsp_audio_mix_law[(p[t] << 8) | q[r]];
-				t = (t + 1) & CMX_BUFF_MASK;
-				r = (r + 1) & CMX_BUFF_MASK;
-			}
-			while (r != rr) {
-				*d++ = q[r]; /* echo */
-				r = (r + 1) & CMX_BUFF_MASK;
-			}
-		}
-		dsp->tx_R = t;
-		goto send_packet;
-	}
-	/* PROCESS DATA (two members) */
-#ifdef CMX_CONF_DEBUG
-	if (0) {
-#else
-	if (members == 2) {
-#endif
-		/* "other" becomes other party */
-		other = (list_entry(conf->mlist.next,
-				    struct dsp_conf_member, list))->dsp;
-		if (other == member)
-			other = (list_entry(conf->mlist.prev,
-				    struct dsp_conf_member, list))->dsp;
-		o_q = other->rx_buff; /* received data */
-		o_rr = (other->rx_R + len) & CMX_BUFF_MASK;
-		/* end of rx-pointer */
-		o_r = (o_rr - rr + r) & CMX_BUFF_MASK;
-		/* start rx-pointer at current read position*/
-		/* -> if echo is NOT enabled */
-		if (!dsp->echo.software) {
-			/*
-			 * -> copy other member's rx-data,
-			 * if tx-data is available, mix
-			 */
-			while (o_r != o_rr && t != tt) {
-				*d++ = dsp_audio_mix_law[(p[t] << 8) | o_q[o_r]];
-				t = (t + 1) & CMX_BUFF_MASK;
-				o_r = (o_r + 1) & CMX_BUFF_MASK;
-			}
-			while (o_r != o_rr) {
-				*d++ = o_q[o_r];
-				o_r = (o_r + 1) & CMX_BUFF_MASK;
-			}
-			/* -> if echo is enabled */
-		} else {
-			/*
-			 * -> mix other member's rx-data with echo,
-			 * if tx-data is available, mix
-			 */
-			while (r != rr && t != tt) {
-				sample = dsp_audio_law_to_s32[p[t]] +
-					dsp_audio_law_to_s32[q[r]] +
-					dsp_audio_law_to_s32[o_q[o_r]];
-				if (sample < -32768)
-					sample = -32768;
-				else if (sample > 32767)
-					sample = 32767;
-				*d++ = dsp_audio_s16_to_law[sample & 0xffff];
-				/* tx-data + rx_data + echo */
-				t = (t + 1) & CMX_BUFF_MASK;
-				r = (r + 1) & CMX_BUFF_MASK;
-				o_r = (o_r + 1) & CMX_BUFF_MASK;
-			}
-			while (r != rr) {
-				*d++ = dsp_audio_mix_law[(q[r] << 8) | o_q[o_r]];
-				r = (r + 1) & CMX_BUFF_MASK;
-				o_r = (o_r + 1) & CMX_BUFF_MASK;
-			}
-		}
-		dsp->tx_R = t;
-		goto send_packet;
-	}
-	/* PROCESS DATA (three or more members) */
-	/* -> if echo is NOT enabled */
-	if (!dsp->echo.software) {
-		/*
-		 * -> subtract rx-data from conf-data,
-		 * if tx-data is available, mix
-		 */
-		while (r != rr && t != tt) {
-			sample = dsp_audio_law_to_s32[p[t]] + *c++ -
-				dsp_audio_law_to_s32[q[r]];
-			if (sample < -32768)
-				sample = -32768;
-			else if (sample > 32767)
-				sample = 32767;
-			*d++ = dsp_audio_s16_to_law[sample & 0xffff];
-			/* conf-rx+tx */
-			r = (r + 1) & CMX_BUFF_MASK;
-			t = (t + 1) & CMX_BUFF_MASK;
-		}
-		while (r != rr) {
-			sample = *c++ - dsp_audio_law_to_s32[q[r]];
-			if (sample < -32768)
-				sample = -32768;
-			else if (sample > 32767)
-				sample = 32767;
-			*d++ = dsp_audio_s16_to_law[sample & 0xffff];
-			/* conf-rx */
-			r = (r + 1) & CMX_BUFF_MASK;
-		}
-		/* -> if echo is enabled */
-	} else {
-		/*
-		 * -> encode conf-data, if tx-data
-		 * is available, mix
-		 */
-		while (r != rr && t != tt) {
-			sample = dsp_audio_law_to_s32[p[t]] + *c++;
-			if (sample < -32768)
-				sample = -32768;
-			else if (sample > 32767)
-				sample = 32767;
-			*d++ = dsp_audio_s16_to_law[sample & 0xffff];
-			/* conf(echo)+tx */
-			t = (t + 1) & CMX_BUFF_MASK;
-			r = (r + 1) & CMX_BUFF_MASK;
-		}
-		while (r != rr) {
-			sample = *c++;
-			if (sample < -32768)
-				sample = -32768;
-			else if (sample > 32767)
-				sample = 32767;
-			*d++ = dsp_audio_s16_to_law[sample & 0xffff];
-			/* conf(echo) */
-			r = (r + 1) & CMX_BUFF_MASK;
-		}
-	}
-	dsp->tx_R = t;
-	goto send_packet;
-
-send_packet:
-	/*
-	 * send tx-data if enabled - don't filter,
-	 * because we want what we send, not what we filtered
-	 */
-	if (dsp->tx_data) {
-		if (tx_data_only) {
-			hh->prim = DL_DATA_REQ;
-			hh->id = 0;
-			/* queue and trigger */
-			skb_queue_tail(&dsp->sendq, nskb);
-			schedule_work(&dsp->workq);
-			/* exit because only tx_data is used */
-			return;
-		} else {
-			txskb = mI_alloc_skb(len, GFP_ATOMIC);
-			if (!txskb) {
-				printk(KERN_ERR
-				       "FATAL ERROR in mISDN_dsp.o: "
-				       "cannot alloc %d bytes\n", len);
-			} else {
-				thh = mISDN_HEAD_P(txskb);
-				thh->prim = DL_DATA_REQ;
-				thh->id = 0;
-				skb_put_data(txskb, nskb->data + preload, len);
-				/* queue (trigger later) */
-				skb_queue_tail(&dsp->sendq, txskb);
-			}
-		}
-	}
-
-	/* send data only to card, if we don't just calculated tx_data */
-	/* adjust volume */
-	if (dsp->tx_volume)
-		dsp_change_volume(nskb, dsp->tx_volume);
-	/* pipeline */
-	if (dsp->pipeline.inuse)
-		dsp_pipeline_process_tx(&dsp->pipeline, nskb->data,
-					nskb->len);
-	/* crypt */
-	if (dsp->bf_enable)
-		dsp_bf_encrypt(dsp, nskb->data, nskb->len);
-	/* queue and trigger */
-	skb_queue_tail(&dsp->sendq, nskb);
-	schedule_work(&dsp->workq);
-}
-
-static u32	jittercount; /* counter for jitter check */
-struct timer_list dsp_spl_tl;
-unsigned long	dsp_spl_jiffies; /* calculate the next time to fire */
-static u16	dsp_count; /* last sample count */
-static int	dsp_count_valid; /* if we have last sample count */
-
-void
-dsp_cmx_send(struct timer_list *arg)
-{
-	struct dsp_conf *conf;
-	struct dsp_conf_member *member;
-	struct dsp *dsp;
-	int mustmix, members;
-	static s32 mixbuffer[MAX_POLL + 100];
-	s32 *c;
-	u8 *p, *q;
-	int r, rr;
-	int jittercheck = 0, delay, i;
-	u_long flags;
-	u16 length, count;
-
-	/* lock */
-	spin_lock_irqsave(&dsp_lock, flags);
-
-	if (!dsp_count_valid) {
-		dsp_count = mISDN_clock_get();
-		length = dsp_poll;
-		dsp_count_valid = 1;
-	} else {
-		count = mISDN_clock_get();
-		length = count - dsp_count;
-		dsp_count = count;
-	}
-	if (length > MAX_POLL + 100)
-		length = MAX_POLL + 100;
-	/* printk(KERN_DEBUG "len=%d dsp_count=0x%x\n", length, dsp_count); */
-
-	/*
-	 * check if jitter needs to be checked (this is every second)
-	 */
-	jittercount += length;
-	if (jittercount >= 8000) {
-		jittercount -= 8000;
-		jittercheck = 1;
-	}
-
-	/* loop all members that do not require conference mixing */
-	list_for_each_entry(dsp, &dsp_ilist, list) {
-		if (dsp->hdlc)
-			continue;
-		conf = dsp->conf;
-		mustmix = 0;
-		members = 0;
-		if (conf) {
-			members = list_count_nodes(&conf->mlist);
-#ifdef CMX_CONF_DEBUG
-			if (conf->software && members > 1)
-#else
-			if (conf->software && members > 2)
-#endif
-				mustmix = 1;
-		}
-
-		/* transmission required */
-		if (!mustmix) {
-			dsp_cmx_send_member(dsp, length, mixbuffer, members);
-
-			/*
-			 * unused mixbuffer is given to prevent a
-			 * potential null-pointer-bug
-			 */
-		}
-	}
-
-	/* loop all members that require conference mixing */
-	list_for_each_entry(conf, &conf_ilist, list) {
-		/* count members and check hardware */
-		members = list_count_nodes(&conf->mlist);
-#ifdef CMX_CONF_DEBUG
-		if (conf->software && members > 1) {
-#else
-		if (conf->software && members > 2) {
-#endif
-			/* check for hdlc conf */
-			member = list_entry(conf->mlist.next,
-					    struct dsp_conf_member, list);
-			if (member->dsp->hdlc)
-				continue;
-			/* mix all data */
-			memset(mixbuffer, 0, length * sizeof(s32));
-			list_for_each_entry(member, &conf->mlist, list) {
-				dsp = member->dsp;
-				/* get range of data to mix */
-				c = mixbuffer;
-				q = dsp->rx_buff;
-				r = dsp->rx_R;
-				rr = (r + length) & CMX_BUFF_MASK;
-				/* add member's data */
-				while (r != rr) {
-					*c++ += dsp_audio_law_to_s32[q[r]];
-					r = (r + 1) & CMX_BUFF_MASK;
-				}
-			}
-
-			/* process each member */
-			list_for_each_entry(member, &conf->mlist, list) {
-				/* transmission */
-				dsp_cmx_send_member(member->dsp, length,
-						    mixbuffer, members);
-			}
-		}
-	}
-
-	/* delete rx-data, increment buffers, change pointers */
-	list_for_each_entry(dsp, &dsp_ilist, list) {
-		if (dsp->hdlc)
-			continue;
-		p = dsp->rx_buff;
-		q = dsp->tx_buff;
-		r = dsp->rx_R;
-		/* move receive pointer when receiving */
-		if (!dsp->rx_is_off) {
-			rr = (r + length) & CMX_BUFF_MASK;
-			/* delete rx-data */
-			while (r != rr) {
-				p[r] = dsp_silence;
-				r = (r + 1) & CMX_BUFF_MASK;
-			}
-			/* increment rx-buffer pointer */
-			dsp->rx_R = r; /* write incremented read pointer */
-		}
-
-		/* check current rx_delay */
-		delay = (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK;
-		if (delay >= CMX_BUFF_HALF)
-			delay = 0; /* will be the delay before next write */
-		/* check for lower delay */
-		if (delay < dsp->rx_delay[0])
-			dsp->rx_delay[0] = delay;
-		/* check current tx_delay */
-		delay = (dsp->tx_W-dsp->tx_R) & CMX_BUFF_MASK;
-		if (delay >= CMX_BUFF_HALF)
-			delay = 0; /* will be the delay before next write */
-		/* check for lower delay */
-		if (delay < dsp->tx_delay[0])
-			dsp->tx_delay[0] = delay;
-		if (jittercheck) {
-			/* find the lowest of all rx_delays */
-			delay = dsp->rx_delay[0];
-			i = 1;
-			while (i < MAX_SECONDS_JITTER_CHECK) {
-				if (delay > dsp->rx_delay[i])
-					delay = dsp->rx_delay[i];
-				i++;
-			}
-			/*
-			 * remove rx_delay only if we have delay AND we
-			 * have not preset cmx_delay AND
-			 * the delay is greater dsp_poll
-			 */
-			if (delay > dsp_poll && !dsp->cmx_delay) {
-				if (dsp_debug & DEBUG_DSP_CLOCK)
-					printk(KERN_DEBUG
-					       "%s lowest rx_delay of %d bytes for"
-					       " dsp %s are now removed.\n",
-					       __func__, delay,
-					       dsp->name);
-				r = dsp->rx_R;
-				rr = (r + delay - (dsp_poll >> 1))
-					& CMX_BUFF_MASK;
-				/* delete rx-data */
-				while (r != rr) {
-					p[r] = dsp_silence;
-					r = (r + 1) & CMX_BUFF_MASK;
-				}
-				/* increment rx-buffer pointer */
-				dsp->rx_R = r;
-				/* write incremented read pointer */
-			}
-			/* find the lowest of all tx_delays */
-			delay = dsp->tx_delay[0];
-			i = 1;
-			while (i < MAX_SECONDS_JITTER_CHECK) {
-				if (delay > dsp->tx_delay[i])
-					delay = dsp->tx_delay[i];
-				i++;
-			}
-			/*
-			 * remove delay only if we have delay AND we
-			 * have enabled tx_dejitter
-			 */
-			if (delay > dsp_poll && dsp->tx_dejitter) {
-				if (dsp_debug & DEBUG_DSP_CLOCK)
-					printk(KERN_DEBUG
-					       "%s lowest tx_delay of %d bytes for"
-					       " dsp %s are now removed.\n",
-					       __func__, delay,
-					       dsp->name);
-				r = dsp->tx_R;
-				rr = (r + delay - (dsp_poll >> 1))
-					& CMX_BUFF_MASK;
-				/* delete tx-data */
-				while (r != rr) {
-					q[r] = dsp_silence;
-					r = (r + 1) & CMX_BUFF_MASK;
-				}
-				/* increment rx-buffer pointer */
-				dsp->tx_R = r;
-				/* write incremented read pointer */
-			}
-			/* scroll up delays */
-			i = MAX_SECONDS_JITTER_CHECK - 1;
-			while (i) {
-				dsp->rx_delay[i] = dsp->rx_delay[i - 1];
-				dsp->tx_delay[i] = dsp->tx_delay[i - 1];
-				i--;
-			}
-			dsp->tx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
-			dsp->rx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
-		}
-	}
-
-	/* if next event would be in the past ... */
-	if ((s32)(dsp_spl_jiffies + dsp_tics-jiffies) <= 0)
-		dsp_spl_jiffies = jiffies + 1;
-	else
-		dsp_spl_jiffies += dsp_tics;
-
-	dsp_spl_tl.expires = dsp_spl_jiffies;
-	add_timer(&dsp_spl_tl);
-
-	/* unlock */
-	spin_unlock_irqrestore(&dsp_lock, flags);
-}
-
-/*
- * audio data is transmitted from upper layer to the dsp
- */
-void
-dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb)
-{
-	u_int w, ww;
-	u8 *d, *p;
-	int space; /* todo: , l = skb->len; */
-#ifdef CMX_TX_DEBUG
-	char debugbuf[256] = "";
-#endif
-
-	/* check if there is enough space, and then copy */
-	w = dsp->tx_W;
-	ww = dsp->tx_R;
-	p = dsp->tx_buff;
-	d = skb->data;
-	space = (ww - w - 1) & CMX_BUFF_MASK;
-	/* write-pointer should not overrun nor reach read pointer */
-	if (space < skb->len) {
-		/* write to the space we have left */
-		ww = (ww - 1) & CMX_BUFF_MASK; /* end one byte prior tx_R */
-		if (dsp_debug & DEBUG_DSP_CLOCK)
-			printk(KERN_DEBUG "%s: TX overflow space=%d skb->len="
-			       "%d, w=0x%04x, ww=0x%04x\n", __func__, space,
-			       skb->len, w, ww);
-	} else
-		/* write until all byte are copied */
-		ww = (w + skb->len) & CMX_BUFF_MASK;
-	dsp->tx_W = ww;
-		/* show current buffer */
-#ifdef CMX_DEBUG
-	printk(KERN_DEBUG
-	       "cmx_transmit(dsp=%lx) %d bytes to 0x%x-0x%x. %s\n",
-	       (u_long)dsp, (ww - w) & CMX_BUFF_MASK, w, ww, dsp->name);
-#endif
-
-	/* copy transmit data to tx-buffer */
-#ifdef CMX_TX_DEBUG
-	sprintf(debugbuf, "TX getting (%04x-%04x)%p: ", w, ww, p);
-#endif
-	while (w != ww) {
-#ifdef CMX_TX_DEBUG
-		if (strlen(debugbuf) < 48)
-			sprintf(debugbuf + strlen(debugbuf), " %02x", *d);
-#endif
-		p[w] = *d++;
-		w = (w + 1) & CMX_BUFF_MASK;
-	}
-#ifdef CMX_TX_DEBUG
-	printk(KERN_DEBUG "%s\n", debugbuf);
-#endif
-
-}
-
-/*
- * hdlc data is received from card and sent to all members.
- */
-void
-dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb)
-{
-	struct sk_buff *nskb = NULL;
-	struct dsp_conf_member *member;
-	struct mISDNhead *hh;
-
-	/* not if not active */
-	if (!dsp->b_active)
-		return;
-
-	/* check if we have sompen */
-	if (skb->len < 1)
-		return;
-
-	/* no conf */
-	if (!dsp->conf) {
-		/* in case of software echo */
-		if (dsp->echo.software) {
-			nskb = skb_clone(skb, GFP_ATOMIC);
-			if (nskb) {
-				hh = mISDN_HEAD_P(nskb);
-				hh->prim = PH_DATA_REQ;
-				hh->id = 0;
-				skb_queue_tail(&dsp->sendq, nskb);
-				schedule_work(&dsp->workq);
-			}
-		}
-		return;
-	}
-	/* in case of hardware conference */
-	if (dsp->conf->hardware)
-		return;
-	list_for_each_entry(member, &dsp->conf->mlist, list) {
-		if (dsp->echo.software || member->dsp != dsp) {
-			nskb = skb_clone(skb, GFP_ATOMIC);
-			if (nskb) {
-				hh = mISDN_HEAD_P(nskb);
-				hh->prim = PH_DATA_REQ;
-				hh->id = 0;
-				skb_queue_tail(&member->dsp->sendq, nskb);
-				schedule_work(&member->dsp->workq);
-			}
-		}
-	}
-}
diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c
deleted file mode 100644
index d0aa415a6b09..000000000000
--- a/drivers/isdn/mISDN/dsp_core.c
+++ /dev/null
@@ -1,1227 +0,0 @@
-/*
- * Author       Andreas Eversberg (jolly@eversberg.eu)
- * Based on source code structure by
- *		Karsten Keil (keil@isdn4linux.de)
- *
- *		This file is (c) under GNU PUBLIC LICENSE
- *
- * Thanks to    Karsten Keil (great drivers)
- *              Cologne Chip (great chips)
- *
- * This module does:
- *		Real-time tone generation
- *		DTMF detection
- *		Real-time cross-connection and conferrence
- *		Compensate jitter due to system load and hardware fault.
- *		All features are done in kernel space and will be realized
- *		using hardware, if available and supported by chip set.
- *		Blowfish encryption/decryption
- */
-
-/* STRUCTURE:
- *
- * The dsp module provides layer 2 for b-channels (64kbit). It provides
- * transparent audio forwarding with special digital signal processing:
- *
- * - (1) generation of tones
- * - (2) detection of dtmf tones
- * - (3) crossconnecting and conferences (clocking)
- * - (4) echo generation for delay test
- * - (5) volume control
- * - (6) disable receive data
- * - (7) pipeline
- * - (8) encryption/decryption
- *
- * Look:
- *             TX            RX
- *         ------upper layer------
- *             |             ^
- *             |             |(6)
- *             v             |
- *       +-----+-------------+-----+
- *       |(3)(4)                   |
- *       |           CMX           |
- *       |                         |
- *       |           +-------------+
- *       |           |       ^
- *       |           |       |
- *       |+---------+|  +----+----+
- *       ||(1)      ||  |(2)      |
- *       ||         ||  |         |
- *       ||  Tones  ||  |  DTMF   |
- *       ||         ||  |         |
- *       ||         ||  |         |
- *       |+----+----+|  +----+----+
- *       +-----+-----+       ^
- *             |             |
- *             v             |
- *        +----+----+   +----+----+
- *        |(5)      |   |(5)      |
- *        |         |   |         |
- *        |TX Volume|   |RX Volume|
- *        |         |   |         |
- *        |         |   |         |
- *        +----+----+   +----+----+
- *             |             ^
- *             |             |
- *             v             |
- *        +----+-------------+----+
- *        |(7)                    |
- *        |                       |
- *        |  Pipeline Processing  |
- *        |                       |
- *        |                       |
- *        +----+-------------+----+
- *             |             ^
- *             |             |
- *             v             |
- *        +----+----+   +----+----+
- *        |(8)      |   |(8)      |
- *        |         |   |         |
- *        | Encrypt |   | Decrypt |
- *        |         |   |         |
- *        |         |   |         |
- *        +----+----+   +----+----+
- *             |             ^
- *             |             |
- *             v             |
- *         ------card  layer------
- *             TX            RX
- *
- * Above you can see the logical data flow. If software is used to do the
- * process, it is actually the real data flow. If hardware is used, data
- * may not flow, but hardware commands to the card, to provide the data flow
- * as shown.
- *
- * NOTE: The channel must be activated in order to make dsp work, even if
- * no data flow to the upper layer is intended. Activation can be done
- * after and before controlling the setting using PH_CONTROL requests.
- *
- * DTMF: Will be detected by hardware if possible. It is done before CMX
- * processing.
- *
- * Tones: Will be generated via software if endless looped audio fifos are
- * not supported by hardware. Tones will override all data from CMX.
- * It is not required to join a conference to use tones at any time.
- *
- * CMX: Is transparent when not used. When it is used, it will do
- * crossconnections and conferences via software if not possible through
- * hardware. If hardware capability is available, hardware is used.
- *
- * Echo: Is generated by CMX and is used to check performance of hard and
- * software CMX.
- *
- * The CMX has special functions for conferences with one, two and more
- * members. It will allow different types of data flow. Receive and transmit
- * data to/form upper layer may be switched on/off individually without losing
- * features of CMX, Tones and DTMF.
- *
- * Echo Cancellation: Sometimes we like to cancel echo from the interface.
- * Note that a VoIP call may not have echo caused by the IP phone. The echo
- * is generated by the telephone line connected to it. Because the delay
- * is high, it becomes an echo. RESULT: Echo Cachelation is required if
- * both echo AND delay is applied to an interface.
- * Remember that software CMX always generates a more or less delay.
- *
- * If all used features can be realized in hardware, and if transmit and/or
- * receive data ist disabled, the card may not send/receive any data at all.
- * Not receiving is useful if only announcements are played. Not sending is
- * useful if an answering machine records audio. Not sending and receiving is
- * useful during most states of the call. If supported by hardware, tones
- * will be played without cpu load. Small PBXs and NT-Mode applications will
- * not need expensive hardware when processing calls.
- *
- *
- * LOCKING:
- *
- * When data is received from upper or lower layer (card), the complete dsp
- * module is locked by a global lock.  This lock MUST lock irq, because it
- * must lock timer events by DSP poll timer.
- * When data is ready to be transmitted down, the data is queued and sent
- * outside lock and timer event.
- * PH_CONTROL must not change any settings, join or split conference members
- * during process of data.
- *
- * HDLC:
- *
- * It works quite the same as transparent, except that HDLC data is forwarded
- * to all other conference members if no hardware bridging is possible.
- * Send data will be writte to sendq. Sendq will be sent if confirm is received.
- * Conference cannot join, if one member is not hdlc.
- *
- */
-
-#include <linux/delay.h>
-#include <linux/gfp.h>
-#include <linux/mISDNif.h>
-#include <linux/mISDNdsp.h>
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-#include "core.h"
-#include "dsp.h"
-
-static const char *mISDN_dsp_revision = "2.0";
-
-static int debug;
-static int options;
-static int poll;
-static int dtmfthreshold = 100;
-
-MODULE_AUTHOR("Andreas Eversberg");
-module_param(debug, uint, S_IRUGO | S_IWUSR);
-module_param(options, uint, S_IRUGO | S_IWUSR);
-module_param(poll, uint, S_IRUGO | S_IWUSR);
-module_param(dtmfthreshold, uint, S_IRUGO | S_IWUSR);
-MODULE_DESCRIPTION("mISDN driver for Digital Audio Processing of transparent data");
-MODULE_LICENSE("GPL");
-
-/*int spinnest = 0;*/
-
-DEFINE_SPINLOCK(dsp_lock); /* global dsp lock */
-LIST_HEAD(dsp_ilist);
-LIST_HEAD(conf_ilist);
-int dsp_debug;
-int dsp_options;
-int dsp_poll, dsp_tics;
-
-/* check if rx may be turned off or must be turned on */
-static void
-dsp_rx_off_member(struct dsp *dsp)
-{
-	struct mISDN_ctrl_req	cq;
-	int rx_off = 1;
-
-	memset(&cq, 0, sizeof(cq));
-
-	if (!dsp->features_rx_off)
-		return;
-
-	/* not disabled */
-	if (!dsp->rx_disabled)
-		rx_off = 0;
-	/* software dtmf */
-	else if (dsp->dtmf.software)
-		rx_off = 0;
-	/* echo in software */
-	else if (dsp->echo.software)
-		rx_off = 0;
-	/* bridge in software */
-	else if (dsp->conf && dsp->conf->software)
-		rx_off = 0;
-	/* data is not required by user space and not required
-	 * for echo dtmf detection, soft-echo, soft-bridging */
-
-	if (rx_off == dsp->rx_is_off)
-		return;
-
-	if (!dsp->ch.peer) {
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: no peer, no rx_off\n",
-			       __func__);
-		return;
-	}
-	cq.op = MISDN_CTRL_RX_OFF;
-	cq.p1 = rx_off;
-	if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) {
-		printk(KERN_DEBUG "%s: 2nd CONTROL_CHANNEL failed\n",
-		       __func__);
-		return;
-	}
-	dsp->rx_is_off = rx_off;
-	if (dsp_debug & DEBUG_DSP_CORE)
-		printk(KERN_DEBUG "%s: %s set rx_off = %d\n",
-		       __func__, dsp->name, rx_off);
-}
-static void
-dsp_rx_off(struct dsp *dsp)
-{
-	struct dsp_conf_member	*member;
-
-	if (dsp_options & DSP_OPT_NOHARDWARE)
-		return;
-
-	/* no conf */
-	if (!dsp->conf) {
-		dsp_rx_off_member(dsp);
-		return;
-	}
-	/* check all members in conf */
-	list_for_each_entry(member, &dsp->conf->mlist, list) {
-		dsp_rx_off_member(member->dsp);
-	}
-}
-
-/* enable "fill empty" feature */
-static void
-dsp_fill_empty(struct dsp *dsp)
-{
-	struct mISDN_ctrl_req	cq;
-
-	memset(&cq, 0, sizeof(cq));
-
-	if (!dsp->ch.peer) {
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: no peer, no fill_empty\n",
-			       __func__);
-		return;
-	}
-	cq.op = MISDN_CTRL_FILL_EMPTY;
-	cq.p1 = 1;
-	cq.p2 = dsp_silence;
-	if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) {
-		printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
-		       __func__);
-		return;
-	}
-	if (dsp_debug & DEBUG_DSP_CORE)
-		printk(KERN_DEBUG "%s: %s set fill_empty = 1\n",
-		       __func__, dsp->name);
-}
-
-static int
-dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
-{
-	struct sk_buff	*nskb;
-	int ret = 0;
-	int cont;
-	u8 *data;
-	int len;
-
-	if (skb->len < sizeof(int)) {
-		printk(KERN_ERR "%s: PH_CONTROL message too short\n", __func__);
-		return -EINVAL;
-	}
-	cont = *((int *)skb->data);
-	len = skb->len - sizeof(int);
-	data = skb->data + sizeof(int);
-
-	switch (cont) {
-	case DTMF_TONE_START: /* turn on DTMF */
-		if (dsp->hdlc) {
-			ret = -EINVAL;
-			break;
-		}
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: start dtmf\n", __func__);
-		if (len == sizeof(int)) {
-			if (dsp_debug & DEBUG_DSP_CORE)
-				printk(KERN_NOTICE "changing DTMF Threshold "
-				       "to %d\n", *((int *)data));
-			dsp->dtmf.treshold = (*(int *)data) * 10000;
-		}
-		dsp->dtmf.enable = 1;
-		/* init goertzel */
-		dsp_dtmf_goertzel_init(dsp);
-
-		/* check dtmf hardware */
-		dsp_dtmf_hardware(dsp);
-		dsp_rx_off(dsp);
-		break;
-	case DTMF_TONE_STOP: /* turn off DTMF */
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: stop dtmf\n", __func__);
-		dsp->dtmf.enable = 0;
-		dsp->dtmf.hardware = 0;
-		dsp->dtmf.software = 0;
-		break;
-	case DSP_CONF_JOIN: /* join / update conference */
-		if (len < sizeof(int)) {
-			ret = -EINVAL;
-			break;
-		}
-		if (*((u32 *)data) == 0)
-			goto conf_split;
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: join conference %d\n",
-			       __func__, *((u32 *)data));
-		ret = dsp_cmx_conf(dsp, *((u32 *)data));
-		/* dsp_cmx_hardware will also be called here */
-		dsp_rx_off(dsp);
-		if (dsp_debug & DEBUG_DSP_CMX)
-			dsp_cmx_debug(dsp);
-		break;
-	case DSP_CONF_SPLIT: /* remove from conference */
-	conf_split:
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: release conference\n", __func__);
-		ret = dsp_cmx_conf(dsp, 0);
-		/* dsp_cmx_hardware will also be called here */
-		if (dsp_debug & DEBUG_DSP_CMX)
-			dsp_cmx_debug(dsp);
-		dsp_rx_off(dsp);
-		break;
-	case DSP_TONE_PATT_ON: /* play tone */
-		if (dsp->hdlc) {
-			ret = -EINVAL;
-			break;
-		}
-		if (len < sizeof(int)) {
-			ret = -EINVAL;
-			break;
-		}
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: turn tone 0x%x on\n",
-			       __func__, *((int *)skb->data));
-		ret = dsp_tone(dsp, *((int *)data));
-		if (!ret) {
-			dsp_cmx_hardware(dsp->conf, dsp);
-			dsp_rx_off(dsp);
-		}
-		if (!dsp->tone.tone)
-			goto tone_off;
-		break;
-	case DSP_TONE_PATT_OFF: /* stop tone */
-		if (dsp->hdlc) {
-			ret = -EINVAL;
-			break;
-		}
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: turn tone off\n", __func__);
-		dsp_tone(dsp, 0);
-		dsp_cmx_hardware(dsp->conf, dsp);
-		dsp_rx_off(dsp);
-		/* reset tx buffers (user space data) */
-	tone_off:
-		dsp->rx_W = 0;
-		dsp->rx_R = 0;
-		break;
-	case DSP_VOL_CHANGE_TX: /* change volume */
-		if (dsp->hdlc) {
-			ret = -EINVAL;
-			break;
-		}
-		if (len < sizeof(int)) {
-			ret = -EINVAL;
-			break;
-		}
-		dsp->tx_volume = *((int *)data);
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: change tx vol to %d\n",
-			       __func__, dsp->tx_volume);
-		dsp_cmx_hardware(dsp->conf, dsp);
-		dsp_dtmf_hardware(dsp);
-		dsp_rx_off(dsp);
-		break;
-	case DSP_VOL_CHANGE_RX: /* change volume */
-		if (dsp->hdlc) {
-			ret = -EINVAL;
-			break;
-		}
-		if (len < sizeof(int)) {
-			ret = -EINVAL;
-			break;
-		}
-		dsp->rx_volume = *((int *)data);
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: change rx vol to %d\n",
-			       __func__, dsp->tx_volume);
-		dsp_cmx_hardware(dsp->conf, dsp);
-		dsp_dtmf_hardware(dsp);
-		dsp_rx_off(dsp);
-		break;
-	case DSP_ECHO_ON: /* enable echo */
-		dsp->echo.software = 1; /* soft echo */
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: enable cmx-echo\n", __func__);
-		dsp_cmx_hardware(dsp->conf, dsp);
-		dsp_rx_off(dsp);
-		if (dsp_debug & DEBUG_DSP_CMX)
-			dsp_cmx_debug(dsp);
-		break;
-	case DSP_ECHO_OFF: /* disable echo */
-		dsp->echo.software = 0;
-		dsp->echo.hardware = 0;
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: disable cmx-echo\n", __func__);
-		dsp_cmx_hardware(dsp->conf, dsp);
-		dsp_rx_off(dsp);
-		if (dsp_debug & DEBUG_DSP_CMX)
-			dsp_cmx_debug(dsp);
-		break;
-	case DSP_RECEIVE_ON: /* enable receive to user space */
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: enable receive to user "
-			       "space\n", __func__);
-		dsp->rx_disabled = 0;
-		dsp_rx_off(dsp);
-		break;
-	case DSP_RECEIVE_OFF: /* disable receive to user space */
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: disable receive to "
-			       "user space\n", __func__);
-		dsp->rx_disabled = 1;
-		dsp_rx_off(dsp);
-		break;
-	case DSP_MIX_ON: /* enable mixing of tx data */
-		if (dsp->hdlc) {
-			ret = -EINVAL;
-			break;
-		}
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: enable mixing of "
-			       "tx-data with conf members\n", __func__);
-		dsp->tx_mix = 1;
-		dsp_cmx_hardware(dsp->conf, dsp);
-		dsp_rx_off(dsp);
-		if (dsp_debug & DEBUG_DSP_CMX)
-			dsp_cmx_debug(dsp);
-		break;
-	case DSP_MIX_OFF: /* disable mixing of tx data */
-		if (dsp->hdlc) {
-			ret = -EINVAL;
-			break;
-		}
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: disable mixing of "
-			       "tx-data with conf members\n", __func__);
-		dsp->tx_mix = 0;
-		dsp_cmx_hardware(dsp->conf, dsp);
-		dsp_rx_off(dsp);
-		if (dsp_debug & DEBUG_DSP_CMX)
-			dsp_cmx_debug(dsp);
-		break;
-	case DSP_TXDATA_ON: /* enable txdata */
-		dsp->tx_data = 1;
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: enable tx-data\n", __func__);
-		dsp_cmx_hardware(dsp->conf, dsp);
-		dsp_rx_off(dsp);
-		if (dsp_debug & DEBUG_DSP_CMX)
-			dsp_cmx_debug(dsp);
-		break;
-	case DSP_TXDATA_OFF: /* disable txdata */
-		dsp->tx_data = 0;
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: disable tx-data\n", __func__);
-		dsp_cmx_hardware(dsp->conf, dsp);
-		dsp_rx_off(dsp);
-		if (dsp_debug & DEBUG_DSP_CMX)
-			dsp_cmx_debug(dsp);
-		break;
-	case DSP_DELAY: /* use delay algorithm instead of dynamic
-			   jitter algorithm */
-		if (dsp->hdlc) {
-			ret = -EINVAL;
-			break;
-		}
-		if (len < sizeof(int)) {
-			ret = -EINVAL;
-			break;
-		}
-		dsp->cmx_delay = (*((int *)data)) << 3;
-		/* milliseconds to samples */
-		if (dsp->cmx_delay >= (CMX_BUFF_HALF >> 1))
-			/* clip to half of maximum usable buffer
-			   (half of half buffer) */
-			dsp->cmx_delay = (CMX_BUFF_HALF >> 1) - 1;
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: use delay algorithm to "
-			       "compensate jitter (%d samples)\n",
-			       __func__, dsp->cmx_delay);
-		break;
-	case DSP_JITTER: /* use dynamic jitter algorithm instead of
-			    delay algorithm */
-		if (dsp->hdlc) {
-			ret = -EINVAL;
-			break;
-		}
-		dsp->cmx_delay = 0;
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: use jitter algorithm to "
-			       "compensate jitter\n", __func__);
-		break;
-	case DSP_TX_DEJITTER: /* use dynamic jitter algorithm for tx-buffer */
-		if (dsp->hdlc) {
-			ret = -EINVAL;
-			break;
-		}
-		dsp->tx_dejitter = 1;
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: use dejitter on TX "
-			       "buffer\n", __func__);
-		break;
-	case DSP_TX_DEJ_OFF: /* use tx-buffer without dejittering*/
-		if (dsp->hdlc) {
-			ret = -EINVAL;
-			break;
-		}
-		dsp->tx_dejitter = 0;
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: use TX buffer without "
-			       "dejittering\n", __func__);
-		break;
-	case DSP_PIPELINE_CFG:
-		if (dsp->hdlc) {
-			ret = -EINVAL;
-			break;
-		}
-		if (len > 0 && ((char *)data)[len - 1]) {
-			printk(KERN_DEBUG "%s: pipeline config string "
-			       "is not NULL terminated!\n", __func__);
-			ret = -EINVAL;
-		} else {
-			dsp->pipeline.inuse = 1;
-			dsp_cmx_hardware(dsp->conf, dsp);
-			ret = dsp_pipeline_build(&dsp->pipeline,
-						 len > 0 ? data : NULL);
-			dsp_cmx_hardware(dsp->conf, dsp);
-			dsp_rx_off(dsp);
-		}
-		break;
-	case DSP_BF_ENABLE_KEY: /* turn blowfish on */
-		if (dsp->hdlc) {
-			ret = -EINVAL;
-			break;
-		}
-		if (len < 4 || len > 56) {
-			ret = -EINVAL;
-			break;
-		}
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: turn blowfish on (key "
-			       "not shown)\n", __func__);
-		ret = dsp_bf_init(dsp, (u8 *)data, len);
-		/* set new cont */
-		if (!ret)
-			cont = DSP_BF_ACCEPT;
-		else
-			cont = DSP_BF_REJECT;
-		/* send indication if it worked to set it */
-		nskb = _alloc_mISDN_skb(PH_CONTROL_IND, MISDN_ID_ANY,
-					sizeof(int), &cont, GFP_ATOMIC);
-		if (nskb) {
-			if (dsp->up) {
-				if (dsp->up->send(dsp->up, nskb))
-					dev_kfree_skb(nskb);
-			} else
-				dev_kfree_skb(nskb);
-		}
-		if (!ret) {
-			dsp_cmx_hardware(dsp->conf, dsp);
-			dsp_dtmf_hardware(dsp);
-			dsp_rx_off(dsp);
-		}
-		break;
-	case DSP_BF_DISABLE: /* turn blowfish off */
-		if (dsp->hdlc) {
-			ret = -EINVAL;
-			break;
-		}
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: turn blowfish off\n", __func__);
-		dsp_bf_cleanup(dsp);
-		dsp_cmx_hardware(dsp->conf, dsp);
-		dsp_dtmf_hardware(dsp);
-		dsp_rx_off(dsp);
-		break;
-	default:
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: ctrl req %x unhandled\n",
-			       __func__, cont);
-		ret = -EINVAL;
-	}
-	return ret;
-}
-
-static void
-get_features(struct mISDNchannel *ch)
-{
-	struct dsp		*dsp = container_of(ch, struct dsp, ch);
-	struct mISDN_ctrl_req	cq;
-
-	if (!ch->peer) {
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: no peer, no features\n",
-			       __func__);
-		return;
-	}
-	memset(&cq, 0, sizeof(cq));
-	cq.op = MISDN_CTRL_GETOP;
-	if (ch->peer->ctrl(ch->peer, CONTROL_CHANNEL, &cq) < 0) {
-		printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
-		       __func__);
-		return;
-	}
-	if (cq.op & MISDN_CTRL_RX_OFF)
-		dsp->features_rx_off = 1;
-	if (cq.op & MISDN_CTRL_FILL_EMPTY)
-		dsp->features_fill_empty = 1;
-	if (dsp_options & DSP_OPT_NOHARDWARE)
-		return;
-	if ((cq.op & MISDN_CTRL_HW_FEATURES_OP)) {
-		cq.op = MISDN_CTRL_HW_FEATURES;
-		*((u_long *)&cq.p1) = (u_long)&dsp->features;
-		if (ch->peer->ctrl(ch->peer, CONTROL_CHANNEL, &cq)) {
-			printk(KERN_DEBUG "%s: 2nd CONTROL_CHANNEL failed\n",
-			       __func__);
-		}
-	} else
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: features not supported for %s\n",
-			       __func__, dsp->name);
-}
-
-static int
-dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
-{
-	struct dsp		*dsp = container_of(ch, struct dsp, ch);
-	struct mISDNhead	*hh;
-	int			ret = 0;
-	u8			*digits = NULL;
-	u_long			flags;
-
-	hh = mISDN_HEAD_P(skb);
-	switch (hh->prim) {
-		/* FROM DOWN */
-	case (PH_DATA_CNF):
-		dsp->data_pending = 0;
-		/* trigger next hdlc frame, if any */
-		if (dsp->hdlc) {
-			spin_lock_irqsave(&dsp_lock, flags);
-			if (dsp->b_active)
-				schedule_work(&dsp->workq);
-			spin_unlock_irqrestore(&dsp_lock, flags);
-		}
-		break;
-	case (PH_DATA_IND):
-	case (DL_DATA_IND):
-		if (skb->len < 1) {
-			ret = -EINVAL;
-			break;
-		}
-		if (dsp->rx_is_off) {
-			if (dsp_debug & DEBUG_DSP_CORE)
-				printk(KERN_DEBUG "%s: rx-data during rx_off"
-				       " for %s\n",
-				       __func__, dsp->name);
-		}
-		if (dsp->hdlc) {
-			/* hdlc */
-			spin_lock_irqsave(&dsp_lock, flags);
-			dsp_cmx_hdlc(dsp, skb);
-			spin_unlock_irqrestore(&dsp_lock, flags);
-			if (dsp->rx_disabled) {
-				/* if receive is not allowed */
-				break;
-			}
-			hh->prim = DL_DATA_IND;
-			if (dsp->up)
-				return dsp->up->send(dsp->up, skb);
-			break;
-		}
-
-		spin_lock_irqsave(&dsp_lock, flags);
-
-		/* decrypt if enabled */
-		if (dsp->bf_enable)
-			dsp_bf_decrypt(dsp, skb->data, skb->len);
-		/* pipeline */
-		if (dsp->pipeline.inuse)
-			dsp_pipeline_process_rx(&dsp->pipeline, skb->data,
-						skb->len, hh->id);
-		/* change volume if requested */
-		if (dsp->rx_volume)
-			dsp_change_volume(skb, dsp->rx_volume);
-		/* check if dtmf soft decoding is turned on */
-		if (dsp->dtmf.software) {
-			digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
-							  skb->len, (dsp_options & DSP_OPT_ULAW) ? 1 : 0);
-		}
-		/* we need to process receive data if software */
-		if (dsp->conf && dsp->conf->software) {
-			/* process data from card at cmx */
-			dsp_cmx_receive(dsp, skb);
-		}
-
-		spin_unlock_irqrestore(&dsp_lock, flags);
-
-		/* send dtmf result, if any */
-		if (digits) {
-			while (*digits) {
-				int k;
-				struct sk_buff *nskb;
-				if (dsp_debug & DEBUG_DSP_DTMF)
-					printk(KERN_DEBUG "%s: digit"
-					       "(%c) to layer %s\n",
-					       __func__, *digits, dsp->name);
-				k = *digits | DTMF_TONE_VAL;
-				nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
-							MISDN_ID_ANY, sizeof(int), &k,
-							GFP_ATOMIC);
-				if (nskb) {
-					if (dsp->up) {
-						if (dsp->up->send(
-							    dsp->up, nskb))
-							dev_kfree_skb(nskb);
-					} else
-						dev_kfree_skb(nskb);
-				}
-				digits++;
-			}
-		}
-		if (dsp->rx_disabled) {
-			/* if receive is not allowed */
-			break;
-		}
-		hh->prim = DL_DATA_IND;
-		if (dsp->up)
-			return dsp->up->send(dsp->up, skb);
-		break;
-	case (PH_CONTROL_IND):
-		if (dsp_debug & DEBUG_DSP_DTMFCOEFF)
-			printk(KERN_DEBUG "%s: PH_CONTROL INDICATION "
-			       "received: %x (len %d) %s\n", __func__,
-			       hh->id, skb->len, dsp->name);
-		switch (hh->id) {
-		case (DTMF_HFC_COEF): /* getting coefficients */
-			if (!dsp->dtmf.hardware) {
-				if (dsp_debug & DEBUG_DSP_DTMFCOEFF)
-					printk(KERN_DEBUG "%s: ignoring DTMF "
-					       "coefficients from HFC\n",
-					       __func__);
-				break;
-			}
-			digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
-							  skb->len, 2);
-			while (*digits) {
-				int k;
-				struct sk_buff *nskb;
-				if (dsp_debug & DEBUG_DSP_DTMF)
-					printk(KERN_DEBUG "%s: digit"
-					       "(%c) to layer %s\n",
-					       __func__, *digits, dsp->name);
-				k = *digits | DTMF_TONE_VAL;
-				nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
-							MISDN_ID_ANY, sizeof(int), &k,
-							GFP_ATOMIC);
-				if (nskb) {
-					if (dsp->up) {
-						if (dsp->up->send(
-							    dsp->up, nskb))
-							dev_kfree_skb(nskb);
-					} else
-						dev_kfree_skb(nskb);
-				}
-				digits++;
-			}
-			break;
-		case (HFC_VOL_CHANGE_TX): /* change volume */
-			if (skb->len != sizeof(int)) {
-				ret = -EINVAL;
-				break;
-			}
-			spin_lock_irqsave(&dsp_lock, flags);
-			dsp->tx_volume = *((int *)skb->data);
-			if (dsp_debug & DEBUG_DSP_CORE)
-				printk(KERN_DEBUG "%s: change tx volume to "
-				       "%d\n", __func__, dsp->tx_volume);
-			dsp_cmx_hardware(dsp->conf, dsp);
-			dsp_dtmf_hardware(dsp);
-			dsp_rx_off(dsp);
-			spin_unlock_irqrestore(&dsp_lock, flags);
-			break;
-		default:
-			if (dsp_debug & DEBUG_DSP_CORE)
-				printk(KERN_DEBUG "%s: ctrl ind %x unhandled "
-				       "%s\n", __func__, hh->id, dsp->name);
-			ret = -EINVAL;
-		}
-		break;
-	case (PH_ACTIVATE_IND):
-	case (PH_ACTIVATE_CNF):
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: b_channel is now active %s\n",
-			       __func__, dsp->name);
-		/* bchannel now active */
-		spin_lock_irqsave(&dsp_lock, flags);
-		dsp->b_active = 1;
-		dsp->data_pending = 0;
-		dsp->rx_init = 1;
-		/* rx_W and rx_R will be adjusted on first frame */
-		dsp->rx_W = 0;
-		dsp->rx_R = 0;
-		memset(dsp->rx_buff, 0, sizeof(dsp->rx_buff));
-		dsp_cmx_hardware(dsp->conf, dsp);
-		dsp_dtmf_hardware(dsp);
-		dsp_rx_off(dsp);
-		spin_unlock_irqrestore(&dsp_lock, flags);
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: done with activation, sending "
-			       "confirm to user space. %s\n", __func__,
-			       dsp->name);
-		/* send activation to upper layer */
-		hh->prim = DL_ESTABLISH_CNF;
-		if (dsp->up)
-			return dsp->up->send(dsp->up, skb);
-		break;
-	case (PH_DEACTIVATE_IND):
-	case (PH_DEACTIVATE_CNF):
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: b_channel is now inactive %s\n",
-			       __func__, dsp->name);
-		/* bchannel now inactive */
-		spin_lock_irqsave(&dsp_lock, flags);
-		dsp->b_active = 0;
-		dsp->data_pending = 0;
-		dsp_cmx_hardware(dsp->conf, dsp);
-		dsp_rx_off(dsp);
-		spin_unlock_irqrestore(&dsp_lock, flags);
-		hh->prim = DL_RELEASE_CNF;
-		if (dsp->up)
-			return dsp->up->send(dsp->up, skb);
-		break;
-		/* FROM UP */
-	case (DL_DATA_REQ):
-	case (PH_DATA_REQ):
-		if (skb->len < 1) {
-			ret = -EINVAL;
-			break;
-		}
-		if (dsp->hdlc) {
-			/* hdlc */
-			if (!dsp->b_active) {
-				ret = -EIO;
-				break;
-			}
-			hh->prim = PH_DATA_REQ;
-			spin_lock_irqsave(&dsp_lock, flags);
-			skb_queue_tail(&dsp->sendq, skb);
-			schedule_work(&dsp->workq);
-			spin_unlock_irqrestore(&dsp_lock, flags);
-			return 0;
-		}
-		/* send data to tx-buffer (if no tone is played) */
-		if (!dsp->tone.tone) {
-			spin_lock_irqsave(&dsp_lock, flags);
-			dsp_cmx_transmit(dsp, skb);
-			spin_unlock_irqrestore(&dsp_lock, flags);
-		}
-		break;
-	case (PH_CONTROL_REQ):
-		spin_lock_irqsave(&dsp_lock, flags);
-		ret = dsp_control_req(dsp, hh, skb);
-		spin_unlock_irqrestore(&dsp_lock, flags);
-		break;
-	case (DL_ESTABLISH_REQ):
-	case (PH_ACTIVATE_REQ):
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: activating b_channel %s\n",
-			       __func__, dsp->name);
-		if (dsp->dtmf.hardware || dsp->dtmf.software)
-			dsp_dtmf_goertzel_init(dsp);
-		get_features(ch);
-		/* enable fill_empty feature */
-		if (dsp->features_fill_empty)
-			dsp_fill_empty(dsp);
-		/* send ph_activate */
-		hh->prim = PH_ACTIVATE_REQ;
-		if (ch->peer)
-			return ch->recv(ch->peer, skb);
-		break;
-	case (DL_RELEASE_REQ):
-	case (PH_DEACTIVATE_REQ):
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: releasing b_channel %s\n",
-			       __func__, dsp->name);
-		spin_lock_irqsave(&dsp_lock, flags);
-		dsp->tone.tone = 0;
-		dsp->tone.hardware = 0;
-		dsp->tone.software = 0;
-		if (timer_pending(&dsp->tone.tl))
-			timer_delete(&dsp->tone.tl);
-		if (dsp->conf)
-			dsp_cmx_conf(dsp, 0); /* dsp_cmx_hardware will also be
-						 called here */
-		skb_queue_purge(&dsp->sendq);
-		spin_unlock_irqrestore(&dsp_lock, flags);
-		hh->prim = PH_DEACTIVATE_REQ;
-		if (ch->peer)
-			return ch->recv(ch->peer, skb);
-		break;
-	default:
-		if (dsp_debug & DEBUG_DSP_CORE)
-			printk(KERN_DEBUG "%s: msg %x unhandled %s\n",
-			       __func__, hh->prim, dsp->name);
-		ret = -EINVAL;
-	}
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-static int
-dsp_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
-{
-	struct dsp		*dsp = container_of(ch, struct dsp, ch);
-	u_long		flags;
-
-	if (debug & DEBUG_DSP_CTRL)
-		printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);
-
-	switch (cmd) {
-	case OPEN_CHANNEL:
-		break;
-	case CLOSE_CHANNEL:
-		if (dsp->ch.peer)
-			dsp->ch.peer->ctrl(dsp->ch.peer, CLOSE_CHANNEL, NULL);
-
-		/* wait until workqueue has finished,
-		 * must lock here, or we may hit send-process currently
-		 * queueing. */
-		spin_lock_irqsave(&dsp_lock, flags);
-		dsp->b_active = 0;
-		spin_unlock_irqrestore(&dsp_lock, flags);
-		/* MUST not be locked, because it waits until queue is done. */
-		cancel_work_sync(&dsp->workq);
-		spin_lock_irqsave(&dsp_lock, flags);
-		if (timer_pending(&dsp->tone.tl))
-			timer_delete(&dsp->tone.tl);
-		skb_queue_purge(&dsp->sendq);
-		if (dsp_debug & DEBUG_DSP_CTRL)
-			printk(KERN_DEBUG "%s: releasing member %s\n",
-			       __func__, dsp->name);
-		dsp->b_active = 0;
-		dsp_cmx_conf(dsp, 0); /* dsp_cmx_hardware will also be called
-					 here */
-		dsp_pipeline_destroy(&dsp->pipeline);
-
-		if (dsp_debug & DEBUG_DSP_CTRL)
-			printk(KERN_DEBUG "%s: remove & destroy object %s\n",
-			       __func__, dsp->name);
-		list_del(&dsp->list);
-		spin_unlock_irqrestore(&dsp_lock, flags);
-
-		if (dsp_debug & DEBUG_DSP_CTRL)
-			printk(KERN_DEBUG "%s: dsp instance released\n",
-			       __func__);
-		vfree(dsp);
-		module_put(THIS_MODULE);
-		break;
-	}
-	return 0;
-}
-
-static void
-dsp_send_bh(struct work_struct *work)
-{
-	struct dsp *dsp = container_of(work, struct dsp, workq);
-	struct sk_buff *skb;
-	struct mISDNhead	*hh;
-
-	if (dsp->hdlc && dsp->data_pending)
-		return; /* wait until data has been acknowledged */
-
-	/* send queued data */
-	while ((skb = skb_dequeue(&dsp->sendq))) {
-		/* in locked date, we must have still data in queue */
-		if (dsp->data_pending) {
-			if (dsp_debug & DEBUG_DSP_CORE)
-				printk(KERN_DEBUG "%s: fifo full %s, this is "
-				       "no bug!\n", __func__, dsp->name);
-			/* flush transparent data, if not acked */
-			dev_kfree_skb(skb);
-			continue;
-		}
-		hh = mISDN_HEAD_P(skb);
-		if (hh->prim == DL_DATA_REQ) {
-			/* send packet up */
-			if (dsp->up) {
-				if (dsp->up->send(dsp->up, skb))
-					dev_kfree_skb(skb);
-			} else
-				dev_kfree_skb(skb);
-		} else {
-			/* send packet down */
-			if (dsp->ch.peer) {
-				dsp->data_pending = 1;
-				if (dsp->ch.recv(dsp->ch.peer, skb)) {
-					dev_kfree_skb(skb);
-					dsp->data_pending = 0;
-				}
-			} else
-				dev_kfree_skb(skb);
-		}
-	}
-}
-
-static int
-dspcreate(struct channel_req *crq)
-{
-	struct dsp		*ndsp;
-	u_long		flags;
-
-	if (crq->protocol != ISDN_P_B_L2DSP
-	    && crq->protocol != ISDN_P_B_L2DSPHDLC)
-		return -EPROTONOSUPPORT;
-	ndsp = vzalloc(sizeof(struct dsp));
-	if (!ndsp) {
-		printk(KERN_ERR "%s: vmalloc struct dsp failed\n", __func__);
-		return -ENOMEM;
-	}
-	if (dsp_debug & DEBUG_DSP_CTRL)
-		printk(KERN_DEBUG "%s: creating new dsp instance\n", __func__);
-
-	/* default enabled */
-	INIT_WORK(&ndsp->workq, (void *)dsp_send_bh);
-	skb_queue_head_init(&ndsp->sendq);
-	ndsp->ch.send = dsp_function;
-	ndsp->ch.ctrl = dsp_ctrl;
-	ndsp->up = crq->ch;
-	crq->ch = &ndsp->ch;
-	if (crq->protocol == ISDN_P_B_L2DSP) {
-		crq->protocol = ISDN_P_B_RAW;
-		ndsp->hdlc = 0;
-	} else {
-		crq->protocol = ISDN_P_B_HDLC;
-		ndsp->hdlc = 1;
-	}
-	if (!try_module_get(THIS_MODULE))
-		printk(KERN_WARNING "%s:cannot get module\n",
-		       __func__);
-
-	sprintf(ndsp->name, "DSP_C%x(0x%p)",
-		ndsp->up->st->dev->id + 1, ndsp);
-	/* set frame size to start */
-	ndsp->features.hfc_id = -1; /* current PCM id */
-	ndsp->features.pcm_id = -1; /* current PCM id */
-	ndsp->pcm_slot_rx = -1; /* current CPM slot */
-	ndsp->pcm_slot_tx = -1;
-	ndsp->pcm_bank_rx = -1;
-	ndsp->pcm_bank_tx = -1;
-	ndsp->hfc_conf = -1; /* current conference number */
-	/* set tone timer */
-	timer_setup(&ndsp->tone.tl, dsp_tone_timeout, 0);
-
-	if (dtmfthreshold < 20 || dtmfthreshold > 500)
-		dtmfthreshold = 200;
-	ndsp->dtmf.treshold = dtmfthreshold * 10000;
-
-	/* init pipeline append to list */
-	spin_lock_irqsave(&dsp_lock, flags);
-	dsp_pipeline_init(&ndsp->pipeline);
-	list_add_tail(&ndsp->list, &dsp_ilist);
-	spin_unlock_irqrestore(&dsp_lock, flags);
-
-	return 0;
-}
-
-
-static struct Bprotocol DSP = {
-	.Bprotocols = (1 << (ISDN_P_B_L2DSP & ISDN_P_B_MASK))
-	| (1 << (ISDN_P_B_L2DSPHDLC & ISDN_P_B_MASK)),
-	.name = "dsp",
-	.create = dspcreate
-};
-
-static int __init dsp_init(void)
-{
-	int err;
-	int tics;
-
-	printk(KERN_INFO "DSP module %s\n", mISDN_dsp_revision);
-
-	dsp_options = options;
-	dsp_debug = debug;
-
-	/* set packet size */
-	dsp_poll = poll;
-	if (dsp_poll) {
-		if (dsp_poll > MAX_POLL) {
-			printk(KERN_ERR "%s: Wrong poll value (%d), use %d "
-			       "maximum.\n", __func__, poll, MAX_POLL);
-			err = -EINVAL;
-			return err;
-		}
-		if (dsp_poll < 8) {
-			printk(KERN_ERR "%s: Wrong poll value (%d), use 8 "
-			       "minimum.\n", __func__, dsp_poll);
-			err = -EINVAL;
-			return err;
-		}
-		dsp_tics = poll * HZ / 8000;
-		if (dsp_tics * 8000 != poll * HZ) {
-			printk(KERN_INFO "mISDN_dsp: Cannot clock every %d "
-			       "samples (0,125 ms). It is not a multiple of "
-			       "%d HZ.\n", poll, HZ);
-			err = -EINVAL;
-			return err;
-		}
-	} else {
-		poll = 8;
-		while (poll <= MAX_POLL) {
-			tics = (poll * HZ) / 8000;
-			if (tics * 8000 == poll * HZ) {
-				dsp_tics = tics;
-				dsp_poll = poll;
-				if (poll >= 64)
-					break;
-			}
-			poll++;
-		}
-	}
-	if (dsp_poll == 0) {
-		printk(KERN_INFO "mISDN_dsp: There is no multiple of kernel "
-		       "clock that equals exactly the duration of 8-256 "
-		       "samples. (Choose kernel clock speed like 100, 250, "
-		       "300, 1000)\n");
-		err = -EINVAL;
-		return err;
-	}
-	printk(KERN_INFO "mISDN_dsp: DSP clocks every %d samples. This equals "
-	       "%d jiffies.\n", dsp_poll, dsp_tics);
-
-	/* init conversion tables */
-	dsp_audio_generate_law_tables();
-	dsp_silence = (dsp_options & DSP_OPT_ULAW) ? 0xff : 0x2a;
-	dsp_audio_law_to_s32 = (dsp_options & DSP_OPT_ULAW) ?
-		dsp_audio_ulaw_to_s32 : dsp_audio_alaw_to_s32;
-	dsp_audio_generate_s2law_table();
-	dsp_audio_generate_seven();
-	dsp_audio_generate_mix_table();
-	if (dsp_options & DSP_OPT_ULAW)
-		dsp_audio_generate_ulaw_samples();
-	dsp_audio_generate_volume_changes();
-
-	err = dsp_pipeline_module_init();
-	if (err) {
-		printk(KERN_ERR "mISDN_dsp: Can't initialize pipeline, "
-		       "error(%d)\n", err);
-		return err;
-	}
-
-	err = mISDN_register_Bprotocol(&DSP);
-	if (err) {
-		printk(KERN_ERR "Can't register %s error(%d)\n", DSP.name, err);
-		return err;
-	}
-
-	/* set sample timer */
-	timer_setup(&dsp_spl_tl, dsp_cmx_send, 0);
-	dsp_spl_tl.expires = jiffies + dsp_tics;
-	dsp_spl_jiffies = dsp_spl_tl.expires;
-	add_timer(&dsp_spl_tl);
-
-	return 0;
-}
-
-
-static void __exit dsp_cleanup(void)
-{
-	mISDN_unregister_Bprotocol(&DSP);
-
-	timer_delete_sync(&dsp_spl_tl);
-
-	if (!list_empty(&dsp_ilist)) {
-		printk(KERN_ERR "mISDN_dsp: Audio DSP object inst list not "
-		       "empty.\n");
-	}
-	if (!list_empty(&conf_ilist)) {
-		printk(KERN_ERR "mISDN_dsp: Conference list not empty. Not "
-		       "all memory freed.\n");
-	}
-
-	dsp_pipeline_module_exit();
-}
-
-module_init(dsp_init);
-module_exit(dsp_cleanup);
diff --git a/drivers/isdn/mISDN/dsp_dtmf.c b/drivers/isdn/mISDN/dsp_dtmf.c
deleted file mode 100644
index 642f30be5ce2..000000000000
--- a/drivers/isdn/mISDN/dsp_dtmf.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * DTMF decoder.
- *
- * Copyright            by Andreas Eversberg (jolly@eversberg.eu)
- *			based on different decoders such as ISDN4Linux
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/mISDNif.h>
-#include <linux/mISDNdsp.h>
-#include "core.h"
-#include "dsp.h"
-
-#define NCOEFF            8     /* number of frequencies to be analyzed */
-
-/* For DTMF recognition:
- * 2 * cos(2 * PI * k / N) precalculated for all k
- */
-static u64 cos2pik[NCOEFF] =
-{
-	/* k << 15 (source: hfc-4s/8s documentation (www.colognechip.de)) */
-	55960, 53912, 51402, 48438, 38146, 32650, 26170, 18630
-};
-
-/* digit matrix */
-static char dtmf_matrix[4][4] =
-{
-	{'1', '2', '3', 'A'},
-	{'4', '5', '6', 'B'},
-	{'7', '8', '9', 'C'},
-	{'*', '0', '#', 'D'}
-};
-
-/* dtmf detection using goertzel algorithm
- * init function
- */
-void dsp_dtmf_goertzel_init(struct dsp *dsp)
-{
-	dsp->dtmf.size = 0;
-	dsp->dtmf.lastwhat = '\0';
-	dsp->dtmf.lastdigit = '\0';
-	dsp->dtmf.count = 0;
-}
-
-/* check for hardware or software features
- */
-void dsp_dtmf_hardware(struct dsp *dsp)
-{
-	int hardware = 1;
-
-	if (!dsp->dtmf.enable)
-		return;
-
-	if (!dsp->features.hfc_dtmf)
-		hardware = 0;
-
-	/* check for volume change */
-	if (dsp->tx_volume) {
-		if (dsp_debug & DEBUG_DSP_DTMF)
-			printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
-			       "because tx_volume is changed\n",
-			       __func__, dsp->name);
-		hardware = 0;
-	}
-	if (dsp->rx_volume) {
-		if (dsp_debug & DEBUG_DSP_DTMF)
-			printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
-			       "because rx_volume is changed\n",
-			       __func__, dsp->name);
-		hardware = 0;
-	}
-	/* check if encryption is enabled */
-	if (dsp->bf_enable) {
-		if (dsp_debug & DEBUG_DSP_DTMF)
-			printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
-			       "because encryption is enabled\n",
-			       __func__, dsp->name);
-		hardware = 0;
-	}
-	/* check if pipeline exists */
-	if (dsp->pipeline.inuse) {
-		if (dsp_debug & DEBUG_DSP_DTMF)
-			printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
-			       "because pipeline exists.\n",
-			       __func__, dsp->name);
-		hardware = 0;
-	}
-
-	dsp->dtmf.hardware = hardware;
-	dsp->dtmf.software = !hardware;
-}
-
-
-/*************************************************************
- * calculate the coefficients of the given sample and decode *
- *************************************************************/
-
-/* the given sample is decoded. if the sample is not long enough for a
- * complete frame, the decoding is finished and continued with the next
- * call of this function.
- *
- * the algorithm is very good for detection with a minimum of errors. i
- * tested it allot. it even works with very short tones (40ms). the only
- * disadvantage is, that it doesn't work good with different volumes of both
- * tones. this will happen, if accoustically coupled dialers are used.
- * it sometimes detects tones during speech, which is normal for decoders.
- * use sequences to given commands during calls.
- *
- * dtmf - points to a structure of the current dtmf state
- * spl and len - the sample
- * fmt - 0 = alaw, 1 = ulaw, 2 = coefficients from HFC DTMF hw-decoder
- */
-
-u8
-*dsp_dtmf_goertzel_decode(struct dsp *dsp, u8 *data, int len, int fmt)
-{
-	u8 what;
-	int size;
-	signed short *buf;
-	s32 sk, sk1, sk2;
-	int k, n, i;
-	s32 *hfccoeff;
-	s32 result[NCOEFF], tresh, treshl;
-	int lowgroup, highgroup;
-	s64 cos2pik_;
-
-	dsp->dtmf.digits[0] = '\0';
-
-	/* Note: The function will loop until the buffer has not enough samples
-	 * left to decode a full frame.
-	 */
-again:
-	/* convert samples */
-	size = dsp->dtmf.size;
-	buf = dsp->dtmf.buffer;
-	switch (fmt) {
-	case 0: /* alaw */
-	case 1: /* ulaw */
-		while (size < DSP_DTMF_NPOINTS && len) {
-			buf[size++] = dsp_audio_law_to_s32[*data++];
-			len--;
-		}
-		break;
-
-	case 2: /* HFC coefficients */
-	default:
-		if (len < 64) {
-			if (len > 0)
-				printk(KERN_ERR "%s: coefficients have invalid "
-				       "size. (is=%d < must=%d)\n",
-				       __func__, len, 64);
-			return dsp->dtmf.digits;
-		}
-		hfccoeff = (s32 *)data;
-		for (k = 0; k < NCOEFF; k++) {
-			sk2 = (*hfccoeff++) >> 4;
-			sk = (*hfccoeff++) >> 4;
-			if (sk > 32767 || sk < -32767 || sk2 > 32767
-			    || sk2 < -32767)
-				printk(KERN_WARNING
-				       "DTMF-Detection overflow\n");
-			/* compute |X(k)|**2 */
-			result[k] =
-				(sk * sk) -
-				(((cos2pik[k] * sk) >> 15) * sk2) +
-				(sk2 * sk2);
-		}
-		data += 64;
-		len -= 64;
-		goto coefficients;
-		break;
-	}
-	dsp->dtmf.size = size;
-
-	if (size < DSP_DTMF_NPOINTS)
-		return dsp->dtmf.digits;
-
-	dsp->dtmf.size = 0;
-
-	/* now we have a full buffer of signed long samples - we do goertzel */
-	for (k = 0; k < NCOEFF; k++) {
-		sk = 0;
-		sk1 = 0;
-		sk2 = 0;
-		buf = dsp->dtmf.buffer;
-		cos2pik_ = cos2pik[k];
-		for (n = 0; n < DSP_DTMF_NPOINTS; n++) {
-			sk = ((cos2pik_ * sk1) >> 15) - sk2 + (*buf++);
-			sk2 = sk1;
-			sk1 = sk;
-		}
-		sk >>= 8;
-		sk2 >>= 8;
-		if (sk > 32767 || sk < -32767 || sk2 > 32767 || sk2 < -32767)
-			printk(KERN_WARNING "DTMF-Detection overflow\n");
-		/* compute |X(k)|**2 */
-		result[k] =
-			(sk * sk) -
-			(((cos2pik[k] * sk) >> 15) * sk2) +
-			(sk2 * sk2);
-	}
-
-	/* our (squared) coefficients have been calculated, we need to process
-	 * them.
-	 */
-coefficients:
-	tresh = 0;
-	for (i = 0; i < NCOEFF; i++) {
-		if (result[i] < 0)
-			result[i] = 0;
-		if (result[i] > dsp->dtmf.treshold) {
-			if (result[i] > tresh)
-				tresh = result[i];
-		}
-	}
-
-	if (tresh == 0) {
-		what = 0;
-		goto storedigit;
-	}
-
-	if (dsp_debug & DEBUG_DSP_DTMFCOEFF) {
-		s32 tresh_100 = tresh/100;
-
-		if (tresh_100 == 0) {
-			tresh_100 = 1;
-			printk(KERN_DEBUG
-				"tresh(%d) too small set tresh/100 to 1\n",
-				tresh);
-		}
-		printk(KERN_DEBUG "a %3d %3d %3d %3d %3d %3d %3d %3d"
-		       " tr:%3d r %3d %3d %3d %3d %3d %3d %3d %3d\n",
-		       result[0] / 10000, result[1] / 10000, result[2] / 10000,
-		       result[3] / 10000, result[4] / 10000, result[5] / 10000,
-		       result[6] / 10000, result[7] / 10000, tresh / 10000,
-		       result[0] / (tresh_100), result[1] / (tresh_100),
-		       result[2] / (tresh_100), result[3] / (tresh_100),
-		       result[4] / (tresh_100), result[5] / (tresh_100),
-		       result[6] / (tresh_100), result[7] / (tresh_100));
-	}
-
-	/* calc digit (lowgroup/highgroup) */
-	lowgroup = -1;
-	highgroup = -1;
-	treshl = tresh >> 3;  /* tones which are not on, must be below 9 dB */
-	tresh = tresh >> 2;  /* touchtones must match within 6 dB */
-	for (i = 0; i < NCOEFF; i++) {
-		if (result[i] < treshl)
-			continue;  /* ignore */
-		if (result[i] < tresh) {
-			lowgroup = -1;
-			highgroup = -1;
-			break;  /* noise in between */
-		}
-		/* good level found. This is allowed only one time per group */
-		if (i < NCOEFF / 2) {
-			/* lowgroup */
-			if (lowgroup >= 0) {
-				/* Bad. Another tone found. */
-				lowgroup = -1;
-				break;
-			} else
-				lowgroup = i;
-		} else {
-			/* higroup */
-			if (highgroup >= 0) {
-				/* Bad. Another tone found. */
-				highgroup = -1;
-				break;
-			} else
-				highgroup = i - (NCOEFF / 2);
-		}
-	}
-
-	/* get digit or null */
-	what = 0;
-	if (lowgroup >= 0 && highgroup >= 0)
-		what = dtmf_matrix[lowgroup][highgroup];
-
-storedigit:
-	if (what && (dsp_debug & DEBUG_DSP_DTMF))
-		printk(KERN_DEBUG "DTMF what: %c\n", what);
-
-	if (dsp->dtmf.lastwhat != what)
-		dsp->dtmf.count = 0;
-
-	/* the tone (or no tone) must remain 3 times without change */
-	if (dsp->dtmf.count == 2) {
-		if (dsp->dtmf.lastdigit != what) {
-			dsp->dtmf.lastdigit = what;
-			if (what) {
-				if (dsp_debug & DEBUG_DSP_DTMF)
-					printk(KERN_DEBUG "DTMF digit: %c\n",
-					       what);
-				if ((strlen(dsp->dtmf.digits) + 1)
-				    < sizeof(dsp->dtmf.digits)) {
-					dsp->dtmf.digits[strlen(
-							dsp->dtmf.digits) + 1] = '\0';
-					dsp->dtmf.digits[strlen(
-							dsp->dtmf.digits)] = what;
-				}
-			}
-		}
-	} else
-		dsp->dtmf.count++;
-
-	dsp->dtmf.lastwhat = what;
-
-	goto again;
-}
diff --git a/drivers/isdn/mISDN/dsp_hwec.c b/drivers/isdn/mISDN/dsp_hwec.c
deleted file mode 100644
index 0cd216e28f00..000000000000
--- a/drivers/isdn/mISDN/dsp_hwec.c
+++ /dev/null
@@ -1,122 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * dsp_hwec.c:
- * builtin mISDN dsp pipeline element for enabling the hw echocanceller
- *
- * Copyright (C) 2007, Nadi Sarrar
- *
- * Nadi Sarrar <nadi@beronet.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/mISDNdsp.h>
-#include <linux/mISDNif.h>
-#include "core.h"
-#include "dsp.h"
-#include "dsp_hwec.h"
-
-static struct mISDN_dsp_element_arg args[] = {
-	{ "deftaps", "128", "Set the number of taps of cancellation." },
-};
-
-static struct mISDN_dsp_element dsp_hwec_p = {
-	.name = "hwec",
-	.new = NULL,
-	.free = NULL,
-	.process_tx = NULL,
-	.process_rx = NULL,
-	.num_args = ARRAY_SIZE(args),
-	.args = args,
-};
-struct mISDN_dsp_element *dsp_hwec = &dsp_hwec_p;
-
-void dsp_hwec_enable(struct dsp *dsp, const char *arg)
-{
-	int deftaps = 128,
-		len;
-	struct mISDN_ctrl_req	cq;
-
-	if (!dsp) {
-		printk(KERN_ERR "%s: failed to enable hwec: dsp is NULL\n",
-		       __func__);
-		return;
-	}
-
-	if (!arg)
-		goto _do;
-
-	len = strlen(arg);
-	if (!len)
-		goto _do;
-
-	{
-		char *dup, *next, *tok, *name, *val;
-		int tmp;
-
-		dup = next = kstrdup(arg, GFP_ATOMIC);
-		if (!dup)
-			return;
-
-		while ((tok = strsep(&next, ","))) {
-			if (!strlen(tok))
-				continue;
-			name = strsep(&tok, "=");
-			val = tok;
-
-			if (!val)
-				continue;
-
-			if (!strcmp(name, "deftaps")) {
-				if (sscanf(val, "%d", &tmp) == 1)
-					deftaps = tmp;
-			}
-		}
-
-		kfree(dup);
-	}
-
-_do:
-	printk(KERN_DEBUG "%s: enabling hwec with deftaps=%d\n",
-	       __func__, deftaps);
-	memset(&cq, 0, sizeof(cq));
-	cq.op = MISDN_CTRL_HFC_ECHOCAN_ON;
-	cq.p1 = deftaps;
-	if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) {
-		printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
-		       __func__);
-		return;
-	}
-}
-
-void dsp_hwec_disable(struct dsp *dsp)
-{
-	struct mISDN_ctrl_req	cq;
-
-	if (!dsp) {
-		printk(KERN_ERR "%s: failed to disable hwec: dsp is NULL\n",
-		       __func__);
-		return;
-	}
-
-	printk(KERN_DEBUG "%s: disabling hwec\n", __func__);
-	memset(&cq, 0, sizeof(cq));
-	cq.op = MISDN_CTRL_HFC_ECHOCAN_OFF;
-	if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) {
-		printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
-		       __func__);
-		return;
-	}
-}
-
-int dsp_hwec_init(void)
-{
-	mISDN_dsp_element_register(dsp_hwec);
-
-	return 0;
-}
-
-void dsp_hwec_exit(void)
-{
-	mISDN_dsp_element_unregister(dsp_hwec);
-}
diff --git a/drivers/isdn/mISDN/dsp_pipeline.c b/drivers/isdn/mISDN/dsp_pipeline.c
deleted file mode 100644
index 55693dc7206b..000000000000
--- a/drivers/isdn/mISDN/dsp_pipeline.c
+++ /dev/null
@@ -1,300 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * dsp_pipeline.c: pipelined audio processing
- *
- * Copyright (C) 2007, Nadi Sarrar
- *
- * Nadi Sarrar <nadi@beronet.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <linux/string.h>
-#include <linux/mISDNif.h>
-#include <linux/mISDNdsp.h>
-#include <linux/export.h>
-#include "dsp.h"
-#include "dsp_hwec.h"
-
-struct dsp_pipeline_entry {
-	struct mISDN_dsp_element *elem;
-	void                *p;
-	struct list_head     list;
-};
-struct dsp_element_entry {
-	struct mISDN_dsp_element *elem;
-	struct device	     dev;
-	struct list_head     list;
-};
-
-static LIST_HEAD(dsp_elements);
-
-/* sysfs */
-static const struct class elements_class = {
-	.name = "dsp_pipeline",
-};
-
-static ssize_t
-attr_show_args(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct mISDN_dsp_element *elem = dev_get_drvdata(dev);
-	int i;
-	char *p = buf;
-
-	*buf = 0;
-	for (i = 0; i < elem->num_args; i++)
-		p += sprintf(p, "Name:        %s\n%s%s%sDescription: %s\n\n",
-			     elem->args[i].name,
-			     elem->args[i].def ? "Default:     " : "",
-			     elem->args[i].def ? elem->args[i].def : "",
-			     elem->args[i].def ? "\n" : "",
-			     elem->args[i].desc);
-
-	return p - buf;
-}
-
-static struct device_attribute element_attributes[] = {
-	__ATTR(args, 0444, attr_show_args, NULL),
-};
-
-static void
-mISDN_dsp_dev_release(struct device *dev)
-{
-	struct dsp_element_entry *entry =
-		container_of(dev, struct dsp_element_entry, dev);
-	list_del(&entry->list);
-	kfree(entry);
-}
-
-int mISDN_dsp_element_register(struct mISDN_dsp_element *elem)
-{
-	struct dsp_element_entry *entry;
-	int ret, i;
-
-	if (!elem)
-		return -EINVAL;
-
-	entry = kzalloc_obj(struct dsp_element_entry, GFP_ATOMIC);
-	if (!entry)
-		return -ENOMEM;
-
-	INIT_LIST_HEAD(&entry->list);
-	entry->elem = elem;
-
-	entry->dev.class = &elements_class;
-	entry->dev.release = mISDN_dsp_dev_release;
-	dev_set_drvdata(&entry->dev, elem);
-	dev_set_name(&entry->dev, "%s", elem->name);
-	ret = device_register(&entry->dev);
-	if (ret) {
-		printk(KERN_ERR "%s: failed to register %s\n",
-		       __func__, elem->name);
-		goto err1;
-	}
-	list_add_tail(&entry->list, &dsp_elements);
-
-	for (i = 0; i < ARRAY_SIZE(element_attributes); ++i) {
-		ret = device_create_file(&entry->dev,
-					 &element_attributes[i]);
-		if (ret) {
-			printk(KERN_ERR "%s: failed to create device file\n",
-			       __func__);
-			goto err2;
-		}
-	}
-
-	return 0;
-
-err2:
-	device_unregister(&entry->dev);
-	return ret;
-err1:
-	put_device(&entry->dev);
-	return ret;
-}
-EXPORT_SYMBOL(mISDN_dsp_element_register);
-
-void mISDN_dsp_element_unregister(struct mISDN_dsp_element *elem)
-{
-	struct dsp_element_entry *entry, *n;
-
-	if (!elem)
-		return;
-
-	list_for_each_entry_safe(entry, n, &dsp_elements, list)
-		if (entry->elem == elem) {
-			device_unregister(&entry->dev);
-			return;
-		}
-	printk(KERN_ERR "%s: element %s not in list.\n", __func__, elem->name);
-}
-EXPORT_SYMBOL(mISDN_dsp_element_unregister);
-
-int dsp_pipeline_module_init(void)
-{
-	int err;
-
-	err = class_register(&elements_class);
-	if (err)
-		return err;
-
-	dsp_hwec_init();
-
-	return 0;
-}
-
-void dsp_pipeline_module_exit(void)
-{
-	struct dsp_element_entry *entry, *n;
-
-	dsp_hwec_exit();
-
-	class_unregister(&elements_class);
-
-	list_for_each_entry_safe(entry, n, &dsp_elements, list) {
-		list_del(&entry->list);
-		printk(KERN_WARNING "%s: element was still registered: %s\n",
-		       __func__, entry->elem->name);
-		kfree(entry);
-	}
-}
-
-int dsp_pipeline_init(struct dsp_pipeline *pipeline)
-{
-	if (!pipeline)
-		return -EINVAL;
-
-	INIT_LIST_HEAD(&pipeline->list);
-
-	return 0;
-}
-
-static inline void _dsp_pipeline_destroy(struct dsp_pipeline *pipeline)
-{
-	struct dsp_pipeline_entry *entry, *n;
-
-	list_for_each_entry_safe(entry, n, &pipeline->list, list) {
-		list_del(&entry->list);
-		if (entry->elem == dsp_hwec)
-			dsp_hwec_disable(container_of(pipeline, struct dsp,
-						      pipeline));
-		else
-			entry->elem->free(entry->p);
-		kfree(entry);
-	}
-}
-
-void dsp_pipeline_destroy(struct dsp_pipeline *pipeline)
-{
-
-	if (!pipeline)
-		return;
-
-	_dsp_pipeline_destroy(pipeline);
-}
-
-int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg)
-{
-	int found = 0;
-	char *dup, *next, *tok, *name, *args;
-	struct dsp_element_entry *entry, *n;
-	struct dsp_pipeline_entry *pipeline_entry;
-	struct mISDN_dsp_element *elem;
-
-	if (!pipeline)
-		return -EINVAL;
-
-	if (!list_empty(&pipeline->list))
-		_dsp_pipeline_destroy(pipeline);
-
-	dup = next = kstrdup(cfg, GFP_ATOMIC);
-	if (!dup)
-		return 0;
-	while ((tok = strsep(&next, "|"))) {
-		if (!strlen(tok))
-			continue;
-		name = strsep(&tok, "(");
-		args = strsep(&tok, ")");
-		if (args && !*args)
-			args = NULL;
-
-		list_for_each_entry_safe(entry, n, &dsp_elements, list)
-			if (!strcmp(entry->elem->name, name)) {
-				elem = entry->elem;
-
-				pipeline_entry = kmalloc_obj(struct dsp_pipeline_entry,
-							     GFP_ATOMIC);
-				if (!pipeline_entry) {
-					printk(KERN_ERR "%s: failed to add "
-					       "entry to pipeline: %s (out of "
-					       "memory)\n", __func__, elem->name);
-					goto _out;
-				}
-				pipeline_entry->elem = elem;
-
-				if (elem == dsp_hwec) {
-					/* This is a hack to make the hwec
-					   available as a pipeline module */
-					dsp_hwec_enable(container_of(pipeline,
-								     struct dsp, pipeline), args);
-					list_add_tail(&pipeline_entry->list,
-						      &pipeline->list);
-				} else {
-					pipeline_entry->p = elem->new(args);
-					if (pipeline_entry->p) {
-						list_add_tail(&pipeline_entry->
-							      list, &pipeline->list);
-					} else {
-						printk(KERN_ERR "%s: failed "
-						       "to add entry to pipeline: "
-						       "%s (new() returned NULL)\n",
-						       __func__, elem->name);
-						kfree(pipeline_entry);
-					}
-				}
-				found = 1;
-				break;
-			}
-
-		if (found)
-			found = 0;
-		else
-			printk(KERN_ERR "%s: element not found, skipping: "
-			       "%s\n", __func__, name);
-	}
-
-_out:
-	if (!list_empty(&pipeline->list))
-		pipeline->inuse = 1;
-	else
-		pipeline->inuse = 0;
-
-	kfree(dup);
-	return 0;
-}
-
-void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data, int len)
-{
-	struct dsp_pipeline_entry *entry;
-
-	if (!pipeline)
-		return;
-
-	list_for_each_entry(entry, &pipeline->list, list)
-		if (entry->elem->process_tx)
-			entry->elem->process_tx(entry->p, data, len);
-}
-
-void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len,
-			     unsigned int txlen)
-{
-	struct dsp_pipeline_entry *entry;
-
-	if (!pipeline)
-		return;
-
-	list_for_each_entry_reverse(entry, &pipeline->list, list)
-		if (entry->elem->process_rx)
-			entry->elem->process_rx(entry->p, data, len, txlen);
-}
diff --git a/drivers/isdn/mISDN/dsp_tones.c b/drivers/isdn/mISDN/dsp_tones.c
deleted file mode 100644
index fa7813ae8d97..000000000000
--- a/drivers/isdn/mISDN/dsp_tones.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
- * Audio support data for ISDN4Linux.
- *
- * Copyright Andreas Eversberg (jolly@eversberg.eu)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/gfp.h>
-#include <linux/mISDNif.h>
-#include <linux/mISDNdsp.h>
-#include "core.h"
-#include "dsp.h"
-
-
-#define DATA_S sample_silence
-#define SIZE_S (&sizeof_silence)
-#define DATA_GA sample_german_all
-#define SIZE_GA (&sizeof_german_all)
-#define DATA_GO sample_german_old
-#define SIZE_GO (&sizeof_german_old)
-#define DATA_DT sample_american_dialtone
-#define SIZE_DT (&sizeof_american_dialtone)
-#define DATA_RI sample_american_ringing
-#define SIZE_RI (&sizeof_american_ringing)
-#define DATA_BU sample_american_busy
-#define SIZE_BU (&sizeof_american_busy)
-#define DATA_S1 sample_special1
-#define SIZE_S1 (&sizeof_special1)
-#define DATA_S2 sample_special2
-#define SIZE_S2 (&sizeof_special2)
-#define DATA_S3 sample_special3
-#define SIZE_S3 (&sizeof_special3)
-
-/***************/
-/* tones loops */
-/***************/
-
-/* all tones are alaw encoded */
-/* the last sample+1 is in phase with the first sample. the error is low */
-
-static u8 sample_german_all[] = {
-	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
-	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
-	0xdc, 0xfc, 0x6c,
-	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
-	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
-	0xdc, 0xfc, 0x6c,
-	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
-	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
-	0xdc, 0xfc, 0x6c,
-	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
-	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
-	0xdc, 0xfc, 0x6c,
-};
-static u32 sizeof_german_all = sizeof(sample_german_all);
-
-static u8 sample_german_old[] = {
-	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
-	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
-	0x8c,
-	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
-	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
-	0x8c,
-	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
-	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
-	0x8c,
-	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
-	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
-	0x8c,
-};
-static u32 sizeof_german_old = sizeof(sample_german_old);
-
-static u8 sample_american_dialtone[] = {
-	0x2a, 0x18, 0x90, 0x6c, 0x4c, 0xbc, 0x4c, 0x6c,
-	0x10, 0x58, 0x32, 0xb9, 0x31, 0x2d, 0x8d, 0x0d,
-	0x8d, 0x2d, 0x31, 0x99, 0x0f, 0x28, 0x60, 0xf0,
-	0xd0, 0x50, 0xd0, 0x30, 0x60, 0x08, 0x8e, 0x67,
-	0x09, 0x19, 0x21, 0xe1, 0xd9, 0xb9, 0x29, 0x67,
-	0x83, 0x02, 0xce, 0xbe, 0xee, 0x1a, 0x1b, 0xef,
-	0xbf, 0xcf, 0x03, 0x82, 0x66, 0x28, 0xb8, 0xd8,
-	0xe0, 0x20, 0x18, 0x08, 0x66, 0x8f, 0x09, 0x61,
-	0x31, 0xd1, 0x51, 0xd1, 0xf1, 0x61, 0x29, 0x0e,
-	0x98, 0x30, 0x2c, 0x8c, 0x0c, 0x8c, 0x2c, 0x30,
-	0xb8, 0x33, 0x59, 0x11, 0x6d, 0x4d, 0xbd, 0x4d,
-	0x6d, 0x91, 0x19,
-};
-static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
-
-static u8 sample_american_ringing[] = {
-	0x2a, 0xe0, 0xac, 0x0c, 0xbc, 0x4c, 0x8c, 0x90,
-	0x48, 0xc7, 0xc1, 0xed, 0xcd, 0x4d, 0xcd, 0xed,
-	0xc1, 0xb7, 0x08, 0x30, 0xec, 0xcc, 0xcc, 0x8c,
-	0x10, 0x58, 0x1a, 0x99, 0x71, 0xed, 0x8d, 0x8d,
-	0x2d, 0x41, 0x89, 0x9e, 0x20, 0x70, 0x2c, 0xec,
-	0x2c, 0x70, 0x20, 0x86, 0x77, 0xe1, 0x31, 0x11,
-	0xd1, 0xf1, 0x81, 0x09, 0xa3, 0x56, 0x58, 0x00,
-	0x40, 0xc0, 0x60, 0x38, 0x46, 0x43, 0x57, 0x39,
-	0xd9, 0x59, 0x99, 0xc9, 0x77, 0x2f, 0x2e, 0xc6,
-	0xd6, 0x28, 0xd6, 0x36, 0x26, 0x2e, 0x8a, 0xa3,
-	0x43, 0x63, 0x4b, 0x4a, 0x62, 0x42, 0xa2, 0x8b,
-	0x2f, 0x27, 0x37, 0xd7, 0x29, 0xd7, 0xc7, 0x2f,
-	0x2e, 0x76, 0xc8, 0x98, 0x58, 0xd8, 0x38, 0x56,
-	0x42, 0x47, 0x39, 0x61, 0xc1, 0x41, 0x01, 0x59,
-	0x57, 0xa2, 0x08, 0x80, 0xf0, 0xd0, 0x10, 0x30,
-	0xe0, 0x76, 0x87, 0x21, 0x71, 0x2d, 0xed, 0x2d,
-	0x71, 0x21, 0x9f, 0x88, 0x40, 0x2c, 0x8c, 0x8c,
-	0xec, 0x70, 0x98, 0x1b, 0x59, 0x11, 0x8d, 0xcd,
-	0xcd, 0xed, 0x31, 0x09, 0xb6, 0xc0, 0xec, 0xcc,
-	0x4c, 0xcc, 0xec, 0xc0, 0xc6, 0x49, 0x91, 0x8d,
-	0x4d, 0xbd, 0x0d, 0xad, 0xe1,
-};
-static u32 sizeof_american_ringing = sizeof(sample_american_ringing);
-
-static u8 sample_american_busy[] = {
-	0x2a, 0x00, 0x6c, 0x4c, 0x4c, 0x6c, 0xb0, 0x66,
-	0x99, 0x11, 0x6d, 0x8d, 0x2d, 0x41, 0xd7, 0x96,
-	0x60, 0xf0, 0x70, 0x40, 0x58, 0xf6, 0x53, 0x57,
-	0x09, 0x89, 0xd7, 0x5f, 0xe3, 0x2a, 0xe3, 0x5f,
-	0xd7, 0x89, 0x09, 0x57, 0x53, 0xf6, 0x58, 0x40,
-	0x70, 0xf0, 0x60, 0x96, 0xd7, 0x41, 0x2d, 0x8d,
-	0x6d, 0x11, 0x99, 0x66, 0xb0, 0x6c, 0x4c, 0x4c,
-	0x6c, 0x00, 0x2a, 0x01, 0x6d, 0x4d, 0x4d, 0x6d,
-	0xb1, 0x67, 0x98, 0x10, 0x6c, 0x8c, 0x2c, 0x40,
-	0xd6, 0x97, 0x61, 0xf1, 0x71, 0x41, 0x59, 0xf7,
-	0x52, 0x56, 0x08, 0x88, 0xd6, 0x5e, 0xe2, 0x2a,
-	0xe2, 0x5e, 0xd6, 0x88, 0x08, 0x56, 0x52, 0xf7,
-	0x59, 0x41, 0x71, 0xf1, 0x61, 0x97, 0xd6, 0x40,
-	0x2c, 0x8c, 0x6c, 0x10, 0x98, 0x67, 0xb1, 0x6d,
-	0x4d, 0x4d, 0x6d, 0x01,
-};
-static u32 sizeof_american_busy = sizeof(sample_american_busy);
-
-static u8 sample_special1[] = {
-	0x2a, 0x2c, 0xbc, 0x6c, 0xd6, 0x71, 0xbd, 0x0d,
-	0xd9, 0x80, 0xcc, 0x4c, 0x40, 0x39, 0x0d, 0xbd,
-	0x11, 0x86, 0xec, 0xbc, 0xec, 0x0e, 0x51, 0xbd,
-	0x8d, 0x89, 0x30, 0x4c, 0xcc, 0xe0, 0xe1, 0xcd,
-	0x4d, 0x31, 0x88, 0x8c, 0xbc, 0x50, 0x0f, 0xed,
-	0xbd, 0xed, 0x87, 0x10, 0xbc, 0x0c, 0x38, 0x41,
-	0x4d, 0xcd, 0x81, 0xd8, 0x0c, 0xbc, 0x70, 0xd7,
-	0x6d, 0xbd, 0x2d,
-};
-static u32 sizeof_special1 = sizeof(sample_special1);
-
-static u8 sample_special2[] = {
-	0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
-	0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
-	0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
-	0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
-	0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
-	0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
-	0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
-	0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
-	0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
-	0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
-};
-static u32 sizeof_special2 = sizeof(sample_special2);
-
-static u8 sample_special3[] = {
-	0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
-	0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
-	0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
-	0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
-	0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
-	0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
-	0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
-	0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
-	0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
-	0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
-};
-static u32 sizeof_special3 = sizeof(sample_special3);
-
-static u8 sample_silence[] = {
-	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-};
-static u32 sizeof_silence = sizeof(sample_silence);
-
-struct tones_samples {
-	u32 *len;
-	u8 *data;
-};
-static struct
-tones_samples samples[] = {
-	{&sizeof_german_all, sample_german_all},
-	{&sizeof_german_old, sample_german_old},
-	{&sizeof_american_dialtone, sample_american_dialtone},
-	{&sizeof_american_ringing, sample_american_ringing},
-	{&sizeof_american_busy, sample_american_busy},
-	{&sizeof_special1, sample_special1},
-	{&sizeof_special2, sample_special2},
-	{&sizeof_special3, sample_special3},
-	{NULL, NULL},
-};
-
-/***********************************
- * generate ulaw from alaw samples *
- ***********************************/
-
-void
-dsp_audio_generate_ulaw_samples(void)
-{
-	int i, j;
-
-	i = 0;
-	while (samples[i].len) {
-		j = 0;
-		while (j < (*samples[i].len)) {
-			samples[i].data[j] =
-				dsp_audio_alaw_to_ulaw[samples[i].data[j]];
-			j++;
-		}
-		i++;
-	}
-}
-
-
-/****************************
- * tone sequence definition *
- ****************************/
-
-static struct pattern {
-	int tone;
-	u8 *data[10];
-	u32 *siz[10];
-	u32 seq[10];
-} pattern[] = {
-	{TONE_GERMAN_DIALTONE,
-	 {DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_GERMAN_OLDDIALTONE,
-	 {DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_AMERICAN_DIALTONE,
-	 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_GERMAN_DIALPBX,
-	 {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL,
-	  NULL},
-	 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL,
-	  NULL},
-	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
-
-	{TONE_GERMAN_OLDDIALPBX,
-	 {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL,
-	  NULL},
-	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL,
-	  NULL},
-	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
-
-	{TONE_AMERICAN_DIALPBX,
-	 {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL,
-	  NULL},
-	 {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL,
-	  NULL},
-	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
-
-	{TONE_GERMAN_RINGING,
-	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_GERMAN_OLDRINGING,
-	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_AMERICAN_RINGING,
-	 {DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_GERMAN_RINGPBX,
-	 {DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_GERMAN_OLDRINGPBX,
-	 {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_AMERICAN_RINGPBX,
-	 {DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_GERMAN_BUSY,
-	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_GERMAN_OLDBUSY,
-	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_AMERICAN_BUSY,
-	 {DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_GERMAN_HANGUP,
-	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_GERMAN_OLDHANGUP,
-	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_AMERICAN_HANGUP,
-	 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_SPECIAL_INFO,
-	 {DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_GERMAN_GASSENBESETZT,
-	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
-
-	{TONE_GERMAN_AUFSCHALTTON,
-	 {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
-
-	{0,
-	 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-};
-
-/******************
- * copy tone data *
- ******************/
-
-/* an sk_buff is generated from the number of samples needed.
- * the count will be changed and may begin from 0 each pattern period.
- * the clue is to precalculate the pointers and legths to use only one
- * memcpy per function call, or two memcpy if the tone sequence changes.
- *
- * pattern - the type of the pattern
- * count - the sample from the beginning of the pattern (phase)
- * len - the number of bytes
- *
- * return - the sk_buff with the sample
- *
- * if tones has finished (e.g. knocking tone), dsp->tones is turned off
- */
-void dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
-{
-	int index, count, start, num;
-	struct pattern *pat;
-	struct dsp_tone *tone = &dsp->tone;
-
-	/* if we have no tone, we copy silence */
-	if (!tone->tone) {
-		memset(data, dsp_silence, len);
-		return;
-	}
-
-	/* process pattern */
-	pat = (struct pattern *)tone->pattern;
-	/* points to the current pattern */
-	index = tone->index; /* gives current sequence index */
-	count = tone->count; /* gives current sample */
-
-	/* copy sample */
-	while (len) {
-		/* find sample to start with */
-		while (42) {
-			/* wrap around */
-			if (!pat->seq[index]) {
-				count = 0;
-				index = 0;
-			}
-			/* check if we are currently playing this tone */
-			if (count < pat->seq[index])
-				break;
-			if (dsp_debug & DEBUG_DSP_TONE)
-				printk(KERN_DEBUG "%s: reaching next sequence "
-				       "(index=%d)\n", __func__, index);
-			count -= pat->seq[index];
-			index++;
-		}
-		/* calculate start and number of samples */
-		start = count % (*(pat->siz[index]));
-		num = len;
-		if (num + count > pat->seq[index])
-			num = pat->seq[index] - count;
-		if (num + start > (*(pat->siz[index])))
-			num = (*(pat->siz[index])) - start;
-		/* copy memory */
-		memcpy(data, pat->data[index] + start, num);
-		/* reduce length */
-		data += num;
-		count += num;
-		len -= num;
-	}
-	tone->index = index;
-	tone->count = count;
-
-	/* return sk_buff */
-	return;
-}
-
-
-/*******************************
- * send HW message to hfc card *
- *******************************/
-
-static void
-dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
-{
-	struct sk_buff *nskb;
-
-	/* unlocking is not required, because we don't expect a response */
-	nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
-				(len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
-				GFP_ATOMIC);
-	if (nskb) {
-		if (dsp->ch.peer) {
-			if (dsp->ch.recv(dsp->ch.peer, nskb))
-				dev_kfree_skb(nskb);
-		} else
-			dev_kfree_skb(nskb);
-	}
-}
-
-
-/*****************
- * timer expires *
- *****************/
-void
-dsp_tone_timeout(struct timer_list *t)
-{
-	struct dsp *dsp = timer_container_of(dsp, t, tone.tl);
-	struct dsp_tone *tone = &dsp->tone;
-	struct pattern *pat = (struct pattern *)tone->pattern;
-	int index = tone->index;
-
-	if (!tone->tone)
-		return;
-
-	index++;
-	if (!pat->seq[index])
-		index = 0;
-	tone->index = index;
-
-	/* set next tone */
-	if (pat->data[index] == DATA_S)
-		dsp_tone_hw_message(dsp, NULL, 0);
-	else
-		dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index]));
-	/* set timer */
-	tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
-	add_timer(&tone->tl);
-}
-
-
-/********************
- * set/release tone *
- ********************/
-
-/*
- * tones are relaized by streaming or by special loop commands if supported
- * by hardware. when hardware is used, the patterns will be controlled by
- * timers.
- */
-int
-dsp_tone(struct dsp *dsp, int tone)
-{
-	struct pattern *pat;
-	int i;
-	struct dsp_tone *tonet = &dsp->tone;
-
-	tonet->software = 0;
-	tonet->hardware = 0;
-
-	/* we turn off the tone */
-	if (!tone) {
-		if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
-			timer_delete(&tonet->tl);
-		if (dsp->features.hfc_loops)
-			dsp_tone_hw_message(dsp, NULL, 0);
-		tonet->tone = 0;
-		return 0;
-	}
-
-	pat = NULL;
-	i = 0;
-	while (pattern[i].tone) {
-		if (pattern[i].tone == tone) {
-			pat = &pattern[i];
-			break;
-		}
-		i++;
-	}
-	if (!pat) {
-		printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone);
-		return -EINVAL;
-	}
-	if (dsp_debug & DEBUG_DSP_TONE)
-		printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
-		       __func__, tone, 0);
-	tonet->tone = tone;
-	tonet->pattern = pat;
-	tonet->index = 0;
-	tonet->count = 0;
-
-	if (dsp->features.hfc_loops) {
-		tonet->hardware = 1;
-		/* set first tone */
-		dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
-		/* set timer */
-		if (timer_pending(&tonet->tl))
-			timer_delete(&tonet->tl);
-		tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
-		add_timer(&tonet->tl);
-	} else {
-		tonet->software = 1;
-	}
-
-	return 0;
-}
diff --git a/drivers/isdn/mISDN/fsm.c b/drivers/isdn/mISDN/fsm.c
deleted file mode 100644
index 825b686496d2..000000000000
--- a/drivers/isdn/mISDN/fsm.c
+++ /dev/null
@@ -1,176 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * finite state machine implementation
- *
- * Author       Karsten Keil <kkeil@novell.com>
- *
- * Thanks to    Jan den Ouden
- *              Fritz Elfert
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include "fsm.h"
-
-#define FSM_TIMER_DEBUG 0
-
-int
-mISDN_FsmNew(struct Fsm *fsm,
-	     struct FsmNode *fnlist, int fncount)
-{
-	int i;
-
-	fsm->jumpmatrix =
-		kzalloc(array3_size(sizeof(FSMFNPTR), fsm->state_count,
-				    fsm->event_count),
-			GFP_KERNEL);
-	if (fsm->jumpmatrix == NULL)
-		return -ENOMEM;
-
-	for (i = 0; i < fncount; i++)
-		if ((fnlist[i].state >= fsm->state_count) ||
-		    (fnlist[i].event >= fsm->event_count)) {
-			printk(KERN_ERR
-			       "mISDN_FsmNew Error: %d st(%ld/%ld) ev(%ld/%ld)\n",
-			       i, (long)fnlist[i].state, (long)fsm->state_count,
-			       (long)fnlist[i].event, (long)fsm->event_count);
-		} else
-			fsm->jumpmatrix[fsm->state_count * fnlist[i].event +
-					fnlist[i].state] = (FSMFNPTR) fnlist[i].routine;
-	return 0;
-}
-EXPORT_SYMBOL(mISDN_FsmNew);
-
-void
-mISDN_FsmFree(struct Fsm *fsm)
-{
-	kfree((void *) fsm->jumpmatrix);
-}
-EXPORT_SYMBOL(mISDN_FsmFree);
-
-int
-mISDN_FsmEvent(struct FsmInst *fi, int event, void *arg)
-{
-	FSMFNPTR r;
-
-	if ((fi->state >= fi->fsm->state_count) ||
-	    (event >= fi->fsm->event_count)) {
-		printk(KERN_ERR
-		       "mISDN_FsmEvent Error st(%ld/%ld) ev(%d/%ld)\n",
-		       (long)fi->state, (long)fi->fsm->state_count, event,
-		       (long)fi->fsm->event_count);
-		return 1;
-	}
-	r = fi->fsm->jumpmatrix[fi->fsm->state_count * event + fi->state];
-	if (r) {
-		if (fi->debug)
-			fi->printdebug(fi, "State %s Event %s",
-				       fi->fsm->strState[fi->state],
-				       fi->fsm->strEvent[event]);
-		r(fi, event, arg);
-		return 0;
-	} else {
-		if (fi->debug)
-			fi->printdebug(fi, "State %s Event %s no action",
-				       fi->fsm->strState[fi->state],
-				       fi->fsm->strEvent[event]);
-		return 1;
-	}
-}
-EXPORT_SYMBOL(mISDN_FsmEvent);
-
-void
-mISDN_FsmChangeState(struct FsmInst *fi, int newstate)
-{
-	fi->state = newstate;
-	if (fi->debug)
-		fi->printdebug(fi, "ChangeState %s",
-			       fi->fsm->strState[newstate]);
-}
-EXPORT_SYMBOL(mISDN_FsmChangeState);
-
-static void
-FsmExpireTimer(struct timer_list *t)
-{
-	struct FsmTimer *ft = timer_container_of(ft, t, tl);
-#if FSM_TIMER_DEBUG
-	if (ft->fi->debug)
-		ft->fi->printdebug(ft->fi, "FsmExpireTimer %lx", (long) ft);
-#endif
-	mISDN_FsmEvent(ft->fi, ft->event, ft->arg);
-}
-
-void
-mISDN_FsmInitTimer(struct FsmInst *fi, struct FsmTimer *ft)
-{
-	ft->fi = fi;
-#if FSM_TIMER_DEBUG
-	if (ft->fi->debug)
-		ft->fi->printdebug(ft->fi, "mISDN_FsmInitTimer %lx", (long) ft);
-#endif
-	timer_setup(&ft->tl, FsmExpireTimer, 0);
-}
-EXPORT_SYMBOL(mISDN_FsmInitTimer);
-
-void
-mISDN_FsmDelTimer(struct FsmTimer *ft, int where)
-{
-#if FSM_TIMER_DEBUG
-	if (ft->fi->debug)
-		ft->fi->printdebug(ft->fi, "mISDN_FsmDelTimer %lx %d",
-				   (long) ft, where);
-#endif
-	timer_delete(&ft->tl);
-}
-EXPORT_SYMBOL(mISDN_FsmDelTimer);
-
-int
-mISDN_FsmAddTimer(struct FsmTimer *ft,
-		  int millisec, int event, void *arg, int where)
-{
-
-#if FSM_TIMER_DEBUG
-	if (ft->fi->debug)
-		ft->fi->printdebug(ft->fi, "mISDN_FsmAddTimer %lx %d %d",
-				   (long) ft, millisec, where);
-#endif
-
-	if (timer_pending(&ft->tl)) {
-		if (ft->fi->debug) {
-			printk(KERN_WARNING
-			       "mISDN_FsmAddTimer: timer already active!\n");
-			ft->fi->printdebug(ft->fi,
-					   "mISDN_FsmAddTimer already active!");
-		}
-		return -1;
-	}
-	ft->event = event;
-	ft->arg = arg;
-	ft->tl.expires = jiffies + (millisec * HZ) / 1000;
-	add_timer(&ft->tl);
-	return 0;
-}
-EXPORT_SYMBOL(mISDN_FsmAddTimer);
-
-void
-mISDN_FsmRestartTimer(struct FsmTimer *ft,
-		      int millisec, int event, void *arg, int where)
-{
-
-#if FSM_TIMER_DEBUG
-	if (ft->fi->debug)
-		ft->fi->printdebug(ft->fi, "mISDN_FsmRestartTimer %lx %d %d",
-				   (long) ft, millisec, where);
-#endif
-
-	if (timer_pending(&ft->tl))
-		timer_delete(&ft->tl);
-	ft->event = event;
-	ft->arg = arg;
-	ft->tl.expires = jiffies + (millisec * HZ) / 1000;
-	add_timer(&ft->tl);
-}
-EXPORT_SYMBOL(mISDN_FsmRestartTimer);
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c
deleted file mode 100644
index 8c93af06ed02..000000000000
--- a/drivers/isdn/mISDN/hwchannel.c
+++ /dev/null
@@ -1,516 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *
- * Author	Karsten Keil <kkeil@novell.com>
- *
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- */
-
-#include <linux/gfp.h>
-#include <linux/module.h>
-#include <linux/mISDNhw.h>
-
-static void
-dchannel_bh(struct work_struct *ws)
-{
-	struct dchannel	*dch  = container_of(ws, struct dchannel, workq);
-	struct sk_buff	*skb;
-	int		err;
-
-	if (test_and_clear_bit(FLG_RECVQUEUE, &dch->Flags)) {
-		while ((skb = skb_dequeue(&dch->rqueue))) {
-			if (likely(dch->dev.D.peer)) {
-				err = dch->dev.D.recv(dch->dev.D.peer, skb);
-				if (err)
-					dev_kfree_skb(skb);
-			} else
-				dev_kfree_skb(skb);
-		}
-	}
-	if (test_and_clear_bit(FLG_PHCHANGE, &dch->Flags)) {
-		if (dch->phfunc)
-			dch->phfunc(dch);
-	}
-}
-
-static void
-bchannel_bh(struct work_struct *ws)
-{
-	struct bchannel	*bch  = container_of(ws, struct bchannel, workq);
-	struct sk_buff	*skb;
-	int		err;
-
-	if (test_and_clear_bit(FLG_RECVQUEUE, &bch->Flags)) {
-		while ((skb = skb_dequeue(&bch->rqueue))) {
-			bch->rcount--;
-			if (likely(bch->ch.peer)) {
-				err = bch->ch.recv(bch->ch.peer, skb);
-				if (err)
-					dev_kfree_skb(skb);
-			} else
-				dev_kfree_skb(skb);
-		}
-	}
-}
-
-int
-mISDN_initdchannel(struct dchannel *ch, int maxlen, void *phf)
-{
-	test_and_set_bit(FLG_HDLC, &ch->Flags);
-	ch->maxlen = maxlen;
-	ch->hw = NULL;
-	ch->rx_skb = NULL;
-	ch->tx_skb = NULL;
-	ch->tx_idx = 0;
-	ch->phfunc = phf;
-	skb_queue_head_init(&ch->squeue);
-	skb_queue_head_init(&ch->rqueue);
-	INIT_LIST_HEAD(&ch->dev.bchannels);
-	INIT_WORK(&ch->workq, dchannel_bh);
-	return 0;
-}
-EXPORT_SYMBOL(mISDN_initdchannel);
-
-int
-mISDN_initbchannel(struct bchannel *ch, unsigned short maxlen,
-		   unsigned short minlen)
-{
-	ch->Flags = 0;
-	ch->minlen = minlen;
-	ch->next_minlen = minlen;
-	ch->init_minlen = minlen;
-	ch->maxlen = maxlen;
-	ch->next_maxlen = maxlen;
-	ch->init_maxlen = maxlen;
-	ch->hw = NULL;
-	ch->rx_skb = NULL;
-	ch->tx_skb = NULL;
-	ch->tx_idx = 0;
-	skb_queue_head_init(&ch->rqueue);
-	ch->rcount = 0;
-	ch->next_skb = NULL;
-	INIT_WORK(&ch->workq, bchannel_bh);
-	return 0;
-}
-EXPORT_SYMBOL(mISDN_initbchannel);
-
-int
-mISDN_freedchannel(struct dchannel *ch)
-{
-	if (ch->tx_skb) {
-		dev_kfree_skb(ch->tx_skb);
-		ch->tx_skb = NULL;
-	}
-	if (ch->rx_skb) {
-		dev_kfree_skb(ch->rx_skb);
-		ch->rx_skb = NULL;
-	}
-	skb_queue_purge(&ch->squeue);
-	skb_queue_purge(&ch->rqueue);
-	flush_work(&ch->workq);
-	return 0;
-}
-EXPORT_SYMBOL(mISDN_freedchannel);
-
-void
-mISDN_clear_bchannel(struct bchannel *ch)
-{
-	if (ch->tx_skb) {
-		dev_kfree_skb(ch->tx_skb);
-		ch->tx_skb = NULL;
-	}
-	ch->tx_idx = 0;
-	if (ch->rx_skb) {
-		dev_kfree_skb(ch->rx_skb);
-		ch->rx_skb = NULL;
-	}
-	if (ch->next_skb) {
-		dev_kfree_skb(ch->next_skb);
-		ch->next_skb = NULL;
-	}
-	test_and_clear_bit(FLG_TX_BUSY, &ch->Flags);
-	test_and_clear_bit(FLG_TX_NEXT, &ch->Flags);
-	test_and_clear_bit(FLG_ACTIVE, &ch->Flags);
-	test_and_clear_bit(FLG_FILLEMPTY, &ch->Flags);
-	test_and_clear_bit(FLG_TX_EMPTY, &ch->Flags);
-	test_and_clear_bit(FLG_RX_OFF, &ch->Flags);
-	ch->dropcnt = 0;
-	ch->minlen = ch->init_minlen;
-	ch->next_minlen = ch->init_minlen;
-	ch->maxlen = ch->init_maxlen;
-	ch->next_maxlen = ch->init_maxlen;
-	skb_queue_purge(&ch->rqueue);
-	ch->rcount = 0;
-}
-EXPORT_SYMBOL(mISDN_clear_bchannel);
-
-void
-mISDN_freebchannel(struct bchannel *ch)
-{
-	cancel_work_sync(&ch->workq);
-	mISDN_clear_bchannel(ch);
-}
-EXPORT_SYMBOL(mISDN_freebchannel);
-
-int
-mISDN_ctrl_bchannel(struct bchannel *bch, struct mISDN_ctrl_req *cq)
-{
-	int ret = 0;
-
-	switch (cq->op) {
-	case MISDN_CTRL_GETOP:
-		cq->op = MISDN_CTRL_RX_BUFFER | MISDN_CTRL_FILL_EMPTY |
-			 MISDN_CTRL_RX_OFF;
-		break;
-	case MISDN_CTRL_FILL_EMPTY:
-		if (cq->p1) {
-			memset(bch->fill, cq->p2 & 0xff, MISDN_BCH_FILL_SIZE);
-			test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
-		} else {
-			test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
-		}
-		break;
-	case MISDN_CTRL_RX_OFF:
-		/* read back dropped byte count */
-		cq->p2 = bch->dropcnt;
-		if (cq->p1)
-			test_and_set_bit(FLG_RX_OFF, &bch->Flags);
-		else
-			test_and_clear_bit(FLG_RX_OFF, &bch->Flags);
-		bch->dropcnt = 0;
-		break;
-	case MISDN_CTRL_RX_BUFFER:
-		if (cq->p2 > MISDN_CTRL_RX_SIZE_IGNORE)
-			bch->next_maxlen = cq->p2;
-		if (cq->p1 > MISDN_CTRL_RX_SIZE_IGNORE)
-			bch->next_minlen = cq->p1;
-		/* we return the old values */
-		cq->p1 = bch->minlen;
-		cq->p2 = bch->maxlen;
-		break;
-	default:
-		pr_info("mISDN unhandled control %x operation\n", cq->op);
-		ret = -EINVAL;
-		break;
-	}
-	return ret;
-}
-EXPORT_SYMBOL(mISDN_ctrl_bchannel);
-
-static inline u_int
-get_sapi_tei(u_char *p)
-{
-	u_int	sapi, tei;
-
-	sapi = *p >> 2;
-	tei = p[1] >> 1;
-	return sapi | (tei << 8);
-}
-
-void
-recv_Dchannel(struct dchannel *dch)
-{
-	struct mISDNhead *hh;
-
-	if (dch->rx_skb->len < 2) { /* at least 2 for sapi / tei */
-		dev_kfree_skb(dch->rx_skb);
-		dch->rx_skb = NULL;
-		return;
-	}
-	hh = mISDN_HEAD_P(dch->rx_skb);
-	hh->prim = PH_DATA_IND;
-	hh->id = get_sapi_tei(dch->rx_skb->data);
-	skb_queue_tail(&dch->rqueue, dch->rx_skb);
-	dch->rx_skb = NULL;
-	schedule_event(dch, FLG_RECVQUEUE);
-}
-EXPORT_SYMBOL(recv_Dchannel);
-
-void
-recv_Echannel(struct dchannel *ech, struct dchannel *dch)
-{
-	struct mISDNhead *hh;
-
-	if (ech->rx_skb->len < 2) { /* at least 2 for sapi / tei */
-		dev_kfree_skb(ech->rx_skb);
-		ech->rx_skb = NULL;
-		return;
-	}
-	hh = mISDN_HEAD_P(ech->rx_skb);
-	hh->prim = PH_DATA_E_IND;
-	hh->id = get_sapi_tei(ech->rx_skb->data);
-	skb_queue_tail(&dch->rqueue, ech->rx_skb);
-	ech->rx_skb = NULL;
-	schedule_event(dch, FLG_RECVQUEUE);
-}
-EXPORT_SYMBOL(recv_Echannel);
-
-void
-recv_Bchannel(struct bchannel *bch, unsigned int id, bool force)
-{
-	struct mISDNhead *hh;
-
-	/* if allocation did fail upper functions still may call us */
-	if (unlikely(!bch->rx_skb))
-		return;
-	if (unlikely(!bch->rx_skb->len)) {
-		/* we have no data to send - this may happen after recovery
-		 * from overflow or too small allocation.
-		 * We need to free the buffer here */
-		dev_kfree_skb(bch->rx_skb);
-		bch->rx_skb = NULL;
-	} else {
-		if (test_bit(FLG_TRANSPARENT, &bch->Flags) &&
-		    (bch->rx_skb->len < bch->minlen) && !force)
-				return;
-		hh = mISDN_HEAD_P(bch->rx_skb);
-		hh->prim = PH_DATA_IND;
-		hh->id = id;
-		if (bch->rcount >= 64) {
-			printk(KERN_WARNING
-			       "B%d receive queue overflow - flushing!\n",
-			       bch->nr);
-			skb_queue_purge(&bch->rqueue);
-		}
-		bch->rcount++;
-		skb_queue_tail(&bch->rqueue, bch->rx_skb);
-		bch->rx_skb = NULL;
-		schedule_event(bch, FLG_RECVQUEUE);
-	}
-}
-EXPORT_SYMBOL(recv_Bchannel);
-
-void
-recv_Dchannel_skb(struct dchannel *dch, struct sk_buff *skb)
-{
-	skb_queue_tail(&dch->rqueue, skb);
-	schedule_event(dch, FLG_RECVQUEUE);
-}
-EXPORT_SYMBOL(recv_Dchannel_skb);
-
-void
-recv_Bchannel_skb(struct bchannel *bch, struct sk_buff *skb)
-{
-	if (bch->rcount >= 64) {
-		printk(KERN_WARNING "B-channel %p receive queue overflow, "
-		       "flushing!\n", bch);
-		skb_queue_purge(&bch->rqueue);
-		bch->rcount = 0;
-	}
-	bch->rcount++;
-	skb_queue_tail(&bch->rqueue, skb);
-	schedule_event(bch, FLG_RECVQUEUE);
-}
-EXPORT_SYMBOL(recv_Bchannel_skb);
-
-static void
-confirm_Dsend(struct dchannel *dch)
-{
-	struct sk_buff	*skb;
-
-	skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(dch->tx_skb),
-			       0, NULL, GFP_ATOMIC);
-	if (!skb) {
-		printk(KERN_ERR "%s: no skb id %x\n", __func__,
-		       mISDN_HEAD_ID(dch->tx_skb));
-		return;
-	}
-	skb_queue_tail(&dch->rqueue, skb);
-	schedule_event(dch, FLG_RECVQUEUE);
-}
-
-int
-get_next_dframe(struct dchannel *dch)
-{
-	dch->tx_idx = 0;
-	dch->tx_skb = skb_dequeue(&dch->squeue);
-	if (dch->tx_skb) {
-		confirm_Dsend(dch);
-		return 1;
-	}
-	dch->tx_skb = NULL;
-	test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
-	return 0;
-}
-EXPORT_SYMBOL(get_next_dframe);
-
-static void
-confirm_Bsend(struct bchannel *bch)
-{
-	struct sk_buff	*skb;
-
-	if (bch->rcount >= 64) {
-		printk(KERN_WARNING "B-channel %p receive queue overflow, "
-		       "flushing!\n", bch);
-		skb_queue_purge(&bch->rqueue);
-		bch->rcount = 0;
-	}
-	skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(bch->tx_skb),
-			       0, NULL, GFP_ATOMIC);
-	if (!skb) {
-		printk(KERN_ERR "%s: no skb id %x\n", __func__,
-		       mISDN_HEAD_ID(bch->tx_skb));
-		return;
-	}
-	bch->rcount++;
-	skb_queue_tail(&bch->rqueue, skb);
-	schedule_event(bch, FLG_RECVQUEUE);
-}
-
-int
-get_next_bframe(struct bchannel *bch)
-{
-	bch->tx_idx = 0;
-	if (test_bit(FLG_TX_NEXT, &bch->Flags)) {
-		bch->tx_skb = bch->next_skb;
-		if (bch->tx_skb) {
-			bch->next_skb = NULL;
-			test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
-			/* confirm imediately to allow next data */
-			confirm_Bsend(bch);
-			return 1;
-		} else {
-			test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
-			printk(KERN_WARNING "B TX_NEXT without skb\n");
-		}
-	}
-	bch->tx_skb = NULL;
-	test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
-	return 0;
-}
-EXPORT_SYMBOL(get_next_bframe);
-
-void
-queue_ch_frame(struct mISDNchannel *ch, u_int pr, int id, struct sk_buff *skb)
-{
-	struct mISDNhead *hh;
-
-	if (!skb) {
-		_queue_data(ch, pr, id, 0, NULL, GFP_ATOMIC);
-	} else {
-		if (ch->peer) {
-			hh = mISDN_HEAD_P(skb);
-			hh->prim = pr;
-			hh->id = id;
-			if (!ch->recv(ch->peer, skb))
-				return;
-		}
-		dev_kfree_skb(skb);
-	}
-}
-EXPORT_SYMBOL(queue_ch_frame);
-
-int
-dchannel_senddata(struct dchannel *ch, struct sk_buff *skb)
-{
-	/* check oversize */
-	if (skb->len <= 0) {
-		printk(KERN_WARNING "%s: skb too small\n", __func__);
-		return -EINVAL;
-	}
-	if (skb->len > ch->maxlen) {
-		printk(KERN_WARNING "%s: skb too large(%d/%d)\n",
-		       __func__, skb->len, ch->maxlen);
-		return -EINVAL;
-	}
-	/* HW lock must be obtained */
-	if (test_and_set_bit(FLG_TX_BUSY, &ch->Flags)) {
-		skb_queue_tail(&ch->squeue, skb);
-		return 0;
-	} else {
-		/* write to fifo */
-		ch->tx_skb = skb;
-		ch->tx_idx = 0;
-		return 1;
-	}
-}
-EXPORT_SYMBOL(dchannel_senddata);
-
-int
-bchannel_senddata(struct bchannel *ch, struct sk_buff *skb)
-{
-
-	/* check oversize */
-	if (skb->len <= 0) {
-		printk(KERN_WARNING "%s: skb too small\n", __func__);
-		return -EINVAL;
-	}
-	if (skb->len > ch->maxlen) {
-		printk(KERN_WARNING "%s: skb too large(%d/%d)\n",
-		       __func__, skb->len, ch->maxlen);
-		return -EINVAL;
-	}
-	/* HW lock must be obtained */
-	/* check for pending next_skb */
-	if (ch->next_skb) {
-		printk(KERN_WARNING
-		       "%s: next_skb exist ERROR (skb->len=%d next_skb->len=%d)\n",
-		       __func__, skb->len, ch->next_skb->len);
-		return -EBUSY;
-	}
-	if (test_and_set_bit(FLG_TX_BUSY, &ch->Flags)) {
-		test_and_set_bit(FLG_TX_NEXT, &ch->Flags);
-		ch->next_skb = skb;
-		return 0;
-	} else {
-		/* write to fifo */
-		ch->tx_skb = skb;
-		ch->tx_idx = 0;
-		confirm_Bsend(ch);
-		return 1;
-	}
-}
-EXPORT_SYMBOL(bchannel_senddata);
-
-/* The function allocates a new receive skb on demand with a size for the
- * requirements of the current protocol. It returns the tailroom of the
- * receive skb or an error.
- */
-int
-bchannel_get_rxbuf(struct bchannel *bch, int reqlen)
-{
-	int len;
-
-	if (bch->rx_skb) {
-		len = skb_tailroom(bch->rx_skb);
-		if (len < reqlen) {
-			pr_warn("B%d no space for %d (only %d) bytes\n",
-				bch->nr, reqlen, len);
-			if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
-				/* send what we have now and try a new buffer */
-				recv_Bchannel(bch, 0, true);
-			} else {
-				/* on HDLC we have to drop too big frames */
-				return -EMSGSIZE;
-			}
-		} else {
-			return len;
-		}
-	}
-	/* update current min/max length first */
-	if (unlikely(bch->maxlen != bch->next_maxlen))
-		bch->maxlen = bch->next_maxlen;
-	if (unlikely(bch->minlen != bch->next_minlen))
-		bch->minlen = bch->next_minlen;
-	if (unlikely(reqlen > bch->maxlen))
-		return -EMSGSIZE;
-	if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
-		if (reqlen >= bch->minlen) {
-			len = reqlen;
-		} else {
-			len = 2 * bch->minlen;
-			if (len > bch->maxlen)
-				len = bch->maxlen;
-		}
-	} else {
-		/* with HDLC we do not know the length yet */
-		len = bch->maxlen;
-	}
-	bch->rx_skb = mI_alloc_skb(len, GFP_ATOMIC);
-	if (!bch->rx_skb) {
-		pr_warn("B%d receive no memory for %d bytes\n", bch->nr, len);
-		len = -ENOMEM;
-	}
-	return len;
-}
-EXPORT_SYMBOL(bchannel_get_rxbuf);
diff --git a/drivers/isdn/mISDN/l1oip_codec.c b/drivers/isdn/mISDN/l1oip_codec.c
deleted file mode 100644
index 1059234fbc67..000000000000
--- a/drivers/isdn/mISDN/l1oip_codec.c
+++ /dev/null
@@ -1,358 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
-
- * l1oip_codec.c  generic codec using lookup table
- *  -> conversion from a-Law to u-Law
- *  -> conversion from u-Law to a-Law
- *  -> compression by reducing the number of sample resolution to 4
- *
- * NOTE: It is not compatible with any standard codec like ADPCM.
- *
- * Author	Andreas Eversberg (jolly@eversberg.eu)
- *
-
- */
-
-/*
-
-  How the codec works:
-  --------------------
-
-  The volume is increased to increase the dynamic range of the audio signal.
-  Each sample is converted to a-LAW with only 16 steps of level resolution.
-  A pair of two samples are stored in one byte.
-
-  The first byte is stored in the upper bits, the second byte is stored in the
-  lower bits.
-
-  To speed up compression and decompression, two lookup tables are formed:
-
-  - 16 bits index for two samples (law encoded) with 8 bit compressed result.
-  - 8 bits index for one compressed data with 16 bits decompressed result.
-
-  NOTE: The bytes are handled as they are law-encoded.
-
-*/
-
-#include <linux/vmalloc.h>
-#include <linux/mISDNif.h>
-#include <linux/in.h>
-#include "core.h"
-#include "l1oip.h"
-
-/* definitions of codec. don't use calculations, code may run slower. */
-
-static u8 *table_com;
-static u16 *table_dec;
-
-
-/* alaw -> ulaw */
-static u8 alaw_to_ulaw[256] =
-{
-	0xab, 0x2b, 0xe3, 0x63, 0x8b, 0x0b, 0xc9, 0x49,
-	0xba, 0x3a, 0xf6, 0x76, 0x9b, 0x1b, 0xd7, 0x57,
-	0xa3, 0x23, 0xdd, 0x5d, 0x83, 0x03, 0xc1, 0x41,
-	0xb2, 0x32, 0xeb, 0x6b, 0x93, 0x13, 0xcf, 0x4f,
-	0xaf, 0x2f, 0xe7, 0x67, 0x8f, 0x0f, 0xcd, 0x4d,
-	0xbe, 0x3e, 0xfe, 0x7e, 0x9f, 0x1f, 0xdb, 0x5b,
-	0xa7, 0x27, 0xdf, 0x5f, 0x87, 0x07, 0xc5, 0x45,
-	0xb6, 0x36, 0xef, 0x6f, 0x97, 0x17, 0xd3, 0x53,
-	0xa9, 0x29, 0xe1, 0x61, 0x89, 0x09, 0xc7, 0x47,
-	0xb8, 0x38, 0xf2, 0x72, 0x99, 0x19, 0xd5, 0x55,
-	0xa1, 0x21, 0xdc, 0x5c, 0x81, 0x01, 0xbf, 0x3f,
-	0xb0, 0x30, 0xe9, 0x69, 0x91, 0x11, 0xce, 0x4e,
-	0xad, 0x2d, 0xe5, 0x65, 0x8d, 0x0d, 0xcb, 0x4b,
-	0xbc, 0x3c, 0xfa, 0x7a, 0x9d, 0x1d, 0xd9, 0x59,
-	0xa5, 0x25, 0xde, 0x5e, 0x85, 0x05, 0xc3, 0x43,
-	0xb4, 0x34, 0xed, 0x6d, 0x95, 0x15, 0xd1, 0x51,
-	0xac, 0x2c, 0xe4, 0x64, 0x8c, 0x0c, 0xca, 0x4a,
-	0xbb, 0x3b, 0xf8, 0x78, 0x9c, 0x1c, 0xd8, 0x58,
-	0xa4, 0x24, 0xde, 0x5e, 0x84, 0x04, 0xc2, 0x42,
-	0xb3, 0x33, 0xec, 0x6c, 0x94, 0x14, 0xd0, 0x50,
-	0xb0, 0x30, 0xe8, 0x68, 0x90, 0x10, 0xce, 0x4e,
-	0xbf, 0x3f, 0xfe, 0x7e, 0xa0, 0x20, 0xdc, 0x5c,
-	0xa8, 0x28, 0xe0, 0x60, 0x88, 0x08, 0xc6, 0x46,
-	0xb7, 0x37, 0xf0, 0x70, 0x98, 0x18, 0xd4, 0x54,
-	0xaa, 0x2a, 0xe2, 0x62, 0x8a, 0x0a, 0xc8, 0x48,
-	0xb9, 0x39, 0xf4, 0x74, 0x9a, 0x1a, 0xd6, 0x56,
-	0xa2, 0x22, 0xdd, 0x5d, 0x82, 0x02, 0xc0, 0x40,
-	0xb1, 0x31, 0xea, 0x6a, 0x92, 0x12, 0xcf, 0x4f,
-	0xae, 0x2e, 0xe6, 0x66, 0x8e, 0x0e, 0xcc, 0x4c,
-	0xbd, 0x3d, 0xfc, 0x7c, 0x9e, 0x1e, 0xda, 0x5a,
-	0xa6, 0x26, 0xdf, 0x5f, 0x86, 0x06, 0xc4, 0x44,
-	0xb5, 0x35, 0xee, 0x6e, 0x96, 0x16, 0xd2, 0x52
-};
-
-/* ulaw -> alaw */
-static u8 ulaw_to_alaw[256] =
-{
-	0xab, 0x55, 0xd5, 0x15, 0x95, 0x75, 0xf5, 0x35,
-	0xb5, 0x45, 0xc5, 0x05, 0x85, 0x65, 0xe5, 0x25,
-	0xa5, 0x5d, 0xdd, 0x1d, 0x9d, 0x7d, 0xfd, 0x3d,
-	0xbd, 0x4d, 0xcd, 0x0d, 0x8d, 0x6d, 0xed, 0x2d,
-	0xad, 0x51, 0xd1, 0x11, 0x91, 0x71, 0xf1, 0x31,
-	0xb1, 0x41, 0xc1, 0x01, 0x81, 0x61, 0xe1, 0x21,
-	0x59, 0xd9, 0x19, 0x99, 0x79, 0xf9, 0x39, 0xb9,
-	0x49, 0xc9, 0x09, 0x89, 0x69, 0xe9, 0x29, 0xa9,
-	0xd7, 0x17, 0x97, 0x77, 0xf7, 0x37, 0xb7, 0x47,
-	0xc7, 0x07, 0x87, 0x67, 0xe7, 0x27, 0xa7, 0xdf,
-	0x9f, 0x7f, 0xff, 0x3f, 0xbf, 0x4f, 0xcf, 0x0f,
-	0x8f, 0x6f, 0xef, 0x2f, 0x53, 0x13, 0x73, 0x33,
-	0xb3, 0x43, 0xc3, 0x03, 0x83, 0x63, 0xe3, 0x23,
-	0xa3, 0x5b, 0xdb, 0x1b, 0x9b, 0x7b, 0xfb, 0x3b,
-	0xbb, 0xbb, 0x4b, 0x4b, 0xcb, 0xcb, 0x0b, 0x0b,
-	0x8b, 0x8b, 0x6b, 0x6b, 0xeb, 0xeb, 0x2b, 0x2b,
-	0xab, 0x54, 0xd4, 0x14, 0x94, 0x74, 0xf4, 0x34,
-	0xb4, 0x44, 0xc4, 0x04, 0x84, 0x64, 0xe4, 0x24,
-	0xa4, 0x5c, 0xdc, 0x1c, 0x9c, 0x7c, 0xfc, 0x3c,
-	0xbc, 0x4c, 0xcc, 0x0c, 0x8c, 0x6c, 0xec, 0x2c,
-	0xac, 0x50, 0xd0, 0x10, 0x90, 0x70, 0xf0, 0x30,
-	0xb0, 0x40, 0xc0, 0x00, 0x80, 0x60, 0xe0, 0x20,
-	0x58, 0xd8, 0x18, 0x98, 0x78, 0xf8, 0x38, 0xb8,
-	0x48, 0xc8, 0x08, 0x88, 0x68, 0xe8, 0x28, 0xa8,
-	0xd6, 0x16, 0x96, 0x76, 0xf6, 0x36, 0xb6, 0x46,
-	0xc6, 0x06, 0x86, 0x66, 0xe6, 0x26, 0xa6, 0xde,
-	0x9e, 0x7e, 0xfe, 0x3e, 0xbe, 0x4e, 0xce, 0x0e,
-	0x8e, 0x6e, 0xee, 0x2e, 0x52, 0x12, 0x72, 0x32,
-	0xb2, 0x42, 0xc2, 0x02, 0x82, 0x62, 0xe2, 0x22,
-	0xa2, 0x5a, 0xda, 0x1a, 0x9a, 0x7a, 0xfa, 0x3a,
-	0xba, 0xba, 0x4a, 0x4a, 0xca, 0xca, 0x0a, 0x0a,
-	0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a
-};
-
-/* alaw -> 4bit compression */
-static u8 alaw_to_4bit[256] = {
-	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
-	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
-	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
-	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
-	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
-	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
-	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
-	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
-	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
-	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
-	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0d, 0x02,
-	0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
-	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
-	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
-	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
-	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
-	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
-	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
-	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
-	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
-	0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
-	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x01, 0x0a, 0x05,
-	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
-	0x0d, 0x02, 0x09, 0x07, 0x0f, 0x00, 0x0b, 0x04,
-	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
-	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
-	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
-	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
-	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
-	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
-	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
-	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
-};
-
-/* 4bit -> alaw decompression */
-static u8 _4bit_to_alaw[16] = {
-	0x5d, 0x51, 0xd9, 0xd7, 0x5f, 0x53, 0xa3, 0x4b,
-	0x2a, 0x3a, 0x22, 0x2e, 0x26, 0x56, 0x20, 0x2c,
-};
-
-/* ulaw -> 4bit compression */
-static u8 ulaw_to_4bit[256] = {
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04,
-	0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-	0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
-	0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-	0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08,
-	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-	0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-	0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-	0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-	0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b,
-	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-	0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a,
-	0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-	0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-	0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-};
-
-/* 4bit -> ulaw decompression */
-static u8 _4bit_to_ulaw[16] = {
-	0x11, 0x21, 0x31, 0x40, 0x4e, 0x5c, 0x68, 0x71,
-	0xfe, 0xef, 0xe7, 0xdb, 0xcd, 0xbf, 0xaf, 0x9f,
-};
-
-
-/*
- * Compresses data to the result buffer
- * The result size must be at least half of the input buffer.
- * The number of samples also must be even!
- */
-int
-l1oip_law_to_4bit(u8 *data, int len, u8 *result, u32 *state)
-{
-	int ii, i = 0, o = 0;
-
-	if (!len)
-		return 0;
-
-	/* send saved byte and first input byte */
-	if (*state) {
-		*result++ = table_com[(((*state) << 8) & 0xff00) | (*data++)];
-		len--;
-		o++;
-	}
-
-	ii = len >> 1;
-
-	while (i < ii) {
-		*result++ = table_com[(data[0]<<8) | (data[1])];
-		data += 2;
-		i++;
-		o++;
-	}
-
-	/* if len has an odd number, we save byte for next call */
-	if (len & 1)
-		*state = 0x100 + *data;
-	else
-		*state = 0;
-
-	return o;
-}
-
-/* Decompress data to the result buffer
- * The result size must be the number of sample in packet. (2 * input data)
- * The number of samples in the result are even!
- */
-int
-l1oip_4bit_to_law(u8 *data, int len, u8 *result)
-{
-	int i = 0;
-	u16 r;
-
-	while (i < len) {
-		r = table_dec[*data++];
-		*result++ = r >> 8;
-		*result++ = r;
-		i++;
-	}
-
-	return len << 1;
-}
-
-
-/*
- * law conversion
- */
-int
-l1oip_alaw_to_ulaw(u8 *data, int len, u8 *result)
-{
-	int i = 0;
-
-	while (i < len) {
-		*result++ = alaw_to_ulaw[*data++];
-		i++;
-	}
-
-	return len;
-}
-
-int
-l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result)
-{
-	int i = 0;
-
-	while (i < len) {
-		*result++ = ulaw_to_alaw[*data++];
-		i++;
-	}
-
-	return len;
-}
-
-
-/*
- * generate/free compression and decompression table
- */
-void
-l1oip_4bit_free(void)
-{
-	vfree(table_dec);
-	vfree(table_com);
-	table_com = NULL;
-	table_dec = NULL;
-}
-
-int
-l1oip_4bit_alloc(int ulaw)
-{
-	int i1, i2, c, sample;
-
-	/* in case, it is called again */
-	if (table_dec)
-		return 0;
-
-	/* alloc conversion tables */
-	table_com = vzalloc(65536);
-	table_dec = vzalloc(512);
-	if (!table_com || !table_dec) {
-		l1oip_4bit_free();
-		return -ENOMEM;
-	}
-	/* generate compression table */
-	i1 = 0;
-	while (i1 < 256) {
-		if (ulaw)
-			c = ulaw_to_4bit[i1];
-		else
-			c = alaw_to_4bit[i1];
-		i2 = 0;
-		while (i2 < 256) {
-			table_com[(i1 << 8) | i2] |= (c << 4);
-			table_com[(i2 << 8) | i1] |= c;
-			i2++;
-		}
-		i1++;
-	}
-
-	/* generate decompression table */
-	i1 = 0;
-	while (i1 < 16) {
-		if (ulaw)
-			sample = _4bit_to_ulaw[i1];
-		else
-			sample = _4bit_to_alaw[i1];
-		i2 = 0;
-		while (i2 < 16) {
-			table_dec[(i1 << 4) | i2] |= (sample << 8);
-			table_dec[(i2 << 4) | i1] |= sample;
-			i2++;
-		}
-		i1++;
-	}
-
-	return 0;
-}
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c
deleted file mode 100644
index 6866a0d6b382..000000000000
--- a/drivers/isdn/mISDN/l1oip_core.c
+++ /dev/null
@@ -1,1505 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
-
- * l1oip.c  low level driver for tunneling layer 1 over IP
- *
- * NOTE: It is not compatible with TDMoIP nor "ISDN over IP".
- *
- * Author	Andreas Eversberg (jolly@eversberg.eu)
- */
-
-/* module parameters:
- * type:
- Value 1	= BRI
- Value 2	= PRI
- Value 3 = BRI (multi channel frame, not supported yet)
- Value 4 = PRI (multi channel frame, not supported yet)
- A multi channel frame reduces overhead to a single frame for all
- b-channels, but increases delay.
- (NOTE: Multi channel frames are not implemented yet.)
-
- * codec:
- Value 0 = transparent (default)
- Value 1 = transfer ALAW
- Value 2 = transfer ULAW
- Value 3 = transfer generic 4 bit compression.
-
- * ulaw:
- 0 = we use a-Law (default)
- 1 = we use u-Law
-
- * limit:
- limitation of B-channels to control bandwidth (1...126)
- BRI: 1 or 2
- PRI: 1-30, 31-126 (126, because dchannel ist not counted here)
- Also limited ressources are used for stack, resulting in less channels.
- It is possible to have more channels than 30 in PRI mode, this must
- be supported by the application.
-
- * ip:
- byte representation of remote ip address (127.0.0.1 -> 127,0,0,1)
- If not given or four 0, no remote address is set.
- For multiple interfaces, concat ip addresses. (127,0,0,1,127,0,0,1)
-
- * port:
- port number (local interface)
- If not given or 0, port 931 is used for fist instance, 932 for next...
- For multiple interfaces, different ports must be given.
-
- * remoteport:
- port number (remote interface)
- If not given or 0, remote port equals local port
- For multiple interfaces on equal sites, different ports must be given.
-
- * ondemand:
- 0 = fixed (always transmit packets, even when remote side timed out)
- 1 = on demand (only transmit packets, when remote side is detected)
- the default is 0
- NOTE: ID must also be set for on demand.
-
- * id:
- optional value to identify frames. This value must be equal on both
- peers and should be random. If omitted or 0, no ID is transmitted.
-
- * debug:
- NOTE: only one debug value must be given for all cards
- enable debugging (see l1oip.h for debug options)
-
-
- Special mISDN controls:
-
- op = MISDN_CTRL_SETPEER*
- p1 = bytes 0-3 : remote IP address in network order (left element first)
- p2 = bytes 1-2 : remote port in network order (high byte first)
- optional:
- p2 = bytes 3-4 : local port in network order (high byte first)
-
- op = MISDN_CTRL_UNSETPEER*
-
- * Use l1oipctrl for comfortable setting or removing ip address.
- (Layer 1 Over IP CTRL)
-
-
- L1oIP-Protocol
- --------------
-
- Frame Header:
-
- 7 6 5 4 3 2 1 0
- +---------------+
- |Ver|T|I|Coding |
- +---------------+
- |  ID byte 3 *  |
- +---------------+
- |  ID byte 2 *  |
- +---------------+
- |  ID byte 1 *  |
- +---------------+
- |  ID byte 0 *  |
- +---------------+
- |M|   Channel   |
- +---------------+
- |    Length *   |
- +---------------+
- | Time Base MSB |
- +---------------+
- | Time Base LSB |
- +---------------+
- | Data....	|
-
- ...
-
- |               |
- +---------------+
- |M|   Channel   |
- +---------------+
- |    Length *   |
- +---------------+
- | Time Base MSB |
- +---------------+
- | Time Base LSB |
- +---------------+
- | Data....	|
-
- ...
-
-
- * Only included in some cases.
-
- - Ver = Version
- If version is missmatch, the frame must be ignored.
-
- - T = Type of interface
- Must be 0 for S0 or 1 for E1.
-
- - I = Id present
- If bit is set, four ID bytes are included in frame.
-
- - ID = Connection ID
- Additional ID to prevent Denial of Service attacs. Also it prevents hijacking
- connections with dynamic IP. The ID should be random and must not be 0.
-
- - Coding = Type of codec
- Must be 0 for no transcoding. Also for D-channel and other HDLC frames.
- 1 and 2 are reserved for explicitly use of a-LAW or u-LAW codec.
- 3 is used for generic table compressor.
-
- - M = More channels to come. If this flag is 1, the following byte contains
- the length of the channel data. After the data block, the next channel will
- be defined. The flag for the last channel block (or if only one channel is
- transmitted), must be 0 and no length is given.
-
- - Channel = Channel number
- 0 reserved
- 1-3 channel data for S0 (3 is D-channel)
- 1-31 channel data for E1 (16 is D-channel)
- 32-127 channel data for extended E1 (16 is D-channel)
-
- - The length is used if the M-flag is 1. It is used to find the next channel
- inside frame.
- NOTE: A value of 0 equals 256 bytes of data.
- -> For larger data blocks, a single frame must be used.
- -> For larger streams, a single frame or multiple blocks with same channel ID
- must be used.
-
- - Time Base = Timestamp of first sample in frame
- The "Time Base" is used to rearange packets and to detect packet loss.
- The 16 bits are sent in network order (MSB first) and count 1/8000 th of a
- second. This causes a wrap around each 8,192 seconds. There is no requirement
- for the initial "Time Base", but 0 should be used for the first packet.
- In case of HDLC data, this timestamp counts the packet or byte number.
-
-
- Two Timers:
-
- After initialisation, a timer of 15 seconds is started. Whenever a packet is
- transmitted, the timer is reset to 15 seconds again. If the timer expires, an
- empty packet is transmitted. This keep the connection alive.
-
- When a valid packet is received, a timer 65 seconds is started. The interface
- become ACTIVE. If the timer expires, the interface becomes INACTIVE.
-
-
- Dynamic IP handling:
-
- To allow dynamic IP, the ID must be non 0. In this case, any packet with the
- correct port number and ID will be accepted. If the remote side changes its IP
- the new IP is used for all transmitted packets until it changes again.
-
-
- On Demand:
-
- If the ondemand parameter is given, the remote IP is set to 0 on timeout.
- This will stop keepalive traffic to remote. If the remote is online again,
- traffic will continue to the remote address. This is useful for road warriors.
- This feature only works with ID set, otherwhise it is highly unsecure.
-
-
- Socket and Thread
- -----------------
-
- The complete socket opening and closing is done by a thread.
- When the thread opened a socket, the hc->socket descriptor is set. Whenever a
- packet shall be sent to the socket, the hc->socket must be checked whether not
- NULL. To prevent change in socket descriptor, the hc->socket_lock must be used.
- To change the socket, a recall of l1oip_socket_open() will safely kill the
- socket process and create a new one.
-
-*/
-
-#define L1OIP_VERSION	0	/* 0...3 */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/mISDNif.h>
-#include <linux/mISDNhw.h>
-#include <linux/mISDNdsp.h>
-#include <linux/init.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/workqueue.h>
-#include <linux/kthread.h>
-#include <linux/slab.h>
-#include <linux/sched/signal.h>
-
-#include <net/sock.h>
-#include "core.h"
-#include "l1oip.h"
-
-static const char *l1oip_revision = "2.00";
-
-static int l1oip_cnt;
-static DEFINE_SPINLOCK(l1oip_lock);
-static LIST_HEAD(l1oip_ilist);
-
-#define MAX_CARDS	16
-static u_int type[MAX_CARDS];
-static u_int codec[MAX_CARDS];
-static u_int ip[MAX_CARDS * 4];
-static u_int port[MAX_CARDS];
-static u_int remoteport[MAX_CARDS];
-static u_int ondemand[MAX_CARDS];
-static u_int limit[MAX_CARDS];
-static u_int id[MAX_CARDS];
-static int debug;
-static int ulaw;
-
-MODULE_AUTHOR("Andreas Eversberg");
-MODULE_DESCRIPTION("mISDN driver for tunneling layer 1 over IP");
-MODULE_LICENSE("GPL");
-module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR);
-module_param_array(codec, uint, NULL, S_IRUGO | S_IWUSR);
-module_param_array(ip, uint, NULL, S_IRUGO | S_IWUSR);
-module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);
-module_param_array(remoteport, uint, NULL, S_IRUGO | S_IWUSR);
-module_param_array(ondemand, uint, NULL, S_IRUGO | S_IWUSR);
-module_param_array(limit, uint, NULL, S_IRUGO | S_IWUSR);
-module_param_array(id, uint, NULL, S_IRUGO | S_IWUSR);
-module_param(ulaw, uint, S_IRUGO | S_IWUSR);
-module_param(debug, uint, S_IRUGO | S_IWUSR);
-
-/*
- * send a frame via socket, if open and restart timer
- */
-static int
-l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
-		  u16 timebase, u8 *buf, int len)
-{
-	u8 *p;
-	u8 frame[MAX_DFRAME_LEN_L1 + 32];
-	struct socket *socket = NULL;
-
-	if (debug & DEBUG_L1OIP_MSG)
-		printk(KERN_DEBUG "%s: sending data to socket (len = %d)\n",
-		       __func__, len);
-
-	p = frame;
-
-	/* restart timer */
-	if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ) && !hc->shutdown)
-		mod_timer(&hc->keep_tl, jiffies + L1OIP_KEEPALIVE * HZ);
-	else
-		hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ;
-
-	if (debug & DEBUG_L1OIP_MSG)
-		printk(KERN_DEBUG "%s: resetting timer\n", __func__);
-
-	/* drop if we have no remote ip or port */
-	if (!hc->sin_remote.sin_addr.s_addr || !hc->sin_remote.sin_port) {
-		if (debug & DEBUG_L1OIP_MSG)
-			printk(KERN_DEBUG "%s: dropping frame, because remote "
-			       "IP is not set.\n", __func__);
-		return len;
-	}
-
-	/* assemble frame */
-	*p++ = (L1OIP_VERSION << 6) /* version and coding */
-		| (hc->pri ? 0x20 : 0x00) /* type */
-		| (hc->id ? 0x10 : 0x00) /* id */
-		| localcodec;
-	if (hc->id) {
-		*p++ = hc->id >> 24; /* id */
-		*p++ = hc->id >> 16;
-		*p++ = hc->id >> 8;
-		*p++ = hc->id;
-	}
-	*p++ =  0x00 + channel; /* m-flag, channel */
-	*p++ = timebase >> 8; /* time base */
-	*p++ = timebase;
-
-	if (buf && len) { /* add data to frame */
-		if (localcodec == 1 && ulaw)
-			l1oip_ulaw_to_alaw(buf, len, p);
-		else if (localcodec == 2 && !ulaw)
-			l1oip_alaw_to_ulaw(buf, len, p);
-		else if (localcodec == 3)
-			len = l1oip_law_to_4bit(buf, len, p,
-						&hc->chan[channel].codecstate);
-		else
-			memcpy(p, buf, len);
-	}
-	len += p - frame;
-
-	/* check for socket in safe condition */
-	spin_lock(&hc->socket_lock);
-	if (!hc->socket) {
-		spin_unlock(&hc->socket_lock);
-		return 0;
-	}
-	/* seize socket */
-	socket = hc->socket;
-	hc->socket = NULL;
-	spin_unlock(&hc->socket_lock);
-	/* send packet */
-	if (debug & DEBUG_L1OIP_MSG)
-		printk(KERN_DEBUG "%s: sending packet to socket (len "
-		       "= %d)\n", __func__, len);
-	hc->sendiov.iov_base = frame;
-	hc->sendiov.iov_len  = len;
-	len = kernel_sendmsg(socket, &hc->sendmsg, &hc->sendiov, 1, len);
-	/* give socket back */
-	hc->socket = socket; /* no locking required */
-
-	return len;
-}
-
-
-/*
- * receive channel data from socket
- */
-static void
-l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase,
-		  u8 *buf, int len)
-{
-	struct sk_buff *nskb;
-	struct bchannel *bch;
-	struct dchannel *dch;
-	u8 *p;
-	u32 rx_counter;
-
-	if (len == 0) {
-		if (debug & DEBUG_L1OIP_MSG)
-			printk(KERN_DEBUG "%s: received empty keepalive data, "
-			       "ignoring\n", __func__);
-		return;
-	}
-
-	if (debug & DEBUG_L1OIP_MSG)
-		printk(KERN_DEBUG "%s: received data, sending to mISDN (%d)\n",
-		       __func__, len);
-
-	if (channel < 1 || channel > 127) {
-		printk(KERN_WARNING "%s: packet error - channel %d out of "
-		       "range\n", __func__, channel);
-		return;
-	}
-	dch = hc->chan[channel].dch;
-	bch = hc->chan[channel].bch;
-	if (!dch && !bch) {
-		printk(KERN_WARNING "%s: packet error - channel %d not in "
-		       "stack\n", __func__, channel);
-		return;
-	}
-
-	/* prepare message */
-	nskb = mI_alloc_skb((remotecodec == 3) ? (len << 1) : len, GFP_ATOMIC);
-	if (!nskb) {
-		printk(KERN_ERR "%s: No mem for skb.\n", __func__);
-		return;
-	}
-	p = skb_put(nskb, (remotecodec == 3) ? (len << 1) : len);
-
-	if (remotecodec == 1 && ulaw)
-		l1oip_alaw_to_ulaw(buf, len, p);
-	else if (remotecodec == 2 && !ulaw)
-		l1oip_ulaw_to_alaw(buf, len, p);
-	else if (remotecodec == 3)
-		len = l1oip_4bit_to_law(buf, len, p);
-	else
-		memcpy(p, buf, len);
-
-	/* send message up */
-	if (dch && len >= 2) {
-		dch->rx_skb = nskb;
-		recv_Dchannel(dch);
-	}
-	if (bch) {
-		/* expand 16 bit sequence number to 32 bit sequence number */
-		rx_counter = hc->chan[channel].rx_counter;
-		if (((s16)(timebase - rx_counter)) >= 0) {
-			/* time has changed forward */
-			if (timebase >= (rx_counter & 0xffff))
-				rx_counter =
-					(rx_counter & 0xffff0000) | timebase;
-			else
-				rx_counter = ((rx_counter & 0xffff0000) + 0x10000)
-					| timebase;
-		} else {
-			/* time has changed backwards */
-			if (timebase < (rx_counter & 0xffff))
-				rx_counter =
-					(rx_counter & 0xffff0000) | timebase;
-			else
-				rx_counter = ((rx_counter & 0xffff0000) - 0x10000)
-					| timebase;
-		}
-		hc->chan[channel].rx_counter = rx_counter;
-
-#ifdef REORDER_DEBUG
-		if (hc->chan[channel].disorder_flag) {
-			swap(hc->chan[channel].disorder_skb, nskb);
-			swap(hc->chan[channel].disorder_cnt, rx_counter);
-		}
-		hc->chan[channel].disorder_flag ^= 1;
-		if (nskb)
-#endif
-			queue_ch_frame(&bch->ch, PH_DATA_IND, rx_counter, nskb);
-	}
-}
-
-
-/*
- * parse frame and extract channel data
- */
-static void
-l1oip_socket_parse(struct l1oip *hc, struct sockaddr_in *sin, u8 *buf, int len)
-{
-	u32			packet_id;
-	u8			channel;
-	u8			remotecodec;
-	u16			timebase;
-	int			m, mlen;
-	int			len_start = len; /* initial frame length */
-	struct dchannel		*dch = hc->chan[hc->d_idx].dch;
-
-	if (debug & DEBUG_L1OIP_MSG)
-		printk(KERN_DEBUG "%s: received frame, parsing... (%d)\n",
-		       __func__, len);
-
-	/* check length */
-	if (len < 1 + 1 + 2) {
-		printk(KERN_WARNING "%s: packet error - length %d below "
-		       "4 bytes\n", __func__, len);
-		return;
-	}
-
-	/* check version */
-	if (((*buf) >> 6) != L1OIP_VERSION) {
-		printk(KERN_WARNING "%s: packet error - unknown version %d\n",
-		       __func__, buf[0]>>6);
-		return;
-	}
-
-	/* check type */
-	if (((*buf) & 0x20) && !hc->pri) {
-		printk(KERN_WARNING "%s: packet error - received E1 packet "
-		       "on S0 interface\n", __func__);
-		return;
-	}
-	if (!((*buf) & 0x20) && hc->pri) {
-		printk(KERN_WARNING "%s: packet error - received S0 packet "
-		       "on E1 interface\n", __func__);
-		return;
-	}
-
-	/* get id flag */
-	packet_id = (*buf >> 4) & 1;
-
-	/* check coding */
-	remotecodec = (*buf) & 0x0f;
-	if (remotecodec > 3) {
-		printk(KERN_WARNING "%s: packet error - remotecodec %d "
-		       "unsupported\n", __func__, remotecodec);
-		return;
-	}
-	buf++;
-	len--;
-
-	/* check packet_id */
-	if (packet_id) {
-		if (!hc->id) {
-			printk(KERN_WARNING "%s: packet error - packet has id "
-			       "0x%x, but we have not\n", __func__, packet_id);
-			return;
-		}
-		if (len < 4) {
-			printk(KERN_WARNING "%s: packet error - packet too "
-			       "short for ID value\n", __func__);
-			return;
-		}
-		packet_id = (*buf++) << 24;
-		packet_id += (*buf++) << 16;
-		packet_id += (*buf++) << 8;
-		packet_id += (*buf++);
-		len -= 4;
-
-		if (packet_id != hc->id) {
-			printk(KERN_WARNING "%s: packet error - ID mismatch, "
-			       "got 0x%x, we 0x%x\n",
-			       __func__, packet_id, hc->id);
-			return;
-		}
-	} else {
-		if (hc->id) {
-			printk(KERN_WARNING "%s: packet error - packet has no "
-			       "ID, but we have\n", __func__);
-			return;
-		}
-	}
-
-multiframe:
-	if (len < 1) {
-		printk(KERN_WARNING "%s: packet error - packet too short, "
-		       "channel expected at position %d.\n",
-		       __func__, len-len_start + 1);
-		return;
-	}
-
-	/* get channel and multiframe flag */
-	channel = *buf & 0x7f;
-	m = *buf >> 7;
-	buf++;
-	len--;
-
-	/* check length on multiframe */
-	if (m) {
-		if (len < 1) {
-			printk(KERN_WARNING "%s: packet error - packet too "
-			       "short, length expected at position %d.\n",
-			       __func__, len_start - len - 1);
-			return;
-		}
-
-		mlen = *buf++;
-		len--;
-		if (mlen == 0)
-			mlen = 256;
-		if (len < mlen + 3) {
-			printk(KERN_WARNING "%s: packet error - length %d at "
-			       "position %d exceeds total length %d.\n",
-			       __func__, mlen, len_start-len - 1, len_start);
-			return;
-		}
-		if (len == mlen + 3) {
-			printk(KERN_WARNING "%s: packet error - length %d at "
-			       "position %d will not allow additional "
-			       "packet.\n",
-			       __func__, mlen, len_start-len + 1);
-			return;
-		}
-	} else
-		mlen = len - 2; /* single frame, subtract timebase */
-
-	if (len < 2) {
-		printk(KERN_WARNING "%s: packet error - packet too short, time "
-		       "base expected at position %d.\n",
-		       __func__, len-len_start + 1);
-		return;
-	}
-
-	/* get time base */
-	timebase = (*buf++) << 8;
-	timebase |= (*buf++);
-	len -= 2;
-
-	/* if inactive, we send up a PH_ACTIVATE and activate */
-	if (!test_bit(FLG_ACTIVE, &dch->Flags)) {
-		if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
-			printk(KERN_DEBUG "%s: interface become active due to "
-			       "received packet\n", __func__);
-		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
-		_queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-			    NULL, GFP_ATOMIC);
-	}
-
-	/* distribute packet */
-	l1oip_socket_recv(hc, remotecodec, channel, timebase, buf, mlen);
-	buf += mlen;
-	len -= mlen;
-
-	/* multiframe */
-	if (m)
-		goto multiframe;
-
-	/* restart timer */
-	if ((time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) ||
-	     !hc->timeout_on) &&
-	    !hc->shutdown) {
-		hc->timeout_on = 1;
-		mod_timer(&hc->timeout_tl, jiffies + L1OIP_TIMEOUT * HZ);
-	} else /* only adjust timer */
-		hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT * HZ;
-
-	/* if ip or source port changes */
-	if ((hc->sin_remote.sin_addr.s_addr != sin->sin_addr.s_addr)
-	    || (hc->sin_remote.sin_port != sin->sin_port)) {
-		if (debug & DEBUG_L1OIP_SOCKET)
-			printk(KERN_DEBUG "%s: remote address changes from "
-			       "0x%08x to 0x%08x (port %d to %d)\n", __func__,
-			       ntohl(hc->sin_remote.sin_addr.s_addr),
-			       ntohl(sin->sin_addr.s_addr),
-			       ntohs(hc->sin_remote.sin_port),
-			       ntohs(sin->sin_port));
-		hc->sin_remote.sin_addr.s_addr = sin->sin_addr.s_addr;
-		hc->sin_remote.sin_port = sin->sin_port;
-	}
-}
-
-
-/*
- * socket stuff
- */
-static int
-l1oip_socket_thread(void *data)
-{
-	struct l1oip *hc = (struct l1oip *)data;
-	int ret = 0;
-	struct sockaddr_in sin_rx;
-	struct kvec iov;
-	struct msghdr msg = {.msg_name = &sin_rx,
-			     .msg_namelen = sizeof(sin_rx)};
-	unsigned char *recvbuf;
-	size_t recvbuf_size = 1500;
-	int recvlen;
-	struct socket *socket = NULL;
-	DECLARE_COMPLETION_ONSTACK(wait);
-
-	/* allocate buffer memory */
-	recvbuf = kmalloc(recvbuf_size, GFP_KERNEL);
-	if (!recvbuf) {
-		printk(KERN_ERR "%s: Failed to alloc recvbuf.\n", __func__);
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	iov.iov_base = recvbuf;
-	iov.iov_len = recvbuf_size;
-
-	/* make daemon */
-	allow_signal(SIGTERM);
-
-	/* create socket */
-	if (sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &socket)) {
-		printk(KERN_ERR "%s: Failed to create socket.\n", __func__);
-		ret = -EIO;
-		goto fail;
-	}
-
-	/* set incoming address */
-	hc->sin_local.sin_family = AF_INET;
-	hc->sin_local.sin_addr.s_addr = INADDR_ANY;
-	hc->sin_local.sin_port = htons((unsigned short)hc->localport);
-
-	/* set outgoing address */
-	hc->sin_remote.sin_family = AF_INET;
-	hc->sin_remote.sin_addr.s_addr = htonl(hc->remoteip);
-	hc->sin_remote.sin_port = htons((unsigned short)hc->remoteport);
-
-	/* bind to incoming port */
-	if (socket->ops->bind(socket, (struct sockaddr_unsized *)&hc->sin_local,
-			      sizeof(hc->sin_local))) {
-		printk(KERN_ERR "%s: Failed to bind socket to port %d.\n",
-		       __func__, hc->localport);
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	/* check sk */
-	if (socket->sk == NULL) {
-		printk(KERN_ERR "%s: socket->sk == NULL\n", __func__);
-		ret = -EIO;
-		goto fail;
-	}
-
-	/* build send message */
-	hc->sendmsg.msg_name = &hc->sin_remote;
-	hc->sendmsg.msg_namelen = sizeof(hc->sin_remote);
-	hc->sendmsg.msg_control = NULL;
-	hc->sendmsg.msg_controllen = 0;
-
-	/* give away socket */
-	spin_lock(&hc->socket_lock);
-	hc->socket = socket;
-	spin_unlock(&hc->socket_lock);
-
-	/* read loop */
-	if (debug & DEBUG_L1OIP_SOCKET)
-		printk(KERN_DEBUG "%s: socket created and open\n",
-		       __func__);
-	while (!signal_pending(current)) {
-		iov_iter_kvec(&msg.msg_iter, ITER_DEST, &iov, 1, recvbuf_size);
-		recvlen = sock_recvmsg(socket, &msg, 0);
-		if (recvlen > 0) {
-			l1oip_socket_parse(hc, &sin_rx, recvbuf, recvlen);
-		} else {
-			if (debug & DEBUG_L1OIP_SOCKET)
-				printk(KERN_WARNING
-				       "%s: broken pipe on socket\n", __func__);
-		}
-	}
-
-	/* get socket back, check first if in use, maybe by send function */
-	spin_lock(&hc->socket_lock);
-	/* if hc->socket is NULL, it is in use until it is given back */
-	while (!hc->socket) {
-		spin_unlock(&hc->socket_lock);
-		schedule_timeout(HZ / 10);
-		spin_lock(&hc->socket_lock);
-	}
-	hc->socket = NULL;
-	spin_unlock(&hc->socket_lock);
-
-	if (debug & DEBUG_L1OIP_SOCKET)
-		printk(KERN_DEBUG "%s: socket thread terminating\n",
-		       __func__);
-
-fail:
-	/* free recvbuf */
-	kfree(recvbuf);
-
-	/* close socket */
-	if (socket)
-		sock_release(socket);
-
-	/* if we got killed, signal completion */
-	complete(&hc->socket_complete);
-	hc->socket_thread = NULL; /* show termination of thread */
-
-	if (debug & DEBUG_L1OIP_SOCKET)
-		printk(KERN_DEBUG "%s: socket thread terminated\n",
-		       __func__);
-	return ret;
-}
-
-static void
-l1oip_socket_close(struct l1oip *hc)
-{
-	struct dchannel *dch = hc->chan[hc->d_idx].dch;
-
-	/* kill thread */
-	if (hc->socket_thread) {
-		if (debug & DEBUG_L1OIP_SOCKET)
-			printk(KERN_DEBUG "%s: socket thread exists, "
-			       "killing...\n", __func__);
-		send_sig(SIGTERM, hc->socket_thread, 0);
-		wait_for_completion(&hc->socket_complete);
-	}
-
-	/* if active, we send up a PH_DEACTIVATE and deactivate */
-	if (test_bit(FLG_ACTIVE, &dch->Flags)) {
-		if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
-			printk(KERN_DEBUG "%s: interface become deactivated "
-			       "due to timeout\n", __func__);
-		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
-		_queue_data(&dch->dev.D, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			    NULL, GFP_ATOMIC);
-	}
-}
-
-static int
-l1oip_socket_open(struct l1oip *hc)
-{
-	/* in case of reopen, we need to close first */
-	l1oip_socket_close(hc);
-
-	init_completion(&hc->socket_complete);
-
-	/* create receive process */
-	hc->socket_thread = kthread_run(l1oip_socket_thread, hc, "l1oip_%s",
-					hc->name);
-	if (IS_ERR(hc->socket_thread)) {
-		int err = PTR_ERR(hc->socket_thread);
-		printk(KERN_ERR "%s: Failed (%d) to create socket process.\n",
-		       __func__, err);
-		hc->socket_thread = NULL;
-		sock_release(hc->socket);
-		return err;
-	}
-	if (debug & DEBUG_L1OIP_SOCKET)
-		printk(KERN_DEBUG "%s: socket thread created\n", __func__);
-
-	return 0;
-}
-
-
-static void
-l1oip_send_bh(struct work_struct *work)
-{
-	struct l1oip *hc = container_of(work, struct l1oip, workq);
-
-	if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
-		printk(KERN_DEBUG "%s: keepalive timer expired, sending empty "
-		       "frame on dchannel\n", __func__);
-
-	/* send an empty l1oip frame at D-channel */
-	l1oip_socket_send(hc, 0, hc->d_idx, 0, 0, NULL, 0);
-}
-
-
-/*
- * timer stuff
- */
-static void
-l1oip_keepalive(struct timer_list *t)
-{
-	struct l1oip *hc = timer_container_of(hc, t, keep_tl);
-
-	schedule_work(&hc->workq);
-}
-
-static void
-l1oip_timeout(struct timer_list *t)
-{
-	struct l1oip			*hc = timer_container_of(hc, t,
-								     timeout_tl);
-	struct dchannel		*dch = hc->chan[hc->d_idx].dch;
-
-	if (debug & DEBUG_L1OIP_MSG)
-		printk(KERN_DEBUG "%s: timeout timer expired, turn layer one "
-		       "down.\n", __func__);
-
-	hc->timeout_on = 0; /* state that timer must be initialized next time */
-
-	/* if timeout, we send up a PH_DEACTIVATE and deactivate */
-	if (test_bit(FLG_ACTIVE, &dch->Flags)) {
-		if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
-			printk(KERN_DEBUG "%s: interface become deactivated "
-			       "due to timeout\n", __func__);
-		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
-		_queue_data(&dch->dev.D, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			    NULL, GFP_ATOMIC);
-	}
-
-	/* if we have ondemand set, we remove ip address */
-	if (hc->ondemand) {
-		if (debug & DEBUG_L1OIP_MSG)
-			printk(KERN_DEBUG "%s: on demand causes ip address to "
-			       "be removed\n", __func__);
-		hc->sin_remote.sin_addr.s_addr = 0;
-	}
-}
-
-
-/*
- * message handling
- */
-static int
-handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
-	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
-	struct l1oip			*hc = dch->hw;
-	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
-	int			ret = -EINVAL;
-	int			l, ll;
-	unsigned char		*p;
-
-	switch (hh->prim) {
-	case PH_DATA_REQ:
-		if (skb->len < 1) {
-			printk(KERN_WARNING "%s: skb too small\n",
-			       __func__);
-			break;
-		}
-		if (skb->len > MAX_DFRAME_LEN_L1 || skb->len > L1OIP_MAX_LEN) {
-			printk(KERN_WARNING "%s: skb too large\n",
-			       __func__);
-			break;
-		}
-		/* send frame */
-		p = skb->data;
-		l = skb->len;
-		while (l) {
-			/*
-			 * This is technically bounded by L1OIP_MAX_PERFRAME but
-			 * MAX_DFRAME_LEN_L1 < L1OIP_MAX_PERFRAME
-			 */
-			ll = (l < MAX_DFRAME_LEN_L1) ? l : MAX_DFRAME_LEN_L1;
-			l1oip_socket_send(hc, 0, dch->slot, 0,
-					  hc->chan[dch->slot].tx_counter++, p, ll);
-			p += ll;
-			l -= ll;
-		}
-		skb_trim(skb, 0);
-		queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
-		return 0;
-	case PH_ACTIVATE_REQ:
-		if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
-			printk(KERN_DEBUG "%s: PH_ACTIVATE channel %d (1..%d)\n"
-			       , __func__, dch->slot, hc->b_num + 1);
-		skb_trim(skb, 0);
-		if (test_bit(FLG_ACTIVE, &dch->Flags))
-			queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb);
-		else
-			queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb);
-		return 0;
-	case PH_DEACTIVATE_REQ:
-		if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
-			printk(KERN_DEBUG "%s: PH_DEACTIVATE channel %d "
-			       "(1..%d)\n", __func__, dch->slot,
-			       hc->b_num + 1);
-		skb_trim(skb, 0);
-		if (test_bit(FLG_ACTIVE, &dch->Flags))
-			queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb);
-		else
-			queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb);
-		return 0;
-	}
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-static int
-channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
-{
-	int	ret = 0;
-	struct l1oip	*hc = dch->hw;
-
-	switch (cq->op) {
-	case MISDN_CTRL_GETOP:
-		cq->op = MISDN_CTRL_SETPEER | MISDN_CTRL_UNSETPEER
-			| MISDN_CTRL_GETPEER;
-		break;
-	case MISDN_CTRL_SETPEER:
-		hc->remoteip = (u32)cq->p1;
-		hc->remoteport = cq->p2 & 0xffff;
-		hc->localport = cq->p2 >> 16;
-		if (!hc->remoteport)
-			hc->remoteport = hc->localport;
-		if (debug & DEBUG_L1OIP_SOCKET)
-			printk(KERN_DEBUG "%s: got new ip address from user "
-			       "space.\n", __func__);
-		l1oip_socket_open(hc);
-		break;
-	case MISDN_CTRL_UNSETPEER:
-		if (debug & DEBUG_L1OIP_SOCKET)
-			printk(KERN_DEBUG "%s: removing ip address.\n",
-			       __func__);
-		hc->remoteip = 0;
-		l1oip_socket_open(hc);
-		break;
-	case MISDN_CTRL_GETPEER:
-		if (debug & DEBUG_L1OIP_SOCKET)
-			printk(KERN_DEBUG "%s: getting ip address.\n",
-			       __func__);
-		cq->p1 = hc->remoteip;
-		cq->p2 = hc->remoteport | (hc->localport << 16);
-		break;
-	default:
-		printk(KERN_WARNING "%s: unknown Op %x\n",
-		       __func__, cq->op);
-		ret = -EINVAL;
-		break;
-	}
-	return ret;
-}
-
-static int
-open_dchannel(struct l1oip *hc, struct dchannel *dch, struct channel_req *rq)
-{
-	if (debug & DEBUG_HW_OPEN)
-		printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,
-		       dch->dev.id, __builtin_return_address(0));
-	if (rq->protocol == ISDN_P_NONE)
-		return -EINVAL;
-	if ((dch->dev.D.protocol != ISDN_P_NONE) &&
-	    (dch->dev.D.protocol != rq->protocol)) {
-		if (debug & DEBUG_HW_OPEN)
-			printk(KERN_WARNING "%s: change protocol %x to %x\n",
-			       __func__, dch->dev.D.protocol, rq->protocol);
-	}
-	if (dch->dev.D.protocol != rq->protocol)
-		dch->dev.D.protocol = rq->protocol;
-
-	if (test_bit(FLG_ACTIVE, &dch->Flags)) {
-		_queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY,
-			    0, NULL, GFP_KERNEL);
-	}
-	rq->ch = &dch->dev.D;
-	if (!try_module_get(THIS_MODULE))
-		printk(KERN_WARNING "%s:cannot get module\n", __func__);
-	return 0;
-}
-
-static int
-open_bchannel(struct l1oip *hc, struct dchannel *dch, struct channel_req *rq)
-{
-	struct bchannel	*bch;
-	int		ch;
-
-	if (!test_channelmap(rq->adr.channel, dch->dev.channelmap))
-		return -EINVAL;
-	if (rq->protocol == ISDN_P_NONE)
-		return -EINVAL;
-	ch = rq->adr.channel; /* BRI: 1=B1 2=B2  PRI: 1..15,17.. */
-	bch = hc->chan[ch].bch;
-	if (!bch) {
-		printk(KERN_ERR "%s:internal error ch %d has no bch\n",
-		       __func__, ch);
-		return -EINVAL;
-	}
-	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
-		return -EBUSY; /* b-channel can be only open once */
-	bch->ch.protocol = rq->protocol;
-	rq->ch = &bch->ch;
-	if (!try_module_get(THIS_MODULE))
-		printk(KERN_WARNING "%s:cannot get module\n", __func__);
-	return 0;
-}
-
-static int
-l1oip_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
-{
-	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
-	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
-	struct l1oip			*hc = dch->hw;
-	struct channel_req	*rq;
-	int			err = 0;
-
-	if (dch->debug & DEBUG_HW)
-		printk(KERN_DEBUG "%s: cmd:%x %p\n",
-		       __func__, cmd, arg);
-	switch (cmd) {
-	case OPEN_CHANNEL:
-		rq = arg;
-		switch (rq->protocol) {
-		case ISDN_P_TE_S0:
-		case ISDN_P_NT_S0:
-			if (hc->pri) {
-				err = -EINVAL;
-				break;
-			}
-			err = open_dchannel(hc, dch, rq);
-			break;
-		case ISDN_P_TE_E1:
-		case ISDN_P_NT_E1:
-			if (!hc->pri) {
-				err = -EINVAL;
-				break;
-			}
-			err = open_dchannel(hc, dch, rq);
-			break;
-		default:
-			err = open_bchannel(hc, dch, rq);
-		}
-		break;
-	case CLOSE_CHANNEL:
-		if (debug & DEBUG_HW_OPEN)
-			printk(KERN_DEBUG "%s: dev(%d) close from %p\n",
-			       __func__, dch->dev.id,
-			       __builtin_return_address(0));
-		module_put(THIS_MODULE);
-		break;
-	case CONTROL_CHANNEL:
-		err = channel_dctrl(dch, arg);
-		break;
-	default:
-		if (dch->debug & DEBUG_HW)
-			printk(KERN_DEBUG "%s: unknown command %x\n",
-			       __func__, cmd);
-		err = -EINVAL;
-	}
-	return err;
-}
-
-static int
-handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct bchannel		*bch = container_of(ch, struct bchannel, ch);
-	struct l1oip			*hc = bch->hw;
-	int			ret = -EINVAL;
-	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
-	int			l, ll;
-	unsigned char		*p;
-
-	switch (hh->prim) {
-	case PH_DATA_REQ:
-		if (skb->len <= 0) {
-			printk(KERN_WARNING "%s: skb too small\n",
-			       __func__);
-			break;
-		}
-		if (skb->len > MAX_DFRAME_LEN_L1 || skb->len > L1OIP_MAX_LEN) {
-			printk(KERN_WARNING "%s: skb too large\n",
-			       __func__);
-			break;
-		}
-		/* check for AIS / ulaw-silence */
-		l = skb->len;
-		if (!memchr_inv(skb->data, 0xff, l)) {
-			if (debug & DEBUG_L1OIP_MSG)
-				printk(KERN_DEBUG "%s: got AIS, not sending, "
-				       "but counting\n", __func__);
-			hc->chan[bch->slot].tx_counter += l;
-			skb_trim(skb, 0);
-			queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
-			return 0;
-		}
-		/* check for silence */
-		l = skb->len;
-		if (!memchr_inv(skb->data, 0x2a, l)) {
-			if (debug & DEBUG_L1OIP_MSG)
-				printk(KERN_DEBUG "%s: got silence, not sending"
-				       ", but counting\n", __func__);
-			hc->chan[bch->slot].tx_counter += l;
-			skb_trim(skb, 0);
-			queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
-			return 0;
-		}
-
-		/* send frame */
-		p = skb->data;
-		l = skb->len;
-		while (l) {
-			/*
-			 * This is technically bounded by L1OIP_MAX_PERFRAME but
-			 * MAX_DFRAME_LEN_L1 < L1OIP_MAX_PERFRAME
-			 */
-			ll = (l < MAX_DFRAME_LEN_L1) ? l : MAX_DFRAME_LEN_L1;
-			l1oip_socket_send(hc, hc->codec, bch->slot, 0,
-					  hc->chan[bch->slot].tx_counter, p, ll);
-			hc->chan[bch->slot].tx_counter += ll;
-			p += ll;
-			l -= ll;
-		}
-		skb_trim(skb, 0);
-		queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
-		return 0;
-	case PH_ACTIVATE_REQ:
-		if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
-			printk(KERN_DEBUG "%s: PH_ACTIVATE channel %d (1..%d)\n"
-			       , __func__, bch->slot, hc->b_num + 1);
-		hc->chan[bch->slot].codecstate = 0;
-		test_and_set_bit(FLG_ACTIVE, &bch->Flags);
-		skb_trim(skb, 0);
-		queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb);
-		return 0;
-	case PH_DEACTIVATE_REQ:
-		if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
-			printk(KERN_DEBUG "%s: PH_DEACTIVATE channel %d "
-			       "(1..%d)\n", __func__, bch->slot,
-			       hc->b_num + 1);
-		test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
-		skb_trim(skb, 0);
-		queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb);
-		return 0;
-	}
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-static int
-channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
-{
-	int			ret = 0;
-	struct dsp_features	*features =
-		(struct dsp_features *)(*((u_long *)&cq->p1));
-
-	switch (cq->op) {
-	case MISDN_CTRL_GETOP:
-		cq->op = MISDN_CTRL_HW_FEATURES_OP;
-		break;
-	case MISDN_CTRL_HW_FEATURES: /* fill features structure */
-		if (debug & DEBUG_L1OIP_MSG)
-			printk(KERN_DEBUG "%s: HW_FEATURE request\n",
-			       __func__);
-		/* create confirm */
-		features->unclocked = 1;
-		features->unordered = 1;
-		break;
-	default:
-		printk(KERN_WARNING "%s: unknown Op %x\n",
-		       __func__, cq->op);
-		ret = -EINVAL;
-		break;
-	}
-	return ret;
-}
-
-static int
-l1oip_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
-{
-	struct bchannel	*bch = container_of(ch, struct bchannel, ch);
-	int		err = -EINVAL;
-
-	if (bch->debug & DEBUG_HW)
-		printk(KERN_DEBUG "%s: cmd:%x %p\n",
-		       __func__, cmd, arg);
-	switch (cmd) {
-	case CLOSE_CHANNEL:
-		test_and_clear_bit(FLG_OPEN, &bch->Flags);
-		test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
-		ch->protocol = ISDN_P_NONE;
-		ch->peer = NULL;
-		module_put(THIS_MODULE);
-		err = 0;
-		break;
-	case CONTROL_CHANNEL:
-		err = channel_bctrl(bch, arg);
-		break;
-	default:
-		printk(KERN_WARNING "%s: unknown prim(%x)\n",
-		       __func__, cmd);
-	}
-	return err;
-}
-
-
-/*
- * cleanup module and stack
- */
-static void
-release_card(struct l1oip *hc)
-{
-	int	ch;
-
-	hc->shutdown = true;
-
-	timer_shutdown_sync(&hc->keep_tl);
-	timer_shutdown_sync(&hc->timeout_tl);
-
-	cancel_work_sync(&hc->workq);
-
-	if (hc->socket_thread)
-		l1oip_socket_close(hc);
-
-	if (hc->registered && hc->chan[hc->d_idx].dch)
-		mISDN_unregister_device(&hc->chan[hc->d_idx].dch->dev);
-	for (ch = 0; ch < 128; ch++) {
-		if (hc->chan[ch].dch) {
-			mISDN_freedchannel(hc->chan[ch].dch);
-			kfree(hc->chan[ch].dch);
-		}
-		if (hc->chan[ch].bch) {
-			mISDN_freebchannel(hc->chan[ch].bch);
-			kfree(hc->chan[ch].bch);
-#ifdef REORDER_DEBUG
-			dev_kfree_skb(hc->chan[ch].disorder_skb);
-#endif
-		}
-	}
-
-	spin_lock(&l1oip_lock);
-	list_del(&hc->list);
-	spin_unlock(&l1oip_lock);
-
-	kfree(hc);
-}
-
-static void
-l1oip_cleanup(void)
-{
-	struct l1oip *hc, *next;
-
-	list_for_each_entry_safe(hc, next, &l1oip_ilist, list)
-		release_card(hc);
-
-	l1oip_4bit_free();
-}
-
-
-/*
- * module and stack init
- */
-static int
-init_card(struct l1oip *hc, int pri, int bundle)
-{
-	struct dchannel	*dch;
-	struct bchannel	*bch;
-	int		ret;
-	int		i, ch;
-
-	spin_lock_init(&hc->socket_lock);
-	hc->idx = l1oip_cnt;
-	hc->pri = pri;
-	hc->d_idx = pri ? 16 : 3;
-	hc->b_num = pri ? 30 : 2;
-	hc->bundle = bundle;
-	if (hc->pri)
-		sprintf(hc->name, "l1oip-e1.%d", l1oip_cnt + 1);
-	else
-		sprintf(hc->name, "l1oip-s0.%d", l1oip_cnt + 1);
-
-	switch (codec[l1oip_cnt]) {
-	case 0: /* as is */
-	case 1: /* alaw */
-	case 2: /* ulaw */
-	case 3: /* 4bit */
-		break;
-	default:
-		printk(KERN_ERR "Codec(%d) not supported.\n",
-		       codec[l1oip_cnt]);
-		return -EINVAL;
-	}
-	hc->codec = codec[l1oip_cnt];
-	if (debug & DEBUG_L1OIP_INIT)
-		printk(KERN_DEBUG "%s: using codec %d\n",
-		       __func__, hc->codec);
-
-	if (id[l1oip_cnt] == 0) {
-		printk(KERN_WARNING "Warning: No 'id' value given or "
-		       "0, this is highly unsecure. Please use 32 "
-		       "bit random number 0x...\n");
-	}
-	hc->id = id[l1oip_cnt];
-	if (debug & DEBUG_L1OIP_INIT)
-		printk(KERN_DEBUG "%s: using id 0x%x\n", __func__, hc->id);
-
-	hc->ondemand = ondemand[l1oip_cnt];
-	if (hc->ondemand && !hc->id) {
-		printk(KERN_ERR "%s: ondemand option only allowed in "
-		       "conjunction with non 0 ID\n", __func__);
-		return -EINVAL;
-	}
-
-	if (limit[l1oip_cnt])
-		hc->b_num = limit[l1oip_cnt];
-	if (!pri && hc->b_num > 2) {
-		printk(KERN_ERR "Maximum limit for BRI interface is 2 "
-		       "channels.\n");
-		return -EINVAL;
-	}
-	if (pri && hc->b_num > 126) {
-		printk(KERN_ERR "Maximum limit for PRI interface is 126 "
-		       "channels.\n");
-		return -EINVAL;
-	}
-	if (pri && hc->b_num > 30) {
-		printk(KERN_WARNING "Maximum limit for BRI interface is 30 "
-		       "channels.\n");
-		printk(KERN_WARNING "Your selection of %d channels must be "
-		       "supported by application.\n", hc->limit);
-	}
-
-	hc->remoteip = ip[l1oip_cnt << 2] << 24
-		| ip[(l1oip_cnt << 2) + 1] << 16
-		| ip[(l1oip_cnt << 2) + 2] << 8
-		| ip[(l1oip_cnt << 2) + 3];
-	hc->localport = port[l1oip_cnt]?:(L1OIP_DEFAULTPORT + l1oip_cnt);
-	if (remoteport[l1oip_cnt])
-		hc->remoteport = remoteport[l1oip_cnt];
-	else
-		hc->remoteport = hc->localport;
-	if (debug & DEBUG_L1OIP_INIT)
-		printk(KERN_DEBUG "%s: using local port %d remote ip "
-		       "%d.%d.%d.%d port %d ondemand %d\n", __func__,
-		       hc->localport, hc->remoteip >> 24,
-		       (hc->remoteip >> 16) & 0xff,
-		       (hc->remoteip >> 8) & 0xff, hc->remoteip & 0xff,
-		       hc->remoteport, hc->ondemand);
-
-	dch = kzalloc_obj(struct dchannel);
-	if (!dch)
-		return -ENOMEM;
-	dch->debug = debug;
-	mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, NULL);
-	dch->hw = hc;
-	if (pri)
-		dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1);
-	else
-		dch->dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
-	dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
-	dch->dev.D.send = handle_dmsg;
-	dch->dev.D.ctrl = l1oip_dctrl;
-	dch->dev.nrbchan = hc->b_num;
-	dch->slot = hc->d_idx;
-	hc->chan[hc->d_idx].dch = dch;
-	i = 1;
-	for (ch = 0; ch < dch->dev.nrbchan; ch++) {
-		if (ch == 15)
-			i++;
-		bch = kzalloc_obj(struct bchannel);
-		if (!bch) {
-			printk(KERN_ERR "%s: no memory for bchannel\n",
-			       __func__);
-			return -ENOMEM;
-		}
-		bch->nr = i + ch;
-		bch->slot = i + ch;
-		bch->debug = debug;
-		mISDN_initbchannel(bch, MAX_DATA_MEM, 0);
-		bch->hw = hc;
-		bch->ch.send = handle_bmsg;
-		bch->ch.ctrl = l1oip_bctrl;
-		bch->ch.nr = i + ch;
-		list_add(&bch->ch.list, &dch->dev.bchannels);
-		hc->chan[i + ch].bch = bch;
-		set_channelmap(bch->nr, dch->dev.channelmap);
-	}
-	/* TODO: create a parent device for this driver */
-	ret = mISDN_register_device(&dch->dev, NULL, hc->name);
-	if (ret)
-		return ret;
-	hc->registered = 1;
-
-	if (debug & DEBUG_L1OIP_INIT)
-		printk(KERN_DEBUG "%s: Setting up network card(%d)\n",
-		       __func__, l1oip_cnt + 1);
-	ret = l1oip_socket_open(hc);
-	if (ret)
-		return ret;
-
-	timer_setup(&hc->keep_tl, l1oip_keepalive, 0);
-	hc->keep_tl.expires = jiffies + 2 * HZ; /* two seconds first time */
-	add_timer(&hc->keep_tl);
-
-	timer_setup(&hc->timeout_tl, l1oip_timeout, 0);
-	hc->timeout_on = 0; /* state that we have timer off */
-
-	return 0;
-}
-
-static int __init
-l1oip_init(void)
-{
-	int		pri, bundle;
-	struct l1oip		*hc;
-	int		ret;
-
-	printk(KERN_INFO "mISDN: Layer-1-over-IP driver Rev. %s\n",
-	       l1oip_revision);
-
-	if (l1oip_4bit_alloc(ulaw))
-		return -ENOMEM;
-
-	l1oip_cnt = 0;
-	while (l1oip_cnt < MAX_CARDS && type[l1oip_cnt]) {
-		switch (type[l1oip_cnt] & 0xff) {
-		case 1:
-			pri = 0;
-			bundle = 0;
-			break;
-		case 2:
-			pri = 1;
-			bundle = 0;
-			break;
-		case 3:
-			pri = 0;
-			bundle = 1;
-			break;
-		case 4:
-			pri = 1;
-			bundle = 1;
-			break;
-		default:
-			printk(KERN_ERR "Card type(%d) not supported.\n",
-			       type[l1oip_cnt] & 0xff);
-			l1oip_cleanup();
-			return -EINVAL;
-		}
-
-		if (debug & DEBUG_L1OIP_INIT)
-			printk(KERN_DEBUG "%s: interface %d is %s with %s.\n",
-			       __func__, l1oip_cnt, pri ? "PRI" : "BRI",
-			       bundle ? "bundled IP packet for all B-channels" :
-			       "separate IP packets for every B-channel");
-
-		hc = kzalloc_obj(struct l1oip, GFP_ATOMIC);
-		if (!hc) {
-			printk(KERN_ERR "No kmem for L1-over-IP driver.\n");
-			l1oip_cleanup();
-			return -ENOMEM;
-		}
-		INIT_WORK(&hc->workq, (void *)l1oip_send_bh);
-
-		spin_lock(&l1oip_lock);
-		list_add_tail(&hc->list, &l1oip_ilist);
-		spin_unlock(&l1oip_lock);
-
-		ret = init_card(hc, pri, bundle);
-		if (ret) {
-			l1oip_cleanup();
-			return ret;
-		}
-
-		l1oip_cnt++;
-	}
-	printk(KERN_INFO "%d virtual devices registered\n", l1oip_cnt);
-	return 0;
-}
-
-module_init(l1oip_init);
-module_exit(l1oip_cleanup);
diff --git a/drivers/isdn/mISDN/layer1.c b/drivers/isdn/mISDN/layer1.c
deleted file mode 100644
index 3fbc170acf9a..000000000000
--- a/drivers/isdn/mISDN/layer1.c
+++ /dev/null
@@ -1,415 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *
- * Author	Karsten Keil <kkeil@novell.com>
- *
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- */
-
-
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/mISDNhw.h>
-#include "core.h"
-#include "layer1.h"
-#include "fsm.h"
-
-static u_int *debug;
-
-struct layer1 {
-	u_long Flags;
-	struct FsmInst l1m;
-	struct FsmTimer timer3;
-	struct FsmTimer timerX;
-	int delay;
-	int t3_value;
-	struct dchannel *dch;
-	dchannel_l1callback *dcb;
-};
-
-#define TIMER3_DEFAULT_VALUE	7000
-
-static
-struct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL};
-
-enum {
-	ST_L1_F2,
-	ST_L1_F3,
-	ST_L1_F4,
-	ST_L1_F5,
-	ST_L1_F6,
-	ST_L1_F7,
-	ST_L1_F8,
-};
-
-#define L1S_STATE_COUNT (ST_L1_F8 + 1)
-
-static char *strL1SState[] =
-{
-	"ST_L1_F2",
-	"ST_L1_F3",
-	"ST_L1_F4",
-	"ST_L1_F5",
-	"ST_L1_F6",
-	"ST_L1_F7",
-	"ST_L1_F8",
-};
-
-enum {
-	EV_PH_ACTIVATE,
-	EV_PH_DEACTIVATE,
-	EV_RESET_IND,
-	EV_DEACT_CNF,
-	EV_DEACT_IND,
-	EV_POWER_UP,
-	EV_ANYSIG_IND,
-	EV_INFO2_IND,
-	EV_INFO4_IND,
-	EV_TIMER_DEACT,
-	EV_TIMER_ACT,
-	EV_TIMER3,
-};
-
-#define L1_EVENT_COUNT (EV_TIMER3 + 1)
-
-static char *strL1Event[] =
-{
-	"EV_PH_ACTIVATE",
-	"EV_PH_DEACTIVATE",
-	"EV_RESET_IND",
-	"EV_DEACT_CNF",
-	"EV_DEACT_IND",
-	"EV_POWER_UP",
-	"EV_ANYSIG_IND",
-	"EV_INFO2_IND",
-	"EV_INFO4_IND",
-	"EV_TIMER_DEACT",
-	"EV_TIMER_ACT",
-	"EV_TIMER3",
-};
-
-static void
-l1m_debug(struct FsmInst *fi, char *fmt, ...)
-{
-	struct layer1 *l1 = fi->userdata;
-	struct va_format vaf;
-	va_list va;
-
-	va_start(va, fmt);
-
-	vaf.fmt = fmt;
-	vaf.va = &va;
-
-	printk(KERN_DEBUG "%s: %pV\n", dev_name(&l1->dch->dev.dev), &vaf);
-
-	va_end(va);
-}
-
-static void
-l1_reset(struct FsmInst *fi, int event, void *arg)
-{
-	mISDN_FsmChangeState(fi, ST_L1_F3);
-}
-
-static void
-l1_deact_cnf(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer1 *l1 = fi->userdata;
-
-	mISDN_FsmChangeState(fi, ST_L1_F3);
-	if (test_bit(FLG_L1_ACTIVATING, &l1->Flags))
-		l1->dcb(l1->dch, HW_POWERUP_REQ);
-}
-
-static void
-l1_deact_req_s(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer1 *l1 = fi->userdata;
-
-	mISDN_FsmChangeState(fi, ST_L1_F3);
-	mISDN_FsmRestartTimer(&l1->timerX, 550, EV_TIMER_DEACT, NULL, 2);
-	test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags);
-}
-
-static void
-l1_power_up_s(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer1 *l1 = fi->userdata;
-
-	if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) {
-		mISDN_FsmChangeState(fi, ST_L1_F4);
-		l1->dcb(l1->dch, INFO3_P8);
-	} else
-		mISDN_FsmChangeState(fi, ST_L1_F3);
-}
-
-static void
-l1_go_F5(struct FsmInst *fi, int event, void *arg)
-{
-	mISDN_FsmChangeState(fi, ST_L1_F5);
-}
-
-static void
-l1_go_F8(struct FsmInst *fi, int event, void *arg)
-{
-	mISDN_FsmChangeState(fi, ST_L1_F8);
-}
-
-static void
-l1_info2_ind(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer1 *l1 = fi->userdata;
-
-	mISDN_FsmChangeState(fi, ST_L1_F6);
-	l1->dcb(l1->dch, INFO3_P8);
-}
-
-static void
-l1_info4_ind(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer1 *l1 = fi->userdata;
-
-	mISDN_FsmChangeState(fi, ST_L1_F7);
-	l1->dcb(l1->dch, INFO3_P8);
-	if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags))
-		mISDN_FsmDelTimer(&l1->timerX, 4);
-	if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) {
-		if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags))
-			mISDN_FsmDelTimer(&l1->timer3, 3);
-		mISDN_FsmRestartTimer(&l1->timerX, 110, EV_TIMER_ACT, NULL, 2);
-		test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags);
-	}
-}
-
-static void
-l1_timer3(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer1 *l1 = fi->userdata;
-
-	test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags);
-	if (test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags)) {
-		if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags))
-			l1->dcb(l1->dch, HW_D_NOBLOCKED);
-		l1->dcb(l1->dch, PH_DEACTIVATE_IND);
-	}
-	if (l1->l1m.state != ST_L1_F6) {
-		mISDN_FsmChangeState(fi, ST_L1_F3);
-		/* do not force anything here, we need send INFO 0 */
-	}
-}
-
-static void
-l1_timer_act(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer1 *l1 = fi->userdata;
-
-	test_and_clear_bit(FLG_L1_ACTTIMER, &l1->Flags);
-	test_and_set_bit(FLG_L1_ACTIVATED, &l1->Flags);
-	l1->dcb(l1->dch, PH_ACTIVATE_IND);
-}
-
-static void
-l1_timer_deact(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer1 *l1 = fi->userdata;
-
-	test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags);
-	test_and_clear_bit(FLG_L1_ACTIVATED, &l1->Flags);
-	if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags))
-		l1->dcb(l1->dch, HW_D_NOBLOCKED);
-	l1->dcb(l1->dch, PH_DEACTIVATE_IND);
-	l1->dcb(l1->dch, HW_DEACT_REQ);
-}
-
-static void
-l1_activate_s(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer1 *l1 = fi->userdata;
-
-	mISDN_FsmRestartTimer(&l1->timer3, l1->t3_value, EV_TIMER3, NULL, 2);
-	test_and_set_bit(FLG_L1_T3RUN, &l1->Flags);
-	/* Tell HW to send INFO 1 */
-	l1->dcb(l1->dch, HW_RESET_REQ);
-}
-
-static void
-l1_activate_no(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer1 *l1 = fi->userdata;
-
-	if ((!test_bit(FLG_L1_DEACTTIMER, &l1->Flags)) &&
-	    (!test_bit(FLG_L1_T3RUN, &l1->Flags))) {
-		test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags);
-		if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags))
-			l1->dcb(l1->dch, HW_D_NOBLOCKED);
-		l1->dcb(l1->dch, PH_DEACTIVATE_IND);
-	}
-}
-
-static struct FsmNode L1SFnList[] =
-{
-	{ST_L1_F3, EV_PH_ACTIVATE, l1_activate_s},
-	{ST_L1_F6, EV_PH_ACTIVATE, l1_activate_no},
-	{ST_L1_F8, EV_PH_ACTIVATE, l1_activate_no},
-	{ST_L1_F3, EV_RESET_IND, l1_reset},
-	{ST_L1_F4, EV_RESET_IND, l1_reset},
-	{ST_L1_F5, EV_RESET_IND, l1_reset},
-	{ST_L1_F6, EV_RESET_IND, l1_reset},
-	{ST_L1_F7, EV_RESET_IND, l1_reset},
-	{ST_L1_F8, EV_RESET_IND, l1_reset},
-	{ST_L1_F3, EV_DEACT_CNF, l1_deact_cnf},
-	{ST_L1_F4, EV_DEACT_CNF, l1_deact_cnf},
-	{ST_L1_F5, EV_DEACT_CNF, l1_deact_cnf},
-	{ST_L1_F6, EV_DEACT_CNF, l1_deact_cnf},
-	{ST_L1_F7, EV_DEACT_CNF, l1_deact_cnf},
-	{ST_L1_F8, EV_DEACT_CNF, l1_deact_cnf},
-	{ST_L1_F6, EV_DEACT_IND, l1_deact_req_s},
-	{ST_L1_F7, EV_DEACT_IND, l1_deact_req_s},
-	{ST_L1_F8, EV_DEACT_IND, l1_deact_req_s},
-	{ST_L1_F3, EV_POWER_UP,  l1_power_up_s},
-	{ST_L1_F4, EV_ANYSIG_IND, l1_go_F5},
-	{ST_L1_F6, EV_ANYSIG_IND, l1_go_F8},
-	{ST_L1_F7, EV_ANYSIG_IND, l1_go_F8},
-	{ST_L1_F3, EV_INFO2_IND, l1_info2_ind},
-	{ST_L1_F4, EV_INFO2_IND, l1_info2_ind},
-	{ST_L1_F5, EV_INFO2_IND, l1_info2_ind},
-	{ST_L1_F7, EV_INFO2_IND, l1_info2_ind},
-	{ST_L1_F8, EV_INFO2_IND, l1_info2_ind},
-	{ST_L1_F3, EV_INFO4_IND, l1_info4_ind},
-	{ST_L1_F4, EV_INFO4_IND, l1_info4_ind},
-	{ST_L1_F5, EV_INFO4_IND, l1_info4_ind},
-	{ST_L1_F6, EV_INFO4_IND, l1_info4_ind},
-	{ST_L1_F8, EV_INFO4_IND, l1_info4_ind},
-	{ST_L1_F3, EV_TIMER3, l1_timer3},
-	{ST_L1_F4, EV_TIMER3, l1_timer3},
-	{ST_L1_F5, EV_TIMER3, l1_timer3},
-	{ST_L1_F6, EV_TIMER3, l1_timer3},
-	{ST_L1_F8, EV_TIMER3, l1_timer3},
-	{ST_L1_F7, EV_TIMER_ACT, l1_timer_act},
-	{ST_L1_F3, EV_TIMER_DEACT, l1_timer_deact},
-	{ST_L1_F4, EV_TIMER_DEACT, l1_timer_deact},
-	{ST_L1_F5, EV_TIMER_DEACT, l1_timer_deact},
-	{ST_L1_F6, EV_TIMER_DEACT, l1_timer_deact},
-	{ST_L1_F7, EV_TIMER_DEACT, l1_timer_deact},
-	{ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact},
-};
-
-static void
-release_l1(struct layer1 *l1) {
-	mISDN_FsmDelTimer(&l1->timerX, 0);
-	mISDN_FsmDelTimer(&l1->timer3, 0);
-	if (l1->dch)
-		l1->dch->l1 = NULL;
-	module_put(THIS_MODULE);
-	kfree(l1);
-}
-
-int
-l1_event(struct layer1 *l1, u_int event)
-{
-	int		err = 0;
-
-	if (!l1)
-		return -EINVAL;
-	switch (event) {
-	case HW_RESET_IND:
-		mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL);
-		break;
-	case HW_DEACT_IND:
-		mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL);
-		break;
-	case HW_POWERUP_IND:
-		mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL);
-		break;
-	case HW_DEACT_CNF:
-		mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL);
-		break;
-	case ANYSIGNAL:
-		mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL);
-		break;
-	case LOSTFRAMING:
-		mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL);
-		break;
-	case INFO2:
-		mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL);
-		break;
-	case INFO4_P8:
-		mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL);
-		break;
-	case INFO4_P10:
-		mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL);
-		break;
-	case PH_ACTIVATE_REQ:
-		if (test_bit(FLG_L1_ACTIVATED, &l1->Flags))
-			l1->dcb(l1->dch, PH_ACTIVATE_IND);
-		else {
-			test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags);
-			mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL);
-		}
-		break;
-	case CLOSE_CHANNEL:
-		release_l1(l1);
-		break;
-	default:
-		if ((event & ~HW_TIMER3_VMASK) == HW_TIMER3_VALUE) {
-			int val = event & HW_TIMER3_VMASK;
-
-			if (val < 5)
-				val = 5;
-			if (val > 30)
-				val = 30;
-			l1->t3_value = val;
-			break;
-		}
-		if (*debug & DEBUG_L1)
-			printk(KERN_DEBUG "%s %x unhandled\n",
-			       __func__, event);
-		err = -EINVAL;
-	}
-	return err;
-}
-EXPORT_SYMBOL(l1_event);
-
-int
-create_l1(struct dchannel *dch, dchannel_l1callback *dcb) {
-	struct layer1	*nl1;
-
-	nl1 = kzalloc_obj(struct layer1, GFP_ATOMIC);
-	if (!nl1) {
-		printk(KERN_ERR "kmalloc struct layer1 failed\n");
-		return -ENOMEM;
-	}
-	nl1->l1m.fsm = &l1fsm_s;
-	nl1->l1m.state = ST_L1_F3;
-	nl1->Flags = 0;
-	nl1->t3_value = TIMER3_DEFAULT_VALUE;
-	nl1->l1m.debug = *debug & DEBUG_L1_FSM;
-	nl1->l1m.userdata = nl1;
-	nl1->l1m.userint = 0;
-	nl1->l1m.printdebug = l1m_debug;
-	nl1->dch = dch;
-	nl1->dcb = dcb;
-	mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer3);
-	mISDN_FsmInitTimer(&nl1->l1m, &nl1->timerX);
-	__module_get(THIS_MODULE);
-	dch->l1 = nl1;
-	return 0;
-}
-EXPORT_SYMBOL(create_l1);
-
-int
-Isdnl1_Init(u_int *deb)
-{
-	debug = deb;
-	l1fsm_s.state_count = L1S_STATE_COUNT;
-	l1fsm_s.event_count = L1_EVENT_COUNT;
-	l1fsm_s.strEvent = strL1Event;
-	l1fsm_s.strState = strL1SState;
-	return mISDN_FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList));
-}
-
-void
-Isdnl1_cleanup(void)
-{
-	mISDN_FsmFree(&l1fsm_s);
-}
diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c
deleted file mode 100644
index b75869c9f78f..000000000000
--- a/drivers/isdn/mISDN/layer2.c
+++ /dev/null
@@ -1,2266 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *
- * Author	Karsten Keil <kkeil@novell.com>
- *
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- */
-
-#include <linux/mISDNif.h>
-#include <linux/slab.h>
-#include "core.h"
-#include "fsm.h"
-#include "layer2.h"
-
-static u_int *debug;
-
-static
-struct Fsm l2fsm = {NULL, 0, 0, NULL, NULL};
-
-static char *strL2State[] =
-{
-	"ST_L2_1",
-	"ST_L2_2",
-	"ST_L2_3",
-	"ST_L2_4",
-	"ST_L2_5",
-	"ST_L2_6",
-	"ST_L2_7",
-	"ST_L2_8",
-};
-
-enum {
-	EV_L2_UI,
-	EV_L2_SABME,
-	EV_L2_DISC,
-	EV_L2_DM,
-	EV_L2_UA,
-	EV_L2_FRMR,
-	EV_L2_SUPER,
-	EV_L2_I,
-	EV_L2_DL_DATA,
-	EV_L2_ACK_PULL,
-	EV_L2_DL_UNITDATA,
-	EV_L2_DL_ESTABLISH_REQ,
-	EV_L2_DL_RELEASE_REQ,
-	EV_L2_MDL_ASSIGN,
-	EV_L2_MDL_REMOVE,
-	EV_L2_MDL_ERROR,
-	EV_L1_DEACTIVATE,
-	EV_L2_T200,
-	EV_L2_T203,
-	EV_L2_T200I,
-	EV_L2_T203I,
-	EV_L2_SET_OWN_BUSY,
-	EV_L2_CLEAR_OWN_BUSY,
-	EV_L2_FRAME_ERROR,
-};
-
-#define L2_EVENT_COUNT (EV_L2_FRAME_ERROR + 1)
-
-static char *strL2Event[] =
-{
-	"EV_L2_UI",
-	"EV_L2_SABME",
-	"EV_L2_DISC",
-	"EV_L2_DM",
-	"EV_L2_UA",
-	"EV_L2_FRMR",
-	"EV_L2_SUPER",
-	"EV_L2_I",
-	"EV_L2_DL_DATA",
-	"EV_L2_ACK_PULL",
-	"EV_L2_DL_UNITDATA",
-	"EV_L2_DL_ESTABLISH_REQ",
-	"EV_L2_DL_RELEASE_REQ",
-	"EV_L2_MDL_ASSIGN",
-	"EV_L2_MDL_REMOVE",
-	"EV_L2_MDL_ERROR",
-	"EV_L1_DEACTIVATE",
-	"EV_L2_T200",
-	"EV_L2_T203",
-	"EV_L2_T200I",
-	"EV_L2_T203I",
-	"EV_L2_SET_OWN_BUSY",
-	"EV_L2_CLEAR_OWN_BUSY",
-	"EV_L2_FRAME_ERROR",
-};
-
-static void
-l2m_debug(struct FsmInst *fi, char *fmt, ...)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct va_format vaf;
-	va_list va;
-
-	if (!(*debug & DEBUG_L2_FSM))
-		return;
-
-	va_start(va, fmt);
-
-	vaf.fmt = fmt;
-	vaf.va = &va;
-
-	printk(KERN_DEBUG "%s l2 (sapi %d tei %d): %pV\n",
-	       mISDNDevName4ch(&l2->ch), l2->sapi, l2->tei, &vaf);
-
-	va_end(va);
-}
-
-inline u_int
-l2headersize(struct layer2 *l2, int ui)
-{
-	return ((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) +
-		(test_bit(FLG_LAPD, &l2->flag) ? 2 : 1);
-}
-
-inline u_int
-l2addrsize(struct layer2 *l2)
-{
-	return test_bit(FLG_LAPD, &l2->flag) ? 2 : 1;
-}
-
-static u_int
-l2_newid(struct layer2 *l2)
-{
-	u_int	id;
-
-	id = l2->next_id++;
-	if (id == 0x7fff)
-		l2->next_id = 1;
-	id <<= 16;
-	id |= l2->tei << 8;
-	id |= l2->sapi;
-	return id;
-}
-
-static void
-l2up(struct layer2 *l2, u_int prim, struct sk_buff *skb)
-{
-	int	err;
-
-	if (!l2->up)
-		return;
-	mISDN_HEAD_PRIM(skb) = prim;
-	mISDN_HEAD_ID(skb) = (l2->ch.nr << 16) | l2->ch.addr;
-	err = l2->up->send(l2->up, skb);
-	if (err) {
-		printk(KERN_WARNING "%s: dev %s err=%d\n", __func__,
-		       mISDNDevName4ch(&l2->ch), err);
-		dev_kfree_skb(skb);
-	}
-}
-
-static void
-l2up_create(struct layer2 *l2, u_int prim, int len, void *arg)
-{
-	struct sk_buff	*skb;
-	struct mISDNhead *hh;
-	int		err;
-
-	if (!l2->up)
-		return;
-	skb = mI_alloc_skb(len, GFP_ATOMIC);
-	if (!skb)
-		return;
-	hh = mISDN_HEAD_P(skb);
-	hh->prim = prim;
-	hh->id = (l2->ch.nr << 16) | l2->ch.addr;
-	if (len)
-		skb_put_data(skb, arg, len);
-	err = l2->up->send(l2->up, skb);
-	if (err) {
-		printk(KERN_WARNING "%s: dev %s err=%d\n", __func__,
-		       mISDNDevName4ch(&l2->ch), err);
-		dev_kfree_skb(skb);
-	}
-}
-
-static int
-l2down_skb(struct layer2 *l2, struct sk_buff *skb) {
-	int ret;
-
-	ret = l2->ch.recv(l2->ch.peer, skb);
-	if (ret && (*debug & DEBUG_L2_RECV))
-		printk(KERN_DEBUG "l2down_skb: dev %s ret(%d)\n",
-		       mISDNDevName4ch(&l2->ch), ret);
-	return ret;
-}
-
-static int
-l2down_raw(struct layer2 *l2, struct sk_buff *skb)
-{
-	struct mISDNhead *hh = mISDN_HEAD_P(skb);
-
-	if (hh->prim == PH_DATA_REQ) {
-		if (test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) {
-			skb_queue_tail(&l2->down_queue, skb);
-			return 0;
-		}
-		l2->down_id = mISDN_HEAD_ID(skb);
-	}
-	return l2down_skb(l2, skb);
-}
-
-static int
-l2down(struct layer2 *l2, u_int prim, u_int id, struct sk_buff *skb)
-{
-	struct mISDNhead *hh = mISDN_HEAD_P(skb);
-
-	hh->prim = prim;
-	hh->id = id;
-	return l2down_raw(l2, skb);
-}
-
-static int
-l2down_create(struct layer2 *l2, u_int prim, u_int id, int len, void *arg)
-{
-	struct sk_buff	*skb;
-	int		err;
-	struct mISDNhead *hh;
-
-	skb = mI_alloc_skb(len, GFP_ATOMIC);
-	if (!skb)
-		return -ENOMEM;
-	hh = mISDN_HEAD_P(skb);
-	hh->prim = prim;
-	hh->id = id;
-	if (len)
-		skb_put_data(skb, arg, len);
-	err = l2down_raw(l2, skb);
-	if (err)
-		dev_kfree_skb(skb);
-	return err;
-}
-
-static int
-ph_data_confirm(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb) {
-	struct sk_buff *nskb = skb;
-	int ret = -EAGAIN;
-
-	if (test_bit(FLG_L1_NOTREADY, &l2->flag)) {
-		if (hh->id == l2->down_id) {
-			nskb = skb_dequeue(&l2->down_queue);
-			if (nskb) {
-				l2->down_id = mISDN_HEAD_ID(nskb);
-				if (l2down_skb(l2, nskb)) {
-					dev_kfree_skb(nskb);
-					l2->down_id = MISDN_ID_NONE;
-				}
-			} else
-				l2->down_id = MISDN_ID_NONE;
-			if (ret) {
-				dev_kfree_skb(skb);
-				ret = 0;
-			}
-			if (l2->down_id == MISDN_ID_NONE) {
-				test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
-				mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);
-			}
-		}
-	}
-	if (!test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) {
-		nskb = skb_dequeue(&l2->down_queue);
-		if (nskb) {
-			l2->down_id = mISDN_HEAD_ID(nskb);
-			if (l2down_skb(l2, nskb)) {
-				dev_kfree_skb(nskb);
-				l2->down_id = MISDN_ID_NONE;
-				test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
-			}
-		} else
-			test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
-	}
-	return ret;
-}
-
-static void
-l2_timeout(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb;
-	struct mISDNhead *hh;
-
-	skb = mI_alloc_skb(0, GFP_ATOMIC);
-	if (!skb) {
-		printk(KERN_WARNING "%s: L2(%d,%d) nr:%x timer %s no skb\n",
-		       mISDNDevName4ch(&l2->ch), l2->sapi, l2->tei,
-		       l2->ch.nr, event == EV_L2_T200 ? "T200" : "T203");
-		return;
-	}
-	hh = mISDN_HEAD_P(skb);
-	hh->prim = event == EV_L2_T200 ? DL_TIMER200_IND : DL_TIMER203_IND;
-	hh->id = l2->ch.nr;
-	if (*debug & DEBUG_TIMER)
-		printk(KERN_DEBUG "%s: L2(%d,%d) nr:%x timer %s expired\n",
-		       mISDNDevName4ch(&l2->ch), l2->sapi, l2->tei,
-		       l2->ch.nr, event == EV_L2_T200 ? "T200" : "T203");
-	if (l2->ch.st)
-		l2->ch.st->own.recv(&l2->ch.st->own, skb);
-}
-
-static int
-l2mgr(struct layer2 *l2, u_int prim, void *arg) {
-	long c = (long)arg;
-
-	printk(KERN_WARNING "l2mgr: dev %s addr:%x prim %x %c\n",
-	       mISDNDevName4ch(&l2->ch), l2->id, prim, (char)c);
-	if (test_bit(FLG_LAPD, &l2->flag) &&
-	    !test_bit(FLG_FIXED_TEI, &l2->flag)) {
-		switch (c) {
-		case 'C':
-		case 'D':
-		case 'G':
-		case 'H':
-			l2_tei(l2, prim, (u_long)arg);
-			break;
-		}
-	}
-	return 0;
-}
-
-static void
-set_peer_busy(struct layer2 *l2) {
-	test_and_set_bit(FLG_PEER_BUSY, &l2->flag);
-	if (skb_queue_len(&l2->i_queue) || skb_queue_len(&l2->ui_queue))
-		test_and_set_bit(FLG_L2BLOCK, &l2->flag);
-}
-
-static void
-clear_peer_busy(struct layer2 *l2) {
-	if (test_and_clear_bit(FLG_PEER_BUSY, &l2->flag))
-		test_and_clear_bit(FLG_L2BLOCK, &l2->flag);
-}
-
-static void
-InitWin(struct layer2 *l2)
-{
-	int i;
-
-	for (i = 0; i < MAX_WINDOW; i++)
-		l2->windowar[i] = NULL;
-}
-
-static int
-freewin(struct layer2 *l2)
-{
-	int i, cnt = 0;
-
-	for (i = 0; i < MAX_WINDOW; i++) {
-		if (l2->windowar[i]) {
-			cnt++;
-			dev_kfree_skb(l2->windowar[i]);
-			l2->windowar[i] = NULL;
-		}
-	}
-	return cnt;
-}
-
-static void
-ReleaseWin(struct layer2 *l2)
-{
-	int cnt = freewin(l2);
-
-	if (cnt)
-		printk(KERN_WARNING
-		       "isdnl2 freed %d skbuffs in release\n", cnt);
-}
-
-inline unsigned int
-cansend(struct layer2 *l2)
-{
-	unsigned int p1;
-
-	if (test_bit(FLG_MOD128, &l2->flag))
-		p1 = (l2->vs - l2->va) % 128;
-	else
-		p1 = (l2->vs - l2->va) % 8;
-	return (p1 < l2->window) && !test_bit(FLG_PEER_BUSY, &l2->flag);
-}
-
-inline void
-clear_exception(struct layer2 *l2)
-{
-	test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
-	test_and_clear_bit(FLG_REJEXC, &l2->flag);
-	test_and_clear_bit(FLG_OWN_BUSY, &l2->flag);
-	clear_peer_busy(l2);
-}
-
-static int
-sethdraddr(struct layer2 *l2, u_char *header, int rsp)
-{
-	u_char *ptr = header;
-	int crbit = rsp;
-
-	if (test_bit(FLG_LAPD, &l2->flag)) {
-		if (test_bit(FLG_LAPD_NET, &l2->flag))
-			crbit = !crbit;
-		*ptr++ = (l2->sapi << 2) | (crbit ? 2 : 0);
-		*ptr++ = (l2->tei << 1) | 1;
-		return 2;
-	} else {
-		if (test_bit(FLG_ORIG, &l2->flag))
-			crbit = !crbit;
-		if (crbit)
-			*ptr++ = l2->addr.B;
-		else
-			*ptr++ = l2->addr.A;
-		return 1;
-	}
-}
-
-static inline void
-enqueue_super(struct layer2 *l2, struct sk_buff *skb)
-{
-	if (l2down(l2, PH_DATA_REQ, l2_newid(l2), skb))
-		dev_kfree_skb(skb);
-}
-
-static inline void
-enqueue_ui(struct layer2 *l2, struct sk_buff *skb)
-{
-	if (l2->tm)
-		l2_tei(l2, MDL_STATUS_UI_IND, 0);
-	if (l2down(l2, PH_DATA_REQ, l2_newid(l2), skb))
-		dev_kfree_skb(skb);
-}
-
-inline int
-IsUI(u_char *data)
-{
-	return (data[0] & 0xef) == UI;
-}
-
-inline int
-IsUA(u_char *data)
-{
-	return (data[0] & 0xef) == UA;
-}
-
-inline int
-IsDM(u_char *data)
-{
-	return (data[0] & 0xef) == DM;
-}
-
-inline int
-IsDISC(u_char *data)
-{
-	return (data[0] & 0xef) == DISC;
-}
-
-inline int
-IsRR(u_char *data, struct layer2 *l2)
-{
-	if (test_bit(FLG_MOD128, &l2->flag))
-		return data[0] == RR;
-	else
-		return (data[0] & 0xf) == 1;
-}
-
-inline int
-IsSFrame(u_char *data, struct layer2 *l2)
-{
-	register u_char d = *data;
-
-	if (!test_bit(FLG_MOD128, &l2->flag))
-		d &= 0xf;
-	return ((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c);
-}
-
-inline int
-IsSABME(u_char *data, struct layer2 *l2)
-{
-	u_char d = data[0] & ~0x10;
-
-	return test_bit(FLG_MOD128, &l2->flag) ? d == SABME : d == SABM;
-}
-
-inline int
-IsREJ(u_char *data, struct layer2 *l2)
-{
-	return test_bit(FLG_MOD128, &l2->flag) ?
-		data[0] == REJ : (data[0] & 0xf) == REJ;
-}
-
-inline int
-IsFRMR(u_char *data)
-{
-	return (data[0] & 0xef) == FRMR;
-}
-
-inline int
-IsRNR(u_char *data, struct layer2 *l2)
-{
-	return test_bit(FLG_MOD128, &l2->flag) ?
-		data[0] == RNR : (data[0] & 0xf) == RNR;
-}
-
-static int
-iframe_error(struct layer2 *l2, struct sk_buff *skb)
-{
-	u_int	i;
-	int	rsp = *skb->data & 0x2;
-
-	i = l2addrsize(l2) + (test_bit(FLG_MOD128, &l2->flag) ? 2 : 1);
-	if (test_bit(FLG_ORIG, &l2->flag))
-		rsp = !rsp;
-	if (rsp)
-		return 'L';
-	if (skb->len < i)
-		return 'N';
-	if ((skb->len - i) > l2->maxlen)
-		return 'O';
-	return 0;
-}
-
-static int
-super_error(struct layer2 *l2, struct sk_buff *skb)
-{
-	if (skb->len != l2addrsize(l2) +
-	    (test_bit(FLG_MOD128, &l2->flag) ? 2 : 1))
-		return 'N';
-	return 0;
-}
-
-static int
-unnum_error(struct layer2 *l2, struct sk_buff *skb, int wantrsp)
-{
-	int rsp = (*skb->data & 0x2) >> 1;
-	if (test_bit(FLG_ORIG, &l2->flag))
-		rsp = !rsp;
-	if (rsp != wantrsp)
-		return 'L';
-	if (skb->len != l2addrsize(l2) + 1)
-		return 'N';
-	return 0;
-}
-
-static int
-UI_error(struct layer2 *l2, struct sk_buff *skb)
-{
-	int rsp = *skb->data & 0x2;
-	if (test_bit(FLG_ORIG, &l2->flag))
-		rsp = !rsp;
-	if (rsp)
-		return 'L';
-	if (skb->len > l2->maxlen + l2addrsize(l2) + 1)
-		return 'O';
-	return 0;
-}
-
-static int
-FRMR_error(struct layer2 *l2, struct sk_buff *skb)
-{
-	u_int	headers = l2addrsize(l2) + 1;
-	u_char	*datap = skb->data + headers;
-	int	rsp = *skb->data & 0x2;
-
-	if (test_bit(FLG_ORIG, &l2->flag))
-		rsp = !rsp;
-	if (!rsp)
-		return 'L';
-	if (test_bit(FLG_MOD128, &l2->flag)) {
-		if (skb->len < headers + 5)
-			return 'N';
-		else if (*debug & DEBUG_L2)
-			l2m_debug(&l2->l2m,
-				  "FRMR information %2x %2x %2x %2x %2x",
-				  datap[0], datap[1], datap[2], datap[3], datap[4]);
-	} else {
-		if (skb->len < headers + 3)
-			return 'N';
-		else if (*debug & DEBUG_L2)
-			l2m_debug(&l2->l2m,
-				  "FRMR information %2x %2x %2x",
-				  datap[0], datap[1], datap[2]);
-	}
-	return 0;
-}
-
-static unsigned int
-legalnr(struct layer2 *l2, unsigned int nr)
-{
-	if (test_bit(FLG_MOD128, &l2->flag))
-		return ((nr - l2->va) % 128) <= ((l2->vs - l2->va) % 128);
-	else
-		return ((nr - l2->va) % 8) <= ((l2->vs - l2->va) % 8);
-}
-
-static void
-setva(struct layer2 *l2, unsigned int nr)
-{
-	struct sk_buff	*skb;
-
-	while (l2->va != nr) {
-		l2->va++;
-		if (test_bit(FLG_MOD128, &l2->flag))
-			l2->va %= 128;
-		else
-			l2->va %= 8;
-		if (l2->windowar[l2->sow]) {
-			skb_trim(l2->windowar[l2->sow], 0);
-			skb_queue_tail(&l2->tmp_queue, l2->windowar[l2->sow]);
-			l2->windowar[l2->sow] = NULL;
-		}
-		l2->sow = (l2->sow + 1) % l2->window;
-	}
-	skb = skb_dequeue(&l2->tmp_queue);
-	while (skb) {
-		dev_kfree_skb(skb);
-		skb = skb_dequeue(&l2->tmp_queue);
-	}
-}
-
-static void
-send_uframe(struct layer2 *l2, struct sk_buff *skb, u_char cmd, u_char cr)
-{
-	u_char tmp[MAX_L2HEADER_LEN];
-	int i;
-
-	i = sethdraddr(l2, tmp, cr);
-	tmp[i++] = cmd;
-	if (skb)
-		skb_trim(skb, 0);
-	else {
-		skb = mI_alloc_skb(i, GFP_ATOMIC);
-		if (!skb) {
-			printk(KERN_WARNING "%s: can't alloc skbuff in %s\n",
-			       mISDNDevName4ch(&l2->ch), __func__);
-			return;
-		}
-	}
-	skb_put_data(skb, tmp, i);
-	enqueue_super(l2, skb);
-}
-
-
-inline u_char
-get_PollFlag(struct layer2 *l2, struct sk_buff *skb)
-{
-	return skb->data[l2addrsize(l2)] & 0x10;
-}
-
-inline u_char
-get_PollFlagFree(struct layer2 *l2, struct sk_buff *skb)
-{
-	u_char PF;
-
-	PF = get_PollFlag(l2, skb);
-	dev_kfree_skb(skb);
-	return PF;
-}
-
-inline void
-start_t200(struct layer2 *l2, int i)
-{
-	mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, i);
-	test_and_set_bit(FLG_T200_RUN, &l2->flag);
-}
-
-inline void
-restart_t200(struct layer2 *l2, int i)
-{
-	mISDN_FsmRestartTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, i);
-	test_and_set_bit(FLG_T200_RUN, &l2->flag);
-}
-
-inline void
-stop_t200(struct layer2 *l2, int i)
-{
-	if (test_and_clear_bit(FLG_T200_RUN, &l2->flag))
-		mISDN_FsmDelTimer(&l2->t200, i);
-}
-
-inline void
-st5_dl_release_l2l3(struct layer2 *l2)
-{
-	int pr;
-
-	if (test_and_clear_bit(FLG_PEND_REL, &l2->flag))
-		pr = DL_RELEASE_CNF;
-	else
-		pr = DL_RELEASE_IND;
-	l2up_create(l2, pr, 0, NULL);
-}
-
-inline void
-lapb_dl_release_l2l3(struct layer2 *l2, int f)
-{
-	if (test_bit(FLG_LAPB, &l2->flag))
-		l2down_create(l2, PH_DEACTIVATE_REQ, l2_newid(l2), 0, NULL);
-	l2up_create(l2, f, 0, NULL);
-}
-
-static void
-establishlink(struct FsmInst *fi)
-{
-	struct layer2 *l2 = fi->userdata;
-	u_char cmd;
-
-	clear_exception(l2);
-	l2->rc = 0;
-	cmd = (test_bit(FLG_MOD128, &l2->flag) ? SABME : SABM) | 0x10;
-	send_uframe(l2, NULL, cmd, CMD);
-	mISDN_FsmDelTimer(&l2->t203, 1);
-	restart_t200(l2, 1);
-	test_and_clear_bit(FLG_PEND_REL, &l2->flag);
-	freewin(l2);
-	mISDN_FsmChangeState(fi, ST_L2_5);
-}
-
-static void
-l2_mdl_error_ua(struct FsmInst *fi, int event, void *arg)
-{
-	struct sk_buff *skb = arg;
-	struct layer2 *l2 = fi->userdata;
-
-	if (get_PollFlagFree(l2, skb))
-		l2mgr(l2, MDL_ERROR_IND, (void *) 'C');
-	else
-		l2mgr(l2, MDL_ERROR_IND, (void *) 'D');
-
-}
-
-static void
-l2_mdl_error_dm(struct FsmInst *fi, int event, void *arg)
-{
-	struct sk_buff *skb = arg;
-	struct layer2 *l2 = fi->userdata;
-
-	if (get_PollFlagFree(l2, skb))
-		l2mgr(l2, MDL_ERROR_IND, (void *) 'B');
-	else {
-		l2mgr(l2, MDL_ERROR_IND, (void *) 'E');
-		establishlink(fi);
-		test_and_clear_bit(FLG_L3_INIT, &l2->flag);
-	}
-}
-
-static void
-l2_st8_mdl_error_dm(struct FsmInst *fi, int event, void *arg)
-{
-	struct sk_buff *skb = arg;
-	struct layer2 *l2 = fi->userdata;
-
-	if (get_PollFlagFree(l2, skb))
-		l2mgr(l2, MDL_ERROR_IND, (void *) 'B');
-	else
-		l2mgr(l2, MDL_ERROR_IND, (void *) 'E');
-	establishlink(fi);
-	test_and_clear_bit(FLG_L3_INIT, &l2->flag);
-}
-
-static void
-l2_go_st3(struct FsmInst *fi, int event, void *arg)
-{
-	dev_kfree_skb((struct sk_buff *)arg);
-	mISDN_FsmChangeState(fi, ST_L2_3);
-}
-
-static void
-l2_mdl_assign(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2	*l2 = fi->userdata;
-
-	mISDN_FsmChangeState(fi, ST_L2_3);
-	dev_kfree_skb((struct sk_buff *)arg);
-	l2_tei(l2, MDL_ASSIGN_IND, 0);
-}
-
-static void
-l2_queue_ui_assign(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	skb_queue_tail(&l2->ui_queue, skb);
-	mISDN_FsmChangeState(fi, ST_L2_2);
-	l2_tei(l2, MDL_ASSIGN_IND, 0);
-}
-
-static void
-l2_queue_ui(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	skb_queue_tail(&l2->ui_queue, skb);
-}
-
-static void
-tx_ui(struct layer2 *l2)
-{
-	struct sk_buff *skb;
-	u_char header[MAX_L2HEADER_LEN];
-	int i;
-
-	i = sethdraddr(l2, header, CMD);
-	if (test_bit(FLG_LAPD_NET, &l2->flag))
-		header[1] = 0xff; /* tei 127 */
-	header[i++] = UI;
-	while ((skb = skb_dequeue(&l2->ui_queue))) {
-		memcpy(skb_push(skb, i), header, i);
-		enqueue_ui(l2, skb);
-	}
-}
-
-static void
-l2_send_ui(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	skb_queue_tail(&l2->ui_queue, skb);
-	tx_ui(l2);
-}
-
-static void
-l2_got_ui(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	skb_pull(skb, l2headersize(l2, 1));
-/*
- *		in states 1-3 for broadcast
- */
-
-	if (l2->tm)
-		l2_tei(l2, MDL_STATUS_UI_IND, 0);
-	l2up(l2, DL_UNITDATA_IND, skb);
-}
-
-static void
-l2_establish(struct FsmInst *fi, int event, void *arg)
-{
-	struct sk_buff *skb = arg;
-	struct layer2 *l2 = fi->userdata;
-
-	establishlink(fi);
-	test_and_set_bit(FLG_L3_INIT, &l2->flag);
-	dev_kfree_skb(skb);
-}
-
-static void
-l2_discard_i_setl3(struct FsmInst *fi, int event, void *arg)
-{
-	struct sk_buff *skb = arg;
-	struct layer2 *l2 = fi->userdata;
-
-	skb_queue_purge(&l2->i_queue);
-	test_and_set_bit(FLG_L3_INIT, &l2->flag);
-	test_and_clear_bit(FLG_PEND_REL, &l2->flag);
-	dev_kfree_skb(skb);
-}
-
-static void
-l2_l3_reestablish(struct FsmInst *fi, int event, void *arg)
-{
-	struct sk_buff *skb = arg;
-	struct layer2 *l2 = fi->userdata;
-
-	skb_queue_purge(&l2->i_queue);
-	establishlink(fi);
-	test_and_set_bit(FLG_L3_INIT, &l2->flag);
-	dev_kfree_skb(skb);
-}
-
-static void
-l2_release(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	skb_trim(skb, 0);
-	l2up(l2, DL_RELEASE_CNF, skb);
-}
-
-static void
-l2_pend_rel(struct FsmInst *fi, int event, void *arg)
-{
-	struct sk_buff *skb = arg;
-	struct layer2 *l2 = fi->userdata;
-
-	test_and_set_bit(FLG_PEND_REL, &l2->flag);
-	dev_kfree_skb(skb);
-}
-
-static void
-l2_disconnect(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	skb_queue_purge(&l2->i_queue);
-	freewin(l2);
-	mISDN_FsmChangeState(fi, ST_L2_6);
-	l2->rc = 0;
-	send_uframe(l2, NULL, DISC | 0x10, CMD);
-	mISDN_FsmDelTimer(&l2->t203, 1);
-	restart_t200(l2, 2);
-	dev_kfree_skb(skb);
-}
-
-static void
-l2_start_multi(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2	*l2 = fi->userdata;
-	struct sk_buff	*skb = arg;
-
-	l2->vs = 0;
-	l2->va = 0;
-	l2->vr = 0;
-	l2->sow = 0;
-	clear_exception(l2);
-	send_uframe(l2, NULL, UA | get_PollFlag(l2, skb), RSP);
-	mISDN_FsmChangeState(fi, ST_L2_7);
-	mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
-	skb_trim(skb, 0);
-	l2up(l2, DL_ESTABLISH_IND, skb);
-	if (l2->tm)
-		l2_tei(l2, MDL_STATUS_UP_IND, 0);
-}
-
-static void
-l2_send_UA(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
-}
-
-static void
-l2_send_DM(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	send_uframe(l2, skb, DM | get_PollFlag(l2, skb), RSP);
-}
-
-static void
-l2_restart_multi(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2	*l2 = fi->userdata;
-	struct sk_buff	*skb = arg;
-	int		est = 0;
-
-	send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
-
-	l2mgr(l2, MDL_ERROR_IND, (void *) 'F');
-
-	if (l2->vs != l2->va) {
-		skb_queue_purge(&l2->i_queue);
-		est = 1;
-	}
-
-	clear_exception(l2);
-	l2->vs = 0;
-	l2->va = 0;
-	l2->vr = 0;
-	l2->sow = 0;
-	mISDN_FsmChangeState(fi, ST_L2_7);
-	stop_t200(l2, 3);
-	mISDN_FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
-
-	if (est)
-		l2up_create(l2, DL_ESTABLISH_IND, 0, NULL);
-/*		mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST,
- *		    MGR_SHORTSTATUS | INDICATION, SSTATUS_L2_ESTABLISHED,
- *		    0, NULL, 0);
- */
-	if (skb_queue_len(&l2->i_queue) && cansend(l2))
-		mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
-}
-
-static void
-l2_stop_multi(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2	*l2 = fi->userdata;
-	struct sk_buff	*skb = arg;
-
-	mISDN_FsmChangeState(fi, ST_L2_4);
-	mISDN_FsmDelTimer(&l2->t203, 3);
-	stop_t200(l2, 4);
-
-	send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
-	skb_queue_purge(&l2->i_queue);
-	freewin(l2);
-	lapb_dl_release_l2l3(l2, DL_RELEASE_IND);
-	if (l2->tm)
-		l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
-}
-
-static void
-l2_connected(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2	*l2 = fi->userdata;
-	struct sk_buff	*skb = arg;
-	int pr = -1;
-
-	if (!get_PollFlag(l2, skb)) {
-		l2_mdl_error_ua(fi, event, arg);
-		return;
-	}
-	dev_kfree_skb(skb);
-	if (test_and_clear_bit(FLG_PEND_REL, &l2->flag))
-		l2_disconnect(fi, event, NULL);
-	if (test_and_clear_bit(FLG_L3_INIT, &l2->flag)) {
-		pr = DL_ESTABLISH_CNF;
-	} else if (l2->vs != l2->va) {
-		skb_queue_purge(&l2->i_queue);
-		pr = DL_ESTABLISH_IND;
-	}
-	stop_t200(l2, 5);
-	l2->vr = 0;
-	l2->vs = 0;
-	l2->va = 0;
-	l2->sow = 0;
-	mISDN_FsmChangeState(fi, ST_L2_7);
-	mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 4);
-	if (pr != -1)
-		l2up_create(l2, pr, 0, NULL);
-
-	if (skb_queue_len(&l2->i_queue) && cansend(l2))
-		mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
-
-	if (l2->tm)
-		l2_tei(l2, MDL_STATUS_UP_IND, 0);
-}
-
-static void
-l2_released(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	if (!get_PollFlag(l2, skb)) {
-		l2_mdl_error_ua(fi, event, arg);
-		return;
-	}
-	dev_kfree_skb(skb);
-	stop_t200(l2, 6);
-	lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);
-	mISDN_FsmChangeState(fi, ST_L2_4);
-	if (l2->tm)
-		l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
-}
-
-static void
-l2_reestablish(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	if (!get_PollFlagFree(l2, skb)) {
-		establishlink(fi);
-		test_and_set_bit(FLG_L3_INIT, &l2->flag);
-	}
-}
-
-static void
-l2_st5_dm_release(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	if (get_PollFlagFree(l2, skb)) {
-		stop_t200(l2, 7);
-		if (!test_bit(FLG_L3_INIT, &l2->flag))
-			skb_queue_purge(&l2->i_queue);
-		if (test_bit(FLG_LAPB, &l2->flag))
-			l2down_create(l2, PH_DEACTIVATE_REQ,
-				      l2_newid(l2), 0, NULL);
-		st5_dl_release_l2l3(l2);
-		mISDN_FsmChangeState(fi, ST_L2_4);
-		if (l2->tm)
-			l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
-	}
-}
-
-static void
-l2_st6_dm_release(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	if (get_PollFlagFree(l2, skb)) {
-		stop_t200(l2, 8);
-		lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);
-		mISDN_FsmChangeState(fi, ST_L2_4);
-		if (l2->tm)
-			l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
-	}
-}
-
-static void
-enquiry_cr(struct layer2 *l2, u_char typ, u_char cr, u_char pf)
-{
-	struct sk_buff *skb;
-	u_char tmp[MAX_L2HEADER_LEN];
-	int i;
-
-	i = sethdraddr(l2, tmp, cr);
-	if (test_bit(FLG_MOD128, &l2->flag)) {
-		tmp[i++] = typ;
-		tmp[i++] = (l2->vr << 1) | (pf ? 1 : 0);
-	} else
-		tmp[i++] = (l2->vr << 5) | typ | (pf ? 0x10 : 0);
-	skb = mI_alloc_skb(i, GFP_ATOMIC);
-	if (!skb) {
-		printk(KERN_WARNING "%s: isdnl2 can't alloc sbbuff in %s\n",
-		       mISDNDevName4ch(&l2->ch), __func__);
-		return;
-	}
-	skb_put_data(skb, tmp, i);
-	enqueue_super(l2, skb);
-}
-
-inline void
-enquiry_response(struct layer2 *l2)
-{
-	if (test_bit(FLG_OWN_BUSY, &l2->flag))
-		enquiry_cr(l2, RNR, RSP, 1);
-	else
-		enquiry_cr(l2, RR, RSP, 1);
-	test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
-}
-
-inline void
-transmit_enquiry(struct layer2 *l2)
-{
-	if (test_bit(FLG_OWN_BUSY, &l2->flag))
-		enquiry_cr(l2, RNR, CMD, 1);
-	else
-		enquiry_cr(l2, RR, CMD, 1);
-	test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
-	start_t200(l2, 9);
-}
-
-
-static void
-nrerrorrecovery(struct FsmInst *fi)
-{
-	struct layer2 *l2 = fi->userdata;
-
-	l2mgr(l2, MDL_ERROR_IND, (void *) 'J');
-	establishlink(fi);
-	test_and_clear_bit(FLG_L3_INIT, &l2->flag);
-}
-
-static void
-invoke_retransmission(struct layer2 *l2, unsigned int nr)
-{
-	u_int	p1;
-
-	if (l2->vs != nr) {
-		while (l2->vs != nr) {
-			(l2->vs)--;
-			if (test_bit(FLG_MOD128, &l2->flag)) {
-				l2->vs %= 128;
-				p1 = (l2->vs - l2->va) % 128;
-			} else {
-				l2->vs %= 8;
-				p1 = (l2->vs - l2->va) % 8;
-			}
-			p1 = (p1 + l2->sow) % l2->window;
-			if (l2->windowar[p1])
-				skb_queue_head(&l2->i_queue, l2->windowar[p1]);
-			else
-				printk(KERN_WARNING
-				       "%s: windowar[%d] is NULL\n",
-				       mISDNDevName4ch(&l2->ch), p1);
-			l2->windowar[p1] = NULL;
-		}
-		mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);
-	}
-}
-
-static void
-l2_st7_got_super(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-	int PollFlag, rsp, typ = RR;
-	unsigned int nr;
-
-	rsp = *skb->data & 0x2;
-	if (test_bit(FLG_ORIG, &l2->flag))
-		rsp = !rsp;
-
-	skb_pull(skb, l2addrsize(l2));
-	if (IsRNR(skb->data, l2)) {
-		set_peer_busy(l2);
-		typ = RNR;
-	} else
-		clear_peer_busy(l2);
-	if (IsREJ(skb->data, l2))
-		typ = REJ;
-
-	if (test_bit(FLG_MOD128, &l2->flag)) {
-		PollFlag = (skb->data[1] & 0x1) == 0x1;
-		nr = skb->data[1] >> 1;
-	} else {
-		PollFlag = (skb->data[0] & 0x10);
-		nr = (skb->data[0] >> 5) & 0x7;
-	}
-	dev_kfree_skb(skb);
-
-	if (PollFlag) {
-		if (rsp)
-			l2mgr(l2, MDL_ERROR_IND, (void *) 'A');
-		else
-			enquiry_response(l2);
-	}
-	if (legalnr(l2, nr)) {
-		if (typ == REJ) {
-			setva(l2, nr);
-			invoke_retransmission(l2, nr);
-			stop_t200(l2, 10);
-			if (mISDN_FsmAddTimer(&l2->t203, l2->T203,
-					      EV_L2_T203, NULL, 6))
-				l2m_debug(&l2->l2m, "Restart T203 ST7 REJ");
-		} else if ((nr == l2->vs) && (typ == RR)) {
-			setva(l2, nr);
-			stop_t200(l2, 11);
-			mISDN_FsmRestartTimer(&l2->t203, l2->T203,
-					      EV_L2_T203, NULL, 7);
-		} else if ((l2->va != nr) || (typ == RNR)) {
-			setva(l2, nr);
-			if (typ != RR)
-				mISDN_FsmDelTimer(&l2->t203, 9);
-			restart_t200(l2, 12);
-		}
-		if (skb_queue_len(&l2->i_queue) && (typ == RR))
-			mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
-	} else
-		nrerrorrecovery(fi);
-}
-
-static void
-l2_feed_i_if_reest(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	if (!test_bit(FLG_L3_INIT, &l2->flag))
-		skb_queue_tail(&l2->i_queue, skb);
-	else
-		dev_kfree_skb(skb);
-}
-
-static void
-l2_feed_i_pull(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	skb_queue_tail(&l2->i_queue, skb);
-	mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
-}
-
-static void
-l2_feed_iqueue(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	skb_queue_tail(&l2->i_queue, skb);
-}
-
-static void
-l2_got_iframe(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2	*l2 = fi->userdata;
-	struct sk_buff	*skb = arg;
-	int		PollFlag, i;
-	u_int		ns, nr;
-
-	i = l2addrsize(l2);
-	if (test_bit(FLG_MOD128, &l2->flag)) {
-		PollFlag = ((skb->data[i + 1] & 0x1) == 0x1);
-		ns = skb->data[i] >> 1;
-		nr = (skb->data[i + 1] >> 1) & 0x7f;
-	} else {
-		PollFlag = (skb->data[i] & 0x10);
-		ns = (skb->data[i] >> 1) & 0x7;
-		nr = (skb->data[i] >> 5) & 0x7;
-	}
-	if (test_bit(FLG_OWN_BUSY, &l2->flag)) {
-		dev_kfree_skb(skb);
-		if (PollFlag)
-			enquiry_response(l2);
-	} else {
-		if (l2->vr == ns) {
-			l2->vr++;
-			if (test_bit(FLG_MOD128, &l2->flag))
-				l2->vr %= 128;
-			else
-				l2->vr %= 8;
-			test_and_clear_bit(FLG_REJEXC, &l2->flag);
-			if (PollFlag)
-				enquiry_response(l2);
-			else
-				test_and_set_bit(FLG_ACK_PEND, &l2->flag);
-			skb_pull(skb, l2headersize(l2, 0));
-			l2up(l2, DL_DATA_IND, skb);
-		} else {
-			/* n(s)!=v(r) */
-			dev_kfree_skb(skb);
-			if (test_and_set_bit(FLG_REJEXC, &l2->flag)) {
-				if (PollFlag)
-					enquiry_response(l2);
-			} else {
-				enquiry_cr(l2, REJ, RSP, PollFlag);
-				test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
-			}
-		}
-	}
-	if (legalnr(l2, nr)) {
-		if (!test_bit(FLG_PEER_BUSY, &l2->flag) &&
-		    (fi->state == ST_L2_7)) {
-			if (nr == l2->vs) {
-				stop_t200(l2, 13);
-				mISDN_FsmRestartTimer(&l2->t203, l2->T203,
-						      EV_L2_T203, NULL, 7);
-			} else if (nr != l2->va)
-				restart_t200(l2, 14);
-		}
-		setva(l2, nr);
-	} else {
-		nrerrorrecovery(fi);
-		return;
-	}
-	if (skb_queue_len(&l2->i_queue) && (fi->state == ST_L2_7))
-		mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
-	if (test_and_clear_bit(FLG_ACK_PEND, &l2->flag))
-		enquiry_cr(l2, RR, RSP, 0);
-}
-
-static void
-l2_got_tei(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2	*l2 = fi->userdata;
-	u_int		info;
-
-	l2->tei = (signed char)(long)arg;
-	set_channel_address(&l2->ch, l2->sapi, l2->tei);
-	info = DL_INFO_L2_CONNECT;
-	l2up_create(l2, DL_INFORMATION_IND, sizeof(info), &info);
-	if (fi->state == ST_L2_3) {
-		establishlink(fi);
-		test_and_set_bit(FLG_L3_INIT, &l2->flag);
-	} else
-		mISDN_FsmChangeState(fi, ST_L2_4);
-	if (skb_queue_len(&l2->ui_queue))
-		tx_ui(l2);
-}
-
-static void
-l2_st5_tout_200(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-
-	if (test_bit(FLG_LAPD, &l2->flag) &&
-	    test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
-		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
-	} else if (l2->rc == l2->N200) {
-		mISDN_FsmChangeState(fi, ST_L2_4);
-		test_and_clear_bit(FLG_T200_RUN, &l2->flag);
-		skb_queue_purge(&l2->i_queue);
-		l2mgr(l2, MDL_ERROR_IND, (void *) 'G');
-		if (test_bit(FLG_LAPB, &l2->flag))
-			l2down_create(l2, PH_DEACTIVATE_REQ,
-				      l2_newid(l2), 0, NULL);
-		st5_dl_release_l2l3(l2);
-		if (l2->tm)
-			l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
-	} else {
-		l2->rc++;
-		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
-		send_uframe(l2, NULL, (test_bit(FLG_MOD128, &l2->flag) ?
-				       SABME : SABM) | 0x10, CMD);
-	}
-}
-
-static void
-l2_st6_tout_200(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-
-	if (test_bit(FLG_LAPD, &l2->flag) &&
-	    test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
-		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
-	} else if (l2->rc == l2->N200) {
-		mISDN_FsmChangeState(fi, ST_L2_4);
-		test_and_clear_bit(FLG_T200_RUN, &l2->flag);
-		l2mgr(l2, MDL_ERROR_IND, (void *) 'H');
-		lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);
-		if (l2->tm)
-			l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
-	} else {
-		l2->rc++;
-		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200,
-				  NULL, 9);
-		send_uframe(l2, NULL, DISC | 0x10, CMD);
-	}
-}
-
-static void
-l2_st7_tout_200(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-
-	if (test_bit(FLG_LAPD, &l2->flag) &&
-	    test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
-		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
-		return;
-	}
-	test_and_clear_bit(FLG_T200_RUN, &l2->flag);
-	l2->rc = 0;
-	mISDN_FsmChangeState(fi, ST_L2_8);
-	transmit_enquiry(l2);
-	l2->rc++;
-}
-
-static void
-l2_st8_tout_200(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-
-	if (test_bit(FLG_LAPD, &l2->flag) &&
-	    test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
-		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
-		return;
-	}
-	test_and_clear_bit(FLG_T200_RUN, &l2->flag);
-	if (l2->rc == l2->N200) {
-		l2mgr(l2, MDL_ERROR_IND, (void *) 'I');
-		establishlink(fi);
-		test_and_clear_bit(FLG_L3_INIT, &l2->flag);
-	} else {
-		transmit_enquiry(l2);
-		l2->rc++;
-	}
-}
-
-static void
-l2_st7_tout_203(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-
-	if (test_bit(FLG_LAPD, &l2->flag) &&
-	    test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
-		mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 9);
-		return;
-	}
-	mISDN_FsmChangeState(fi, ST_L2_8);
-	transmit_enquiry(l2);
-	l2->rc = 0;
-}
-
-static void
-l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2	*l2 = fi->userdata;
-	struct sk_buff	*skb, *nskb;
-	u_char		header[MAX_L2HEADER_LEN];
-	u_int		i, p1;
-
-	if (!cansend(l2))
-		return;
-
-	skb = skb_dequeue(&l2->i_queue);
-	if (!skb)
-		return;
-	i = sethdraddr(l2, header, CMD);
-	if (test_bit(FLG_MOD128, &l2->flag)) {
-		header[i++] = l2->vs << 1;
-		header[i++] = l2->vr << 1;
-	} else
-		header[i++] = (l2->vr << 5) | (l2->vs << 1);
-	nskb = skb_realloc_headroom(skb, i);
-	if (!nskb) {
-		printk(KERN_WARNING "%s: no headroom(%d) copy for IFrame\n",
-		       mISDNDevName4ch(&l2->ch), i);
-		skb_queue_head(&l2->i_queue, skb);
-		return;
-	}
-	if (test_bit(FLG_MOD128, &l2->flag)) {
-		p1 = (l2->vs - l2->va) % 128;
-		l2->vs = (l2->vs + 1) % 128;
-	} else {
-		p1 = (l2->vs - l2->va) % 8;
-		l2->vs = (l2->vs + 1) % 8;
-	}
-	p1 = (p1 + l2->sow) % l2->window;
-	if (l2->windowar[p1]) {
-		printk(KERN_WARNING "%s: l2 try overwrite ack queue entry %d\n",
-		       mISDNDevName4ch(&l2->ch), p1);
-		dev_kfree_skb(l2->windowar[p1]);
-	}
-	l2->windowar[p1] = skb;
-	memcpy(skb_push(nskb, i), header, i);
-	l2down(l2, PH_DATA_REQ, l2_newid(l2), nskb);
-	test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
-	if (!test_and_set_bit(FLG_T200_RUN, &l2->flag)) {
-		mISDN_FsmDelTimer(&l2->t203, 13);
-		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 11);
-	}
-}
-
-static void
-l2_st8_got_super(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-	int PollFlag, rsp, rnr = 0;
-	unsigned int nr;
-
-	rsp = *skb->data & 0x2;
-	if (test_bit(FLG_ORIG, &l2->flag))
-		rsp = !rsp;
-
-	skb_pull(skb, l2addrsize(l2));
-
-	if (IsRNR(skb->data, l2)) {
-		set_peer_busy(l2);
-		rnr = 1;
-	} else
-		clear_peer_busy(l2);
-
-	if (test_bit(FLG_MOD128, &l2->flag)) {
-		PollFlag = (skb->data[1] & 0x1) == 0x1;
-		nr = skb->data[1] >> 1;
-	} else {
-		PollFlag = (skb->data[0] & 0x10);
-		nr = (skb->data[0] >> 5) & 0x7;
-	}
-	dev_kfree_skb(skb);
-	if (rsp && PollFlag) {
-		if (legalnr(l2, nr)) {
-			if (rnr) {
-				restart_t200(l2, 15);
-			} else {
-				stop_t200(l2, 16);
-				mISDN_FsmAddTimer(&l2->t203, l2->T203,
-						  EV_L2_T203, NULL, 5);
-				setva(l2, nr);
-			}
-			invoke_retransmission(l2, nr);
-			mISDN_FsmChangeState(fi, ST_L2_7);
-			if (skb_queue_len(&l2->i_queue) && cansend(l2))
-				mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
-		} else
-			nrerrorrecovery(fi);
-	} else {
-		if (!rsp && PollFlag)
-			enquiry_response(l2);
-		if (legalnr(l2, nr))
-			setva(l2, nr);
-		else
-			nrerrorrecovery(fi);
-	}
-}
-
-static void
-l2_got_FRMR(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	skb_pull(skb, l2addrsize(l2) + 1);
-
-	if (!(skb->data[0] & 1) || ((skb->data[0] & 3) == 1) || /* I or S */
-	    (IsUA(skb->data) && (fi->state == ST_L2_7))) {
-		l2mgr(l2, MDL_ERROR_IND, (void *) 'K');
-		establishlink(fi);
-		test_and_clear_bit(FLG_L3_INIT, &l2->flag);
-	}
-	dev_kfree_skb(skb);
-}
-
-static void
-l2_st24_tei_remove(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-
-	skb_queue_purge(&l2->ui_queue);
-	l2->tei = GROUP_TEI;
-	mISDN_FsmChangeState(fi, ST_L2_1);
-}
-
-static void
-l2_st3_tei_remove(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-
-	skb_queue_purge(&l2->ui_queue);
-	l2->tei = GROUP_TEI;
-	l2up_create(l2, DL_RELEASE_IND, 0, NULL);
-	mISDN_FsmChangeState(fi, ST_L2_1);
-}
-
-static void
-l2_st5_tei_remove(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-
-	skb_queue_purge(&l2->i_queue);
-	skb_queue_purge(&l2->ui_queue);
-	freewin(l2);
-	l2->tei = GROUP_TEI;
-	stop_t200(l2, 17);
-	st5_dl_release_l2l3(l2);
-	mISDN_FsmChangeState(fi, ST_L2_1);
-}
-
-static void
-l2_st6_tei_remove(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-
-	skb_queue_purge(&l2->ui_queue);
-	l2->tei = GROUP_TEI;
-	stop_t200(l2, 18);
-	l2up_create(l2, DL_RELEASE_IND, 0, NULL);
-	mISDN_FsmChangeState(fi, ST_L2_1);
-}
-
-static void
-l2_tei_remove(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-
-	skb_queue_purge(&l2->i_queue);
-	skb_queue_purge(&l2->ui_queue);
-	freewin(l2);
-	l2->tei = GROUP_TEI;
-	stop_t200(l2, 17);
-	mISDN_FsmDelTimer(&l2->t203, 19);
-	l2up_create(l2, DL_RELEASE_IND, 0, NULL);
-/*	mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST,
- *		MGR_SHORTSTATUS_IND, SSTATUS_L2_RELEASED,
- *		0, NULL, 0);
- */
-	mISDN_FsmChangeState(fi, ST_L2_1);
-}
-
-static void
-l2_st14_persistent_da(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	skb_queue_purge(&l2->i_queue);
-	skb_queue_purge(&l2->ui_queue);
-	if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag))
-		l2up(l2, DL_RELEASE_IND, skb);
-	else
-		dev_kfree_skb(skb);
-}
-
-static void
-l2_st5_persistent_da(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	skb_queue_purge(&l2->i_queue);
-	skb_queue_purge(&l2->ui_queue);
-	freewin(l2);
-	stop_t200(l2, 19);
-	st5_dl_release_l2l3(l2);
-	mISDN_FsmChangeState(fi, ST_L2_4);
-	if (l2->tm)
-		l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
-	dev_kfree_skb(skb);
-}
-
-static void
-l2_st6_persistent_da(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	skb_queue_purge(&l2->ui_queue);
-	stop_t200(l2, 20);
-	l2up(l2, DL_RELEASE_CNF, skb);
-	mISDN_FsmChangeState(fi, ST_L2_4);
-	if (l2->tm)
-		l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
-}
-
-static void
-l2_persistent_da(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	skb_queue_purge(&l2->i_queue);
-	skb_queue_purge(&l2->ui_queue);
-	freewin(l2);
-	stop_t200(l2, 19);
-	mISDN_FsmDelTimer(&l2->t203, 19);
-	l2up(l2, DL_RELEASE_IND, skb);
-	mISDN_FsmChangeState(fi, ST_L2_4);
-	if (l2->tm)
-		l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
-}
-
-static void
-l2_set_own_busy(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	if (!test_and_set_bit(FLG_OWN_BUSY, &l2->flag)) {
-		enquiry_cr(l2, RNR, RSP, 0);
-		test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
-	}
-	dev_kfree_skb(skb);
-}
-
-static void
-l2_clear_own_busy(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-	struct sk_buff *skb = arg;
-
-	if (!test_and_clear_bit(FLG_OWN_BUSY, &l2->flag)) {
-		enquiry_cr(l2, RR, RSP, 0);
-		test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
-	}
-	dev_kfree_skb(skb);
-}
-
-static void
-l2_frame_error(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-
-	l2mgr(l2, MDL_ERROR_IND, arg);
-}
-
-static void
-l2_frame_error_reest(struct FsmInst *fi, int event, void *arg)
-{
-	struct layer2 *l2 = fi->userdata;
-
-	l2mgr(l2, MDL_ERROR_IND, arg);
-	establishlink(fi);
-	test_and_clear_bit(FLG_L3_INIT, &l2->flag);
-}
-
-static struct FsmNode L2FnList[] =
-{
-	{ST_L2_1, EV_L2_DL_ESTABLISH_REQ, l2_mdl_assign},
-	{ST_L2_2, EV_L2_DL_ESTABLISH_REQ, l2_go_st3},
-	{ST_L2_4, EV_L2_DL_ESTABLISH_REQ, l2_establish},
-	{ST_L2_5, EV_L2_DL_ESTABLISH_REQ, l2_discard_i_setl3},
-	{ST_L2_7, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish},
-	{ST_L2_8, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish},
-	{ST_L2_4, EV_L2_DL_RELEASE_REQ, l2_release},
-	{ST_L2_5, EV_L2_DL_RELEASE_REQ, l2_pend_rel},
-	{ST_L2_7, EV_L2_DL_RELEASE_REQ, l2_disconnect},
-	{ST_L2_8, EV_L2_DL_RELEASE_REQ, l2_disconnect},
-	{ST_L2_5, EV_L2_DL_DATA, l2_feed_i_if_reest},
-	{ST_L2_7, EV_L2_DL_DATA, l2_feed_i_pull},
-	{ST_L2_8, EV_L2_DL_DATA, l2_feed_iqueue},
-	{ST_L2_1, EV_L2_DL_UNITDATA, l2_queue_ui_assign},
-	{ST_L2_2, EV_L2_DL_UNITDATA, l2_queue_ui},
-	{ST_L2_3, EV_L2_DL_UNITDATA, l2_queue_ui},
-	{ST_L2_4, EV_L2_DL_UNITDATA, l2_send_ui},
-	{ST_L2_5, EV_L2_DL_UNITDATA, l2_send_ui},
-	{ST_L2_6, EV_L2_DL_UNITDATA, l2_send_ui},
-	{ST_L2_7, EV_L2_DL_UNITDATA, l2_send_ui},
-	{ST_L2_8, EV_L2_DL_UNITDATA, l2_send_ui},
-	{ST_L2_1, EV_L2_MDL_ASSIGN, l2_got_tei},
-	{ST_L2_2, EV_L2_MDL_ASSIGN, l2_got_tei},
-	{ST_L2_3, EV_L2_MDL_ASSIGN, l2_got_tei},
-	{ST_L2_2, EV_L2_MDL_ERROR, l2_st24_tei_remove},
-	{ST_L2_3, EV_L2_MDL_ERROR, l2_st3_tei_remove},
-	{ST_L2_4, EV_L2_MDL_REMOVE, l2_st24_tei_remove},
-	{ST_L2_5, EV_L2_MDL_REMOVE, l2_st5_tei_remove},
-	{ST_L2_6, EV_L2_MDL_REMOVE, l2_st6_tei_remove},
-	{ST_L2_7, EV_L2_MDL_REMOVE, l2_tei_remove},
-	{ST_L2_8, EV_L2_MDL_REMOVE, l2_tei_remove},
-	{ST_L2_4, EV_L2_SABME, l2_start_multi},
-	{ST_L2_5, EV_L2_SABME, l2_send_UA},
-	{ST_L2_6, EV_L2_SABME, l2_send_DM},
-	{ST_L2_7, EV_L2_SABME, l2_restart_multi},
-	{ST_L2_8, EV_L2_SABME, l2_restart_multi},
-	{ST_L2_4, EV_L2_DISC, l2_send_DM},
-	{ST_L2_5, EV_L2_DISC, l2_send_DM},
-	{ST_L2_6, EV_L2_DISC, l2_send_UA},
-	{ST_L2_7, EV_L2_DISC, l2_stop_multi},
-	{ST_L2_8, EV_L2_DISC, l2_stop_multi},
-	{ST_L2_4, EV_L2_UA, l2_mdl_error_ua},
-	{ST_L2_5, EV_L2_UA, l2_connected},
-	{ST_L2_6, EV_L2_UA, l2_released},
-	{ST_L2_7, EV_L2_UA, l2_mdl_error_ua},
-	{ST_L2_8, EV_L2_UA, l2_mdl_error_ua},
-	{ST_L2_4, EV_L2_DM, l2_reestablish},
-	{ST_L2_5, EV_L2_DM, l2_st5_dm_release},
-	{ST_L2_6, EV_L2_DM, l2_st6_dm_release},
-	{ST_L2_7, EV_L2_DM, l2_mdl_error_dm},
-	{ST_L2_8, EV_L2_DM, l2_st8_mdl_error_dm},
-	{ST_L2_1, EV_L2_UI, l2_got_ui},
-	{ST_L2_2, EV_L2_UI, l2_got_ui},
-	{ST_L2_3, EV_L2_UI, l2_got_ui},
-	{ST_L2_4, EV_L2_UI, l2_got_ui},
-	{ST_L2_5, EV_L2_UI, l2_got_ui},
-	{ST_L2_6, EV_L2_UI, l2_got_ui},
-	{ST_L2_7, EV_L2_UI, l2_got_ui},
-	{ST_L2_8, EV_L2_UI, l2_got_ui},
-	{ST_L2_7, EV_L2_FRMR, l2_got_FRMR},
-	{ST_L2_8, EV_L2_FRMR, l2_got_FRMR},
-	{ST_L2_7, EV_L2_SUPER, l2_st7_got_super},
-	{ST_L2_8, EV_L2_SUPER, l2_st8_got_super},
-	{ST_L2_7, EV_L2_I, l2_got_iframe},
-	{ST_L2_8, EV_L2_I, l2_got_iframe},
-	{ST_L2_5, EV_L2_T200, l2_timeout},
-	{ST_L2_6, EV_L2_T200, l2_timeout},
-	{ST_L2_7, EV_L2_T200, l2_timeout},
-	{ST_L2_8, EV_L2_T200, l2_timeout},
-	{ST_L2_7, EV_L2_T203, l2_timeout},
-	{ST_L2_5, EV_L2_T200I, l2_st5_tout_200},
-	{ST_L2_6, EV_L2_T200I, l2_st6_tout_200},
-	{ST_L2_7, EV_L2_T200I, l2_st7_tout_200},
-	{ST_L2_8, EV_L2_T200I, l2_st8_tout_200},
-	{ST_L2_7, EV_L2_T203I, l2_st7_tout_203},
-	{ST_L2_7, EV_L2_ACK_PULL, l2_pull_iqueue},
-	{ST_L2_7, EV_L2_SET_OWN_BUSY, l2_set_own_busy},
-	{ST_L2_8, EV_L2_SET_OWN_BUSY, l2_set_own_busy},
-	{ST_L2_7, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy},
-	{ST_L2_8, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy},
-	{ST_L2_4, EV_L2_FRAME_ERROR, l2_frame_error},
-	{ST_L2_5, EV_L2_FRAME_ERROR, l2_frame_error},
-	{ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error},
-	{ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest},
-	{ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest},
-	{ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistent_da},
-	{ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove},
-	{ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove},
-	{ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistent_da},
-	{ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistent_da},
-	{ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistent_da},
-	{ST_L2_7, EV_L1_DEACTIVATE, l2_persistent_da},
-	{ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da},
-};
-
-static int
-ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
-{
-	u_char	*datap = skb->data;
-	int	ret = -EINVAL;
-	int	psapi, ptei;
-	u_int	l;
-	int	c = 0;
-
-	l = l2addrsize(l2);
-	if (skb->len <= l) {
-		mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *) 'N');
-		return ret;
-	}
-	if (test_bit(FLG_LAPD, &l2->flag)) { /* Maybe not needed */
-		psapi = *datap++;
-		ptei = *datap++;
-		if ((psapi & 1) || !(ptei & 1)) {
-			printk(KERN_WARNING
-			       "%s l2 D-channel frame wrong EA0/EA1\n",
-			       mISDNDevName4ch(&l2->ch));
-			return ret;
-		}
-		psapi >>= 2;
-		ptei >>= 1;
-		if (psapi != l2->sapi) {
-			/* not our business */
-			if (*debug & DEBUG_L2)
-				printk(KERN_DEBUG "%s: sapi %d/%d mismatch\n",
-				       mISDNDevName4ch(&l2->ch), psapi,
-				       l2->sapi);
-			dev_kfree_skb(skb);
-			return 0;
-		}
-		if ((ptei != l2->tei) && (ptei != GROUP_TEI)) {
-			/* not our business */
-			if (*debug & DEBUG_L2)
-				printk(KERN_DEBUG "%s: tei %d/%d mismatch\n",
-				       mISDNDevName4ch(&l2->ch), ptei, l2->tei);
-			dev_kfree_skb(skb);
-			return 0;
-		}
-	} else
-		datap += l;
-	if (!(*datap & 1)) {	/* I-Frame */
-		c = iframe_error(l2, skb);
-		if (!c)
-			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_I, skb);
-	} else if (IsSFrame(datap, l2)) {	/* S-Frame */
-		c = super_error(l2, skb);
-		if (!c)
-			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SUPER, skb);
-	} else if (IsUI(datap)) {
-		c = UI_error(l2, skb);
-		if (!c)
-			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UI, skb);
-	} else if (IsSABME(datap, l2)) {
-		c = unnum_error(l2, skb, CMD);
-		if (!c)
-			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SABME, skb);
-	} else if (IsUA(datap)) {
-		c = unnum_error(l2, skb, RSP);
-		if (!c)
-			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UA, skb);
-	} else if (IsDISC(datap)) {
-		c = unnum_error(l2, skb, CMD);
-		if (!c)
-			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DISC, skb);
-	} else if (IsDM(datap)) {
-		c = unnum_error(l2, skb, RSP);
-		if (!c)
-			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DM, skb);
-	} else if (IsFRMR(datap)) {
-		c = FRMR_error(l2, skb);
-		if (!c)
-			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_FRMR, skb);
-	} else
-		c = 'L';
-	if (c) {
-		printk(KERN_WARNING "%s:l2 D-channel frame error %c\n",
-		       mISDNDevName4ch(&l2->ch), c);
-		mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *)(long)c);
-	}
-	return ret;
-}
-
-static int
-l2_send(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct layer2		*l2 = container_of(ch, struct layer2, ch);
-	struct mISDNhead	*hh =  mISDN_HEAD_P(skb);
-	int			ret = -EINVAL;
-
-	if (*debug & DEBUG_L2_RECV)
-		printk(KERN_DEBUG "%s: %s prim(%x) id(%x) sapi(%d) tei(%d)\n",
-		       __func__, mISDNDevName4ch(&l2->ch), hh->prim, hh->id,
-		       l2->sapi, l2->tei);
-	if (hh->prim == DL_INTERN_MSG) {
-		struct mISDNhead *chh = hh + 1; /* saved copy */
-
-		*hh = *chh;
-		if (*debug & DEBUG_L2_RECV)
-			printk(KERN_DEBUG "%s: prim(%x) id(%x) internal msg\n",
-				mISDNDevName4ch(&l2->ch), hh->prim, hh->id);
-	}
-	switch (hh->prim) {
-	case PH_DATA_IND:
-		ret = ph_data_indication(l2, hh, skb);
-		break;
-	case PH_DATA_CNF:
-		ret = ph_data_confirm(l2, hh, skb);
-		break;
-	case PH_ACTIVATE_IND:
-		test_and_set_bit(FLG_L1_ACTIV, &l2->flag);
-		l2up_create(l2, MPH_ACTIVATE_IND, 0, NULL);
-		if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag))
-			ret = mISDN_FsmEvent(&l2->l2m,
-					     EV_L2_DL_ESTABLISH_REQ, skb);
-		break;
-	case PH_DEACTIVATE_IND:
-		test_and_clear_bit(FLG_L1_ACTIV, &l2->flag);
-		l2up_create(l2, MPH_DEACTIVATE_IND, 0, NULL);
-		ret = mISDN_FsmEvent(&l2->l2m, EV_L1_DEACTIVATE, skb);
-		break;
-	case MPH_INFORMATION_IND:
-		if (!l2->up)
-			break;
-		ret = l2->up->send(l2->up, skb);
-		break;
-	case DL_DATA_REQ:
-		ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_DATA, skb);
-		break;
-	case DL_UNITDATA_REQ:
-		ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_UNITDATA, skb);
-		break;
-	case DL_ESTABLISH_REQ:
-		if (test_bit(FLG_LAPB, &l2->flag))
-			test_and_set_bit(FLG_ORIG, &l2->flag);
-		if (test_bit(FLG_L1_ACTIV, &l2->flag)) {
-			if (test_bit(FLG_LAPD, &l2->flag) ||
-			    test_bit(FLG_ORIG, &l2->flag))
-				ret = mISDN_FsmEvent(&l2->l2m,
-						     EV_L2_DL_ESTABLISH_REQ, skb);
-		} else {
-			if (test_bit(FLG_LAPD, &l2->flag) ||
-			    test_bit(FLG_ORIG, &l2->flag)) {
-				test_and_set_bit(FLG_ESTAB_PEND,
-						 &l2->flag);
-			}
-			ret = l2down(l2, PH_ACTIVATE_REQ, l2_newid(l2),
-				     skb);
-		}
-		break;
-	case DL_RELEASE_REQ:
-		if (test_bit(FLG_LAPB, &l2->flag))
-			l2down_create(l2, PH_DEACTIVATE_REQ,
-				      l2_newid(l2), 0, NULL);
-		ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_RELEASE_REQ,
-				     skb);
-		break;
-	case DL_TIMER200_IND:
-		mISDN_FsmEvent(&l2->l2m, EV_L2_T200I, NULL);
-		break;
-	case DL_TIMER203_IND:
-		mISDN_FsmEvent(&l2->l2m, EV_L2_T203I, NULL);
-		break;
-	default:
-		if (*debug & DEBUG_L2)
-			l2m_debug(&l2->l2m, "l2 unknown pr %04x",
-				  hh->prim);
-	}
-	if (ret) {
-		dev_kfree_skb(skb);
-		ret = 0;
-	}
-	return ret;
-}
-
-int
-tei_l2(struct layer2 *l2, u_int cmd, u_long arg)
-{
-	int		ret = -EINVAL;
-
-	if (*debug & DEBUG_L2_TEI)
-		printk(KERN_DEBUG "%s: cmd(%x) in %s\n",
-		       mISDNDevName4ch(&l2->ch), cmd, __func__);
-	switch (cmd) {
-	case (MDL_ASSIGN_REQ):
-		ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ASSIGN, (void *)arg);
-		break;
-	case (MDL_REMOVE_REQ):
-		ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_REMOVE, NULL);
-		break;
-	case (MDL_ERROR_IND):
-		ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, NULL);
-		break;
-	case (MDL_ERROR_RSP):
-		/* ETS 300-125 5.3.2.1 Test: TC13010 */
-		printk(KERN_NOTICE "%s: MDL_ERROR|REQ (tei_l2)\n",
-		       mISDNDevName4ch(&l2->ch));
-		ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, NULL);
-		break;
-	}
-	return ret;
-}
-
-static void
-release_l2(struct layer2 *l2)
-{
-	mISDN_FsmDelTimer(&l2->t200, 21);
-	mISDN_FsmDelTimer(&l2->t203, 16);
-	skb_queue_purge(&l2->i_queue);
-	skb_queue_purge(&l2->ui_queue);
-	skb_queue_purge(&l2->down_queue);
-	ReleaseWin(l2);
-	if (test_bit(FLG_LAPD, &l2->flag)) {
-		TEIrelease(l2);
-		if (l2->ch.st)
-			l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D,
-					       CLOSE_CHANNEL, NULL);
-	}
-	kfree(l2);
-}
-
-static int
-l2_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
-{
-	struct layer2		*l2 = container_of(ch, struct layer2, ch);
-	u_int			info;
-
-	if (*debug & DEBUG_L2_CTRL)
-		printk(KERN_DEBUG "%s: %s cmd(%x)\n",
-		       mISDNDevName4ch(ch), __func__, cmd);
-
-	switch (cmd) {
-	case OPEN_CHANNEL:
-		if (test_bit(FLG_LAPD, &l2->flag)) {
-			set_channel_address(&l2->ch, l2->sapi, l2->tei);
-			info = DL_INFO_L2_CONNECT;
-			l2up_create(l2, DL_INFORMATION_IND,
-				    sizeof(info), &info);
-		}
-		break;
-	case CLOSE_CHANNEL:
-		if (l2->ch.peer)
-			l2->ch.peer->ctrl(l2->ch.peer, CLOSE_CHANNEL, NULL);
-		release_l2(l2);
-		break;
-	}
-	return 0;
-}
-
-struct layer2 *
-create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei,
-	  int sapi)
-{
-	struct layer2		*l2;
-	struct channel_req	rq;
-
-	l2 = kzalloc_obj(struct layer2);
-	if (!l2) {
-		printk(KERN_ERR "kzalloc layer2 failed\n");
-		return NULL;
-	}
-	l2->next_id = 1;
-	l2->down_id = MISDN_ID_NONE;
-	l2->up = ch;
-	l2->ch.st = ch->st;
-	l2->ch.send = l2_send;
-	l2->ch.ctrl = l2_ctrl;
-	switch (protocol) {
-	case ISDN_P_LAPD_NT:
-		test_and_set_bit(FLG_LAPD, &l2->flag);
-		test_and_set_bit(FLG_LAPD_NET, &l2->flag);
-		test_and_set_bit(FLG_MOD128, &l2->flag);
-		l2->sapi = sapi;
-		l2->maxlen = MAX_DFRAME_LEN;
-		if (test_bit(OPTION_L2_PMX, &options))
-			l2->window = 7;
-		else
-			l2->window = 1;
-		if (test_bit(OPTION_L2_PTP, &options))
-			test_and_set_bit(FLG_PTP, &l2->flag);
-		if (test_bit(OPTION_L2_FIXEDTEI, &options))
-			test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
-		l2->tei = tei;
-		l2->T200 = 1000;
-		l2->N200 = 3;
-		l2->T203 = 10000;
-		if (test_bit(OPTION_L2_PMX, &options))
-			rq.protocol = ISDN_P_NT_E1;
-		else
-			rq.protocol = ISDN_P_NT_S0;
-		rq.adr.channel = 0;
-		l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, OPEN_CHANNEL, &rq);
-		break;
-	case ISDN_P_LAPD_TE:
-		test_and_set_bit(FLG_LAPD, &l2->flag);
-		test_and_set_bit(FLG_MOD128, &l2->flag);
-		test_and_set_bit(FLG_ORIG, &l2->flag);
-		l2->sapi = sapi;
-		l2->maxlen = MAX_DFRAME_LEN;
-		if (test_bit(OPTION_L2_PMX, &options))
-			l2->window = 7;
-		else
-			l2->window = 1;
-		if (test_bit(OPTION_L2_PTP, &options))
-			test_and_set_bit(FLG_PTP, &l2->flag);
-		if (test_bit(OPTION_L2_FIXEDTEI, &options))
-			test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
-		l2->tei = tei;
-		l2->T200 = 1000;
-		l2->N200 = 3;
-		l2->T203 = 10000;
-		if (test_bit(OPTION_L2_PMX, &options))
-			rq.protocol = ISDN_P_TE_E1;
-		else
-			rq.protocol = ISDN_P_TE_S0;
-		rq.adr.channel = 0;
-		l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, OPEN_CHANNEL, &rq);
-		break;
-	case ISDN_P_B_X75SLP:
-		test_and_set_bit(FLG_LAPB, &l2->flag);
-		l2->window = 7;
-		l2->maxlen = MAX_DATA_SIZE;
-		l2->T200 = 1000;
-		l2->N200 = 4;
-		l2->T203 = 5000;
-		l2->addr.A = 3;
-		l2->addr.B = 1;
-		break;
-	default:
-		printk(KERN_ERR "layer2 create failed prt %x\n",
-		       protocol);
-		kfree(l2);
-		return NULL;
-	}
-	skb_queue_head_init(&l2->i_queue);
-	skb_queue_head_init(&l2->ui_queue);
-	skb_queue_head_init(&l2->down_queue);
-	skb_queue_head_init(&l2->tmp_queue);
-	InitWin(l2);
-	l2->l2m.fsm = &l2fsm;
-	if (test_bit(FLG_LAPB, &l2->flag) ||
-	    test_bit(FLG_FIXED_TEI, &l2->flag) ||
-	    test_bit(FLG_LAPD_NET, &l2->flag))
-		l2->l2m.state = ST_L2_4;
-	else
-		l2->l2m.state = ST_L2_1;
-	l2->l2m.debug = *debug;
-	l2->l2m.userdata = l2;
-	l2->l2m.userint = 0;
-	l2->l2m.printdebug = l2m_debug;
-
-	mISDN_FsmInitTimer(&l2->l2m, &l2->t200);
-	mISDN_FsmInitTimer(&l2->l2m, &l2->t203);
-	return l2;
-}
-
-static int
-x75create(struct channel_req *crq)
-{
-	struct layer2	*l2;
-
-	if (crq->protocol != ISDN_P_B_X75SLP)
-		return -EPROTONOSUPPORT;
-	l2 = create_l2(crq->ch, crq->protocol, 0, 0, 0);
-	if (!l2)
-		return -ENOMEM;
-	crq->ch = &l2->ch;
-	crq->protocol = ISDN_P_B_HDLC;
-	return 0;
-}
-
-static struct Bprotocol X75SLP = {
-	.Bprotocols = (1 << (ISDN_P_B_X75SLP & ISDN_P_B_MASK)),
-	.name = "X75SLP",
-	.create = x75create
-};
-
-int
-Isdnl2_Init(u_int *deb)
-{
-	int res;
-	debug = deb;
-	mISDN_register_Bprotocol(&X75SLP);
-	l2fsm.state_count = L2_STATE_COUNT;
-	l2fsm.event_count = L2_EVENT_COUNT;
-	l2fsm.strEvent = strL2Event;
-	l2fsm.strState = strL2State;
-	res = mISDN_FsmNew(&l2fsm, L2FnList, ARRAY_SIZE(L2FnList));
-	if (res)
-		goto error;
-	res = TEIInit(deb);
-	if (res)
-		goto error_fsm;
-	return 0;
-
-error_fsm:
-	mISDN_FsmFree(&l2fsm);
-error:
-	mISDN_unregister_Bprotocol(&X75SLP);
-	return res;
-}
-
-void
-Isdnl2_cleanup(void)
-{
-	mISDN_unregister_Bprotocol(&X75SLP);
-	TEIFree();
-	mISDN_FsmFree(&l2fsm);
-}
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
deleted file mode 100644
index 77b900db1cac..000000000000
--- a/drivers/isdn/mISDN/socket.c
+++ /dev/null
@@ -1,825 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *
- * Author	Karsten Keil <kkeil@novell.com>
- *
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- */
-
-#include <linux/mISDNif.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include "core.h"
-
-static u_int	*debug;
-
-static struct proto mISDN_proto = {
-	.name		= "misdn",
-	.owner		= THIS_MODULE,
-	.obj_size	= sizeof(struct mISDN_sock)
-};
-
-#define _pms(sk)	((struct mISDN_sock *)sk)
-
-static struct mISDN_sock_list	data_sockets = {
-	.lock = __RW_LOCK_UNLOCKED(data_sockets.lock)
-};
-
-static struct mISDN_sock_list	base_sockets = {
-	.lock = __RW_LOCK_UNLOCKED(base_sockets.lock)
-};
-
-#define L2_HEADER_LEN	4
-
-static inline struct sk_buff *
-_l2_alloc_skb(unsigned int len, gfp_t gfp_mask)
-{
-	struct sk_buff  *skb;
-
-	skb = alloc_skb(len + L2_HEADER_LEN, gfp_mask);
-	if (likely(skb))
-		skb_reserve(skb, L2_HEADER_LEN);
-	return skb;
-}
-
-static void
-mISDN_sock_link(struct mISDN_sock_list *l, struct sock *sk)
-{
-	write_lock_bh(&l->lock);
-	sk_add_node(sk, &l->head);
-	write_unlock_bh(&l->lock);
-}
-
-static void mISDN_sock_unlink(struct mISDN_sock_list *l, struct sock *sk)
-{
-	write_lock_bh(&l->lock);
-	sk_del_node_init(sk);
-	write_unlock_bh(&l->lock);
-}
-
-static int
-mISDN_send(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct mISDN_sock *msk;
-	int	err;
-
-	msk = container_of(ch, struct mISDN_sock, ch);
-	if (*debug & DEBUG_SOCKET)
-		printk(KERN_DEBUG "%s len %d %p\n", __func__, skb->len, skb);
-	if (msk->sk.sk_state == MISDN_CLOSED)
-		return -EUNATCH;
-	__net_timestamp(skb);
-	err = sock_queue_rcv_skb(&msk->sk, skb);
-	if (err)
-		printk(KERN_WARNING "%s: error %d\n", __func__, err);
-	return err;
-}
-
-static int
-mISDN_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
-{
-	struct mISDN_sock *msk;
-
-	msk = container_of(ch, struct mISDN_sock, ch);
-	if (*debug & DEBUG_SOCKET)
-		printk(KERN_DEBUG "%s(%p, %x, %p)\n", __func__, ch, cmd, arg);
-	switch (cmd) {
-	case CLOSE_CHANNEL:
-		msk->sk.sk_state = MISDN_CLOSED;
-		break;
-	}
-	return 0;
-}
-
-static inline void
-mISDN_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
-{
-	struct __kernel_old_timeval	tv;
-
-	if (_pms(sk)->cmask & MISDN_TIME_STAMP) {
-		skb_get_timestamp(skb, &tv);
-		put_cmsg(msg, SOL_MISDN, MISDN_TIME_STAMP, sizeof(tv), &tv);
-	}
-}
-
-static int
-mISDN_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
-		   int flags)
-{
-	struct sk_buff		*skb;
-	struct sock		*sk = sock->sk;
-
-	int		copied, err;
-
-	if (*debug & DEBUG_SOCKET)
-		printk(KERN_DEBUG "%s: len %d, flags %x ch.nr %d, proto %x\n",
-		       __func__, (int)len, flags, _pms(sk)->ch.nr,
-		       sk->sk_protocol);
-	if (flags & (MSG_OOB))
-		return -EOPNOTSUPP;
-
-	if (sk->sk_state == MISDN_CLOSED)
-		return 0;
-
-	skb = skb_recv_datagram(sk, flags, &err);
-	if (!skb)
-		return err;
-
-	if (msg->msg_name) {
-		DECLARE_SOCKADDR(struct sockaddr_mISDN *, maddr, msg->msg_name);
-
-		maddr->family = AF_ISDN;
-		maddr->dev = _pms(sk)->dev->id;
-		if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
-		    (sk->sk_protocol == ISDN_P_LAPD_NT)) {
-			maddr->channel = (mISDN_HEAD_ID(skb) >> 16) & 0xff;
-			maddr->tei =  (mISDN_HEAD_ID(skb) >> 8) & 0xff;
-			maddr->sapi = mISDN_HEAD_ID(skb) & 0xff;
-		} else {
-			maddr->channel = _pms(sk)->ch.nr;
-			maddr->sapi = _pms(sk)->ch.addr & 0xFF;
-			maddr->tei =  (_pms(sk)->ch.addr >> 8) & 0xFF;
-		}
-		msg->msg_namelen = sizeof(*maddr);
-	}
-
-	copied = skb->len + MISDN_HEADER_LEN;
-	if (len < copied) {
-		if (flags & MSG_PEEK)
-			refcount_dec(&skb->users);
-		else
-			skb_queue_head(&sk->sk_receive_queue, skb);
-		return -ENOSPC;
-	}
-	memcpy(skb_push(skb, MISDN_HEADER_LEN), mISDN_HEAD_P(skb),
-	       MISDN_HEADER_LEN);
-
-	err = skb_copy_datagram_msg(skb, 0, msg, copied);
-
-	mISDN_sock_cmsg(sk, msg, skb);
-
-	skb_free_datagram(sk, skb);
-
-	return err ? : copied;
-}
-
-static int
-mISDN_sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
-{
-	struct sock		*sk = sock->sk;
-	struct sk_buff		*skb;
-	int			err = -ENOMEM;
-
-	if (*debug & DEBUG_SOCKET)
-		printk(KERN_DEBUG "%s: len %d flags %x ch %d proto %x\n",
-		       __func__, (int)len, msg->msg_flags, _pms(sk)->ch.nr,
-		       sk->sk_protocol);
-
-	if (msg->msg_flags & MSG_OOB)
-		return -EOPNOTSUPP;
-
-	if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_NOSIGNAL | MSG_ERRQUEUE))
-		return -EINVAL;
-
-	if (len < MISDN_HEADER_LEN)
-		return -EINVAL;
-
-	if (sk->sk_state != MISDN_BOUND)
-		return -EBADFD;
-
-	lock_sock(sk);
-
-	skb = _l2_alloc_skb(len, GFP_KERNEL);
-	if (!skb)
-		goto done;
-
-	if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
-		err = -EFAULT;
-		goto done;
-	}
-
-	memcpy(mISDN_HEAD_P(skb), skb->data, MISDN_HEADER_LEN);
-	skb_pull(skb, MISDN_HEADER_LEN);
-
-	if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
-		/* if we have a address, we use it */
-		DECLARE_SOCKADDR(struct sockaddr_mISDN *, maddr, msg->msg_name);
-		mISDN_HEAD_ID(skb) = maddr->channel;
-	} else { /* use default for L2 messages */
-		if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
-		    (sk->sk_protocol == ISDN_P_LAPD_NT))
-			mISDN_HEAD_ID(skb) = _pms(sk)->ch.nr;
-	}
-
-	if (*debug & DEBUG_SOCKET)
-		printk(KERN_DEBUG "%s: ID:%x\n",
-		       __func__, mISDN_HEAD_ID(skb));
-
-	err = -ENODEV;
-	if (!_pms(sk)->ch.peer)
-		goto done;
-	err = _pms(sk)->ch.recv(_pms(sk)->ch.peer, skb);
-	if (err)
-		goto done;
-	else {
-		skb = NULL;
-		err = len;
-	}
-
-done:
-	kfree_skb(skb);
-	release_sock(sk);
-	return err;
-}
-
-static int
-data_sock_release(struct socket *sock)
-{
-	struct sock *sk = sock->sk;
-
-	if (*debug & DEBUG_SOCKET)
-		printk(KERN_DEBUG "%s(%p) sk=%p\n", __func__, sock, sk);
-	if (!sk)
-		return 0;
-	switch (sk->sk_protocol) {
-	case ISDN_P_TE_S0:
-	case ISDN_P_NT_S0:
-	case ISDN_P_TE_E1:
-	case ISDN_P_NT_E1:
-		if (sk->sk_state == MISDN_BOUND)
-			delete_channel(&_pms(sk)->ch);
-		else
-			mISDN_sock_unlink(&data_sockets, sk);
-		break;
-	case ISDN_P_LAPD_TE:
-	case ISDN_P_LAPD_NT:
-	case ISDN_P_B_RAW:
-	case ISDN_P_B_HDLC:
-	case ISDN_P_B_X75SLP:
-	case ISDN_P_B_L2DTMF:
-	case ISDN_P_B_L2DSP:
-	case ISDN_P_B_L2DSPHDLC:
-		delete_channel(&_pms(sk)->ch);
-		mISDN_sock_unlink(&data_sockets, sk);
-		break;
-	}
-
-	lock_sock(sk);
-
-	sock_orphan(sk);
-	skb_queue_purge(&sk->sk_receive_queue);
-
-	release_sock(sk);
-	sock_put(sk);
-
-	return 0;
-}
-
-static int
-data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
-{
-	struct mISDN_ctrl_req	cq;
-	int			err = -EINVAL, val[2];
-	struct mISDNchannel	*bchan, *next;
-
-	lock_sock(sk);
-	if (!_pms(sk)->dev) {
-		err = -ENODEV;
-		goto done;
-	}
-	switch (cmd) {
-	case IMCTRLREQ:
-		if (copy_from_user(&cq, p, sizeof(cq))) {
-			err = -EFAULT;
-			break;
-		}
-		if ((sk->sk_protocol & ~ISDN_P_B_MASK) == ISDN_P_B_START) {
-			list_for_each_entry_safe(bchan, next,
-						 &_pms(sk)->dev->bchannels, list) {
-				if (bchan->nr == cq.channel) {
-					err = bchan->ctrl(bchan,
-							  CONTROL_CHANNEL, &cq);
-					break;
-				}
-			}
-		} else
-			err = _pms(sk)->dev->D.ctrl(&_pms(sk)->dev->D,
-						    CONTROL_CHANNEL, &cq);
-		if (err)
-			break;
-		if (copy_to_user(p, &cq, sizeof(cq)))
-			err = -EFAULT;
-		break;
-	case IMCLEAR_L2:
-		if (sk->sk_protocol != ISDN_P_LAPD_NT) {
-			err = -EINVAL;
-			break;
-		}
-		val[0] = cmd;
-		if (get_user(val[1], (int __user *)p)) {
-			err = -EFAULT;
-			break;
-		}
-		err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
-						  CONTROL_CHANNEL, val);
-		break;
-	case IMHOLD_L1:
-		if (sk->sk_protocol != ISDN_P_LAPD_NT
-		    && sk->sk_protocol != ISDN_P_LAPD_TE) {
-			err = -EINVAL;
-			break;
-		}
-		val[0] = cmd;
-		if (get_user(val[1], (int __user *)p)) {
-			err = -EFAULT;
-			break;
-		}
-		err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
-						  CONTROL_CHANNEL, val);
-		break;
-	default:
-		err = -EINVAL;
-		break;
-	}
-done:
-	release_sock(sk);
-	return err;
-}
-
-static int
-data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
-	int			err = 0, id;
-	struct sock		*sk = sock->sk;
-	struct mISDNdevice	*dev;
-	struct mISDNversion	ver;
-
-	switch (cmd) {
-	case IMGETVERSION:
-		ver.major = MISDN_MAJOR_VERSION;
-		ver.minor = MISDN_MINOR_VERSION;
-		ver.release = MISDN_RELEASE;
-		if (copy_to_user((void __user *)arg, &ver, sizeof(ver)))
-			err = -EFAULT;
-		break;
-	case IMGETCOUNT:
-		id = get_mdevice_count();
-		if (put_user(id, (int __user *)arg))
-			err = -EFAULT;
-		break;
-	case IMGETDEVINFO:
-		if (get_user(id, (int __user *)arg)) {
-			err = -EFAULT;
-			break;
-		}
-		dev = get_mdevice(id);
-		if (dev) {
-			struct mISDN_devinfo di;
-
-			memset(&di, 0, sizeof(di));
-			di.id = dev->id;
-			di.Dprotocols = dev->Dprotocols;
-			di.Bprotocols = dev->Bprotocols | get_all_Bprotocols();
-			di.protocol = dev->D.protocol;
-			memcpy(di.channelmap, dev->channelmap,
-			       sizeof(di.channelmap));
-			di.nrbchan = dev->nrbchan;
-			strscpy(di.name, dev_name(&dev->dev), sizeof(di.name));
-			if (copy_to_user((void __user *)arg, &di, sizeof(di)))
-				err = -EFAULT;
-		} else
-			err = -ENODEV;
-		break;
-	default:
-		if (sk->sk_state == MISDN_BOUND)
-			err = data_sock_ioctl_bound(sk, cmd,
-						    (void __user *)arg);
-		else
-			err = -ENOTCONN;
-	}
-	return err;
-}
-
-static int data_sock_setsockopt(struct socket *sock, int level, int optname,
-				sockptr_t optval, unsigned int optlen)
-{
-	struct sock *sk = sock->sk;
-	int err = 0, opt = 0;
-
-	if (*debug & DEBUG_SOCKET)
-		printk(KERN_DEBUG "%s(%p, %d, %x, optval, %d)\n", __func__, sock,
-		       level, optname, optlen);
-
-	lock_sock(sk);
-
-	switch (optname) {
-	case MISDN_TIME_STAMP:
-		err = copy_safe_from_sockptr(&opt, sizeof(opt),
-					     optval, optlen);
-		if (err)
-			break;
-
-		if (opt)
-			_pms(sk)->cmask |= MISDN_TIME_STAMP;
-		else
-			_pms(sk)->cmask &= ~MISDN_TIME_STAMP;
-		break;
-	default:
-		err = -ENOPROTOOPT;
-		break;
-	}
-	release_sock(sk);
-	return err;
-}
-
-static int data_sock_getsockopt(struct socket *sock, int level, int optname,
-				char __user *optval, int __user *optlen)
-{
-	struct sock *sk = sock->sk;
-	int len, opt;
-
-	if (get_user(len, optlen))
-		return -EFAULT;
-
-	if (len != sizeof(char))
-		return -EINVAL;
-
-	switch (optname) {
-	case MISDN_TIME_STAMP:
-		if (_pms(sk)->cmask & MISDN_TIME_STAMP)
-			opt = 1;
-		else
-			opt = 0;
-
-		if (put_user(opt, optval))
-			return -EFAULT;
-		break;
-	default:
-		return -ENOPROTOOPT;
-	}
-
-	return 0;
-}
-
-static int
-data_sock_bind(struct socket *sock, struct sockaddr_unsized *addr, int addr_len)
-{
-	struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
-	struct sock *sk = sock->sk;
-	struct sock *csk;
-	int err = 0;
-
-	if (*debug & DEBUG_SOCKET)
-		printk(KERN_DEBUG "%s(%p) sk=%p\n", __func__, sock, sk);
-	if (addr_len != sizeof(struct sockaddr_mISDN))
-		return -EINVAL;
-	if (!maddr || maddr->family != AF_ISDN)
-		return -EINVAL;
-
-	lock_sock(sk);
-
-	if (_pms(sk)->dev) {
-		err = -EALREADY;
-		goto done;
-	}
-	_pms(sk)->dev = get_mdevice(maddr->dev);
-	if (!_pms(sk)->dev) {
-		err = -ENODEV;
-		goto done;
-	}
-
-	if (sk->sk_protocol < ISDN_P_B_START) {
-		read_lock_bh(&data_sockets.lock);
-		sk_for_each(csk, &data_sockets.head) {
-			if (sk == csk)
-				continue;
-			if (_pms(csk)->dev != _pms(sk)->dev)
-				continue;
-			if (csk->sk_protocol >= ISDN_P_B_START)
-				continue;
-			if (IS_ISDN_P_TE(csk->sk_protocol)
-			    == IS_ISDN_P_TE(sk->sk_protocol))
-				continue;
-			read_unlock_bh(&data_sockets.lock);
-			err = -EBUSY;
-			goto done;
-		}
-		read_unlock_bh(&data_sockets.lock);
-	}
-
-	_pms(sk)->ch.send = mISDN_send;
-	_pms(sk)->ch.ctrl = mISDN_ctrl;
-
-	switch (sk->sk_protocol) {
-	case ISDN_P_TE_S0:
-	case ISDN_P_NT_S0:
-	case ISDN_P_TE_E1:
-	case ISDN_P_NT_E1:
-		mISDN_sock_unlink(&data_sockets, sk);
-		err = connect_layer1(_pms(sk)->dev, &_pms(sk)->ch,
-				     sk->sk_protocol, maddr);
-		if (err)
-			mISDN_sock_link(&data_sockets, sk);
-		break;
-	case ISDN_P_LAPD_TE:
-	case ISDN_P_LAPD_NT:
-		err = create_l2entity(_pms(sk)->dev, &_pms(sk)->ch,
-				      sk->sk_protocol, maddr);
-		break;
-	case ISDN_P_B_RAW:
-	case ISDN_P_B_HDLC:
-	case ISDN_P_B_X75SLP:
-	case ISDN_P_B_L2DTMF:
-	case ISDN_P_B_L2DSP:
-	case ISDN_P_B_L2DSPHDLC:
-		err = connect_Bstack(_pms(sk)->dev, &_pms(sk)->ch,
-				     sk->sk_protocol, maddr);
-		break;
-	default:
-		err = -EPROTONOSUPPORT;
-	}
-	if (err)
-		goto done;
-	sk->sk_state = MISDN_BOUND;
-	_pms(sk)->ch.protocol = sk->sk_protocol;
-
-done:
-	release_sock(sk);
-	return err;
-}
-
-static int
-data_sock_getname(struct socket *sock, struct sockaddr *addr,
-		  int peer)
-{
-	struct sockaddr_mISDN	*maddr = (struct sockaddr_mISDN *) addr;
-	struct sock		*sk = sock->sk;
-
-	if (!_pms(sk)->dev)
-		return -EBADFD;
-
-	lock_sock(sk);
-
-	maddr->family = AF_ISDN;
-	maddr->dev = _pms(sk)->dev->id;
-	maddr->channel = _pms(sk)->ch.nr;
-	maddr->sapi = _pms(sk)->ch.addr & 0xff;
-	maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xff;
-	release_sock(sk);
-	return sizeof(*maddr);
-}
-
-static const struct proto_ops data_sock_ops = {
-	.family		= PF_ISDN,
-	.owner		= THIS_MODULE,
-	.release	= data_sock_release,
-	.ioctl		= data_sock_ioctl,
-	.bind		= data_sock_bind,
-	.getname	= data_sock_getname,
-	.sendmsg	= mISDN_sock_sendmsg,
-	.recvmsg	= mISDN_sock_recvmsg,
-	.poll		= datagram_poll,
-	.listen		= sock_no_listen,
-	.shutdown	= sock_no_shutdown,
-	.setsockopt	= data_sock_setsockopt,
-	.getsockopt	= data_sock_getsockopt,
-	.connect	= sock_no_connect,
-	.socketpair	= sock_no_socketpair,
-	.accept		= sock_no_accept,
-	.mmap		= sock_no_mmap
-};
-
-static int
-data_sock_create(struct net *net, struct socket *sock, int protocol, int kern)
-{
-	struct sock *sk;
-
-	if (sock->type != SOCK_DGRAM)
-		return -ESOCKTNOSUPPORT;
-
-	sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto, kern);
-	if (!sk)
-		return -ENOMEM;
-
-	sock_init_data(sock, sk);
-
-	sock->ops = &data_sock_ops;
-	sock->state = SS_UNCONNECTED;
-	sock_reset_flag(sk, SOCK_ZAPPED);
-
-	sk->sk_protocol = protocol;
-	sk->sk_state    = MISDN_OPEN;
-	mISDN_sock_link(&data_sockets, sk);
-
-	return 0;
-}
-
-static int
-base_sock_release(struct socket *sock)
-{
-	struct sock *sk = sock->sk;
-
-	printk(KERN_DEBUG "%s(%p) sk=%p\n", __func__, sock, sk);
-	if (!sk)
-		return 0;
-
-	mISDN_sock_unlink(&base_sockets, sk);
-	sock_orphan(sk);
-	sock_put(sk);
-
-	return 0;
-}
-
-static int
-base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
-	int			err = 0, id;
-	struct mISDNdevice	*dev;
-	struct mISDNversion	ver;
-
-	switch (cmd) {
-	case IMGETVERSION:
-		ver.major = MISDN_MAJOR_VERSION;
-		ver.minor = MISDN_MINOR_VERSION;
-		ver.release = MISDN_RELEASE;
-		if (copy_to_user((void __user *)arg, &ver, sizeof(ver)))
-			err = -EFAULT;
-		break;
-	case IMGETCOUNT:
-		id = get_mdevice_count();
-		if (put_user(id, (int __user *)arg))
-			err = -EFAULT;
-		break;
-	case IMGETDEVINFO:
-		if (get_user(id, (int __user *)arg)) {
-			err = -EFAULT;
-			break;
-		}
-		dev = get_mdevice(id);
-		if (dev) {
-			struct mISDN_devinfo di;
-
-			memset(&di, 0, sizeof(di));
-			di.id = dev->id;
-			di.Dprotocols = dev->Dprotocols;
-			di.Bprotocols = dev->Bprotocols | get_all_Bprotocols();
-			di.protocol = dev->D.protocol;
-			memcpy(di.channelmap, dev->channelmap,
-			       sizeof(di.channelmap));
-			di.nrbchan = dev->nrbchan;
-			strscpy(di.name, dev_name(&dev->dev), sizeof(di.name));
-			if (copy_to_user((void __user *)arg, &di, sizeof(di)))
-				err = -EFAULT;
-		} else
-			err = -ENODEV;
-		break;
-	case IMSETDEVNAME:
-	{
-		struct mISDN_devrename dn;
-		if (copy_from_user(&dn, (void __user *)arg,
-				   sizeof(dn))) {
-			err = -EFAULT;
-			break;
-		}
-		dn.name[sizeof(dn.name) - 1] = '\0';
-		dev = get_mdevice(dn.id);
-		if (dev)
-			err = device_rename(&dev->dev, dn.name);
-		else
-			err = -ENODEV;
-	}
-	break;
-	default:
-		err = -EINVAL;
-	}
-	return err;
-}
-
-static int
-base_sock_bind(struct socket *sock, struct sockaddr_unsized *addr, int addr_len)
-{
-	struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
-	struct sock *sk = sock->sk;
-	int err = 0;
-
-	if (addr_len < sizeof(struct sockaddr_mISDN))
-		return -EINVAL;
-
-	if (!maddr || maddr->family != AF_ISDN)
-		return -EINVAL;
-
-	lock_sock(sk);
-
-	if (_pms(sk)->dev) {
-		err = -EALREADY;
-		goto done;
-	}
-
-	_pms(sk)->dev = get_mdevice(maddr->dev);
-	if (!_pms(sk)->dev) {
-		err = -ENODEV;
-		goto done;
-	}
-	sk->sk_state = MISDN_BOUND;
-
-done:
-	release_sock(sk);
-	return err;
-}
-
-static const struct proto_ops base_sock_ops = {
-	.family		= PF_ISDN,
-	.owner		= THIS_MODULE,
-	.release	= base_sock_release,
-	.ioctl		= base_sock_ioctl,
-	.bind		= base_sock_bind,
-	.getname	= sock_no_getname,
-	.sendmsg	= sock_no_sendmsg,
-	.recvmsg	= sock_no_recvmsg,
-	.listen		= sock_no_listen,
-	.shutdown	= sock_no_shutdown,
-	.connect	= sock_no_connect,
-	.socketpair	= sock_no_socketpair,
-	.accept		= sock_no_accept,
-	.mmap		= sock_no_mmap
-};
-
-
-static int
-base_sock_create(struct net *net, struct socket *sock, int protocol, int kern)
-{
-	struct sock *sk;
-
-	if (sock->type != SOCK_RAW)
-		return -ESOCKTNOSUPPORT;
-	if (!capable(CAP_NET_RAW))
-		return -EPERM;
-
-	sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto, kern);
-	if (!sk)
-		return -ENOMEM;
-
-	sock_init_data(sock, sk);
-	sock->ops = &base_sock_ops;
-	sock->state = SS_UNCONNECTED;
-	sock_reset_flag(sk, SOCK_ZAPPED);
-	sk->sk_protocol = protocol;
-	sk->sk_state    = MISDN_OPEN;
-	mISDN_sock_link(&base_sockets, sk);
-
-	return 0;
-}
-
-static int
-mISDN_sock_create(struct net *net, struct socket *sock, int proto, int kern)
-{
-	int err = -EPROTONOSUPPORT;
-
-	switch (proto) {
-	case ISDN_P_BASE:
-		err = base_sock_create(net, sock, proto, kern);
-		break;
-	case ISDN_P_TE_S0:
-	case ISDN_P_NT_S0:
-	case ISDN_P_TE_E1:
-	case ISDN_P_NT_E1:
-	case ISDN_P_LAPD_TE:
-	case ISDN_P_LAPD_NT:
-	case ISDN_P_B_RAW:
-	case ISDN_P_B_HDLC:
-	case ISDN_P_B_X75SLP:
-	case ISDN_P_B_L2DTMF:
-	case ISDN_P_B_L2DSP:
-	case ISDN_P_B_L2DSPHDLC:
-		err = data_sock_create(net, sock, proto, kern);
-		break;
-	default:
-		return err;
-	}
-
-	return err;
-}
-
-static const struct net_proto_family mISDN_sock_family_ops = {
-	.owner  = THIS_MODULE,
-	.family = PF_ISDN,
-	.create = mISDN_sock_create,
-};
-
-int
-misdn_sock_init(u_int *deb)
-{
-	int err;
-
-	debug = deb;
-	err = sock_register(&mISDN_sock_family_ops);
-	if (err)
-		printk(KERN_ERR "%s: error(%d)\n", __func__, err);
-	return err;
-}
-
-void
-misdn_sock_cleanup(void)
-{
-	sock_unregister(PF_ISDN);
-}
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c
deleted file mode 100644
index 4e96684af0aa..000000000000
--- a/drivers/isdn/mISDN/stack.c
+++ /dev/null
@@ -1,654 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *
- * Author	Karsten Keil <kkeil@novell.com>
- *
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- */
-
-#include <linux/slab.h>
-#include <linux/mISDNif.h>
-#include <linux/kthread.h>
-#include <linux/sched.h>
-#include <linux/sched/cputime.h>
-#include <linux/signal.h>
-
-#include "core.h"
-
-static u_int	*debug;
-
-static inline void
-_queue_message(struct mISDNstack *st, struct sk_buff *skb)
-{
-	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
-
-	if (*debug & DEBUG_QUEUE_FUNC)
-		printk(KERN_DEBUG "%s prim(%x) id(%x) %p\n",
-		       __func__, hh->prim, hh->id, skb);
-	skb_queue_tail(&st->msgq, skb);
-	if (likely(!test_bit(mISDN_STACK_STOPPED, &st->status))) {
-		test_and_set_bit(mISDN_STACK_WORK, &st->status);
-		wake_up_interruptible(&st->workq);
-	}
-}
-
-static int
-mISDN_queue_message(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	_queue_message(ch->st, skb);
-	return 0;
-}
-
-static struct mISDNchannel *
-get_channel4id(struct mISDNstack *st, u_int id)
-{
-	struct mISDNchannel	*ch;
-
-	mutex_lock(&st->lmutex);
-	list_for_each_entry(ch, &st->layer2, list) {
-		if (id == ch->nr)
-			goto unlock;
-	}
-	ch = NULL;
-unlock:
-	mutex_unlock(&st->lmutex);
-	return ch;
-}
-
-static void
-send_socklist(struct mISDN_sock_list *sl, struct sk_buff *skb)
-{
-	struct sock		*sk;
-	struct sk_buff		*cskb = NULL;
-
-	read_lock(&sl->lock);
-	sk_for_each(sk, &sl->head) {
-		if (sk->sk_state != MISDN_BOUND)
-			continue;
-		if (!cskb)
-			cskb = skb_copy(skb, GFP_ATOMIC);
-		if (!cskb) {
-			printk(KERN_WARNING "%s no skb\n", __func__);
-			break;
-		}
-		if (!sock_queue_rcv_skb(sk, cskb))
-			cskb = NULL;
-	}
-	read_unlock(&sl->lock);
-	dev_kfree_skb(cskb);
-}
-
-static void
-send_layer2(struct mISDNstack *st, struct sk_buff *skb)
-{
-	struct sk_buff		*cskb;
-	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
-	struct mISDNchannel	*ch;
-	int			ret;
-
-	if (!st)
-		return;
-	mutex_lock(&st->lmutex);
-	if ((hh->id & MISDN_ID_ADDR_MASK) == MISDN_ID_ANY) { /* L2 for all */
-		list_for_each_entry(ch, &st->layer2, list) {
-			if (list_is_last(&ch->list, &st->layer2)) {
-				cskb = skb;
-				skb = NULL;
-			} else {
-				cskb = skb_copy(skb, GFP_KERNEL);
-			}
-			if (cskb) {
-				ret = ch->send(ch, cskb);
-				if (ret) {
-					if (*debug & DEBUG_SEND_ERR)
-						printk(KERN_DEBUG
-						       "%s ch%d prim(%x) addr(%x)"
-						       " err %d\n",
-						       __func__, ch->nr,
-						       hh->prim, ch->addr, ret);
-					dev_kfree_skb(cskb);
-				}
-			} else {
-				printk(KERN_WARNING "%s ch%d addr %x no mem\n",
-				       __func__, ch->nr, ch->addr);
-				goto out;
-			}
-		}
-	} else {
-		list_for_each_entry(ch, &st->layer2, list) {
-			if ((hh->id & MISDN_ID_ADDR_MASK) == ch->addr) {
-				ret = ch->send(ch, skb);
-				if (!ret)
-					skb = NULL;
-				goto out;
-			}
-		}
-		ret = st->dev->teimgr->ctrl(st->dev->teimgr, CHECK_DATA, skb);
-		if (!ret)
-			skb = NULL;
-		else if (*debug & DEBUG_SEND_ERR)
-			printk(KERN_DEBUG
-			       "%s mgr prim(%x) err %d\n",
-			       __func__, hh->prim, ret);
-	}
-out:
-	mutex_unlock(&st->lmutex);
-	dev_kfree_skb(skb);
-}
-
-static inline int
-send_msg_to_layer(struct mISDNstack *st, struct sk_buff *skb)
-{
-	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
-	struct mISDNchannel	*ch;
-	int	lm;
-
-	lm = hh->prim & MISDN_LAYERMASK;
-	if (*debug & DEBUG_QUEUE_FUNC)
-		printk(KERN_DEBUG "%s prim(%x) id(%x) %p\n",
-		       __func__, hh->prim, hh->id, skb);
-	if (lm == 0x1) {
-		if (!hlist_empty(&st->l1sock.head)) {
-			__net_timestamp(skb);
-			send_socklist(&st->l1sock, skb);
-		}
-		return st->layer1->send(st->layer1, skb);
-	} else if (lm == 0x2) {
-		if (!hlist_empty(&st->l1sock.head))
-			send_socklist(&st->l1sock, skb);
-		send_layer2(st, skb);
-		return 0;
-	} else if (lm == 0x4) {
-		ch = get_channel4id(st, hh->id);
-		if (ch)
-			return ch->send(ch, skb);
-		else
-			printk(KERN_WARNING
-			       "%s: dev(%s) prim(%x) id(%x) no channel\n",
-			       __func__, dev_name(&st->dev->dev), hh->prim,
-			       hh->id);
-	} else if (lm == 0x8) {
-		WARN_ON(lm == 0x8);
-		ch = get_channel4id(st, hh->id);
-		if (ch)
-			return ch->send(ch, skb);
-		else
-			printk(KERN_WARNING
-			       "%s: dev(%s) prim(%x) id(%x) no channel\n",
-			       __func__, dev_name(&st->dev->dev), hh->prim,
-			       hh->id);
-	} else {
-		/* broadcast not handled yet */
-		printk(KERN_WARNING "%s: dev(%s) prim %x not delivered\n",
-		       __func__, dev_name(&st->dev->dev), hh->prim);
-	}
-	return -ESRCH;
-}
-
-static void
-do_clear_stack(struct mISDNstack *st)
-{
-}
-
-static int
-mISDNStackd(void *data)
-{
-	struct mISDNstack *st = data;
-#ifdef MISDN_MSG_STATS
-	u64 utime, stime;
-#endif
-	int err = 0;
-
-	sigfillset(&current->blocked);
-	if (*debug & DEBUG_MSG_THREAD)
-		printk(KERN_DEBUG "mISDNStackd %s started\n",
-		       dev_name(&st->dev->dev));
-
-	if (st->notify != NULL) {
-		complete(st->notify);
-		st->notify = NULL;
-	}
-
-	for (;;) {
-		struct sk_buff	*skb;
-
-		if (unlikely(test_bit(mISDN_STACK_STOPPED, &st->status))) {
-			test_and_clear_bit(mISDN_STACK_WORK, &st->status);
-			test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
-		} else
-			test_and_set_bit(mISDN_STACK_RUNNING, &st->status);
-		while (test_bit(mISDN_STACK_WORK, &st->status)) {
-			skb = skb_dequeue(&st->msgq);
-			if (!skb) {
-				test_and_clear_bit(mISDN_STACK_WORK,
-						   &st->status);
-				/* test if a race happens */
-				skb = skb_dequeue(&st->msgq);
-				if (!skb)
-					continue;
-				test_and_set_bit(mISDN_STACK_WORK,
-						 &st->status);
-			}
-#ifdef MISDN_MSG_STATS
-			st->msg_cnt++;
-#endif
-			err = send_msg_to_layer(st, skb);
-			if (unlikely(err)) {
-				if (*debug & DEBUG_SEND_ERR)
-					printk(KERN_DEBUG
-					       "%s: %s prim(%x) id(%x) "
-					       "send call(%d)\n",
-					       __func__, dev_name(&st->dev->dev),
-					       mISDN_HEAD_PRIM(skb),
-					       mISDN_HEAD_ID(skb), err);
-				dev_kfree_skb(skb);
-				continue;
-			}
-			if (unlikely(test_bit(mISDN_STACK_STOPPED,
-					      &st->status))) {
-				test_and_clear_bit(mISDN_STACK_WORK,
-						   &st->status);
-				test_and_clear_bit(mISDN_STACK_RUNNING,
-						   &st->status);
-				break;
-			}
-		}
-		if (test_bit(mISDN_STACK_CLEARING, &st->status)) {
-			test_and_set_bit(mISDN_STACK_STOPPED, &st->status);
-			test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
-			do_clear_stack(st);
-			test_and_clear_bit(mISDN_STACK_CLEARING, &st->status);
-			test_and_set_bit(mISDN_STACK_RESTART, &st->status);
-		}
-		if (test_and_clear_bit(mISDN_STACK_RESTART, &st->status)) {
-			test_and_clear_bit(mISDN_STACK_STOPPED, &st->status);
-			test_and_set_bit(mISDN_STACK_RUNNING, &st->status);
-			if (!skb_queue_empty(&st->msgq))
-				test_and_set_bit(mISDN_STACK_WORK,
-						 &st->status);
-		}
-		if (test_bit(mISDN_STACK_ABORT, &st->status))
-			break;
-		if (st->notify != NULL) {
-			complete(st->notify);
-			st->notify = NULL;
-		}
-#ifdef MISDN_MSG_STATS
-		st->sleep_cnt++;
-#endif
-		test_and_clear_bit(mISDN_STACK_ACTIVE, &st->status);
-		wait_event_interruptible(st->workq, (st->status &
-						     mISDN_STACK_ACTION_MASK));
-		if (*debug & DEBUG_MSG_THREAD)
-			printk(KERN_DEBUG "%s: %s wake status %08lx\n",
-			       __func__, dev_name(&st->dev->dev), st->status);
-		test_and_set_bit(mISDN_STACK_ACTIVE, &st->status);
-
-		test_and_clear_bit(mISDN_STACK_WAKEUP, &st->status);
-
-		if (test_bit(mISDN_STACK_STOPPED, &st->status)) {
-			test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
-#ifdef MISDN_MSG_STATS
-			st->stopped_cnt++;
-#endif
-		}
-	}
-#ifdef MISDN_MSG_STATS
-	printk(KERN_DEBUG "mISDNStackd daemon for %s proceed %d "
-	       "msg %d sleep %d stopped\n",
-	       dev_name(&st->dev->dev), st->msg_cnt, st->sleep_cnt,
-	       st->stopped_cnt);
-	task_cputime(st->thread, &utime, &stime);
-	printk(KERN_DEBUG
-	       "mISDNStackd daemon for %s utime(%llu) stime(%llu)\n",
-	       dev_name(&st->dev->dev), utime, stime);
-	printk(KERN_DEBUG
-	       "mISDNStackd daemon for %s nvcsw(%ld) nivcsw(%ld)\n",
-	       dev_name(&st->dev->dev), st->thread->nvcsw, st->thread->nivcsw);
-	printk(KERN_DEBUG "mISDNStackd daemon for %s killed now\n",
-	       dev_name(&st->dev->dev));
-#endif
-	test_and_set_bit(mISDN_STACK_KILLED, &st->status);
-	test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
-	test_and_clear_bit(mISDN_STACK_ACTIVE, &st->status);
-	test_and_clear_bit(mISDN_STACK_ABORT, &st->status);
-	skb_queue_purge(&st->msgq);
-	st->thread = NULL;
-	if (st->notify != NULL) {
-		complete(st->notify);
-		st->notify = NULL;
-	}
-	return 0;
-}
-
-static int
-l1_receive(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	if (!ch->st)
-		return -ENODEV;
-	__net_timestamp(skb);
-	_queue_message(ch->st, skb);
-	return 0;
-}
-
-void
-set_channel_address(struct mISDNchannel *ch, u_int sapi, u_int tei)
-{
-	ch->addr = sapi | (tei << 8);
-}
-
-void
-__add_layer2(struct mISDNchannel *ch, struct mISDNstack *st)
-{
-	list_add_tail(&ch->list, &st->layer2);
-}
-
-void
-add_layer2(struct mISDNchannel *ch, struct mISDNstack *st)
-{
-	mutex_lock(&st->lmutex);
-	__add_layer2(ch, st);
-	mutex_unlock(&st->lmutex);
-}
-
-static int
-st_own_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
-{
-	if (!ch->st || !ch->st->layer1)
-		return -EINVAL;
-	return ch->st->layer1->ctrl(ch->st->layer1, cmd, arg);
-}
-
-int
-create_stack(struct mISDNdevice *dev)
-{
-	struct mISDNstack	*newst;
-	int			err;
-	DECLARE_COMPLETION_ONSTACK(done);
-
-	newst = kzalloc_obj(struct mISDNstack);
-	if (!newst) {
-		printk(KERN_ERR "kmalloc mISDN_stack failed\n");
-		return -ENOMEM;
-	}
-	newst->dev = dev;
-	INIT_LIST_HEAD(&newst->layer2);
-	INIT_HLIST_HEAD(&newst->l1sock.head);
-	rwlock_init(&newst->l1sock.lock);
-	init_waitqueue_head(&newst->workq);
-	skb_queue_head_init(&newst->msgq);
-	mutex_init(&newst->lmutex);
-	dev->D.st = newst;
-	err = create_teimanager(dev);
-	if (err) {
-		printk(KERN_ERR "kmalloc teimanager failed\n");
-		kfree(newst);
-		return err;
-	}
-	dev->teimgr->peer = &newst->own;
-	dev->teimgr->recv = mISDN_queue_message;
-	dev->teimgr->st = newst;
-	newst->layer1 = &dev->D;
-	dev->D.recv = l1_receive;
-	dev->D.peer = &newst->own;
-	newst->own.st = newst;
-	newst->own.ctrl = st_own_ctrl;
-	newst->own.send = mISDN_queue_message;
-	newst->own.recv = mISDN_queue_message;
-	if (*debug & DEBUG_CORE_FUNC)
-		printk(KERN_DEBUG "%s: st(%s)\n", __func__,
-		       dev_name(&newst->dev->dev));
-	newst->notify = &done;
-	newst->thread = kthread_run(mISDNStackd, (void *)newst, "mISDN_%s",
-				    dev_name(&newst->dev->dev));
-	if (IS_ERR(newst->thread)) {
-		err = PTR_ERR(newst->thread);
-		printk(KERN_ERR
-		       "mISDN:cannot create kernel thread for %s (%d)\n",
-		       dev_name(&newst->dev->dev), err);
-		delete_teimanager(dev->teimgr);
-		kfree(newst);
-	} else
-		wait_for_completion(&done);
-	return err;
-}
-
-int
-connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch,
-	       u_int protocol, struct sockaddr_mISDN *adr)
-{
-	struct mISDN_sock	*msk = container_of(ch, struct mISDN_sock, ch);
-	struct channel_req	rq;
-	int			err;
-
-
-	if (*debug &  DEBUG_CORE_FUNC)
-		printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
-		       __func__, dev_name(&dev->dev), protocol, adr->dev,
-		       adr->channel, adr->sapi, adr->tei);
-	switch (protocol) {
-	case ISDN_P_NT_S0:
-	case ISDN_P_NT_E1:
-	case ISDN_P_TE_S0:
-	case ISDN_P_TE_E1:
-		ch->recv = mISDN_queue_message;
-		ch->peer = &dev->D.st->own;
-		ch->st = dev->D.st;
-		rq.protocol = protocol;
-		rq.adr.channel = adr->channel;
-		err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
-		printk(KERN_DEBUG "%s: ret %d (dev %d)\n", __func__, err,
-		       dev->id);
-		if (err)
-			return err;
-		write_lock_bh(&dev->D.st->l1sock.lock);
-		sk_add_node(&msk->sk, &dev->D.st->l1sock.head);
-		write_unlock_bh(&dev->D.st->l1sock.lock);
-		break;
-	default:
-		return -ENOPROTOOPT;
-	}
-	return 0;
-}
-
-int
-connect_Bstack(struct mISDNdevice *dev, struct mISDNchannel *ch,
-	       u_int protocol, struct sockaddr_mISDN *adr)
-{
-	struct channel_req	rq, rq2;
-	int			pmask, err;
-	struct Bprotocol	*bp;
-
-	if (*debug &  DEBUG_CORE_FUNC)
-		printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
-		       __func__, dev_name(&dev->dev), protocol,
-		       adr->dev, adr->channel, adr->sapi,
-		       adr->tei);
-	ch->st = dev->D.st;
-	pmask = 1 << (protocol & ISDN_P_B_MASK);
-	if (pmask & dev->Bprotocols) {
-		rq.protocol = protocol;
-		rq.adr = *adr;
-		err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
-		if (err)
-			return err;
-		ch->recv = rq.ch->send;
-		ch->peer = rq.ch;
-		rq.ch->recv = ch->send;
-		rq.ch->peer = ch;
-		rq.ch->st = dev->D.st;
-	} else {
-		bp = get_Bprotocol4mask(pmask);
-		if (!bp)
-			return -ENOPROTOOPT;
-		rq2.protocol = protocol;
-		rq2.adr = *adr;
-		rq2.ch = ch;
-		err = bp->create(&rq2);
-		if (err)
-			return err;
-		ch->recv = rq2.ch->send;
-		ch->peer = rq2.ch;
-		rq2.ch->st = dev->D.st;
-		rq.protocol = rq2.protocol;
-		rq.adr = *adr;
-		err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
-		if (err) {
-			rq2.ch->ctrl(rq2.ch, CLOSE_CHANNEL, NULL);
-			return err;
-		}
-		rq2.ch->recv = rq.ch->send;
-		rq2.ch->peer = rq.ch;
-		rq.ch->recv = rq2.ch->send;
-		rq.ch->peer = rq2.ch;
-		rq.ch->st = dev->D.st;
-	}
-	ch->protocol = protocol;
-	ch->nr = rq.ch->nr;
-	return 0;
-}
-
-int
-create_l2entity(struct mISDNdevice *dev, struct mISDNchannel *ch,
-		u_int protocol, struct sockaddr_mISDN *adr)
-{
-	struct channel_req	rq;
-	int			err;
-
-	if (*debug &  DEBUG_CORE_FUNC)
-		printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
-		       __func__, dev_name(&dev->dev), protocol,
-		       adr->dev, adr->channel, adr->sapi,
-		       adr->tei);
-	rq.protocol = ISDN_P_TE_S0;
-	if (dev->Dprotocols & (1 << ISDN_P_TE_E1))
-		rq.protocol = ISDN_P_TE_E1;
-	switch (protocol) {
-	case ISDN_P_LAPD_NT:
-		rq.protocol = ISDN_P_NT_S0;
-		if (dev->Dprotocols & (1 << ISDN_P_NT_E1))
-			rq.protocol = ISDN_P_NT_E1;
-		fallthrough;
-	case ISDN_P_LAPD_TE:
-		ch->recv = mISDN_queue_message;
-		ch->peer = &dev->D.st->own;
-		ch->st = dev->D.st;
-		rq.adr.channel = 0;
-		err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
-		printk(KERN_DEBUG "%s: ret 1 %d\n", __func__, err);
-		if (err)
-			break;
-		rq.protocol = protocol;
-		rq.adr = *adr;
-		rq.ch = ch;
-		err = dev->teimgr->ctrl(dev->teimgr, OPEN_CHANNEL, &rq);
-		printk(KERN_DEBUG "%s: ret 2 %d\n", __func__, err);
-		if (!err) {
-			if ((protocol == ISDN_P_LAPD_NT) && !rq.ch)
-				break;
-			add_layer2(rq.ch, dev->D.st);
-			rq.ch->recv = mISDN_queue_message;
-			rq.ch->peer = &dev->D.st->own;
-			rq.ch->ctrl(rq.ch, OPEN_CHANNEL, NULL); /* can't fail */
-		}
-		break;
-	default:
-		err = -EPROTONOSUPPORT;
-	}
-	return err;
-}
-
-void
-delete_channel(struct mISDNchannel *ch)
-{
-	struct mISDN_sock	*msk = container_of(ch, struct mISDN_sock, ch);
-	struct mISDNchannel	*pch;
-
-	if (!ch->st) {
-		printk(KERN_WARNING "%s: no stack\n", __func__);
-		return;
-	}
-	if (*debug & DEBUG_CORE_FUNC)
-		printk(KERN_DEBUG "%s: st(%s) protocol(%x)\n", __func__,
-		       dev_name(&ch->st->dev->dev), ch->protocol);
-	if (ch->protocol >= ISDN_P_B_START) {
-		if (ch->peer) {
-			ch->peer->ctrl(ch->peer, CLOSE_CHANNEL, NULL);
-			ch->peer = NULL;
-		}
-		return;
-	}
-	switch (ch->protocol) {
-	case ISDN_P_NT_S0:
-	case ISDN_P_TE_S0:
-	case ISDN_P_NT_E1:
-	case ISDN_P_TE_E1:
-		write_lock_bh(&ch->st->l1sock.lock);
-		sk_del_node_init(&msk->sk);
-		write_unlock_bh(&ch->st->l1sock.lock);
-		ch->st->dev->D.ctrl(&ch->st->dev->D, CLOSE_CHANNEL, NULL);
-		break;
-	case ISDN_P_LAPD_TE:
-		pch = get_channel4id(ch->st, ch->nr);
-		if (pch) {
-			mutex_lock(&ch->st->lmutex);
-			list_del(&pch->list);
-			mutex_unlock(&ch->st->lmutex);
-			pch->ctrl(pch, CLOSE_CHANNEL, NULL);
-			pch = ch->st->dev->teimgr;
-			pch->ctrl(pch, CLOSE_CHANNEL, NULL);
-		} else
-			printk(KERN_WARNING "%s: no l2 channel\n",
-			       __func__);
-		break;
-	case ISDN_P_LAPD_NT:
-		pch = ch->st->dev->teimgr;
-		if (pch) {
-			pch->ctrl(pch, CLOSE_CHANNEL, NULL);
-		} else
-			printk(KERN_WARNING "%s: no l2 channel\n",
-			       __func__);
-		break;
-	default:
-		break;
-	}
-	return;
-}
-
-void
-delete_stack(struct mISDNdevice *dev)
-{
-	struct mISDNstack	*st = dev->D.st;
-	DECLARE_COMPLETION_ONSTACK(done);
-
-	if (*debug & DEBUG_CORE_FUNC)
-		printk(KERN_DEBUG "%s: st(%s)\n", __func__,
-		       dev_name(&st->dev->dev));
-	if (dev->teimgr)
-		delete_teimanager(dev->teimgr);
-	if (st->thread) {
-		if (st->notify) {
-			printk(KERN_WARNING "%s: notifier in use\n",
-			       __func__);
-			complete(st->notify);
-		}
-		st->notify = &done;
-		test_and_set_bit(mISDN_STACK_ABORT, &st->status);
-		test_and_set_bit(mISDN_STACK_WAKEUP, &st->status);
-		wake_up_interruptible(&st->workq);
-		wait_for_completion(&done);
-	}
-	if (!list_empty(&st->layer2))
-		printk(KERN_WARNING "%s: layer2 list not empty\n",
-		       __func__);
-	if (!hlist_empty(&st->l1sock.head))
-		printk(KERN_WARNING "%s: layer1 list not empty\n",
-		       __func__);
-	kfree(st);
-}
-
-void
-mISDN_initstack(u_int *dp)
-{
-	debug = dp;
-}
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
deleted file mode 100644
index 2bad3083be90..000000000000
--- a/drivers/isdn/mISDN/tei.c
+++ /dev/null
@@ -1,1416 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *
- * Author	Karsten Keil <kkeil@novell.com>
- *
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- */
-#include "layer2.h"
-#include <linux/random.h>
-#include <linux/slab.h>
-#include "core.h"
-
-#define ID_REQUEST	1
-#define ID_ASSIGNED	2
-#define ID_DENIED	3
-#define ID_CHK_REQ	4
-#define ID_CHK_RES	5
-#define ID_REMOVE	6
-#define ID_VERIFY	7
-
-#define TEI_ENTITY_ID	0xf
-
-#define MGR_PH_ACTIVE	16
-#define MGR_PH_NOTREADY	17
-
-#define DATIMER_VAL	10000
-
-static	u_int	*debug;
-
-static struct Fsm deactfsm = {NULL, 0, 0, NULL, NULL};
-static struct Fsm teifsmu = {NULL, 0, 0, NULL, NULL};
-static struct Fsm teifsmn = {NULL, 0, 0, NULL, NULL};
-
-enum {
-	ST_L1_DEACT,
-	ST_L1_DEACT_PENDING,
-	ST_L1_ACTIV,
-};
-#define DEACT_STATE_COUNT (ST_L1_ACTIV + 1)
-
-static char *strDeactState[] =
-{
-	"ST_L1_DEACT",
-	"ST_L1_DEACT_PENDING",
-	"ST_L1_ACTIV",
-};
-
-enum {
-	EV_ACTIVATE,
-	EV_ACTIVATE_IND,
-	EV_DEACTIVATE,
-	EV_DEACTIVATE_IND,
-	EV_UI,
-	EV_DATIMER,
-};
-
-#define DEACT_EVENT_COUNT (EV_DATIMER + 1)
-
-static char *strDeactEvent[] =
-{
-	"EV_ACTIVATE",
-	"EV_ACTIVATE_IND",
-	"EV_DEACTIVATE",
-	"EV_DEACTIVATE_IND",
-	"EV_UI",
-	"EV_DATIMER",
-};
-
-static void
-da_debug(struct FsmInst *fi, char *fmt, ...)
-{
-	struct manager	*mgr = fi->userdata;
-	struct va_format vaf;
-	va_list va;
-
-	if (!(*debug & DEBUG_L2_TEIFSM))
-		return;
-
-	va_start(va, fmt);
-
-	vaf.fmt = fmt;
-	vaf.va = &va;
-
-	printk(KERN_DEBUG "mgr(%d): %pV\n", mgr->ch.st->dev->id, &vaf);
-
-	va_end(va);
-}
-
-static void
-da_activate(struct FsmInst *fi, int event, void *arg)
-{
-	struct manager	*mgr = fi->userdata;
-
-	if (fi->state == ST_L1_DEACT_PENDING)
-		mISDN_FsmDelTimer(&mgr->datimer, 1);
-	mISDN_FsmChangeState(fi, ST_L1_ACTIV);
-}
-
-static void
-da_deactivate_ind(struct FsmInst *fi, int event, void *arg)
-{
-	mISDN_FsmChangeState(fi, ST_L1_DEACT);
-}
-
-static void
-da_deactivate(struct FsmInst *fi, int event, void *arg)
-{
-	struct manager	*mgr = fi->userdata;
-	struct layer2	*l2;
-	u_long		flags;
-
-	read_lock_irqsave(&mgr->lock, flags);
-	list_for_each_entry(l2, &mgr->layer2, list) {
-		if (l2->l2m.state > ST_L2_4) {
-			/* have still activ TEI */
-			read_unlock_irqrestore(&mgr->lock, flags);
-			return;
-		}
-	}
-	read_unlock_irqrestore(&mgr->lock, flags);
-	/* All TEI are inactiv */
-	if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
-		mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
-				  NULL, 1);
-		mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING);
-	}
-}
-
-static void
-da_ui(struct FsmInst *fi, int event, void *arg)
-{
-	struct manager	*mgr = fi->userdata;
-
-	/* restart da timer */
-	if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
-		mISDN_FsmDelTimer(&mgr->datimer, 2);
-		mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
-				  NULL, 2);
-	}
-}
-
-static void
-da_timer(struct FsmInst *fi, int event, void *arg)
-{
-	struct manager	*mgr = fi->userdata;
-	struct layer2	*l2;
-	u_long		flags;
-
-	/* check again */
-	read_lock_irqsave(&mgr->lock, flags);
-	list_for_each_entry(l2, &mgr->layer2, list) {
-		if (l2->l2m.state > ST_L2_4) {
-			/* have still activ TEI */
-			read_unlock_irqrestore(&mgr->lock, flags);
-			mISDN_FsmChangeState(fi, ST_L1_ACTIV);
-			return;
-		}
-	}
-	read_unlock_irqrestore(&mgr->lock, flags);
-	/* All TEI are inactiv */
-	mISDN_FsmChangeState(fi, ST_L1_DEACT);
-	_queue_data(&mgr->ch, PH_DEACTIVATE_REQ, MISDN_ID_ANY, 0, NULL,
-		    GFP_ATOMIC);
-}
-
-static struct FsmNode DeactFnList[] =
-{
-	{ST_L1_DEACT, EV_ACTIVATE_IND, da_activate},
-	{ST_L1_ACTIV, EV_DEACTIVATE_IND, da_deactivate_ind},
-	{ST_L1_ACTIV, EV_DEACTIVATE, da_deactivate},
-	{ST_L1_DEACT_PENDING, EV_ACTIVATE, da_activate},
-	{ST_L1_DEACT_PENDING, EV_UI, da_ui},
-	{ST_L1_DEACT_PENDING, EV_DATIMER, da_timer},
-};
-
-enum {
-	ST_TEI_NOP,
-	ST_TEI_IDREQ,
-	ST_TEI_IDVERIFY,
-};
-
-#define TEI_STATE_COUNT (ST_TEI_IDVERIFY + 1)
-
-static char *strTeiState[] =
-{
-	"ST_TEI_NOP",
-	"ST_TEI_IDREQ",
-	"ST_TEI_IDVERIFY",
-};
-
-enum {
-	EV_IDREQ,
-	EV_ASSIGN,
-	EV_ASSIGN_REQ,
-	EV_DENIED,
-	EV_CHKREQ,
-	EV_CHKRESP,
-	EV_REMOVE,
-	EV_VERIFY,
-	EV_TIMER,
-};
-
-#define TEI_EVENT_COUNT (EV_TIMER + 1)
-
-static char *strTeiEvent[] =
-{
-	"EV_IDREQ",
-	"EV_ASSIGN",
-	"EV_ASSIGN_REQ",
-	"EV_DENIED",
-	"EV_CHKREQ",
-	"EV_CHKRESP",
-	"EV_REMOVE",
-	"EV_VERIFY",
-	"EV_TIMER",
-};
-
-static void
-tei_debug(struct FsmInst *fi, char *fmt, ...)
-{
-	struct teimgr	*tm = fi->userdata;
-	struct va_format vaf;
-	va_list va;
-
-	if (!(*debug & DEBUG_L2_TEIFSM))
-		return;
-
-	va_start(va, fmt);
-
-	vaf.fmt = fmt;
-	vaf.va = &va;
-
-	printk(KERN_DEBUG "sapi(%d) tei(%d): %pV\n",
-	       tm->l2->sapi, tm->l2->tei, &vaf);
-
-	va_end(va);
-}
-
-
-
-static int
-get_free_id(struct manager *mgr)
-{
-	DECLARE_BITMAP(ids, 64) = { [0 ... BITS_TO_LONGS(64) - 1] = 0 };
-	int		i;
-	struct layer2	*l2;
-
-	list_for_each_entry(l2, &mgr->layer2, list) {
-		if (l2->ch.nr > 63) {
-			printk(KERN_WARNING
-			       "%s: more as 63 layer2 for one device\n",
-			       __func__);
-			return -EBUSY;
-		}
-		__set_bit(l2->ch.nr, ids);
-	}
-	i = find_next_zero_bit(ids, 64, 1);
-	if (i < 64)
-		return i;
-	printk(KERN_WARNING "%s: more as 63 layer2 for one device\n",
-	       __func__);
-	return -EBUSY;
-}
-
-static int
-get_free_tei(struct manager *mgr)
-{
-	DECLARE_BITMAP(ids, 64) = { [0 ... BITS_TO_LONGS(64) - 1] = 0 };
-	int		i;
-	struct layer2	*l2;
-
-	list_for_each_entry(l2, &mgr->layer2, list) {
-		if (l2->ch.nr == 0)
-			continue;
-		if ((l2->ch.addr & 0xff) != 0)
-			continue;
-		i = l2->ch.addr >> 8;
-		if (i < 64)
-			continue;
-		i -= 64;
-
-		__set_bit(i, ids);
-	}
-	i = find_first_zero_bit(ids, 64);
-	if (i < 64)
-		return i + 64;
-	printk(KERN_WARNING "%s: more as 63 dynamic tei for one device\n",
-	       __func__);
-	return -1;
-}
-
-static void
-teiup_create(struct manager *mgr, u_int prim, int len, void *arg)
-{
-	struct sk_buff	*skb;
-	struct mISDNhead *hh;
-	int		err;
-
-	skb = mI_alloc_skb(len, GFP_ATOMIC);
-	if (!skb)
-		return;
-	hh = mISDN_HEAD_P(skb);
-	hh->prim = prim;
-	hh->id = (mgr->ch.nr << 16) | mgr->ch.addr;
-	if (len)
-		skb_put_data(skb, arg, len);
-	err = mgr->up->send(mgr->up, skb);
-	if (err) {
-		printk(KERN_WARNING "%s: err=%d\n", __func__, err);
-		dev_kfree_skb(skb);
-	}
-}
-
-static u_int
-new_id(struct manager *mgr)
-{
-	u_int	id;
-
-	id = mgr->nextid++;
-	if (id == 0x7fff)
-		mgr->nextid = 1;
-	id <<= 16;
-	id |= GROUP_TEI << 8;
-	id |= TEI_SAPI;
-	return id;
-}
-
-static void
-do_send(struct manager *mgr)
-{
-	if (!test_bit(MGR_PH_ACTIVE, &mgr->options))
-		return;
-
-	if (!test_and_set_bit(MGR_PH_NOTREADY, &mgr->options)) {
-		struct sk_buff	*skb = skb_dequeue(&mgr->sendq);
-
-		if (!skb) {
-			test_and_clear_bit(MGR_PH_NOTREADY, &mgr->options);
-			return;
-		}
-		mgr->lastid = mISDN_HEAD_ID(skb);
-		mISDN_FsmEvent(&mgr->deact, EV_UI, NULL);
-		if (mgr->ch.recv(mgr->ch.peer, skb)) {
-			dev_kfree_skb(skb);
-			test_and_clear_bit(MGR_PH_NOTREADY, &mgr->options);
-			mgr->lastid = MISDN_ID_NONE;
-		}
-	}
-}
-
-static void
-do_ack(struct manager *mgr, u_int id)
-{
-	if (test_bit(MGR_PH_NOTREADY, &mgr->options)) {
-		if (id == mgr->lastid) {
-			if (test_bit(MGR_PH_ACTIVE, &mgr->options)) {
-				struct sk_buff	*skb;
-
-				skb = skb_dequeue(&mgr->sendq);
-				if (skb) {
-					mgr->lastid = mISDN_HEAD_ID(skb);
-					if (!mgr->ch.recv(mgr->ch.peer, skb))
-						return;
-					dev_kfree_skb(skb);
-				}
-			}
-			mgr->lastid = MISDN_ID_NONE;
-			test_and_clear_bit(MGR_PH_NOTREADY, &mgr->options);
-		}
-	}
-}
-
-static void
-mgr_send_down(struct manager *mgr, struct sk_buff *skb)
-{
-	skb_queue_tail(&mgr->sendq, skb);
-	if (!test_bit(MGR_PH_ACTIVE, &mgr->options)) {
-		_queue_data(&mgr->ch, PH_ACTIVATE_REQ, MISDN_ID_ANY, 0,
-			    NULL, GFP_KERNEL);
-	} else {
-		do_send(mgr);
-	}
-}
-
-static int
-dl_unit_data(struct manager *mgr, struct sk_buff *skb)
-{
-	if (!test_bit(MGR_OPT_NETWORK, &mgr->options)) /* only net send UI */
-		return -EINVAL;
-	if (!test_bit(MGR_PH_ACTIVE, &mgr->options))
-		_queue_data(&mgr->ch, PH_ACTIVATE_REQ, MISDN_ID_ANY, 0,
-			    NULL, GFP_KERNEL);
-	skb_push(skb, 3);
-	skb->data[0] = 0x02; /* SAPI 0 C/R = 1 */
-	skb->data[1] = 0xff; /* TEI 127 */
-	skb->data[2] = UI;   /* UI frame */
-	mISDN_HEAD_PRIM(skb) = PH_DATA_REQ;
-	mISDN_HEAD_ID(skb) = new_id(mgr);
-	skb_queue_tail(&mgr->sendq, skb);
-	do_send(mgr);
-	return 0;
-}
-
-static unsigned int
-random_ri(void)
-{
-	u16 x;
-
-	get_random_bytes(&x, sizeof(x));
-	return x;
-}
-
-static struct layer2 *
-findtei(struct manager *mgr, int tei)
-{
-	struct layer2	*l2;
-	u_long		flags;
-
-	read_lock_irqsave(&mgr->lock, flags);
-	list_for_each_entry(l2, &mgr->layer2, list) {
-		if ((l2->sapi == 0) && (l2->tei > 0) &&
-		    (l2->tei != GROUP_TEI) && (l2->tei == tei))
-			goto done;
-	}
-	l2 = NULL;
-done:
-	read_unlock_irqrestore(&mgr->lock, flags);
-	return l2;
-}
-
-static void
-put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, int tei)
-{
-	struct sk_buff *skb;
-	u_char bp[8];
-
-	bp[0] = (TEI_SAPI << 2);
-	if (test_bit(MGR_OPT_NETWORK, &mgr->options))
-		bp[0] |= 2; /* CR:=1 for net command */
-	bp[1] = (GROUP_TEI << 1) | 0x1;
-	bp[2] = UI;
-	bp[3] = TEI_ENTITY_ID;
-	bp[4] = ri >> 8;
-	bp[5] = ri & 0xff;
-	bp[6] = m_id;
-	bp[7] = ((tei << 1) & 0xff) | 1;
-	skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr), 8, bp, GFP_ATOMIC);
-	if (!skb) {
-		printk(KERN_WARNING "%s: no skb for tei msg\n", __func__);
-		return;
-	}
-	mgr_send_down(mgr, skb);
-}
-
-static void
-tei_id_request(struct FsmInst *fi, int event, void *arg)
-{
-	struct teimgr *tm = fi->userdata;
-
-	if (tm->l2->tei != GROUP_TEI) {
-		tm->tei_m.printdebug(&tm->tei_m,
-				     "assign request for already assigned tei %d",
-				     tm->l2->tei);
-		return;
-	}
-	tm->ri = random_ri();
-	if (*debug & DEBUG_L2_TEI)
-		tm->tei_m.printdebug(&tm->tei_m,
-				     "assign request ri %d", tm->ri);
-	put_tei_msg(tm->mgr, ID_REQUEST, tm->ri, GROUP_TEI);
-	mISDN_FsmChangeState(fi, ST_TEI_IDREQ);
-	mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 1);
-	tm->nval = 3;
-}
-
-static void
-tei_id_assign(struct FsmInst *fi, int event, void *arg)
-{
-	struct teimgr	*tm = fi->userdata;
-	struct layer2	*l2;
-	u_char *dp = arg;
-	int ri, tei;
-
-	ri = ((unsigned int) *dp++ << 8);
-	ri += *dp++;
-	dp++;
-	tei = *dp >> 1;
-	if (*debug & DEBUG_L2_TEI)
-		tm->tei_m.printdebug(fi, "identity assign ri %d tei %d",
-				     ri, tei);
-	l2 = findtei(tm->mgr, tei);
-	if (l2) {	/* same tei is in use */
-		if (ri != l2->tm->ri) {
-			tm->tei_m.printdebug(fi,
-					     "possible duplicate assignment tei %d", tei);
-			tei_l2(l2, MDL_ERROR_RSP, 0);
-		}
-	} else if (ri == tm->ri) {
-		mISDN_FsmDelTimer(&tm->timer, 1);
-		mISDN_FsmChangeState(fi, ST_TEI_NOP);
-		tei_l2(tm->l2, MDL_ASSIGN_REQ, tei);
-	}
-}
-
-static void
-tei_id_test_dup(struct FsmInst *fi, int event, void *arg)
-{
-	struct teimgr	*tm = fi->userdata;
-	struct layer2	*l2;
-	u_char *dp = arg;
-	int tei, ri;
-
-	ri = ((unsigned int) *dp++ << 8);
-	ri += *dp++;
-	dp++;
-	tei = *dp >> 1;
-	if (*debug & DEBUG_L2_TEI)
-		tm->tei_m.printdebug(fi, "foreign identity assign ri %d tei %d",
-				     ri, tei);
-	l2 = findtei(tm->mgr, tei);
-	if (l2) {	/* same tei is in use */
-		if (ri != l2->tm->ri) {	/* and it wasn't our request */
-			tm->tei_m.printdebug(fi,
-					     "possible duplicate assignment tei %d", tei);
-			mISDN_FsmEvent(&l2->tm->tei_m, EV_VERIFY, NULL);
-		}
-	}
-}
-
-static void
-tei_id_denied(struct FsmInst *fi, int event, void *arg)
-{
-	struct teimgr *tm = fi->userdata;
-	u_char *dp = arg;
-	int ri, tei;
-
-	ri = ((unsigned int) *dp++ << 8);
-	ri += *dp++;
-	dp++;
-	tei = *dp >> 1;
-	if (*debug & DEBUG_L2_TEI)
-		tm->tei_m.printdebug(fi, "identity denied ri %d tei %d",
-				     ri, tei);
-}
-
-static void
-tei_id_chk_req(struct FsmInst *fi, int event, void *arg)
-{
-	struct teimgr *tm = fi->userdata;
-	u_char *dp = arg;
-	int tei;
-
-	tei = *(dp + 3) >> 1;
-	if (*debug & DEBUG_L2_TEI)
-		tm->tei_m.printdebug(fi, "identity check req tei %d", tei);
-	if ((tm->l2->tei != GROUP_TEI) && ((tei == GROUP_TEI) ||
-					   (tei == tm->l2->tei))) {
-		mISDN_FsmDelTimer(&tm->timer, 4);
-		mISDN_FsmChangeState(&tm->tei_m, ST_TEI_NOP);
-		put_tei_msg(tm->mgr, ID_CHK_RES, random_ri(), tm->l2->tei);
-	}
-}
-
-static void
-tei_id_remove(struct FsmInst *fi, int event, void *arg)
-{
-	struct teimgr *tm = fi->userdata;
-	u_char *dp = arg;
-	int tei;
-
-	tei = *(dp + 3) >> 1;
-	if (*debug & DEBUG_L2_TEI)
-		tm->tei_m.printdebug(fi, "identity remove tei %d", tei);
-	if ((tm->l2->tei != GROUP_TEI) &&
-	    ((tei == GROUP_TEI) || (tei == tm->l2->tei))) {
-		mISDN_FsmDelTimer(&tm->timer, 5);
-		mISDN_FsmChangeState(&tm->tei_m, ST_TEI_NOP);
-		tei_l2(tm->l2, MDL_REMOVE_REQ, 0);
-	}
-}
-
-static void
-tei_id_verify(struct FsmInst *fi, int event, void *arg)
-{
-	struct teimgr *tm = fi->userdata;
-
-	if (*debug & DEBUG_L2_TEI)
-		tm->tei_m.printdebug(fi, "id verify request for tei %d",
-				     tm->l2->tei);
-	put_tei_msg(tm->mgr, ID_VERIFY, 0, tm->l2->tei);
-	mISDN_FsmChangeState(&tm->tei_m, ST_TEI_IDVERIFY);
-	mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 2);
-	tm->nval = 2;
-}
-
-static void
-tei_id_req_tout(struct FsmInst *fi, int event, void *arg)
-{
-	struct teimgr *tm = fi->userdata;
-
-	if (--tm->nval) {
-		tm->ri = random_ri();
-		if (*debug & DEBUG_L2_TEI)
-			tm->tei_m.printdebug(fi, "assign req(%d) ri %d",
-					     4 - tm->nval, tm->ri);
-		put_tei_msg(tm->mgr, ID_REQUEST, tm->ri, GROUP_TEI);
-		mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 3);
-	} else {
-		tm->tei_m.printdebug(fi, "assign req failed");
-		tei_l2(tm->l2, MDL_ERROR_RSP, 0);
-		mISDN_FsmChangeState(fi, ST_TEI_NOP);
-	}
-}
-
-static void
-tei_id_ver_tout(struct FsmInst *fi, int event, void *arg)
-{
-	struct teimgr *tm = fi->userdata;
-
-	if (--tm->nval) {
-		if (*debug & DEBUG_L2_TEI)
-			tm->tei_m.printdebug(fi,
-					     "id verify req(%d) for tei %d",
-					     3 - tm->nval, tm->l2->tei);
-		put_tei_msg(tm->mgr, ID_VERIFY, 0, tm->l2->tei);
-		mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 4);
-	} else {
-		tm->tei_m.printdebug(fi, "verify req for tei %d failed",
-				     tm->l2->tei);
-		tei_l2(tm->l2, MDL_REMOVE_REQ, 0);
-		mISDN_FsmChangeState(fi, ST_TEI_NOP);
-	}
-}
-
-static struct FsmNode TeiFnListUser[] =
-{
-	{ST_TEI_NOP, EV_IDREQ, tei_id_request},
-	{ST_TEI_NOP, EV_ASSIGN, tei_id_test_dup},
-	{ST_TEI_NOP, EV_VERIFY, tei_id_verify},
-	{ST_TEI_NOP, EV_REMOVE, tei_id_remove},
-	{ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req},
-	{ST_TEI_IDREQ, EV_TIMER, tei_id_req_tout},
-	{ST_TEI_IDREQ, EV_ASSIGN, tei_id_assign},
-	{ST_TEI_IDREQ, EV_DENIED, tei_id_denied},
-	{ST_TEI_IDVERIFY, EV_TIMER, tei_id_ver_tout},
-	{ST_TEI_IDVERIFY, EV_REMOVE, tei_id_remove},
-	{ST_TEI_IDVERIFY, EV_CHKREQ, tei_id_chk_req},
-};
-
-static void
-tei_l2remove(struct layer2 *l2)
-{
-	put_tei_msg(l2->tm->mgr, ID_REMOVE, 0, l2->tei);
-	tei_l2(l2, MDL_REMOVE_REQ, 0);
-	list_del(&l2->ch.list);
-	l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
-}
-
-static void
-tei_assign_req(struct FsmInst *fi, int event, void *arg)
-{
-	struct teimgr *tm = fi->userdata;
-	u_char *dp = arg;
-
-	if (tm->l2->tei == GROUP_TEI) {
-		tm->tei_m.printdebug(&tm->tei_m,
-				     "net tei assign request without tei");
-		return;
-	}
-	tm->ri = ((unsigned int) *dp++ << 8);
-	tm->ri += *dp++;
-	if (*debug & DEBUG_L2_TEI)
-		tm->tei_m.printdebug(&tm->tei_m,
-				     "net assign request ri %d teim %d", tm->ri, *dp);
-	put_tei_msg(tm->mgr, ID_ASSIGNED, tm->ri, tm->l2->tei);
-	mISDN_FsmChangeState(fi, ST_TEI_NOP);
-}
-
-static void
-tei_id_chk_req_net(struct FsmInst *fi, int event, void *arg)
-{
-	struct teimgr	*tm = fi->userdata;
-
-	if (*debug & DEBUG_L2_TEI)
-		tm->tei_m.printdebug(fi, "id check request for tei %d",
-				     tm->l2->tei);
-	tm->rcnt = 0;
-	put_tei_msg(tm->mgr, ID_CHK_REQ, 0, tm->l2->tei);
-	mISDN_FsmChangeState(&tm->tei_m, ST_TEI_IDVERIFY);
-	mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 2);
-	tm->nval = 2;
-}
-
-static void
-tei_id_chk_resp(struct FsmInst *fi, int event, void *arg)
-{
-	struct teimgr *tm = fi->userdata;
-	u_char *dp = arg;
-	int tei;
-
-	tei = dp[3] >> 1;
-	if (*debug & DEBUG_L2_TEI)
-		tm->tei_m.printdebug(fi, "identity check resp tei %d", tei);
-	if (tei == tm->l2->tei)
-		tm->rcnt++;
-}
-
-static void
-tei_id_verify_net(struct FsmInst *fi, int event, void *arg)
-{
-	struct teimgr *tm = fi->userdata;
-	u_char *dp = arg;
-	int tei;
-
-	tei = dp[3] >> 1;
-	if (*debug & DEBUG_L2_TEI)
-		tm->tei_m.printdebug(fi, "identity verify req tei %d/%d",
-				     tei, tm->l2->tei);
-	if (tei == tm->l2->tei)
-		tei_id_chk_req_net(fi, event, arg);
-}
-
-static void
-tei_id_ver_tout_net(struct FsmInst *fi, int event, void *arg)
-{
-	struct teimgr *tm = fi->userdata;
-
-	if (tm->rcnt == 1) {
-		if (*debug & DEBUG_L2_TEI)
-			tm->tei_m.printdebug(fi,
-					     "check req for tei %d successful\n", tm->l2->tei);
-		mISDN_FsmChangeState(fi, ST_TEI_NOP);
-	} else if (tm->rcnt > 1) {
-		/* duplicate assignment; remove */
-		tei_l2remove(tm->l2);
-	} else if (--tm->nval) {
-		if (*debug & DEBUG_L2_TEI)
-			tm->tei_m.printdebug(fi,
-					     "id check req(%d) for tei %d",
-					     3 - tm->nval, tm->l2->tei);
-		put_tei_msg(tm->mgr, ID_CHK_REQ, 0, tm->l2->tei);
-		mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 4);
-	} else {
-		tm->tei_m.printdebug(fi, "check req for tei %d failed",
-				     tm->l2->tei);
-		mISDN_FsmChangeState(fi, ST_TEI_NOP);
-		tei_l2remove(tm->l2);
-	}
-}
-
-static struct FsmNode TeiFnListNet[] =
-{
-	{ST_TEI_NOP, EV_ASSIGN_REQ, tei_assign_req},
-	{ST_TEI_NOP, EV_VERIFY, tei_id_verify_net},
-	{ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req_net},
-	{ST_TEI_IDVERIFY, EV_TIMER, tei_id_ver_tout_net},
-	{ST_TEI_IDVERIFY, EV_CHKRESP, tei_id_chk_resp},
-};
-
-static void
-tei_ph_data_ind(struct teimgr *tm, u_int mt, u_char *dp, int len)
-{
-	if (test_bit(FLG_FIXED_TEI, &tm->l2->flag))
-		return;
-	if (*debug & DEBUG_L2_TEI)
-		tm->tei_m.printdebug(&tm->tei_m, "tei handler mt %x", mt);
-	if (mt == ID_ASSIGNED)
-		mISDN_FsmEvent(&tm->tei_m, EV_ASSIGN, dp);
-	else if (mt == ID_DENIED)
-		mISDN_FsmEvent(&tm->tei_m, EV_DENIED, dp);
-	else if (mt == ID_CHK_REQ)
-		mISDN_FsmEvent(&tm->tei_m, EV_CHKREQ, dp);
-	else if (mt == ID_REMOVE)
-		mISDN_FsmEvent(&tm->tei_m, EV_REMOVE, dp);
-	else if (mt == ID_VERIFY)
-		mISDN_FsmEvent(&tm->tei_m, EV_VERIFY, dp);
-	else if (mt == ID_CHK_RES)
-		mISDN_FsmEvent(&tm->tei_m, EV_CHKRESP, dp);
-}
-
-static struct layer2 *
-create_new_tei(struct manager *mgr, int tei, int sapi)
-{
-	unsigned long		opt = 0;
-	unsigned long		flags;
-	int			id;
-	struct layer2		*l2;
-	struct channel_req	rq;
-
-	if (!mgr->up)
-		return NULL;
-	if ((tei >= 0) && (tei < 64))
-		test_and_set_bit(OPTION_L2_FIXEDTEI, &opt);
-	if (mgr->ch.st->dev->Dprotocols & ((1 << ISDN_P_TE_E1) |
-	    (1 << ISDN_P_NT_E1))) {
-		test_and_set_bit(OPTION_L2_PMX, &opt);
-		rq.protocol = ISDN_P_NT_E1;
-	} else {
-		rq.protocol = ISDN_P_NT_S0;
-	}
-	l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, opt, tei, sapi);
-	if (!l2) {
-		printk(KERN_WARNING "%s:no memory for layer2\n", __func__);
-		return NULL;
-	}
-	l2->tm = kzalloc_obj(struct teimgr);
-	if (!l2->tm) {
-		kfree(l2);
-		printk(KERN_WARNING "%s:no memory for teimgr\n", __func__);
-		return NULL;
-	}
-	l2->tm->mgr = mgr;
-	l2->tm->l2 = l2;
-	l2->tm->tei_m.debug = *debug & DEBUG_L2_TEIFSM;
-	l2->tm->tei_m.userdata = l2->tm;
-	l2->tm->tei_m.printdebug = tei_debug;
-	l2->tm->tei_m.fsm = &teifsmn;
-	l2->tm->tei_m.state = ST_TEI_NOP;
-	l2->tm->tval = 2000; /* T202  2 sec */
-	mISDN_FsmInitTimer(&l2->tm->tei_m, &l2->tm->timer);
-	write_lock_irqsave(&mgr->lock, flags);
-	id = get_free_id(mgr);
-	list_add_tail(&l2->list, &mgr->layer2);
-	write_unlock_irqrestore(&mgr->lock, flags);
-	if (id < 0) {
-		l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
-		printk(KERN_WARNING "%s:no free id\n", __func__);
-		return NULL;
-	} else {
-		l2->ch.nr = id;
-		__add_layer2(&l2->ch, mgr->ch.st);
-		l2->ch.recv = mgr->ch.recv;
-		l2->ch.peer = mgr->ch.peer;
-		l2->ch.ctrl(&l2->ch, OPEN_CHANNEL, NULL);
-		/* We need open here L1 for the manager as well (refcounting) */
-		rq.adr.dev = mgr->ch.st->dev->id;
-		id = mgr->ch.st->own.ctrl(&mgr->ch.st->own, OPEN_CHANNEL, &rq);
-		if (id < 0) {
-			printk(KERN_WARNING "%s: cannot open L1\n", __func__);
-			l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
-			l2 = NULL;
-		}
-	}
-	return l2;
-}
-
-static void
-new_tei_req(struct manager *mgr, u_char *dp)
-{
-	int		tei, ri;
-	struct layer2	*l2;
-
-	ri = dp[0] << 8;
-	ri += dp[1];
-	if (!mgr->up)
-		goto denied;
-	if (!(dp[3] & 1)) /* Extension bit != 1 */
-		goto denied;
-	if (dp[3] != 0xff)
-		tei = dp[3] >> 1; /* 3GPP TS 08.56 6.1.11.2 */
-	else
-		tei = get_free_tei(mgr);
-	if (tei < 0) {
-		printk(KERN_WARNING "%s:No free tei\n", __func__);
-		goto denied;
-	}
-	l2 = create_new_tei(mgr, tei, CTRL_SAPI);
-	if (!l2)
-		goto denied;
-	else
-		mISDN_FsmEvent(&l2->tm->tei_m, EV_ASSIGN_REQ, dp);
-	return;
-denied:
-	put_tei_msg(mgr, ID_DENIED, ri, GROUP_TEI);
-}
-
-static int
-ph_data_ind(struct manager *mgr, struct sk_buff *skb)
-{
-	int		ret = -EINVAL;
-	struct layer2	*l2, *nl2;
-	u_char		mt;
-
-	if (skb->len < 8) {
-		if (*debug  & DEBUG_L2_TEI)
-			printk(KERN_DEBUG "%s: short mgr frame %d/8\n",
-			       __func__, skb->len);
-		goto done;
-	}
-
-	if ((skb->data[0] >> 2) != TEI_SAPI) /* not for us */
-		goto done;
-	if (skb->data[0] & 1) /* EA0 formal error */
-		goto done;
-	if (!(skb->data[1] & 1)) /* EA1 formal error */
-		goto done;
-	if ((skb->data[1] >> 1) != GROUP_TEI) /* not for us */
-		goto done;
-	if ((skb->data[2] & 0xef) != UI) /* not UI */
-		goto done;
-	if (skb->data[3] != TEI_ENTITY_ID) /* not tei entity */
-		goto done;
-	mt = skb->data[6];
-	switch (mt) {
-	case ID_REQUEST:
-	case ID_CHK_RES:
-	case ID_VERIFY:
-		if (!test_bit(MGR_OPT_NETWORK, &mgr->options))
-			goto done;
-		break;
-	case ID_ASSIGNED:
-	case ID_DENIED:
-	case ID_CHK_REQ:
-	case ID_REMOVE:
-		if (test_bit(MGR_OPT_NETWORK, &mgr->options))
-			goto done;
-		break;
-	default:
-		goto done;
-	}
-	ret = 0;
-	if (mt == ID_REQUEST) {
-		new_tei_req(mgr, &skb->data[4]);
-		goto done;
-	}
-	list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
-		tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4);
-	}
-done:
-	return ret;
-}
-
-int
-l2_tei(struct layer2 *l2, u_int cmd, u_long arg)
-{
-	struct teimgr	*tm = l2->tm;
-
-	if (test_bit(FLG_FIXED_TEI, &l2->flag))
-		return 0;
-	if (*debug & DEBUG_L2_TEI)
-		printk(KERN_DEBUG "%s: cmd(%x)\n", __func__, cmd);
-	switch (cmd) {
-	case MDL_ASSIGN_IND:
-		mISDN_FsmEvent(&tm->tei_m, EV_IDREQ, NULL);
-		break;
-	case MDL_ERROR_IND:
-		if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
-			mISDN_FsmEvent(&tm->tei_m, EV_CHKREQ, &l2->tei);
-		if (test_bit(MGR_OPT_USER, &tm->mgr->options))
-			mISDN_FsmEvent(&tm->tei_m, EV_VERIFY, NULL);
-		break;
-	case MDL_STATUS_UP_IND:
-		if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
-			mISDN_FsmEvent(&tm->mgr->deact, EV_ACTIVATE, NULL);
-		break;
-	case MDL_STATUS_DOWN_IND:
-		if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
-			mISDN_FsmEvent(&tm->mgr->deact, EV_DEACTIVATE, NULL);
-		break;
-	case MDL_STATUS_UI_IND:
-		if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
-			mISDN_FsmEvent(&tm->mgr->deact, EV_UI, NULL);
-		break;
-	}
-	return 0;
-}
-
-void
-TEIrelease(struct layer2 *l2)
-{
-	struct teimgr	*tm = l2->tm;
-	u_long		flags;
-
-	mISDN_FsmDelTimer(&tm->timer, 1);
-	write_lock_irqsave(&tm->mgr->lock, flags);
-	list_del(&l2->list);
-	write_unlock_irqrestore(&tm->mgr->lock, flags);
-	l2->tm = NULL;
-	kfree(tm);
-}
-
-static int
-create_teimgr(struct manager *mgr, struct channel_req *crq)
-{
-	struct layer2		*l2;
-	unsigned long		opt = 0;
-	unsigned long		flags;
-	int			id;
-	struct channel_req	l1rq;
-
-	if (*debug & DEBUG_L2_TEI)
-		printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
-		       __func__, dev_name(&mgr->ch.st->dev->dev),
-		       crq->protocol, crq->adr.dev, crq->adr.channel,
-		       crq->adr.sapi, crq->adr.tei);
-	if (crq->adr.tei > GROUP_TEI)
-		return -EINVAL;
-	if (crq->adr.tei < 64)
-		test_and_set_bit(OPTION_L2_FIXEDTEI, &opt);
-	if (crq->adr.tei == 0)
-		test_and_set_bit(OPTION_L2_PTP, &opt);
-	if (test_bit(MGR_OPT_NETWORK, &mgr->options)) {
-		if (crq->protocol == ISDN_P_LAPD_TE)
-			return -EPROTONOSUPPORT;
-		if ((crq->adr.tei != 0) && (crq->adr.tei != 127))
-			return -EINVAL;
-		if (mgr->up) {
-			printk(KERN_WARNING
-			       "%s: only one network manager is allowed\n",
-			       __func__);
-			return -EBUSY;
-		}
-	} else if (test_bit(MGR_OPT_USER, &mgr->options)) {
-		if (crq->protocol == ISDN_P_LAPD_NT)
-			return -EPROTONOSUPPORT;
-		if ((crq->adr.tei >= 64) && (crq->adr.tei < GROUP_TEI))
-			return -EINVAL; /* dyn tei */
-	} else {
-		if (crq->protocol == ISDN_P_LAPD_NT)
-			test_and_set_bit(MGR_OPT_NETWORK, &mgr->options);
-		if (crq->protocol == ISDN_P_LAPD_TE)
-			test_and_set_bit(MGR_OPT_USER, &mgr->options);
-	}
-	l1rq.adr = crq->adr;
-	if (mgr->ch.st->dev->Dprotocols
-	    & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1)))
-		test_and_set_bit(OPTION_L2_PMX, &opt);
-	if ((crq->protocol == ISDN_P_LAPD_NT) && (crq->adr.tei == 127)) {
-		mgr->up = crq->ch;
-		id = DL_INFO_L2_CONNECT;
-		teiup_create(mgr, DL_INFORMATION_IND, sizeof(id), &id);
-		if (test_bit(MGR_PH_ACTIVE, &mgr->options))
-			teiup_create(mgr, PH_ACTIVATE_IND, 0, NULL);
-		crq->ch = NULL;
-		if (!list_empty(&mgr->layer2)) {
-			read_lock_irqsave(&mgr->lock, flags);
-			list_for_each_entry(l2, &mgr->layer2, list) {
-				l2->up = mgr->up;
-				l2->ch.ctrl(&l2->ch, OPEN_CHANNEL, NULL);
-			}
-			read_unlock_irqrestore(&mgr->lock, flags);
-		}
-		return 0;
-	}
-	l2 = create_l2(crq->ch, crq->protocol, opt,
-		       crq->adr.tei, crq->adr.sapi);
-	if (!l2)
-		return -ENOMEM;
-	l2->tm = kzalloc_obj(struct teimgr);
-	if (!l2->tm) {
-		kfree(l2);
-		printk(KERN_ERR "kmalloc teimgr failed\n");
-		return -ENOMEM;
-	}
-	l2->tm->mgr = mgr;
-	l2->tm->l2 = l2;
-	l2->tm->tei_m.debug = *debug & DEBUG_L2_TEIFSM;
-	l2->tm->tei_m.userdata = l2->tm;
-	l2->tm->tei_m.printdebug = tei_debug;
-	if (crq->protocol == ISDN_P_LAPD_TE) {
-		l2->tm->tei_m.fsm = &teifsmu;
-		l2->tm->tei_m.state = ST_TEI_NOP;
-		l2->tm->tval = 1000; /* T201  1 sec */
-		if (test_bit(OPTION_L2_PMX, &opt))
-			l1rq.protocol = ISDN_P_TE_E1;
-		else
-			l1rq.protocol = ISDN_P_TE_S0;
-	} else {
-		l2->tm->tei_m.fsm = &teifsmn;
-		l2->tm->tei_m.state = ST_TEI_NOP;
-		l2->tm->tval = 2000; /* T202  2 sec */
-		if (test_bit(OPTION_L2_PMX, &opt))
-			l1rq.protocol = ISDN_P_NT_E1;
-		else
-			l1rq.protocol = ISDN_P_NT_S0;
-	}
-	mISDN_FsmInitTimer(&l2->tm->tei_m, &l2->tm->timer);
-	write_lock_irqsave(&mgr->lock, flags);
-	id = get_free_id(mgr);
-	list_add_tail(&l2->list, &mgr->layer2);
-	write_unlock_irqrestore(&mgr->lock, flags);
-	if (id >= 0) {
-		l2->ch.nr = id;
-		l2->up->nr = id;
-		crq->ch = &l2->ch;
-		/* We need open here L1 for the manager as well (refcounting) */
-		id = mgr->ch.st->own.ctrl(&mgr->ch.st->own, OPEN_CHANNEL,
-					  &l1rq);
-	}
-	if (id < 0)
-		l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
-	return id;
-}
-
-static int
-mgr_send(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct manager	*mgr;
-	struct mISDNhead	*hh =  mISDN_HEAD_P(skb);
-	int			ret = -EINVAL;
-
-	mgr = container_of(ch, struct manager, ch);
-	if (*debug & DEBUG_L2_RECV)
-		printk(KERN_DEBUG "%s: prim(%x) id(%x)\n",
-		       __func__, hh->prim, hh->id);
-	switch (hh->prim) {
-	case PH_DATA_IND:
-		mISDN_FsmEvent(&mgr->deact, EV_UI, NULL);
-		ret = ph_data_ind(mgr, skb);
-		break;
-	case PH_DATA_CNF:
-		do_ack(mgr, hh->id);
-		ret = 0;
-		break;
-	case PH_ACTIVATE_IND:
-		test_and_set_bit(MGR_PH_ACTIVE, &mgr->options);
-		if (mgr->up)
-			teiup_create(mgr, PH_ACTIVATE_IND, 0, NULL);
-		mISDN_FsmEvent(&mgr->deact, EV_ACTIVATE_IND, NULL);
-		do_send(mgr);
-		ret = 0;
-		break;
-	case PH_DEACTIVATE_IND:
-		test_and_clear_bit(MGR_PH_ACTIVE, &mgr->options);
-		if (mgr->up)
-			teiup_create(mgr, PH_DEACTIVATE_IND, 0, NULL);
-		mISDN_FsmEvent(&mgr->deact, EV_DEACTIVATE_IND, NULL);
-		ret = 0;
-		break;
-	case DL_UNITDATA_REQ:
-		return dl_unit_data(mgr, skb);
-	}
-	if (!ret)
-		dev_kfree_skb(skb);
-	return ret;
-}
-
-static int
-free_teimanager(struct manager *mgr)
-{
-	struct layer2	*l2, *nl2;
-
-	test_and_clear_bit(OPTION_L1_HOLD, &mgr->options);
-	if (test_bit(MGR_OPT_NETWORK, &mgr->options)) {
-		/* not locked lock is taken in release tei */
-		mgr->up = NULL;
-		if (test_bit(OPTION_L2_CLEANUP, &mgr->options)) {
-			list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
-				put_tei_msg(mgr, ID_REMOVE, 0, l2->tei);
-				mutex_lock(&mgr->ch.st->lmutex);
-				list_del(&l2->ch.list);
-				mutex_unlock(&mgr->ch.st->lmutex);
-				l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
-			}
-			test_and_clear_bit(MGR_OPT_NETWORK, &mgr->options);
-		} else {
-			list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
-				l2->up = NULL;
-			}
-		}
-	}
-	if (test_bit(MGR_OPT_USER, &mgr->options)) {
-		if (list_empty(&mgr->layer2))
-			test_and_clear_bit(MGR_OPT_USER, &mgr->options);
-	}
-	mgr->ch.st->dev->D.ctrl(&mgr->ch.st->dev->D, CLOSE_CHANNEL, NULL);
-	return 0;
-}
-
-static int
-ctrl_teimanager(struct manager *mgr, void *arg)
-{
-	/* currently we only have one option */
-	unsigned int *val = (unsigned int *)arg;
-
-	switch (val[0]) {
-	case IMCLEAR_L2:
-		if (val[1])
-			test_and_set_bit(OPTION_L2_CLEANUP, &mgr->options);
-		else
-			test_and_clear_bit(OPTION_L2_CLEANUP, &mgr->options);
-		break;
-	case IMHOLD_L1:
-		if (val[1])
-			test_and_set_bit(OPTION_L1_HOLD, &mgr->options);
-		else
-			test_and_clear_bit(OPTION_L1_HOLD, &mgr->options);
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-/* This function does create a L2 for fixed TEI in NT Mode */
-static int
-check_data(struct manager *mgr, struct sk_buff *skb)
-{
-	struct mISDNhead	*hh =  mISDN_HEAD_P(skb);
-	int			ret, tei, sapi;
-	struct layer2		*l2;
-
-	if (*debug & DEBUG_L2_CTRL)
-		printk(KERN_DEBUG "%s: prim(%x) id(%x)\n",
-		       __func__, hh->prim, hh->id);
-	if (test_bit(MGR_OPT_USER, &mgr->options))
-		return -ENOTCONN;
-	if (hh->prim != PH_DATA_IND)
-		return -ENOTCONN;
-	if (skb->len != 3)
-		return -ENOTCONN;
-	if (skb->data[0] & 3) /* EA0 and CR must be  0 */
-		return -EINVAL;
-	sapi = skb->data[0] >> 2;
-	if (!(skb->data[1] & 1)) /* invalid EA1 */
-		return -EINVAL;
-	tei = skb->data[1] >> 1;
-	if (tei > 63) /* not a fixed tei */
-		return -ENOTCONN;
-	if ((skb->data[2] & ~0x10) != SABME)
-		return -ENOTCONN;
-	/* We got a SABME for a fixed TEI */
-	if (*debug & DEBUG_L2_CTRL)
-		printk(KERN_DEBUG "%s: SABME sapi(%d) tei(%d)\n",
-		       __func__, sapi, tei);
-	l2 = create_new_tei(mgr, tei, sapi);
-	if (!l2) {
-		if (*debug & DEBUG_L2_CTRL)
-			printk(KERN_DEBUG "%s: failed to create new tei\n",
-			       __func__);
-		return -ENOMEM;
-	}
-	ret = l2->ch.send(&l2->ch, skb);
-	return ret;
-}
-
-void
-delete_teimanager(struct mISDNchannel *ch)
-{
-	struct manager	*mgr;
-	struct layer2	*l2, *nl2;
-
-	mgr = container_of(ch, struct manager, ch);
-	/* not locked lock is taken in release tei */
-	list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
-		mutex_lock(&mgr->ch.st->lmutex);
-		list_del(&l2->ch.list);
-		mutex_unlock(&mgr->ch.st->lmutex);
-		l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
-	}
-	list_del(&mgr->ch.list);
-	list_del(&mgr->bcast.list);
-	skb_queue_purge(&mgr->sendq);
-	kfree(mgr);
-}
-
-static int
-mgr_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
-{
-	struct manager	*mgr;
-	int		ret = -EINVAL;
-
-	mgr = container_of(ch, struct manager, ch);
-	if (*debug & DEBUG_L2_CTRL)
-		printk(KERN_DEBUG "%s(%x, %p)\n", __func__, cmd, arg);
-	switch (cmd) {
-	case OPEN_CHANNEL:
-		ret = create_teimgr(mgr, arg);
-		break;
-	case CLOSE_CHANNEL:
-		ret = free_teimanager(mgr);
-		break;
-	case CONTROL_CHANNEL:
-		ret = ctrl_teimanager(mgr, arg);
-		break;
-	case CHECK_DATA:
-		ret = check_data(mgr, arg);
-		break;
-	}
-	return ret;
-}
-
-static int
-mgr_bcast(struct mISDNchannel *ch, struct sk_buff *skb)
-{
-	struct manager		*mgr = container_of(ch, struct manager, bcast);
-	struct mISDNhead	*hhc, *hh = mISDN_HEAD_P(skb);
-	struct sk_buff		*cskb = NULL;
-	struct layer2		*l2;
-	u_long			flags;
-	int			ret;
-
-	read_lock_irqsave(&mgr->lock, flags);
-	list_for_each_entry(l2, &mgr->layer2, list) {
-		if ((hh->id & MISDN_ID_SAPI_MASK) ==
-		    (l2->ch.addr & MISDN_ID_SAPI_MASK)) {
-			if (list_is_last(&l2->list, &mgr->layer2)) {
-				cskb = skb;
-				skb = NULL;
-			} else {
-				if (!cskb)
-					cskb = skb_copy(skb, GFP_ATOMIC);
-			}
-			if (cskb) {
-				hhc = mISDN_HEAD_P(cskb);
-				/* save original header behind normal header */
-				hhc++;
-				*hhc = *hh;
-				hhc--;
-				hhc->prim = DL_INTERN_MSG;
-				hhc->id = l2->ch.nr;
-				ret = ch->st->own.recv(&ch->st->own, cskb);
-				if (ret) {
-					if (*debug & DEBUG_SEND_ERR)
-						printk(KERN_DEBUG
-						       "%s ch%d prim(%x) addr(%x)"
-						       " err %d\n",
-						       __func__, l2->ch.nr,
-						       hh->prim, l2->ch.addr, ret);
-				} else
-					cskb = NULL;
-			} else {
-				printk(KERN_WARNING "%s ch%d addr %x no mem\n",
-				       __func__, ch->nr, ch->addr);
-				goto out;
-			}
-		}
-	}
-out:
-	read_unlock_irqrestore(&mgr->lock, flags);
-	dev_kfree_skb(cskb);
-	dev_kfree_skb(skb);
-	return 0;
-}
-
-static int
-mgr_bcast_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
-{
-
-	return -EINVAL;
-}
-
-int
-create_teimanager(struct mISDNdevice *dev)
-{
-	struct manager *mgr;
-
-	mgr = kzalloc_obj(struct manager);
-	if (!mgr)
-		return -ENOMEM;
-	INIT_LIST_HEAD(&mgr->layer2);
-	rwlock_init(&mgr->lock);
-	skb_queue_head_init(&mgr->sendq);
-	mgr->nextid = 1;
-	mgr->lastid = MISDN_ID_NONE;
-	mgr->ch.send = mgr_send;
-	mgr->ch.ctrl = mgr_ctrl;
-	mgr->ch.st = dev->D.st;
-	set_channel_address(&mgr->ch, TEI_SAPI, GROUP_TEI);
-	add_layer2(&mgr->ch, dev->D.st);
-	mgr->bcast.send = mgr_bcast;
-	mgr->bcast.ctrl = mgr_bcast_ctrl;
-	mgr->bcast.st = dev->D.st;
-	set_channel_address(&mgr->bcast, 0, GROUP_TEI);
-	add_layer2(&mgr->bcast, dev->D.st);
-	mgr->deact.debug = *debug & DEBUG_MANAGER;
-	mgr->deact.userdata = mgr;
-	mgr->deact.printdebug = da_debug;
-	mgr->deact.fsm = &deactfsm;
-	mgr->deact.state = ST_L1_DEACT;
-	mISDN_FsmInitTimer(&mgr->deact, &mgr->datimer);
-	dev->teimgr = &mgr->ch;
-	return 0;
-}
-
-int TEIInit(u_int *deb)
-{
-	int res;
-	debug = deb;
-	teifsmu.state_count = TEI_STATE_COUNT;
-	teifsmu.event_count = TEI_EVENT_COUNT;
-	teifsmu.strEvent = strTeiEvent;
-	teifsmu.strState = strTeiState;
-	res = mISDN_FsmNew(&teifsmu, TeiFnListUser, ARRAY_SIZE(TeiFnListUser));
-	if (res)
-		goto error;
-	teifsmn.state_count = TEI_STATE_COUNT;
-	teifsmn.event_count = TEI_EVENT_COUNT;
-	teifsmn.strEvent = strTeiEvent;
-	teifsmn.strState = strTeiState;
-	res = mISDN_FsmNew(&teifsmn, TeiFnListNet, ARRAY_SIZE(TeiFnListNet));
-	if (res)
-		goto error_smn;
-	deactfsm.state_count =  DEACT_STATE_COUNT;
-	deactfsm.event_count = DEACT_EVENT_COUNT;
-	deactfsm.strEvent = strDeactEvent;
-	deactfsm.strState = strDeactState;
-	res = mISDN_FsmNew(&deactfsm, DeactFnList, ARRAY_SIZE(DeactFnList));
-	if (res)
-		goto error_deact;
-	return 0;
-
-error_deact:
-	mISDN_FsmFree(&teifsmn);
-error_smn:
-	mISDN_FsmFree(&teifsmu);
-error:
-	return res;
-}
-
-void TEIFree(void)
-{
-	mISDN_FsmFree(&teifsmu);
-	mISDN_FsmFree(&teifsmn);
-	mISDN_FsmFree(&deactfsm);
-}
diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c
deleted file mode 100644
index a18845755633..000000000000
--- a/drivers/isdn/mISDN/timerdev.c
+++ /dev/null
@@ -1,295 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *
- * general timer device for using in ISDN stacks
- *
- * Author	Karsten Keil <kkeil@novell.com>
- *
- * Copyright 2008  by Karsten Keil <kkeil@novell.com>
- */
-
-#include <linux/poll.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/timer.h>
-#include <linux/miscdevice.h>
-#include <linux/module.h>
-#include <linux/mISDNif.h>
-#include <linux/mutex.h>
-#include <linux/sched/signal.h>
-
-#include "core.h"
-
-static DEFINE_MUTEX(mISDN_mutex);
-static u_int	*debug;
-
-
-struct mISDNtimerdev {
-	int			next_id;
-	struct list_head	pending;
-	struct list_head	expired;
-	wait_queue_head_t	wait;
-	u_int			work;
-	spinlock_t		lock; /* protect lists */
-};
-
-struct mISDNtimer {
-	struct list_head	list;
-	struct  mISDNtimerdev	*dev;
-	struct timer_list	tl;
-	int			id;
-};
-
-static int
-mISDN_open(struct inode *ino, struct file *filep)
-{
-	struct mISDNtimerdev	*dev;
-
-	if (*debug & DEBUG_TIMER)
-		printk(KERN_DEBUG "%s(%p,%p)\n", __func__, ino, filep);
-	dev = kmalloc_obj(struct mISDNtimerdev);
-	if (!dev)
-		return -ENOMEM;
-	dev->next_id = 1;
-	INIT_LIST_HEAD(&dev->pending);
-	INIT_LIST_HEAD(&dev->expired);
-	spin_lock_init(&dev->lock);
-	dev->work = 0;
-	init_waitqueue_head(&dev->wait);
-	filep->private_data = dev;
-	return nonseekable_open(ino, filep);
-}
-
-static int
-mISDN_close(struct inode *ino, struct file *filep)
-{
-	struct mISDNtimerdev	*dev = filep->private_data;
-	struct list_head	*list = &dev->pending;
-	struct mISDNtimer	*timer, *next;
-
-	if (*debug & DEBUG_TIMER)
-		printk(KERN_DEBUG "%s(%p,%p)\n", __func__, ino, filep);
-
-	spin_lock_irq(&dev->lock);
-	while (!list_empty(list)) {
-		timer = list_first_entry(list, struct mISDNtimer, list);
-		spin_unlock_irq(&dev->lock);
-		timer_shutdown_sync(&timer->tl);
-		spin_lock_irq(&dev->lock);
-		/* it might have been moved to ->expired */
-		list_del(&timer->list);
-		kfree(timer);
-	}
-	spin_unlock_irq(&dev->lock);
-
-	list_for_each_entry_safe(timer, next, &dev->expired, list) {
-		kfree(timer);
-	}
-	kfree(dev);
-	return 0;
-}
-
-static ssize_t
-mISDN_read(struct file *filep, char __user *buf, size_t count, loff_t *off)
-{
-	struct mISDNtimerdev	*dev = filep->private_data;
-	struct list_head *list = &dev->expired;
-	struct mISDNtimer	*timer;
-	int	ret = 0;
-
-	if (*debug & DEBUG_TIMER)
-		printk(KERN_DEBUG "%s(%p, %p, %d, %p)\n", __func__,
-		       filep, buf, (int)count, off);
-
-	if (count < sizeof(int))
-		return -ENOSPC;
-
-	spin_lock_irq(&dev->lock);
-	while (list_empty(list) && (dev->work == 0)) {
-		spin_unlock_irq(&dev->lock);
-		if (filep->f_flags & O_NONBLOCK)
-			return -EAGAIN;
-		wait_event_interruptible(dev->wait, (READ_ONCE(dev->work) ||
-						     !list_empty(list)));
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		spin_lock_irq(&dev->lock);
-	}
-	if (dev->work)
-		WRITE_ONCE(dev->work, 0);
-	if (!list_empty(list)) {
-		timer = list_first_entry(list, struct mISDNtimer, list);
-		list_del(&timer->list);
-		spin_unlock_irq(&dev->lock);
-		if (put_user(timer->id, (int __user *)buf))
-			ret = -EFAULT;
-		else
-			ret = sizeof(int);
-		kfree(timer);
-	} else {
-		spin_unlock_irq(&dev->lock);
-	}
-	return ret;
-}
-
-static __poll_t
-mISDN_poll(struct file *filep, poll_table *wait)
-{
-	struct mISDNtimerdev	*dev = filep->private_data;
-	__poll_t		mask = EPOLLERR;
-
-	if (*debug & DEBUG_TIMER)
-		printk(KERN_DEBUG "%s(%p, %p)\n", __func__, filep, wait);
-	if (dev) {
-		u32 work;
-
-		poll_wait(filep, &dev->wait, wait);
-		mask = 0;
-		work = READ_ONCE(dev->work);
-		if (work || !list_empty(&dev->expired))
-			mask |= (EPOLLIN | EPOLLRDNORM);
-		if (*debug & DEBUG_TIMER)
-			printk(KERN_DEBUG "%s work(%d) empty(%d)\n", __func__,
-			       work, list_empty(&dev->expired));
-	}
-	return mask;
-}
-
-static void
-dev_expire_timer(struct timer_list *t)
-{
-	struct mISDNtimer *timer = timer_container_of(timer, t, tl);
-	u_long			flags;
-
-	spin_lock_irqsave(&timer->dev->lock, flags);
-	if (timer->id >= 0)
-		list_move_tail(&timer->list, &timer->dev->expired);
-	wake_up_interruptible(&timer->dev->wait);
-	spin_unlock_irqrestore(&timer->dev->lock, flags);
-}
-
-static int
-misdn_add_timer(struct mISDNtimerdev *dev, int timeout)
-{
-	int			id;
-	struct mISDNtimer	*timer;
-
-	if (!timeout) {
-		WRITE_ONCE(dev->work, 1);
-		wake_up_interruptible(&dev->wait);
-		id = 0;
-	} else {
-		timer = kzalloc_obj(struct mISDNtimer);
-		if (!timer)
-			return -ENOMEM;
-		timer->dev = dev;
-		timer_setup(&timer->tl, dev_expire_timer, 0);
-		spin_lock_irq(&dev->lock);
-		id = timer->id = dev->next_id++;
-		if (dev->next_id < 0)
-			dev->next_id = 1;
-		list_add_tail(&timer->list, &dev->pending);
-		timer->tl.expires = jiffies + ((HZ * (u_long)timeout) / 1000);
-		add_timer(&timer->tl);
-		spin_unlock_irq(&dev->lock);
-	}
-	return id;
-}
-
-static int
-misdn_del_timer(struct mISDNtimerdev *dev, int id)
-{
-	struct mISDNtimer	*timer;
-
-	spin_lock_irq(&dev->lock);
-	list_for_each_entry(timer, &dev->pending, list) {
-		if (timer->id == id) {
-			list_del_init(&timer->list);
-			timer->id = -1;
-			spin_unlock_irq(&dev->lock);
-			timer_shutdown_sync(&timer->tl);
-			kfree(timer);
-			return id;
-		}
-	}
-	spin_unlock_irq(&dev->lock);
-	return 0;
-}
-
-static long
-mISDN_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
-{
-	struct mISDNtimerdev	*dev = filep->private_data;
-	int			id, tout, ret = 0;
-
-
-	if (*debug & DEBUG_TIMER)
-		printk(KERN_DEBUG "%s(%p, %x, %lx)\n", __func__,
-		       filep, cmd, arg);
-	mutex_lock(&mISDN_mutex);
-	switch (cmd) {
-	case IMADDTIMER:
-		if (get_user(tout, (int __user *)arg)) {
-			ret = -EFAULT;
-			break;
-		}
-		id = misdn_add_timer(dev, tout);
-		if (*debug & DEBUG_TIMER)
-			printk(KERN_DEBUG "%s add %d id %d\n", __func__,
-			       tout, id);
-		if (id < 0) {
-			ret = id;
-			break;
-		}
-		if (put_user(id, (int __user *)arg))
-			ret = -EFAULT;
-		break;
-	case IMDELTIMER:
-		if (get_user(id, (int __user *)arg)) {
-			ret = -EFAULT;
-			break;
-		}
-		if (*debug & DEBUG_TIMER)
-			printk(KERN_DEBUG "%s del id %d\n", __func__, id);
-		id = misdn_del_timer(dev, id);
-		if (put_user(id, (int __user *)arg))
-			ret = -EFAULT;
-		break;
-	default:
-		ret = -EINVAL;
-	}
-	mutex_unlock(&mISDN_mutex);
-	return ret;
-}
-
-static const struct file_operations mISDN_fops = {
-	.owner		= THIS_MODULE,
-	.read		= mISDN_read,
-	.poll		= mISDN_poll,
-	.unlocked_ioctl	= mISDN_ioctl,
-	.open		= mISDN_open,
-	.release	= mISDN_close,
-};
-
-static struct miscdevice mISDNtimer = {
-	.minor	= MISC_DYNAMIC_MINOR,
-	.name	= "mISDNtimer",
-	.fops	= &mISDN_fops,
-};
-
-int
-mISDN_inittimer(u_int *deb)
-{
-	int	err;
-
-	debug = deb;
-	err = misc_register(&mISDNtimer);
-	if (err)
-		printk(KERN_WARNING "mISDN: Could not register timer device\n");
-	return err;
-}
-
-void mISDN_timer_cleanup(void)
-{
-	misc_deregister(&mISDNtimer);
-}
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c
deleted file mode 100644
index b95413bffa16..000000000000
--- a/net/bluetooth/cmtp/capi.c
+++ /dev/null
@@ -1,579 +0,0 @@
-/*
-   CMTP implementation for Linux Bluetooth stack (BlueZ).
-   Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-   SOFTWARE IS DISCLAIMED.
-*/
-
-#include <linux/export.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/sched/signal.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/fcntl.h>
-#include <linux/skbuff.h>
-#include <linux/socket.h>
-#include <linux/ioctl.h>
-#include <linux/file.h>
-#include <linux/wait.h>
-#include <linux/kthread.h>
-#include <net/sock.h>
-
-#include <linux/isdn/capilli.h>
-#include <linux/isdn/capicmd.h>
-#include <linux/isdn/capiutil.h>
-
-#include "cmtp.h"
-
-#define CAPI_INTEROPERABILITY		0x20
-
-#define CAPI_INTEROPERABILITY_REQ	CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
-#define CAPI_INTEROPERABILITY_CONF	CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
-#define CAPI_INTEROPERABILITY_IND	CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
-#define CAPI_INTEROPERABILITY_RESP	CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
-
-#define CAPI_INTEROPERABILITY_REQ_LEN	(CAPI_MSG_BASELEN + 2)
-#define CAPI_INTEROPERABILITY_CONF_LEN	(CAPI_MSG_BASELEN + 4)
-#define CAPI_INTEROPERABILITY_IND_LEN	(CAPI_MSG_BASELEN + 2)
-#define CAPI_INTEROPERABILITY_RESP_LEN	(CAPI_MSG_BASELEN + 2)
-
-#define CAPI_FUNCTION_REGISTER		0
-#define CAPI_FUNCTION_RELEASE		1
-#define CAPI_FUNCTION_GET_PROFILE	2
-#define CAPI_FUNCTION_GET_MANUFACTURER	3
-#define CAPI_FUNCTION_GET_VERSION	4
-#define CAPI_FUNCTION_GET_SERIAL_NUMBER	5
-#define CAPI_FUNCTION_MANUFACTURER	6
-#define CAPI_FUNCTION_LOOPBACK		7
-
-
-#define CMTP_MSGNUM	1
-#define CMTP_APPLID	2
-#define CMTP_MAPPING	3
-
-static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
-{
-	struct cmtp_application *app = kzalloc_obj(*app);
-
-	BT_DBG("session %p application %p appl %u", session, app, appl);
-
-	if (!app)
-		return NULL;
-
-	app->state = BT_OPEN;
-	app->appl = appl;
-
-	list_add_tail(&app->list, &session->applications);
-
-	return app;
-}
-
-static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
-{
-	BT_DBG("session %p application %p", session, app);
-
-	if (app) {
-		list_del(&app->list);
-		kfree(app);
-	}
-}
-
-static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
-{
-	struct cmtp_application *app;
-
-	list_for_each_entry(app, &session->applications, list) {
-		switch (pattern) {
-		case CMTP_MSGNUM:
-			if (app->msgnum == value)
-				return app;
-			break;
-		case CMTP_APPLID:
-			if (app->appl == value)
-				return app;
-			break;
-		case CMTP_MAPPING:
-			if (app->mapping == value)
-				return app;
-			break;
-		}
-	}
-
-	return NULL;
-}
-
-static int cmtp_msgnum_get(struct cmtp_session *session)
-{
-	session->msgnum++;
-
-	if ((session->msgnum & 0xff) > 200)
-		session->msgnum = CMTP_INITIAL_MSGNUM + 1;
-
-	return session->msgnum;
-}
-
-static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
-{
-	struct cmtp_scb *scb = (void *) skb->cb;
-
-	BT_DBG("session %p skb %p len %u", session, skb, skb->len);
-
-	scb->id = -1;
-	scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
-
-	skb_queue_tail(&session->transmit, skb);
-
-	wake_up_interruptible(sk_sleep(session->sock->sk));
-}
-
-static void cmtp_send_interopmsg(struct cmtp_session *session,
-					__u8 subcmd, __u16 appl, __u16 msgnum,
-					__u16 function, unsigned char *buf, int len)
-{
-	struct sk_buff *skb;
-	unsigned char *s;
-
-	BT_DBG("session %p subcmd 0x%02x appl %u msgnum %u", session, subcmd, appl, msgnum);
-
-	skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC);
-	if (!skb) {
-		BT_ERR("Can't allocate memory for interoperability packet");
-		return;
-	}
-
-	s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
-
-	capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
-	capimsg_setu16(s, 2, appl);
-	capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
-	capimsg_setu8 (s, 5, subcmd);
-	capimsg_setu16(s, 6, msgnum);
-
-	/* Interoperability selector (Bluetooth Device Management) */
-	capimsg_setu16(s, 8, 0x0001);
-
-	capimsg_setu8 (s, 10, 3 + len);
-	capimsg_setu16(s, 11, function);
-	capimsg_setu8 (s, 13, len);
-
-	if (len > 0)
-		memcpy(s + 14, buf, len);
-
-	cmtp_send_capimsg(session, skb);
-}
-
-static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
-{
-	struct capi_ctr *ctrl = &session->ctrl;
-	struct cmtp_application *application;
-	__u16 appl, msgnum, func, info;
-	__u32 controller;
-
-	BT_DBG("session %p skb %p len %u", session, skb, skb->len);
-
-	switch (CAPIMSG_SUBCOMMAND(skb->data)) {
-	case CAPI_CONF:
-		if (skb->len < CAPI_MSG_BASELEN + 10)
-			break;
-
-		func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
-		info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
-
-		switch (func) {
-		case CAPI_FUNCTION_REGISTER:
-			msgnum = CAPIMSG_MSGID(skb->data);
-
-			application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
-			if (application) {
-				application->state = BT_CONNECTED;
-				application->msgnum = 0;
-				application->mapping = CAPIMSG_APPID(skb->data);
-				wake_up_interruptible(&session->wait);
-			}
-
-			break;
-
-		case CAPI_FUNCTION_RELEASE:
-			appl = CAPIMSG_APPID(skb->data);
-
-			application = cmtp_application_get(session, CMTP_MAPPING, appl);
-			if (application) {
-				application->state = BT_CLOSED;
-				application->msgnum = 0;
-				wake_up_interruptible(&session->wait);
-			}
-
-			break;
-
-		case CAPI_FUNCTION_GET_PROFILE:
-			if (skb->len < CAPI_MSG_BASELEN + 11 + sizeof(capi_profile))
-				break;
-
-			controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
-			msgnum = CAPIMSG_MSGID(skb->data);
-
-			if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
-				session->ncontroller = controller;
-				wake_up_interruptible(&session->wait);
-				break;
-			}
-
-			if (!info && ctrl) {
-				memcpy(&ctrl->profile,
-					skb->data + CAPI_MSG_BASELEN + 11,
-					sizeof(capi_profile));
-				session->state = BT_CONNECTED;
-				capi_ctr_ready(ctrl);
-			}
-
-			break;
-
-		case CAPI_FUNCTION_GET_MANUFACTURER:
-			if (!info && ctrl && skb->len > CAPI_MSG_BASELEN + 14)
-				strscpy_pad(ctrl->manu,
-					    skb->data + CAPI_MSG_BASELEN + 15,
-					    skb->data[CAPI_MSG_BASELEN + 14]);
-			break;
-
-		case CAPI_FUNCTION_GET_VERSION:
-			if (skb->len < CAPI_MSG_BASELEN + 32)
-				break;
-
-			if (!info && ctrl) {
-				ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
-				ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
-				ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
-				ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
-			}
-
-			break;
-
-		case CAPI_FUNCTION_GET_SERIAL_NUMBER:
-			if (!info && ctrl && skb->len > CAPI_MSG_BASELEN + 16)
-				strscpy_pad(ctrl->serial,
-					    skb->data + CAPI_MSG_BASELEN + 17,
-					    skb->data[CAPI_MSG_BASELEN + 16]);
-			break;
-		}
-
-		break;
-
-	case CAPI_IND:
-		if (skb->len < CAPI_MSG_BASELEN + 6)
-			break;
-
-		func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
-
-		if (func == CAPI_FUNCTION_LOOPBACK) {
-			int len = min_t(uint, skb->len - CAPI_MSG_BASELEN - 6,
-						skb->data[CAPI_MSG_BASELEN + 5]);
-			appl = CAPIMSG_APPID(skb->data);
-			msgnum = CAPIMSG_MSGID(skb->data);
-			cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
-						skb->data + CAPI_MSG_BASELEN + 6, len);
-		}
-
-		break;
-	}
-
-	kfree_skb(skb);
-}
-
-void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
-{
-	struct capi_ctr *ctrl = &session->ctrl;
-	struct cmtp_application *application;
-	__u16 appl;
-	__u32 contr;
-
-	BT_DBG("session %p skb %p len %u", session, skb, skb->len);
-
-	if (skb->len < CAPI_MSG_BASELEN)
-		return;
-
-	if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
-		cmtp_recv_interopmsg(session, skb);
-		return;
-	}
-
-	if (session->flags & BIT(CMTP_LOOPBACK)) {
-		kfree_skb(skb);
-		return;
-	}
-
-	appl = CAPIMSG_APPID(skb->data);
-	contr = CAPIMSG_CONTROL(skb->data);
-
-	application = cmtp_application_get(session, CMTP_MAPPING, appl);
-	if (application) {
-		appl = application->appl;
-		CAPIMSG_SETAPPID(skb->data, appl);
-	} else {
-		BT_ERR("Can't find application with id %u", appl);
-		kfree_skb(skb);
-		return;
-	}
-
-	if ((contr & 0x7f) == 0x01) {
-		contr = (contr & 0xffffff80) | session->num;
-		CAPIMSG_SETCONTROL(skb->data, contr);
-	}
-
-	capi_ctr_handle_message(ctrl, appl, skb);
-}
-
-static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
-{
-	BT_DBG("ctrl %p data %p", ctrl, data);
-
-	return 0;
-}
-
-static void cmtp_reset_ctr(struct capi_ctr *ctrl)
-{
-	struct cmtp_session *session = ctrl->driverdata;
-
-	BT_DBG("ctrl %p", ctrl);
-
-	capi_ctr_down(ctrl);
-
-	atomic_inc(&session->terminate);
-	wake_up_process(session->task);
-}
-
-static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	struct cmtp_session *session = ctrl->driverdata;
-	struct cmtp_application *application;
-	unsigned long timeo = CMTP_INTEROP_TIMEOUT;
-	unsigned char buf[8];
-	int err = 0, nconn, want = rp->level3cnt;
-
-	BT_DBG("ctrl %p appl %u level3cnt %u datablkcnt %u datablklen %u",
-	       ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
-
-	application = cmtp_application_add(session, appl);
-	if (!application) {
-		BT_ERR("Can't allocate memory for new application");
-		return;
-	}
-
-	if (want < 0)
-		nconn = ctrl->profile.nbchannel * -want;
-	else
-		nconn = want;
-
-	if (nconn == 0)
-		nconn = ctrl->profile.nbchannel;
-
-	capimsg_setu16(buf, 0, nconn);
-	capimsg_setu16(buf, 2, rp->datablkcnt);
-	capimsg_setu16(buf, 4, rp->datablklen);
-
-	application->state = BT_CONFIG;
-	application->msgnum = cmtp_msgnum_get(session);
-
-	cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
-				CAPI_FUNCTION_REGISTER, buf, 6);
-
-	add_wait_queue(&session->wait, &wait);
-	while (1) {
-		set_current_state(TASK_INTERRUPTIBLE);
-
-		if (!timeo) {
-			err = -EAGAIN;
-			break;
-		}
-
-		if (application->state == BT_CLOSED) {
-			err = -application->err;
-			break;
-		}
-
-		if (application->state == BT_CONNECTED)
-			break;
-
-		if (signal_pending(current)) {
-			err = -EINTR;
-			break;
-		}
-
-		timeo = schedule_timeout(timeo);
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&session->wait, &wait);
-
-	if (err) {
-		cmtp_application_del(session, application);
-		return;
-	}
-}
-
-static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
-{
-	struct cmtp_session *session = ctrl->driverdata;
-	struct cmtp_application *application;
-
-	BT_DBG("ctrl %p appl %u", ctrl, appl);
-
-	application = cmtp_application_get(session, CMTP_APPLID, appl);
-	if (!application) {
-		BT_ERR("Can't find application");
-		return;
-	}
-
-	application->msgnum = cmtp_msgnum_get(session);
-
-	cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
-				CAPI_FUNCTION_RELEASE, NULL, 0);
-
-	wait_event_interruptible_timeout(session->wait,
-			(application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT);
-
-	cmtp_application_del(session, application);
-}
-
-static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
-{
-	struct cmtp_session *session = ctrl->driverdata;
-	struct cmtp_application *application;
-	__u16 appl;
-	__u32 contr;
-
-	BT_DBG("ctrl %p skb %p", ctrl, skb);
-
-	appl = CAPIMSG_APPID(skb->data);
-	contr = CAPIMSG_CONTROL(skb->data);
-
-	application = cmtp_application_get(session, CMTP_APPLID, appl);
-	if ((!application) || (application->state != BT_CONNECTED)) {
-		BT_ERR("Can't find application with id %u", appl);
-		return CAPI_ILLAPPNR;
-	}
-
-	CAPIMSG_SETAPPID(skb->data, application->mapping);
-
-	if ((contr & 0x7f) == session->num) {
-		contr = (contr & 0xffffff80) | 0x01;
-		CAPIMSG_SETCONTROL(skb->data, contr);
-	}
-
-	cmtp_send_capimsg(session, skb);
-
-	return CAPI_NOERROR;
-}
-
-static char *cmtp_procinfo(struct capi_ctr *ctrl)
-{
-	return "CAPI Message Transport Protocol";
-}
-
-static int cmtp_proc_show(struct seq_file *m, void *v)
-{
-	struct capi_ctr *ctrl = m->private;
-	struct cmtp_session *session = ctrl->driverdata;
-	struct cmtp_application *app;
-
-	seq_printf(m, "%s\n\n", cmtp_procinfo(ctrl));
-	seq_printf(m, "addr %s\n", session->name);
-	seq_printf(m, "ctrl %d\n", session->num);
-
-	list_for_each_entry(app, &session->applications, list) {
-		seq_printf(m, "appl %u -> %u\n", app->appl, app->mapping);
-	}
-
-	return 0;
-}
-
-int cmtp_attach_device(struct cmtp_session *session)
-{
-	unsigned char buf[4];
-	long ret;
-
-	BT_DBG("session %p", session);
-
-	capimsg_setu32(buf, 0, 0);
-
-	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
-				CAPI_FUNCTION_GET_PROFILE, buf, 4);
-
-	ret = wait_event_interruptible_timeout(session->wait,
-			session->ncontroller, CMTP_INTEROP_TIMEOUT);
-
-	BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
-
-	if (!ret)
-		return -ETIMEDOUT;
-
-	if (!session->ncontroller)
-		return -ENODEV;
-
-	if (session->ncontroller > 1)
-		BT_INFO("Setting up only CAPI controller 1");
-
-	session->ctrl.owner      = THIS_MODULE;
-	session->ctrl.driverdata = session;
-	strcpy(session->ctrl.name, session->name);
-
-	session->ctrl.driver_name   = "cmtp";
-	session->ctrl.load_firmware = cmtp_load_firmware;
-	session->ctrl.reset_ctr     = cmtp_reset_ctr;
-	session->ctrl.register_appl = cmtp_register_appl;
-	session->ctrl.release_appl  = cmtp_release_appl;
-	session->ctrl.send_message  = cmtp_send_message;
-
-	session->ctrl.procinfo      = cmtp_procinfo;
-	session->ctrl.proc_show     = cmtp_proc_show;
-
-	if (attach_capi_ctr(&session->ctrl) < 0) {
-		BT_ERR("Can't attach new controller");
-		return -EBUSY;
-	}
-
-	session->num = session->ctrl.cnr;
-
-	BT_DBG("session %p num %d", session, session->num);
-
-	capimsg_setu32(buf, 0, 1);
-
-	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-				CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
-
-	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-				CAPI_FUNCTION_GET_VERSION, buf, 4);
-
-	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-				CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
-
-	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-				CAPI_FUNCTION_GET_PROFILE, buf, 4);
-
-	return 0;
-}
-
-void cmtp_detach_device(struct cmtp_session *session)
-{
-	BT_DBG("session %p", session);
-
-	detach_capi_ctr(&session->ctrl);
-}
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c
deleted file mode 100644
index 261aeeda3236..000000000000
--- a/net/bluetooth/cmtp/core.c
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
-   CMTP implementation for Linux Bluetooth stack (BlueZ).
-   Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-   SOFTWARE IS DISCLAIMED.
-*/
-
-#include <linux/module.h>
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/fcntl.h>
-#include <linux/freezer.h>
-#include <linux/skbuff.h>
-#include <linux/socket.h>
-#include <linux/ioctl.h>
-#include <linux/file.h>
-#include <linux/init.h>
-#include <linux/kthread.h>
-#include <net/sock.h>
-
-#include <linux/isdn/capilli.h>
-
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/l2cap.h>
-
-#include "cmtp.h"
-
-#define VERSION "1.0"
-
-static DECLARE_RWSEM(cmtp_session_sem);
-static LIST_HEAD(cmtp_session_list);
-
-static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr)
-{
-	struct cmtp_session *session;
-
-	BT_DBG("");
-
-	list_for_each_entry(session, &cmtp_session_list, list)
-		if (!bacmp(bdaddr, &session->bdaddr))
-			return session;
-
-	return NULL;
-}
-
-static void __cmtp_link_session(struct cmtp_session *session)
-{
-	list_add(&session->list, &cmtp_session_list);
-}
-
-static void __cmtp_unlink_session(struct cmtp_session *session)
-{
-	list_del(&session->list);
-}
-
-static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci)
-{
-	u32 valid_flags = BIT(CMTP_LOOPBACK);
-	memset(ci, 0, sizeof(*ci));
-	bacpy(&ci->bdaddr, &session->bdaddr);
-
-	ci->flags = session->flags & valid_flags;
-	ci->state = session->state;
-
-	ci->num = session->num;
-}
-
-
-static inline int cmtp_alloc_block_id(struct cmtp_session *session)
-{
-	int i, id = -1;
-
-	for (i = 0; i < 16; i++)
-		if (!test_and_set_bit(i, &session->blockids)) {
-			id = i;
-			break;
-		}
-
-	return id;
-}
-
-static inline void cmtp_free_block_id(struct cmtp_session *session, int id)
-{
-	clear_bit(id, &session->blockids);
-}
-
-static inline void cmtp_add_msgpart(struct cmtp_session *session, int id, const unsigned char *buf, int count)
-{
-	struct sk_buff *skb = session->reassembly[id], *nskb;
-	int size;
-
-	BT_DBG("session %p buf %p count %d", session, buf, count);
-
-	size = (skb) ? skb->len + count : count;
-
-	nskb = alloc_skb(size, GFP_ATOMIC);
-	if (!nskb) {
-		BT_ERR("Can't allocate memory for CAPI message");
-		return;
-	}
-
-	if (skb && (skb->len > 0))
-		skb_copy_from_linear_data(skb, skb_put(nskb, skb->len), skb->len);
-
-	skb_put_data(nskb, buf, count);
-
-	session->reassembly[id] = nskb;
-
-	kfree_skb(skb);
-}
-
-static inline int cmtp_recv_frame(struct cmtp_session *session, struct sk_buff *skb)
-{
-	__u8 hdr, hdrlen, id;
-	__u16 len;
-
-	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-
-	while (skb->len > 0) {
-		hdr = skb->data[0];
-
-		switch (hdr & 0xc0) {
-		case 0x40:
-			hdrlen = 2;
-			len = skb->data[1];
-			break;
-		case 0x80:
-			hdrlen = 3;
-			len = skb->data[1] | (skb->data[2] << 8);
-			break;
-		default:
-			hdrlen = 1;
-			len = 0;
-			break;
-		}
-
-		id = (hdr & 0x3c) >> 2;
-
-		BT_DBG("hdr 0x%02x hdrlen %d len %d id %d", hdr, hdrlen, len, id);
-
-		if (hdrlen + len > skb->len) {
-			BT_ERR("Wrong size or header information in CMTP frame");
-			break;
-		}
-
-		if (len == 0) {
-			skb_pull(skb, hdrlen);
-			continue;
-		}
-
-		switch (hdr & 0x03) {
-		case 0x00:
-			cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
-			cmtp_recv_capimsg(session, session->reassembly[id]);
-			session->reassembly[id] = NULL;
-			break;
-		case 0x01:
-			cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
-			break;
-		default:
-			kfree_skb(session->reassembly[id]);
-			session->reassembly[id] = NULL;
-			break;
-		}
-
-		skb_pull(skb, hdrlen + len);
-	}
-
-	kfree_skb(skb);
-	return 0;
-}
-
-static int cmtp_send_frame(struct cmtp_session *session, unsigned char *data, int len)
-{
-	struct socket *sock = session->sock;
-	struct kvec iv = { data, len };
-	struct msghdr msg;
-
-	BT_DBG("session %p data %p len %d", session, data, len);
-
-	if (!len)
-		return 0;
-
-	memset(&msg, 0, sizeof(msg));
-
-	return kernel_sendmsg(sock, &msg, &iv, 1, len);
-}
-
-static void cmtp_process_transmit(struct cmtp_session *session)
-{
-	struct sk_buff *skb, *nskb;
-	unsigned char *hdr;
-	unsigned int size, tail;
-
-	BT_DBG("session %p", session);
-
-	nskb = alloc_skb(session->mtu, GFP_ATOMIC);
-	if (!nskb) {
-		BT_ERR("Can't allocate memory for new frame");
-		return;
-	}
-
-	while ((skb = skb_dequeue(&session->transmit))) {
-		struct cmtp_scb *scb = (void *) skb->cb;
-
-		tail = session->mtu - nskb->len;
-		if (tail < 5) {
-			cmtp_send_frame(session, nskb->data, nskb->len);
-			skb_trim(nskb, 0);
-			tail = session->mtu;
-		}
-
-		size = min_t(uint, ((tail < 258) ? (tail - 2) : (tail - 3)), skb->len);
-
-		if (scb->id < 0) {
-			scb->id = cmtp_alloc_block_id(session);
-			if (scb->id < 0) {
-				skb_queue_head(&session->transmit, skb);
-				break;
-			}
-		}
-
-		if (size < 256) {
-			hdr = skb_put(nskb, 2);
-			hdr[0] = 0x40
-				| ((scb->id << 2) & 0x3c)
-				| ((skb->len == size) ? 0x00 : 0x01);
-			hdr[1] = size;
-		} else {
-			hdr = skb_put(nskb, 3);
-			hdr[0] = 0x80
-				| ((scb->id << 2) & 0x3c)
-				| ((skb->len == size) ? 0x00 : 0x01);
-			hdr[1] = size & 0xff;
-			hdr[2] = size >> 8;
-		}
-
-		skb_copy_from_linear_data(skb, skb_put(nskb, size), size);
-		skb_pull(skb, size);
-
-		if (skb->len > 0) {
-			skb_queue_head(&session->transmit, skb);
-		} else {
-			cmtp_free_block_id(session, scb->id);
-			if (scb->data) {
-				cmtp_send_frame(session, nskb->data, nskb->len);
-				skb_trim(nskb, 0);
-			}
-			kfree_skb(skb);
-		}
-	}
-
-	cmtp_send_frame(session, nskb->data, nskb->len);
-
-	kfree_skb(nskb);
-}
-
-static int cmtp_session(void *arg)
-{
-	struct cmtp_session *session = arg;
-	struct sock *sk = session->sock->sk;
-	struct sk_buff *skb;
-	DEFINE_WAIT_FUNC(wait, woken_wake_function);
-
-	BT_DBG("session %p", session);
-
-	set_user_nice(current, -15);
-
-	add_wait_queue(sk_sleep(sk), &wait);
-	while (1) {
-		if (atomic_read(&session->terminate))
-			break;
-		if (sk->sk_state != BT_CONNECTED)
-			break;
-
-		while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
-			skb_orphan(skb);
-			if (!skb_linearize(skb))
-				cmtp_recv_frame(session, skb);
-			else
-				kfree_skb(skb);
-		}
-
-		cmtp_process_transmit(session);
-
-		/*
-		 * wait_woken() performs the necessary memory barriers
-		 * for us; see the header comment for this primitive.
-		 */
-		wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
-	}
-	remove_wait_queue(sk_sleep(sk), &wait);
-
-	down_write(&cmtp_session_sem);
-
-	if (!(session->flags & BIT(CMTP_LOOPBACK)))
-		cmtp_detach_device(session);
-
-	fput(session->sock->file);
-
-	__cmtp_unlink_session(session);
-
-	up_write(&cmtp_session_sem);
-
-	kfree(session);
-	module_put_and_kthread_exit(0);
-	return 0;
-}
-
-int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
-{
-	u32 valid_flags = BIT(CMTP_LOOPBACK);
-	struct cmtp_session *session, *s;
-	int i, err;
-
-	BT_DBG("");
-
-	if (!l2cap_is_socket(sock))
-		return -EBADFD;
-
-	if (req->flags & ~valid_flags)
-		return -EINVAL;
-
-	session = kzalloc_obj(struct cmtp_session);
-	if (!session)
-		return -ENOMEM;
-
-	down_write(&cmtp_session_sem);
-
-	s = __cmtp_get_session(&l2cap_pi(sock->sk)->chan->dst);
-	if (s && s->state == BT_CONNECTED) {
-		err = -EEXIST;
-		goto failed;
-	}
-
-	bacpy(&session->bdaddr, &l2cap_pi(sock->sk)->chan->dst);
-
-	session->mtu = min_t(uint, l2cap_pi(sock->sk)->chan->omtu,
-					l2cap_pi(sock->sk)->chan->imtu);
-
-	BT_DBG("mtu %d", session->mtu);
-
-	sprintf(session->name, "%pMR", &session->bdaddr);
-
-	session->sock  = sock;
-	session->state = BT_CONFIG;
-
-	init_waitqueue_head(&session->wait);
-
-	session->msgnum = CMTP_INITIAL_MSGNUM;
-
-	INIT_LIST_HEAD(&session->applications);
-
-	skb_queue_head_init(&session->transmit);
-
-	for (i = 0; i < 16; i++)
-		session->reassembly[i] = NULL;
-
-	session->flags = req->flags;
-
-	__cmtp_link_session(session);
-
-	__module_get(THIS_MODULE);
-	session->task = kthread_run(cmtp_session, session, "kcmtpd_ctr_%d",
-								session->num);
-	if (IS_ERR(session->task)) {
-		module_put(THIS_MODULE);
-		err = PTR_ERR(session->task);
-		goto unlink;
-	}
-
-	if (!(session->flags & BIT(CMTP_LOOPBACK))) {
-		err = cmtp_attach_device(session);
-		if (err < 0) {
-			/* Caller will call fput in case of failure, and so
-			 * will cmtp_session kthread.
-			 */
-			get_file(session->sock->file);
-
-			atomic_inc(&session->terminate);
-			wake_up_interruptible(sk_sleep(session->sock->sk));
-			up_write(&cmtp_session_sem);
-			return err;
-		}
-	}
-
-	up_write(&cmtp_session_sem);
-	return 0;
-
-unlink:
-	__cmtp_unlink_session(session);
-
-failed:
-	up_write(&cmtp_session_sem);
-	kfree(session);
-	return err;
-}
-
-int cmtp_del_connection(struct cmtp_conndel_req *req)
-{
-	u32 valid_flags = 0;
-	struct cmtp_session *session;
-	int err = 0;
-
-	BT_DBG("");
-
-	if (req->flags & ~valid_flags)
-		return -EINVAL;
-
-	down_read(&cmtp_session_sem);
-
-	session = __cmtp_get_session(&req->bdaddr);
-	if (session) {
-		/* Flush the transmit queue */
-		skb_queue_purge(&session->transmit);
-
-		/* Stop session thread */
-		atomic_inc(&session->terminate);
-
-		/*
-		 * See the comment preceding the call to wait_woken()
-		 * in cmtp_session().
-		 */
-		wake_up_interruptible(sk_sleep(session->sock->sk));
-	} else
-		err = -ENOENT;
-
-	up_read(&cmtp_session_sem);
-	return err;
-}
-
-int cmtp_get_connlist(struct cmtp_connlist_req *req)
-{
-	struct cmtp_session *session;
-	int err = 0, n = 0;
-
-	BT_DBG("");
-
-	down_read(&cmtp_session_sem);
-
-	list_for_each_entry(session, &cmtp_session_list, list) {
-		struct cmtp_conninfo ci;
-
-		__cmtp_copy_session(session, &ci);
-
-		if (copy_to_user(req->ci, &ci, sizeof(ci))) {
-			err = -EFAULT;
-			break;
-		}
-
-		if (++n >= req->cnum)
-			break;
-
-		req->ci++;
-	}
-	req->cnum = n;
-
-	up_read(&cmtp_session_sem);
-	return err;
-}
-
-int cmtp_get_conninfo(struct cmtp_conninfo *ci)
-{
-	struct cmtp_session *session;
-	int err = 0;
-
-	down_read(&cmtp_session_sem);
-
-	session = __cmtp_get_session(&ci->bdaddr);
-	if (session)
-		__cmtp_copy_session(session, ci);
-	else
-		err = -ENOENT;
-
-	up_read(&cmtp_session_sem);
-	return err;
-}
-
-
-static int __init cmtp_init(void)
-{
-	BT_INFO("CMTP (CAPI Emulation) ver %s", VERSION);
-
-	return cmtp_init_sockets();
-}
-
-static void __exit cmtp_exit(void)
-{
-	cmtp_cleanup_sockets();
-}
-
-module_init(cmtp_init);
-module_exit(cmtp_exit);
-
-MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-MODULE_DESCRIPTION("Bluetooth CMTP ver " VERSION);
-MODULE_VERSION(VERSION);
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("bt-proto-5");
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
deleted file mode 100644
index 96d49d9fae96..000000000000
--- a/net/bluetooth/cmtp/sock.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
-   CMTP implementation for Linux Bluetooth stack (BlueZ).
-   Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-   SOFTWARE IS DISCLAIMED.
-*/
-
-#include <linux/export.h>
-
-#include <linux/types.h>
-#include <linux/capability.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/poll.h>
-#include <linux/fcntl.h>
-#include <linux/skbuff.h>
-#include <linux/socket.h>
-#include <linux/ioctl.h>
-#include <linux/file.h>
-#include <linux/compat.h>
-#include <linux/gfp.h>
-#include <linux/uaccess.h>
-#include <net/sock.h>
-
-#include <linux/isdn/capilli.h>
-
-
-#include "cmtp.h"
-
-static struct bt_sock_list cmtp_sk_list = {
-	.lock = __RW_LOCK_UNLOCKED(cmtp_sk_list.lock)
-};
-
-static int cmtp_sock_release(struct socket *sock)
-{
-	struct sock *sk = sock->sk;
-
-	BT_DBG("sock %p sk %p", sock, sk);
-
-	if (!sk)
-		return 0;
-
-	bt_sock_unlink(&cmtp_sk_list, sk);
-
-	sock_orphan(sk);
-	sock_put(sk);
-
-	return 0;
-}
-
-static int do_cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, void __user *argp)
-{
-	struct cmtp_connadd_req ca;
-	struct cmtp_conndel_req cd;
-	struct cmtp_connlist_req cl;
-	struct cmtp_conninfo ci;
-	struct socket *nsock;
-	int err;
-
-	BT_DBG("cmd %x arg %p", cmd, argp);
-
-	switch (cmd) {
-	case CMTPCONNADD:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-
-		if (copy_from_user(&ca, argp, sizeof(ca)))
-			return -EFAULT;
-
-		nsock = sockfd_lookup(ca.sock, &err);
-		if (!nsock)
-			return err;
-
-		if (nsock->sk->sk_state != BT_CONNECTED) {
-			sockfd_put(nsock);
-			return -EBADFD;
-		}
-
-		err = cmtp_add_connection(&ca, nsock);
-		if (!err) {
-			if (copy_to_user(argp, &ca, sizeof(ca)))
-				err = -EFAULT;
-		} else
-			sockfd_put(nsock);
-
-		return err;
-
-	case CMTPCONNDEL:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-
-		if (copy_from_user(&cd, argp, sizeof(cd)))
-			return -EFAULT;
-
-		return cmtp_del_connection(&cd);
-
-	case CMTPGETCONNLIST:
-		if (copy_from_user(&cl, argp, sizeof(cl)))
-			return -EFAULT;
-
-		if (cl.cnum <= 0)
-			return -EINVAL;
-
-		err = cmtp_get_connlist(&cl);
-		if (!err && copy_to_user(argp, &cl, sizeof(cl)))
-			return -EFAULT;
-
-		return err;
-
-	case CMTPGETCONNINFO:
-		if (copy_from_user(&ci, argp, sizeof(ci)))
-			return -EFAULT;
-
-		err = cmtp_get_conninfo(&ci);
-		if (!err && copy_to_user(argp, &ci, sizeof(ci)))
-			return -EFAULT;
-
-		return err;
-	}
-
-	return -EINVAL;
-}
-
-static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
-	return do_cmtp_sock_ioctl(sock, cmd, (void __user *)arg);
-}
-
-#ifdef CONFIG_COMPAT
-static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
-	void __user *argp = compat_ptr(arg);
-	if (cmd == CMTPGETCONNLIST) {
-		struct cmtp_connlist_req cl;
-		u32 __user *p = argp;
-		u32 uci;
-		int err;
-
-		if (get_user(cl.cnum, p) || get_user(uci, p + 1))
-			return -EFAULT;
-
-		cl.ci = compat_ptr(uci);
-
-		if (cl.cnum <= 0)
-			return -EINVAL;
-
-		err = cmtp_get_connlist(&cl);
-
-		if (!err && put_user(cl.cnum, p))
-			err = -EFAULT;
-
-		return err;
-	}
-
-	return do_cmtp_sock_ioctl(sock, cmd, argp);
-}
-#endif
-
-static const struct proto_ops cmtp_sock_ops = {
-	.family		= PF_BLUETOOTH,
-	.owner		= THIS_MODULE,
-	.release	= cmtp_sock_release,
-	.ioctl		= cmtp_sock_ioctl,
-#ifdef CONFIG_COMPAT
-	.compat_ioctl	= cmtp_sock_compat_ioctl,
-#endif
-	.bind		= sock_no_bind,
-	.getname	= sock_no_getname,
-	.sendmsg	= sock_no_sendmsg,
-	.recvmsg	= sock_no_recvmsg,
-	.listen		= sock_no_listen,
-	.shutdown	= sock_no_shutdown,
-	.connect	= sock_no_connect,
-	.socketpair	= sock_no_socketpair,
-	.accept		= sock_no_accept,
-	.mmap		= sock_no_mmap
-};
-
-static struct proto cmtp_proto = {
-	.name		= "CMTP",
-	.owner		= THIS_MODULE,
-	.obj_size	= sizeof(struct bt_sock)
-};
-
-static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol,
-			    int kern)
-{
-	struct sock *sk;
-
-	BT_DBG("sock %p", sock);
-
-	if (sock->type != SOCK_RAW)
-		return -ESOCKTNOSUPPORT;
-
-	sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, kern);
-	if (!sk)
-		return -ENOMEM;
-
-	sock_init_data(sock, sk);
-
-	sock->ops = &cmtp_sock_ops;
-
-	sock->state = SS_UNCONNECTED;
-
-	sock_reset_flag(sk, SOCK_ZAPPED);
-
-	sk->sk_protocol = protocol;
-	sk->sk_state    = BT_OPEN;
-
-	bt_sock_link(&cmtp_sk_list, sk);
-
-	return 0;
-}
-
-static const struct net_proto_family cmtp_sock_family_ops = {
-	.family	= PF_BLUETOOTH,
-	.owner	= THIS_MODULE,
-	.create	= cmtp_sock_create
-};
-
-int cmtp_init_sockets(void)
-{
-	int err;
-
-	err = proto_register(&cmtp_proto, 0);
-	if (err < 0)
-		return err;
-
-	err = bt_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops);
-	if (err < 0) {
-		BT_ERR("Can't register CMTP socket");
-		goto error;
-	}
-
-	err = bt_procfs_init(&init_net, "cmtp", &cmtp_sk_list, NULL);
-	if (err < 0) {
-		BT_ERR("Failed to create CMTP proc file");
-		bt_sock_unregister(BTPROTO_HIDP);
-		goto error;
-	}
-
-	BT_INFO("CMTP socket layer initialized");
-
-	return 0;
-
-error:
-	proto_unregister(&cmtp_proto);
-	return err;
-}
-
-void cmtp_cleanup_sockets(void)
-{
-	bt_procfs_cleanup(&init_net, "cmtp");
-	bt_sock_unregister(BTPROTO_CMTP);
-	proto_unregister(&cmtp_proto);
-}
diff --git a/CREDITS b/CREDITS
index a03b00452a1e..eeeece8ed868 100644
--- a/CREDITS
+++ b/CREDITS
@@ -3649,6 +3649,11 @@ S: Dag Hammerskjolds v. 3E
 S: S-226 64 LUND
 S: Sweden
 
+N: Tilman Schmidt
+E: tilman@imap.cc
+D: Siemens Gigaset ISDN driver author and maintainer
+D: ISDN CAPI subsystem contributions
+
 N: Henning P. Schmiedehausen
 E: hps@tanstaafl.de
 D: added PCI support to the serial driver
-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH] net: rose: use pskb_may_pull() in CLEAR_REQUEST length check
From: Ashutosh Desai @ 2026-04-21  2:27 UTC (permalink / raw)
  To: andrew
  Cc: netdev, linux-hams, davem, edumazet, kuba, pabeni, horms,
	linux-kernel, Ashutosh Desai
In-Reply-To: <48f45bdb-6edf-4676-a96e-4530634cd7c0@lunn.ch>

On Mon, Apr 20, 2026 at 15:04:30 +0200, Andrew Lunn wrote:
> Did you review all the other comparisons on skb->len in rose?
> Do these need the same fix? Are there other places non linear buffers
> should be considered?

Reviewed all rose files. Thanks for pointing those out - yes, the two
spots in rose_route.c and rose_loopback.c have the same issue and need
the same fix.

While reviewing I also noticed rose_link.c: rose_link_rx_restart()
accesses skb->data[3] in the ROSE_RESTART_REQUEST case and
skb->data[3]/skb->data+4 in the ROSE_DIAGNOSTIC case, with only a
ROSE_MIN_LEN (3 bytes) guard upstream in the caller. Same linearity
concern.

Is it recommended to send a v2 covering all three files?

^ permalink raw reply

* Re: [PATCH] net: rose: use pskb_may_pull() in CLEAR_REQUEST length check
From: Andrew Lunn @ 2026-04-21  2:50 UTC (permalink / raw)
  To: Ashutosh Desai
  Cc: netdev, linux-hams, davem, edumazet, kuba, pabeni, horms,
	linux-kernel
In-Reply-To: <20260421022712.690822-1-ashutoshdesai993@gmail.com>

On Tue, Apr 21, 2026 at 02:27:12AM +0000, Ashutosh Desai wrote:
> On Mon, Apr 20, 2026 at 15:04:30 +0200, Andrew Lunn wrote:
> > Did you review all the other comparisons on skb->len in rose?
> > Do these need the same fix? Are there other places non linear buffers
> > should be considered?
> 
> Reviewed all rose files. Thanks for pointing those out - yes, the two
> spots in rose_route.c and rose_loopback.c have the same issue and need
> the same fix.
> 
> While reviewing I also noticed rose_link.c: rose_link_rx_restart()
> accesses skb->data[3] in the ROSE_RESTART_REQUEST case and
> skb->data[3]/skb->data+4 in the ROSE_DIAGNOSTIC case, with only a
> ROSE_MIN_LEN (3 bytes) guard upstream in the caller. Same linearity
> concern.
> 
> Is it recommended to send a v2 covering all three files?

Too late, Jakub just posted patches deleted it all. See the netdev
mailing list.

    Andrew

^ permalink raw reply

* [PATCH v2 0/2] Bluetooth: ISO: Fix KCSAN data-races on iso_pi(sk)
From: SeungJu Cheon @ 2026-04-21  2:51 UTC (permalink / raw)
  To: luiz.dentz, marcel
  Cc: linux-bluetooth, netdev, linux-kernel, me, skhan,
	linux-kernel-mentees, SeungJu Cheon

Found while auditing iso_pi(sk) field accesses after a KCSAN report.
Patch 1/2 is the reported race on iso_pi(sk)->dst in iso_sock_connect();
patch 2/2 covers related races on other iso_pi(sk) fields accessed in
iso_connect_{bis,cis}() and iso_connect_ind() that were found by
inspection during the same audit.

Changes in v2:
 - Patch 1/2: Use sa->iso_bdaddr directly instead of caching the
   bacmp() result in a local variable, as suggested by Luiz [1].
   This avoids reading from iso_pi(sk) entirely for the broadcast
   check.

 - Patch 2/2: No changes.

v1: https://lore.kernel.org/linux-bluetooth/20260418053239.128190-1-suunj1331@gmail.com/

[1] https://lore.kernel.org/linux-bluetooth/CABBYNZLBoU3byfK_G+=sTkBx3wNwEh2X6_7dG4+4LFtrc3Skpw@mail.gmail.com/

SeungJu Cheon (2):
  Bluetooth: ISO: Fix data-race on dst in iso_sock_connect()
  Bluetooth: ISO: Fix data-race on iso_pi(sk) in socket and HCI event
    paths

 net/bluetooth/iso.c | 56 +++++++++++++++++++++++++--------------------
 1 file changed, 31 insertions(+), 25 deletions(-)

-- 
2.52.0


^ permalink raw reply

* [PATCH v2 1/2] Bluetooth: ISO: Fix data-race on dst in iso_sock_connect()
From: SeungJu Cheon @ 2026-04-21  2:51 UTC (permalink / raw)
  To: luiz.dentz, marcel
  Cc: linux-bluetooth, netdev, linux-kernel, me, skhan,
	linux-kernel-mentees, SeungJu Cheon
In-Reply-To: <20260421025122.55781-1-suunj1331@gmail.com>

iso_sock_connect() copies the destination address into
iso_pi(sk)->dst under lock_sock, then releases the lock and reads
it back with bacmp() to decide between the CIS and BIS connect
paths:

    lock_sock(sk);
    bacpy(&iso_pi(sk)->dst, &sa->iso_bdaddr);
    iso_pi(sk)->dst_type = sa->iso_bdaddr_type;
    release_sock(sk);

    if (bacmp(&iso_pi(sk)->dst, BDADDR_ANY))  // <- no lock held

This read after release_sock() races with any concurrent write to
iso_pi(sk)->dst on the same socket.

Fix by reading the destination address directly from the local
sockaddr argument (sa->iso_bdaddr) instead of iso_pi(sk)->dst.
Since sa is a function-local argument, reading it requires no
locking and avoids the race.

This patch addresses only the bacmp() race in iso_sock_connect();
other unprotected iso_pi(sk) accesses are fixed separately in the
next patch.

KCSAN report:

BUG: KCSAN: data-race in memcmp+0x39/0xb0

race at unknown origin, with read to 0xffff8f96ea66dde3 of 1 bytes by task 549 on cpu 1:
 memcmp+0x39/0xb0
 iso_sock_connect+0x275/0xb40
 __sys_connect_file+0xbd/0xe0
 __sys_connect+0xe0/0x110
 __x64_sys_connect+0x40/0x50
 x64_sys_call+0xcad/0x1c60
 do_syscall_64+0x133/0x590
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

value changed: 0x00 -> 0xee

Reported by Kernel Concurrency Sanitizer on:
CPU: 1 UID: 0 PID: 549 Comm: iso_race_combin Not tainted 7.0.0-08391-g1d51b370a0f8 #40 PREEMPT(lazy)

Fixes: ccf74f2390d6 ("Bluetooth: Add BTPROTO_ISO socket type")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
---
 net/bluetooth/iso.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index be145e2736b7..290a1b9a9daa 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -1193,7 +1193,7 @@ static int iso_sock_connect(struct socket *sock, struct sockaddr_unsized *addr,
 
 	release_sock(sk);
 
-	if (bacmp(&iso_pi(sk)->dst, BDADDR_ANY))
+	if (bacmp(&sa->iso_bdaddr, BDADDR_ANY))
 		err = iso_connect_cis(sk);
 	else
 		err = iso_connect_bis(sk);
-- 
2.52.0


^ permalink raw reply related

* [PATCH v2 2/2] Bluetooth: ISO: Fix data-race on iso_pi(sk) in socket and HCI event paths
From: SeungJu Cheon @ 2026-04-21  2:51 UTC (permalink / raw)
  To: luiz.dentz, marcel
  Cc: linux-bluetooth, netdev, linux-kernel, me, skhan,
	linux-kernel-mentees, SeungJu Cheon
In-Reply-To: <20260421025122.55781-1-suunj1331@gmail.com>

Several iso_pi(sk) fields (qos, qos_user_set, bc_sid, base, base_len,
sync_handle, bc_num_bis) are written under lock_sock in
iso_sock_setsockopt() and iso_sock_bind(), but read and written under
hci_dev_lock only in two other paths:

  - iso_connect_bis() / iso_connect_cis(), invoked from connect(2),
    read qos/base/bc_sid and reset qos to default_qos on the
    qos_user_set validation failure -- all without lock_sock.

  - iso_connect_ind(), invoked from hci_rx_work, writes sync_handle,
    bc_sid, qos.bcast.encryption, bc_num_bis, base and base_len on
    PA_SYNC_ESTABLISHED / PAST_RECEIVED / BIG_INFO_ADV_REPORT /
    PER_ADV_REPORT events. The BIG_INFO handler additionally passes
    &iso_pi(sk)->qos together with sync_handle / bc_num_bis / bc_bis
    to hci_conn_big_create_sync() while setsockopt may be mutating
    them.

Acquire lock_sock around the affected accesses in both paths.

The locking order hci_dev_lock -> lock_sock matches the existing
iso_conn_big_sync() precedent, whose comment documents the same
requirement for hci_conn_big_create_sync(). The HCI connect/bind
helpers do not wait for command completion -- they enqueue work via
hci_cmd_sync_queue{,_once}() / hci_le_create_cis_pending() and
return -- so the added hold time is comparable to iso_conn_big_sync().

KCSAN report:

BUG: KCSAN: data-race in iso_connect_cis / iso_sock_setsockopt

read to 0xffffa3ae8ce3cdc8 of 1 bytes by task 335 on cpu 0:
 iso_connect_cis+0x49f/0xa20
 iso_sock_connect+0x60e/0xb40
 __sys_connect_file+0xbd/0xe0
 __sys_connect+0xe0/0x110
 __x64_sys_connect+0x40/0x50
 x64_sys_call+0xcad/0x1c60
 do_syscall_64+0x133/0x590
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

write to 0xffffa3ae8ce3cdc8 of 60 bytes by task 334 on cpu 1:
 iso_sock_setsockopt+0x69a/0x930
 do_sock_setsockopt+0xc3/0x170
 __sys_setsockopt+0xd1/0x130
 __x64_sys_setsockopt+0x64/0x80
 x64_sys_call+0x1547/0x1c60
 do_syscall_64+0x133/0x590
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

Reported by Kernel Concurrency Sanitizer on:
CPU: 1 UID: 0 PID: 334 Comm: iso_setup_race Not tainted 7.0.0-10949-g8541d8f725c6 #44 PREEMPT(lazy)

The iso_connect_ind() races were found by inspection.

Fixes: ccf74f2390d6 ("Bluetooth: Add BTPROTO_ISO socket type")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
---
 net/bluetooth/iso.c | 54 +++++++++++++++++++++++++--------------------
 1 file changed, 30 insertions(+), 24 deletions(-)

diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index 290a1b9a9daa..7cb2864fe872 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -347,6 +347,7 @@ static int iso_connect_bis(struct sock *sk)
 		return -EHOSTUNREACH;
 
 	hci_dev_lock(hdev);
+	lock_sock(sk);
 
 	if (!bis_capable(hdev)) {
 		err = -EOPNOTSUPP;
@@ -399,13 +400,9 @@ static int iso_connect_bis(struct sock *sk)
 		goto unlock;
 	}
 
-	lock_sock(sk);
-
 	err = iso_chan_add(conn, sk, NULL);
-	if (err) {
-		release_sock(sk);
+	if (err)
 		goto unlock;
-	}
 
 	/* Update source addr of the socket */
 	bacpy(&iso_pi(sk)->src, &hcon->src);
@@ -421,9 +418,8 @@ static int iso_connect_bis(struct sock *sk)
 		iso_sock_set_timer(sk, READ_ONCE(sk->sk_sndtimeo));
 	}
 
-	release_sock(sk);
-
 unlock:
+	release_sock(sk);
 	hci_dev_unlock(hdev);
 	hci_dev_put(hdev);
 	return err;
@@ -444,6 +440,7 @@ static int iso_connect_cis(struct sock *sk)
 		return -EHOSTUNREACH;
 
 	hci_dev_lock(hdev);
+	lock_sock(sk);
 
 	if (!cis_central_capable(hdev)) {
 		err = -EOPNOTSUPP;
@@ -498,13 +495,9 @@ static int iso_connect_cis(struct sock *sk)
 		goto unlock;
 	}
 
-	lock_sock(sk);
-
 	err = iso_chan_add(conn, sk, NULL);
-	if (err) {
-		release_sock(sk);
+	if (err)
 		goto unlock;
-	}
 
 	/* Update source addr of the socket */
 	bacpy(&iso_pi(sk)->src, &hcon->src);
@@ -520,9 +513,8 @@ static int iso_connect_cis(struct sock *sk)
 		iso_sock_set_timer(sk, READ_ONCE(sk->sk_sndtimeo));
 	}
 
-	release_sock(sk);
-
 unlock:
+	release_sock(sk);
 	hci_dev_unlock(hdev);
 	hci_dev_put(hdev);
 	return err;
@@ -2256,8 +2248,10 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
 		sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr, BT_LISTEN,
 				  iso_match_sid, ev1);
 		if (sk && !ev1->status) {
+			lock_sock(sk);
 			iso_pi(sk)->sync_handle = le16_to_cpu(ev1->handle);
 			iso_pi(sk)->bc_sid = ev1->sid;
+			release_sock(sk);
 		}
 
 		goto done;
@@ -2268,8 +2262,10 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
 		sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr, BT_LISTEN,
 				  iso_match_sid_past, ev1a);
 		if (sk && !ev1a->status) {
+			lock_sock(sk);
 			iso_pi(sk)->sync_handle = le16_to_cpu(ev1a->sync_handle);
 			iso_pi(sk)->bc_sid = ev1a->sid;
+			release_sock(sk);
 		}
 
 		goto done;
@@ -2296,27 +2292,35 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
 					  ev2);
 
 		if (sk) {
-			int err;
-			struct hci_conn	*hcon = iso_pi(sk)->conn->hcon;
+			int err = 0;
+			bool big_sync;
+			struct hci_conn *hcon;
 
+			lock_sock(sk);
+
+			hcon = iso_pi(sk)->conn->hcon;
 			iso_pi(sk)->qos.bcast.encryption = ev2->encryption;
 
 			if (ev2->num_bis < iso_pi(sk)->bc_num_bis)
 				iso_pi(sk)->bc_num_bis = ev2->num_bis;
 
-			if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags) &&
-			    !test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
+			big_sync = !test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags) &&
+				   !test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags);
+
+			if (big_sync)
 				err = hci_conn_big_create_sync(hdev, hcon,
 							       &iso_pi(sk)->qos,
 							       iso_pi(sk)->sync_handle,
 							       iso_pi(sk)->bc_num_bis,
 							       iso_pi(sk)->bc_bis);
-				if (err) {
-					bt_dev_err(hdev, "hci_le_big_create_sync: %d",
-						   err);
-					sock_put(sk);
-					sk = NULL;
-				}
+
+			release_sock(sk);
+
+			if (big_sync && err) {
+				bt_dev_err(hdev, "hci_le_big_create_sync: %d",
+					   err);
+				sock_put(sk);
+				sk = NULL;
 			}
 		}
 
@@ -2370,8 +2374,10 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
 			if (!base || base_len > BASE_MAX_LENGTH)
 				goto done;
 
+			lock_sock(sk);
 			memcpy(iso_pi(sk)->base, base, base_len);
 			iso_pi(sk)->base_len = base_len;
+			release_sock(sk);
 		} else {
 			/* This is a PA data fragment. Keep pa_data_len set to 0
 			 * until all data has been reassembled.
-- 
2.52.0


^ permalink raw reply related

* [PATCH net v3] hv_sock: Report EOF instead of -EIO for FIN
From: Dexuan Cui @ 2026-04-21  2:59 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, longli, sgarzare, davem, edumazet,
	kuba, pabeni, horms, niuxuewei.nxw, linux-hyperv, virtualization,
	netdev, linux-kernel
  Cc: stable, Ben Hillis, Mitchell Levy

Commit f0c5827d07cb unluckily causes a regression for the FIN packet,
and the final read syscall gets an error rather than 0.

Ideally, we would want to fix hvs_channel_readable_payload() so that it
could return 0 in the FIN scenario, but it's not good for the hv_sock
driver to use the VMBus ringbuffer's cached priv_read_index, which is
internal data in the VMBus driver.

Fix the regression in hv_sock by returning 0 rather than -EIO.

In case we see a malformed/short packet, we still return -EIO.

Fixes: f0c5827d07cb ("hv_sock: Return the readable bytes in hvs_stream_has_data()")
Cc: stable@vger.kernel.org
Reported-by: Ben Hillis <Ben.Hillis@microsoft.com>
Reported-by: Mitchell Levy <levymitchell0@gmail.com>
Signed-off-by: Dexuan Cui <decui@microsoft.com>

---

Changes since v1:
    Removed the local variable 'need_refill' to make the code more 
    readable. Stefano, thanks!

    No other change.


Changes since v2:
    Added code to test the flag SEND_SHUTDOWN. Copilot, thanks!
    Updated the comment and the commit messages accordingly.

 net/vmw_vsock/hyperv_transport.c | 29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
index 069386a74557..da150de10f0d 100644
--- a/net/vmw_vsock/hyperv_transport.c
+++ b/net/vmw_vsock/hyperv_transport.c
@@ -694,7 +694,6 @@ static ssize_t hvs_stream_enqueue(struct vsock_sock *vsk, struct msghdr *msg,
 static s64 hvs_stream_has_data(struct vsock_sock *vsk)
 {
 	struct hvsock *hvs = vsk->trans;
-	bool need_refill;
 	s64 ret;
 
 	if (hvs->recv_data_len > 0)
@@ -702,9 +701,31 @@ static s64 hvs_stream_has_data(struct vsock_sock *vsk)
 
 	switch (hvs_channel_readable_payload(hvs->chan)) {
 	case 1:
-		need_refill = !hvs->recv_desc;
-		if (!need_refill)
-			return -EIO;
+		if (hvs->recv_desc) {
+			/* Here hvs->recv_data_len is 0, so hvs->recv_desc must
+			 * be NULL unless it points to the 0-byte-payload FIN
+			 * packet or a malformed/short packet: see
+			 * hvs_update_recv_data().
+			 *
+			 * If hvs->recv_desc points to the FIN packet, here all
+			 * the payload has been dequeued and the peer_shutdown
+			 * flag is set, but hvs_channel_readable_payload() still
+			 * returns 1, because the VMBus ringbuffer's read_index
+			 * is not updated for the FIN packet:
+			 * hvs_stream_dequeue() -> hv_pkt_iter_next() updates
+			 * the cached priv_read_index but has no opportunity to
+			 * update the read_index in hv_pkt_iter_close() as
+			 * hvs_stream_has_data() returns 0 for the FIN packet,
+			 * so it won't get dequeued.
+			 *
+			 * In case hvs->recv_desc points to a malformed/short
+			 * packet, return -EIO.
+			 */
+			if (hvs->vsk->peer_shutdown & SEND_SHUTDOWN)
+				return 0;
+			else
+				return -EIO;
+		}
 
 		hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
 		if (!hvs->recv_desc)
-- 
2.49.0


^ permalink raw reply related

* [PATCH-next 00/23] cgroup/cpuset: Enable runtime update of nohz_full and managed_irq CPUs
From: Waiman Long @ 2026-04-21  3:03 UTC (permalink / raw)
  To: Tejun Heo, Johannes Weiner, Michal Koutný, Jonathan Corbet,
	Shuah Khan, Catalin Marinas, Will Deacon, K. Y. Srinivasan,
	Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Guenter Roeck,
	Frederic Weisbecker, Paul E. McKenney, Neeraj Upadhyay,
	Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
	Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
	Anna-Maria Behnsen, Ingo Molnar, Thomas Gleixner, Chen Ridong,
	Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Ben Segall, Mel Gorman, Valentin Schneider, K Prateek Nayak,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
	linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
	Qiliang Yuan, Waiman Long

The "isolcpus=domain" CPU list implied by the HK_TYPE_DOMAIN housekeeping
cpumask is being dynamically updated whenever the set of cpuset isolated
partitions change. This patch series extends the isolated partition code
to make dynamic changes to the "nohz_full" and "isolcpus=managed_irq"
CPU lists. These CPU lists correspoond to equivalent changes in the
HK_TYPE_KERNEL_NOISE and HK_TYPE_MANAGED_IRQ housekeeping cpumasks.

To facilitate the changing of these CPU lists, the CPU hotplug code
which is doing a lot of heavy lifting is now being used. For changing
the "nohz_full" and HK_TYPE_KERNEL_NOISE cpumasks, the affected CPUs
are torn down into offline mode first. Then the housekeeping cpumask
and the corresponding cpumasks in the RCU, tick and watchdog subsystems
are modified. After that, the affected CPUs are brought online again.

It is slightly different with the "managed_irq" HK_TYPE_MANAGED_IRQ
cpumask, the cpumask is updated first and the affected CPUs are torn
down and brought up to move the managed interrupts away from the newly
isolated CPUs.

Using CPU hotplug does have its drawback when multiple isolated
partitions are being managed in a system. The CPU offline process uses
the stop_machine mechanism to stop all the CPUs except the one being torn
down. This will cause latency spike for isolated CPUs in other isolated
partitions. It is not a problem if only one isolated partition is
needed. This is an issue we need to address in the near future.

Patches 1-7 enables runtime updates to the nohz_full/managed_irq
cpumasks in sched/isolation, tick, RCU and watchdog subsystems.

Patches 8-17 modifies various subsystems that need access to the
HK_TYPE_MANAGED_IRQ cpumask and HK_TYPE_KERNEL_NOISE cpumask and its
aliases. Like the runtime modifiable HK_TYPE_DOMAIN cpumask, RCU is used
to protect access to cpumasks to avoid potential UAF problem. Patch 17
updates the housekeeping_dereference_check() to print a WARNING when
lockdep is enabled if those housekeeping cpumasks are used without the
proper lock protection.

Patch 18 introduces a new cpuhp_offline_cb() API that enables the
shutting down of a given list of CPUs, run a callback function and then
brought those CPUs up again while disallowing any concurrent CPU hotplug
activity.

Patches 19-23 updates the cpuset code, selftest and documentation to
allow change in isolated partition configuration to be reflected in
the housekeeping and other cpumasks dynamically.

As there is a slight overhead in enabling dynamic update to the nohz_full
cpumask, this new nohz_full and managed_irq runtime update feature
has to be explicitly opted in by adding a nohz_full kernel command
line parameter with or without a CPU list to indicate a desire to use
this feature. It is also because a number of subsystems have explicit
check of nohz_full at boot time to adjust their behavior which may not
be easy to modify after boot.

Waiman Long (23):
  sched/isolation: Add HK_TYPE_KERNEL_NOISE_BOOT &
    HK_TYPE_MANAGED_IRQ_BOOT
  sched/isolation: Enhance housekeeping_update() to support updating
    more than one HK cpumask
  tick/nohz: Make nohz_full parameter optional
  tick/nohz: Allow runtime changes in full dynticks CPUs
  tick: Pass timer tick job to an online HK CPU in tick_cpu_dying()
  rcu/nocbs: Allow runtime changes in RCU NOCBS cpumask
  watchdog: Sync up with runtime change of isolated CPUs
  arm64: topology: Use RCU to protect access to HK_TYPE_TICK cpumask
  workqueue: Use RCU to protect access of HK_TYPE_TIMER cpumask
  cpu: Use RCU to protect access of HK_TYPE_TIMER cpumask
  hrtimer: Use RCU to protect access of HK_TYPE_TIMER cpumask
  net: Use boot time housekeeping cpumask settings for now
  sched/core: Use RCU to protect access of HK_TYPE_KERNEL_NOISE cpumask
  hwmon/coretemp: Use RCU to protect access of HK_TYPE_MISC cpumask
  Drivers: hv: Use RCU to protect access of HK_TYPE_MANAGED_IRQ cpumask
  genirq/cpuhotplug: Use RCU to protect access of HK_TYPE_MANAGED_IRQ
    cpumask
  sched/isolation: Extend housekeeping_dereference_check() to cover
    changes in nohz_full or manged_irqs           cpumasks
  cpu/hotplug: Add a new cpuhp_offline_cb() API
  cgroup/cpuset: Improve check for calling housekeeping_update()
  cgroup/cpuset: Enable runtime update of
    HK_TYPE_{KERNEL_NOISE,MANAGED_IRQ} cpumasks
  cgroup/cpuset: Limit the side effect of using CPU hotplug on isolated
    partition
  cgroup/cpuset: Prevent offline_disabled CPUs from being used in
    isolated partition
  cgroup/cpuset: Documentation and kselftest updates

 Documentation/admin-guide/cgroup-v2.rst       |  35 ++-
 .../admin-guide/kernel-parameters.txt         |  15 +-
 arch/arm64/kernel/topology.c                  |  17 +-
 drivers/hv/channel_mgmt.c                     |  15 +-
 drivers/hv/vmbus_drv.c                        |   7 +-
 drivers/hwmon/coretemp.c                      |   6 +-
 include/linux/context_tracking.h              |   8 +-
 include/linux/cpuhplock.h                     |   9 +
 include/linux/nmi.h                           |   2 +
 include/linux/rcupdate.h                      |   2 +
 include/linux/sched/isolation.h               |  18 +-
 include/linux/tick.h                          |   2 +
 kernel/cgroup/cpuset-internal.h               |   1 +
 kernel/cgroup/cpuset.c                        | 292 +++++++++++++++++-
 kernel/context_tracking.c                     |  19 +-
 kernel/cpu.c                                  |  72 +++++
 kernel/irq/cpuhotplug.c                       |   1 +
 kernel/irq/manage.c                           |   1 +
 kernel/rcu/tree_nocb.h                        |  24 +-
 kernel/sched/core.c                           |   4 +-
 kernel/sched/isolation.c                      | 135 +++++---
 kernel/time/hrtimer.c                         |   4 +-
 kernel/time/tick-common.c                     |  16 +-
 kernel/time/tick-sched.c                      |  48 ++-
 kernel/watchdog.c                             |  24 ++
 kernel/workqueue.c                            |   6 +-
 net/core/net-sysfs.c                          |   2 +-
 .../selftests/cgroup/test_cpuset_prs.sh       |  70 ++++-
 28 files changed, 747 insertions(+), 108 deletions(-)

-- 
2.53.0


^ permalink raw reply

* [PATCH 01/23] sched/isolation: Add HK_TYPE_KERNEL_NOISE_BOOT & HK_TYPE_MANAGED_IRQ_BOOT
From: Waiman Long @ 2026-04-21  3:03 UTC (permalink / raw)
  To: Tejun Heo, Johannes Weiner, Michal Koutný, Jonathan Corbet,
	Shuah Khan, Catalin Marinas, Will Deacon, K. Y. Srinivasan,
	Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Guenter Roeck,
	Frederic Weisbecker, Paul E. McKenney, Neeraj Upadhyay,
	Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
	Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
	Anna-Maria Behnsen, Ingo Molnar, Thomas Gleixner, Chen Ridong,
	Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Ben Segall, Mel Gorman, Valentin Schneider, K Prateek Nayak,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
	linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
	Qiliang Yuan, Waiman Long
In-Reply-To: <20260421030351.281436-1-longman@redhat.com>

Since commit 4fca0e550d50 ("sched/isolation: Save boot defined
domain flags"), HK_TYPE_DOMAIN_BOOT was added to record the boot
time "isolcpus{=domain}" setting. As we are going to make the
HK_TYPE_MANAGED_IRQ and HK_TYPE_KERNEL_NOISE housekeeping cpumasks
runtime modifiable, we need some additional cpumasks to record the boot
time settings to make sure that those housekeeping cpumasks will always
be a subset of their boot time equivalents.

Introduce the new HK_TYPE_KERNEL_NOISE_BOOT and HK_TYPE_MANAGED_IRQ_BOOT
housekeeping types to do that.

Signed-off-by: Waiman Long <longman@redhat.com>
---
 include/linux/sched/isolation.h | 16 ++++++++++++++--
 kernel/sched/isolation.c        | 16 +++++++++-------
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/include/linux/sched/isolation.h b/include/linux/sched/isolation.h
index dc3975ff1b2e..d1707f121e20 100644
--- a/include/linux/sched/isolation.h
+++ b/include/linux/sched/isolation.h
@@ -14,10 +14,22 @@ enum hk_type {
 	 * is always a subset of HK_TYPE_DOMAIN_BOOT.
 	 */
 	HK_TYPE_DOMAIN,
-	/* Inverse of boot-time isolcpus=managed_irq argument */
-	HK_TYPE_MANAGED_IRQ,
+
 	/* Inverse of boot-time nohz_full= or isolcpus=nohz arguments */
+	HK_TYPE_KERNEL_NOISE_BOOT,
+	/*
+	 * A subset of HK_TYPE_KERNEL_NOISE_BOOT as it may excludes some
+	 * additional isolated CPUs at run time.
+	 */
 	HK_TYPE_KERNEL_NOISE,
+
+	/* Inverse of boot-time isolcpus=managed_irq argument */
+	HK_TYPE_MANAGED_IRQ_BOOT,
+	/*
+	 * A subset of HK_TYPE_MANAGED_IRQ_BOOT as it may excludes some
+	 * additional isolated CPUs at run time.
+	 */
+	HK_TYPE_MANAGED_IRQ,
 	HK_TYPE_MAX,
 
 	/*
diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c
index a947d75b43f1..9ec9ae510dc7 100644
--- a/kernel/sched/isolation.c
+++ b/kernel/sched/isolation.c
@@ -12,10 +12,12 @@
 #include "sched.h"
 
 enum hk_flags {
-	HK_FLAG_DOMAIN_BOOT	= BIT(HK_TYPE_DOMAIN_BOOT),
-	HK_FLAG_DOMAIN		= BIT(HK_TYPE_DOMAIN),
-	HK_FLAG_MANAGED_IRQ	= BIT(HK_TYPE_MANAGED_IRQ),
-	HK_FLAG_KERNEL_NOISE	= BIT(HK_TYPE_KERNEL_NOISE),
+	HK_FLAG_DOMAIN_BOOT	  = BIT(HK_TYPE_DOMAIN_BOOT),
+	HK_FLAG_DOMAIN		  = BIT(HK_TYPE_DOMAIN),
+	HK_FLAG_KERNEL_NOISE_BOOT = BIT(HK_TYPE_KERNEL_NOISE_BOOT),
+	HK_FLAG_KERNEL_NOISE	  = BIT(HK_TYPE_KERNEL_NOISE),
+	HK_FLAG_MANAGED_IRQ_BOOT  = BIT(HK_TYPE_MANAGED_IRQ_BOOT),
+	HK_FLAG_MANAGED_IRQ	  = BIT(HK_TYPE_MANAGED_IRQ),
 };
 
 DEFINE_STATIC_KEY_FALSE(housekeeping_overridden);
@@ -315,7 +317,7 @@ static int __init housekeeping_nohz_full_setup(char *str)
 {
 	unsigned long flags;
 
-	flags = HK_FLAG_KERNEL_NOISE;
+	flags = HK_FLAG_KERNEL_NOISE | HK_FLAG_KERNEL_NOISE_BOOT;
 
 	return housekeeping_setup(str, flags);
 }
@@ -334,7 +336,7 @@ static int __init housekeeping_isolcpus_setup(char *str)
 		 */
 		if (!strncmp(str, "nohz,", 5)) {
 			str += 5;
-			flags |= HK_FLAG_KERNEL_NOISE;
+			flags |= HK_FLAG_KERNEL_NOISE | HK_FLAG_KERNEL_NOISE_BOOT;
 			continue;
 		}
 
@@ -346,7 +348,7 @@ static int __init housekeeping_isolcpus_setup(char *str)
 
 		if (!strncmp(str, "managed_irq,", 12)) {
 			str += 12;
-			flags |= HK_FLAG_MANAGED_IRQ;
+			flags |= HK_FLAG_MANAGED_IRQ | HK_FLAG_MANAGED_IRQ_BOOT;
 			continue;
 		}
 
-- 
2.53.0


^ permalink raw reply related

* [PATCH 02/23] sched/isolation: Enhance housekeeping_update() to support updating more than one HK cpumask
From: Waiman Long @ 2026-04-21  3:03 UTC (permalink / raw)
  To: Tejun Heo, Johannes Weiner, Michal Koutný, Jonathan Corbet,
	Shuah Khan, Catalin Marinas, Will Deacon, K. Y. Srinivasan,
	Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Guenter Roeck,
	Frederic Weisbecker, Paul E. McKenney, Neeraj Upadhyay,
	Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
	Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
	Anna-Maria Behnsen, Ingo Molnar, Thomas Gleixner, Chen Ridong,
	Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Ben Segall, Mel Gorman, Valentin Schneider, K Prateek Nayak,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
	linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
	Qiliang Yuan, Waiman Long
In-Reply-To: <20260421030351.281436-1-longman@redhat.com>

The housekeeping_update() function currently allows update to the
HK_TYPE_DOMAIN cpumask only. As we are going to enable dynamic
modification of the other housekeeping cpumasks, we need to extend
it to support passing in the information about the HK cpumask(s) to
be updated.  In cases where some HK cpumasks happen to be the same,
it will be more efficient to update multiple HK cpumasks in one single
call instead of calling it multiple times. Extend housekeeping_update()
to support that as well.

Also add the restriction that passed in isolated cpumask parameter
of housekeeping_update() must include all the CPUs isolated at boot
time. This is currently the case for cpuset anyway.

Signed-off-by: Waiman Long <longman@redhat.com>
---
 include/linux/sched/isolation.h |  2 +-
 kernel/cgroup/cpuset.c          |  2 +-
 kernel/sched/isolation.c        | 99 +++++++++++++++++++++++----------
 3 files changed, 71 insertions(+), 32 deletions(-)

diff --git a/include/linux/sched/isolation.h b/include/linux/sched/isolation.h
index d1707f121e20..a17f16e0156e 100644
--- a/include/linux/sched/isolation.h
+++ b/include/linux/sched/isolation.h
@@ -51,7 +51,7 @@ extern const struct cpumask *housekeeping_cpumask(enum hk_type type);
 extern bool housekeeping_enabled(enum hk_type type);
 extern void housekeeping_affine(struct task_struct *t, enum hk_type type);
 extern bool housekeeping_test_cpu(int cpu, enum hk_type type);
-extern int housekeeping_update(struct cpumask *isol_mask);
+extern int housekeeping_update(struct cpumask *isol_mask, unsigned long flags);
 extern void __init housekeeping_init(void);
 
 #else
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index 1335e437098e..a4eccb0ec0d1 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -1354,7 +1354,7 @@ static void cpuset_update_sd_hk_unlock(void)
 		 */
 		mutex_unlock(&cpuset_mutex);
 		cpus_read_unlock();
-		WARN_ON_ONCE(housekeeping_update(isolated_hk_cpus));
+		WARN_ON_ONCE(housekeeping_update(isolated_hk_cpus, BIT(HK_TYPE_DOMAIN)));
 		mutex_unlock(&cpuset_top_mutex);
 	} else {
 		cpuset_full_unlock();
diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c
index 9ec9ae510dc7..965d6f8fe344 100644
--- a/kernel/sched/isolation.c
+++ b/kernel/sched/isolation.c
@@ -120,48 +120,87 @@ bool housekeeping_test_cpu(int cpu, enum hk_type type)
 }
 EXPORT_SYMBOL_GPL(housekeeping_test_cpu);
 
-int housekeeping_update(struct cpumask *isol_mask)
-{
-	struct cpumask *trial, *old = NULL;
-	int err;
+/* HK type processing table */
+static struct {
+	int type;
+	int boot_type;
+} hk_types[] = {
+	{ HK_TYPE_DOMAIN,       HK_TYPE_DOMAIN_BOOT	  },
+	{ HK_TYPE_MANAGED_IRQ,  HK_TYPE_MANAGED_IRQ_BOOT  },
+	{ HK_TYPE_KERNEL_NOISE, HK_TYPE_KERNEL_NOISE_BOOT }
+};
 
-	trial = kmalloc(cpumask_size(), GFP_KERNEL);
-	if (!trial)
-		return -ENOMEM;
+#define HK_TYPE_CNT	ARRAY_SIZE(hk_types)
 
-	cpumask_andnot(trial, housekeeping_cpumask(HK_TYPE_DOMAIN_BOOT), isol_mask);
-	if (!cpumask_intersects(trial, cpu_online_mask)) {
-		kfree(trial);
-		return -EINVAL;
+int housekeeping_update(struct cpumask *isol_mask, unsigned long flags)
+{
+	struct cpumask *trial[HK_TYPE_CNT];
+	int i, err = 0;
+
+	for (i = 0; i < HK_TYPE_CNT; i++) {
+		int type = hk_types[i].type;
+		int boot = hk_types[i].boot_type;
+
+		trial[i] = NULL;
+		if (flags & BIT(type)) {
+			trial[i] = kmalloc(cpumask_size(), GFP_KERNEL);
+			if (!trial[i]) {
+				err = -ENOMEM;
+				goto out;
+			}
+			/*
+			 * The new HK cpumask must be a subset of its boot
+			 * cpumask.
+			 */
+			cpumask_andnot(trial[i], cpu_possible_mask, isol_mask);
+			if (!cpumask_intersects(trial[i], cpu_online_mask) ||
+			    !cpumask_subset(trial[i], housekeeping_cpumask(boot))) {
+				i++;
+				err = -EINVAL;
+				goto out;
+			}
+		}
 	}
 
 	if (!housekeeping.flags)
 		static_branch_enable(&housekeeping_overridden);
 
-	if (housekeeping.flags & HK_FLAG_DOMAIN)
-		old = housekeeping_cpumask_dereference(HK_TYPE_DOMAIN);
-	else
-		WRITE_ONCE(housekeeping.flags, housekeeping.flags | HK_FLAG_DOMAIN);
-	rcu_assign_pointer(housekeeping.cpumasks[HK_TYPE_DOMAIN], trial);
-
-	synchronize_rcu();
-
-	pci_probe_flush_workqueue();
-	mem_cgroup_flush_workqueue();
-	vmstat_flush_workqueue();
+	for (i = 0; i < HK_TYPE_CNT; i++) {
+		int type =  hk_types[i].type;
+		struct cpumask *old;
 
-	err = workqueue_unbound_housekeeping_update(housekeeping_cpumask(HK_TYPE_DOMAIN));
-	WARN_ON_ONCE(err < 0);
+		if (!trial[i])
+			continue;
+		old = NULL;
+		if (housekeeping.flags & BIT(type))
+			old = housekeeping_cpumask_dereference(type);
+		rcu_assign_pointer(housekeeping.cpumasks[type], trial[i]);
+		trial[i] = old;
+	}
 
-	err = tmigr_isolated_exclude_cpumask(isol_mask);
-	WARN_ON_ONCE(err < 0);
+	if ((housekeeping.flags & flags) != flags)
+		WRITE_ONCE(housekeeping.flags, housekeeping.flags | flags);
 
-	err = kthreads_update_housekeeping();
-	WARN_ON_ONCE(err < 0);
+	synchronize_rcu();
 
-	kfree(old);
+	if (flags & HK_FLAG_DOMAIN) {
+		/*
+		 * HK_TYPE_DOMAIN specific callbacks
+		 */
+		pci_probe_flush_workqueue();
+		mem_cgroup_flush_workqueue();
+		vmstat_flush_workqueue();
+
+		WARN_ON_ONCE(workqueue_unbound_housekeeping_update(
+				housekeeping_cpumask(HK_TYPE_DOMAIN)) < 0);
+		WARN_ON_ONCE(tmigr_isolated_exclude_cpumask(isol_mask) < 0);
+		WARN_ON_ONCE(kthreads_update_housekeeping() < 0);
+	}
 
-	return 0;
+out:
+	while (--i >= 0)
+		kfree(trial[i]);
+	return err;
 }
 
 void __init housekeeping_init(void)
-- 
2.53.0


^ permalink raw reply related

* [PATCH 03/23] tick/nohz: Make nohz_full parameter optional
From: Waiman Long @ 2026-04-21  3:03 UTC (permalink / raw)
  To: Tejun Heo, Johannes Weiner, Michal Koutný, Jonathan Corbet,
	Shuah Khan, Catalin Marinas, Will Deacon, K. Y. Srinivasan,
	Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Guenter Roeck,
	Frederic Weisbecker, Paul E. McKenney, Neeraj Upadhyay,
	Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
	Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
	Anna-Maria Behnsen, Ingo Molnar, Thomas Gleixner, Chen Ridong,
	Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Ben Segall, Mel Gorman, Valentin Schneider, K Prateek Nayak,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
	linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
	Qiliang Yuan, Waiman Long
In-Reply-To: <20260421030351.281436-1-longman@redhat.com>

To provide nohz_full tick support, there is a set of tick dependency
masks that need to be evaluated on every IRQ and context switch.
Switching on nohz_full tick support at runtime will be problematic
as some of the tick dependency masks may not be properly set causing
problem down the road.

Allow nohz_full boot option to be specified without any
parameter to force enable nohz_full tick support without any
CPU in the tick_nohz_full_mask yet. The context_tracking_key and
tick_nohz_full_running flag will be enabled in this case to make
tick_nohz_full_enabled() return true.

There is still a small performance overhead by force enable nohz_full
this way. So it should only be used if there is a chance that some
CPUs may become isolated later via the cpuset isolated partition
functionality and better CPU isolation closed to nohz_full is desired.

Signed-off-by: Waiman Long <longman@redhat.com>
---
 Documentation/admin-guide/kernel-parameters.txt | 15 +++++++++------
 include/linux/context_tracking.h                |  7 ++++++-
 kernel/context_tracking.c                       |  4 +++-
 kernel/rcu/tree_nocb.h                          |  2 +-
 kernel/sched/isolation.c                        | 13 ++++++++++++-
 kernel/time/tick-sched.c                        | 11 +++++++++--
 6 files changed, 40 insertions(+), 12 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 95f97ce487a4..f0eedaebe9d6 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -4550,13 +4550,16 @@ Kernel parameters
 			Valid arguments: on, off
 			Default: on
 
-	nohz_full=	[KNL,BOOT,SMP,ISOL]
-			The argument is a cpu list, as described above.
+	nohz_full[=cpu-list]
+			[KNL,BOOT,SMP,ISOL]
 			In kernels built with CONFIG_NO_HZ_FULL=y, set
-			the specified list of CPUs whose tick will be stopped
-			whenever possible. The boot CPU will be forced outside
-			the range to maintain the timekeeping.  Any CPUs
-			in this list will have their RCU callbacks offloaded,
+			the specified list of CPUs whose tick will be
+			stopped whenever possible.  If the argument is
+			not specified, nohz_full will be forced enabled
+			without any CPU in the nohz_full list yet.
+			The boot CPU will be forced outside the range
+			to maintain the timekeeping.  Any CPUs in this
+			list will have their RCU callbacks offloaded,
 			just as if they had also been called out in the
 			rcu_nocbs= boot parameter.
 
diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h
index af9fe87a0922..a3fea7f9fef6 100644
--- a/include/linux/context_tracking.h
+++ b/include/linux/context_tracking.h
@@ -9,8 +9,13 @@
 
 #include <asm/ptrace.h>
 
-
 #ifdef CONFIG_CONTEXT_TRACKING_USER
+/*
+ * Pass CONTEXT_TRACKING_FORCE_ENABLE to ct_cpu_track_user() to force enable
+ * user context tracking.
+ */
+#define CONTEXT_TRACKING_FORCE_ENABLE	(-1)
+
 extern void ct_cpu_track_user(int cpu);
 
 /* Called with interrupts disabled.  */
diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c
index a743e7ffa6c0..925999de1a28 100644
--- a/kernel/context_tracking.c
+++ b/kernel/context_tracking.c
@@ -678,7 +678,9 @@ void __init ct_cpu_track_user(int cpu)
 {
 	static __initdata bool initialized = false;
 
-	if (!per_cpu(context_tracking.active, cpu)) {
+	if (cpu == CONTEXT_TRACKING_FORCE_ENABLE) {
+		static_branch_inc(&context_tracking_key);
+	} else if (!per_cpu(context_tracking.active, cpu)) {
 		per_cpu(context_tracking.active, cpu) = true;
 		static_branch_inc(&context_tracking_key);
 	}
diff --git a/kernel/rcu/tree_nocb.h b/kernel/rcu/tree_nocb.h
index b3337c7231cc..2d06dcb61f37 100644
--- a/kernel/rcu/tree_nocb.h
+++ b/kernel/rcu/tree_nocb.h
@@ -1267,7 +1267,7 @@ void __init rcu_init_nohz(void)
 	struct shrinker * __maybe_unused lazy_rcu_shrinker;
 
 #if defined(CONFIG_NO_HZ_FULL)
-	if (tick_nohz_full_running && !cpumask_empty(tick_nohz_full_mask))
+	if (tick_nohz_full_running)
 		cpumask = tick_nohz_full_mask;
 #endif
 
diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c
index 965d6f8fe344..c233d55a1e95 100644
--- a/kernel/sched/isolation.c
+++ b/kernel/sched/isolation.c
@@ -268,6 +268,7 @@ static int __init housekeeping_setup(char *str, unsigned long flags)
 	}
 
 	alloc_bootmem_cpumask_var(&non_housekeeping_mask);
+
 	if (cpulist_parse(str, non_housekeeping_mask) < 0) {
 		pr_warn("Housekeeping: nohz_full= or isolcpus= incorrect CPU range\n");
 		goto free_non_housekeeping_mask;
@@ -277,6 +278,13 @@ static int __init housekeeping_setup(char *str, unsigned long flags)
 	cpumask_andnot(housekeeping_staging,
 		       cpu_possible_mask, non_housekeeping_mask);
 
+	/*
+	 * Allow "nohz_full" without parameter to force enable nohz_full
+	 * at boot time without any CPUs in the nohz_full list yet.
+	 */
+	if ((flags & HK_FLAG_KERNEL_NOISE) && !*str)
+		goto setup_housekeeping_staging;
+
 	first_cpu = cpumask_first_and(cpu_present_mask, housekeeping_staging);
 	if (first_cpu >= nr_cpu_ids || first_cpu >= setup_max_cpus) {
 		__cpumask_set_cpu(smp_processor_id(), housekeeping_staging);
@@ -290,6 +298,7 @@ static int __init housekeeping_setup(char *str, unsigned long flags)
 	if (cpumask_empty(non_housekeeping_mask))
 		goto free_housekeeping_staging;
 
+setup_housekeeping_staging:
 	if (!housekeeping.flags) {
 		/* First setup call ("nohz_full=" or "isolcpus=") */
 		enum hk_type type;
@@ -357,10 +366,12 @@ static int __init housekeeping_nohz_full_setup(char *str)
 	unsigned long flags;
 
 	flags = HK_FLAG_KERNEL_NOISE | HK_FLAG_KERNEL_NOISE_BOOT;
+	if (*str == '=')
+		str++;
 
 	return housekeeping_setup(str, flags);
 }
-__setup("nohz_full=", housekeeping_nohz_full_setup);
+__setup("nohz_full", housekeeping_nohz_full_setup);
 
 static int __init housekeeping_isolcpus_setup(char *str)
 {
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 9e5264458414..ed877b2c9040 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -676,8 +676,15 @@ void __init tick_nohz_init(void)
 		}
 	}
 
-	for_each_cpu(cpu, tick_nohz_full_mask)
-		ct_cpu_track_user(cpu);
+	/*
+	 * Force enable context_tracking_key if tick_nohz_full_mask empty
+	 */
+	if (cpumask_empty(tick_nohz_full_mask)) {
+		ct_cpu_track_user(CONTEXT_TRACKING_FORCE_ENABLE);
+	} else {
+		for_each_cpu(cpu, tick_nohz_full_mask)
+			ct_cpu_track_user(cpu);
+	}
 
 	ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
 					"kernel/nohz:predown", NULL,
-- 
2.53.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox