Compare commits

...

9 Commits

Author SHA1 Message Date
Russ Meyerriecks
91bc5a3b57 net: Update dahdi for alloc_netdev() api change in 3.17+
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c835a677331495cf137a7f8a023463afd9f0~

Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
Acked-by: Shaun Ruffell <sruffell@digium.com>
2014-08-11 09:53:02 -05:00
Russ Meyerriecks
8428452ad1 wcte43x: Reset span alarm to RED on startup
A fresh modprobe and dahdi_cfg would cause a temporary green alarm state on the
spans for a second while the alarm debounced into RED. New logic keeps the
spans alarm state as NONE during the unconfigured state, but sets the alarm
state to RED after the framer reset in the startup logic.

Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
2014-08-01 16:16:08 -05:00
Russ Meyerriecks
90b6712d01 wcte13xp: Reset span alarm to RED on startup
A fresh modprobe and dahdi_cfg would cause a temporary green alarm state on the
driver for a second while the alarm debounced into RED. New logic keeps the
spans alarm state as NONE during the unconfigured state, but sets the alarm
state to RED after the framer reset in the startup logic.

Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
Acked-by: Shaun Ruffell <sruffell@digium.com>
2014-07-23 16:24:01 -05:00
Shaun Ruffell
31cbf7a90e wcte43x: Fix failure to download firmware.
The firmware/Makefile missed a line that added the firmware for the TE436 to the
download list.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
2014-07-18 10:19:09 -05:00
Russ Meyerriecks
bce1ecafda wcte43x: Add support for new te436/te236 cards
Adds driver support for Digium's new te436 and te236 quad and dual span T1/E1 cards.

[removed whitespace at end of line]
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
2014-07-17 15:18:10 -05:00
Shaun Ruffell
a951dd5e32 wcte43x: Do not reconfigure framer when span lineconfig is not changed.
If dahdi_span_ops.spanconfig is called multiple times in a row (like when
running dahdi_cfg; dahdi_cfg ) the tx signaling bits would go through a spurious
state that some far side devices would respond to.

Now, if the dahdi_span_ops.spanconfig callback is called, and the configuration
matches the existing configuration, we will not touch the framer.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
2014-07-11 14:14:15 -05:00
Shaun Ruffell
8210fea5b3 wcte13xp: Do not reconfigure framer when span lineconfig is not changed.
If dahdi_span_ops.spanconfig is called multiple times in a row (like when
running dahdi_cfg; dahdi_cfg ) the tx signaling bits would go through a spurious
state that some far side devices would respond to.

Now, if the dahdi_span_ops.spanconfig callback is called, and the configuration
matches the existing configuration, we will not touch the framer.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
2014-07-11 14:14:15 -05:00
Shaun Ruffell
a1ff3cb0c0 dahdi: Stop tones on channel when updating tone zone.
If a channel is currently playing a tone when the tone zone is updated, the
existing tone zone could be freed while the channel keeps a reference to the
current tone (curtone) that points into the freed zone.

If the newly freed tone is then modified, there was a window where it was
possible to  corrupt 'struct dahdi_chan' (by overrunning swritechunk[])
resulting in a "BUG: unable to handle kernel paging request at virtual address"
panic in the context of __dahdi_transmit_chunk().

Reported-and-Tested-by: Matt Behrens <matt@zigg.com>
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
2014-07-07 12:25:36 -05:00
Shaun Ruffell
089b593b56 wct4xxp: Report rx signalling bit changes after spanconfig.
This fixes a long standing issue where, for CAS signaling, the RX bits were
sometimes misreported after span configuration before the first detected state
change.

The logic in the wct4xxp driver now matches that in the wcte43x driver and
wcte13xp drivers. The wcte12xp driver always polls the sigbits due to how
voicebus works and is not affected by this.

Internal-Issue-ID: DAHDI-1081
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
2014-06-27 22:40:28 -05:00
9 changed files with 155 additions and 20 deletions

View File

@@ -1811,6 +1811,17 @@ static int start_tone(struct dahdi_chan *chan, int tone)
return res;
}
/**
* stop_tone - Stops any tones on a channel.
*
* Must be called with chan->lock held.
*
*/
static inline int stop_tone(struct dahdi_chan *chan)
{
return start_tone(chan, -1);
}
static int set_tone_zone(struct dahdi_chan *chan, int zone)
{
int res = 0;
@@ -1838,6 +1849,9 @@ static int set_tone_zone(struct dahdi_chan *chan, int zone)
return -ENODATA;
spin_lock_irqsave(&chan->lock, flags);
stop_tone(chan);
if (chan->curzone) {
struct dahdi_zone *zone = chan->curzone;
chan->curzone = NULL;

View File

@@ -1063,12 +1063,23 @@ static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type)
used = pvc_is_used(pvc);
if (type == ARPHRD_ETHER)
if (type == ARPHRD_ETHER) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
dev = alloc_netdev(sizeof(struct net_device_stats),
"pvceth%d", NET_NAME_UNKNOWN, ether_setup);
#else
dev = alloc_netdev(sizeof(struct net_device_stats),
"pvceth%d", ether_setup);
else
#endif
} else {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
dev = alloc_netdev(sizeof(struct net_device_stats),
"pvc%d", NET_NAME_UNKNOWN, dlci_setup);
#else
dev = alloc_netdev(sizeof(struct net_device_stats),
"pvc%d", dlci_setup);
#endif
}
if (!dev) {
printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n",

View File

@@ -282,7 +282,12 @@ static void hdlc_setup(struct net_device *dev)
struct net_device *alloc_hdlcdev(void *priv)
{
struct net_device *dev;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
dev = alloc_netdev(sizeof(hdlc_device), "hdlc%d",
NET_NAME_UNKNOWN, hdlc_setup);
#else
dev = alloc_netdev(sizeof(hdlc_device), "hdlc%d", hdlc_setup);
#endif
if (dev)
dev_to_hdlc(dev)->priv = priv;
return dev;

View File

@@ -34,6 +34,7 @@ WCT820_VERSION:=1.76
TE133_VERSION:=780019
TE134_VERSION:=780017
TE435_VERSION:=e0019
TE436_VERSION:=10017
A8A_VERSION:=1d0017
A8B_VERSION:=1d0019
A4A_VERSION:=a0017
@@ -43,7 +44,7 @@ FIRMWARE_URL:=http://downloads.digium.com/pub/telephony/firmware/releases
ALL_FIRMWARE=FIRMWARE-OCT6114-032 FIRMWARE-OCT6114-064 FIRMWARE-OCT6114-128 FIRMWARE-OCT6114-256
ALL_FIRMWARE+=FIRMWARE-TC400M FIRMWARE-HX8 FIRMWARE-VPMOCT032 FIRMWARE-TE820 FIRMWARE-TE133 FIRMWARE-TE134
ALL_FIRMWARE+=FIRMWARE-A8A FIRMWARE-A8B FIRMWARE-A4A FIRMWARE-A4B FIRMWARE-TE435
ALL_FIRMWARE+=FIRMWARE-A8A FIRMWARE-A8B FIRMWARE-A4A FIRMWARE-A4B FIRMWARE-TE435 FIRMWARE-TE436
# Firmware files should use the naming convention: dahdi-fw-<base name>-<sub name>-<version> or dahdi-fw-<base name>-<version>
# First example: dahdi-fw-oct6114-064-1.05.01
@@ -63,6 +64,7 @@ FIRMWARE:=$(FIRMWARE:FIRMWARE-TE820=dahdi-fw-te820-$(WCT820_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE133=dahdi-fw-te133-$(TE133_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE134=dahdi-fw-te134-$(TE134_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE435=dahdi-fw-te435-$(TE435_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE436=dahdi-fw-te436-$(TE436_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-A8A=dahdi-fw-a8b-$(A8B_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-A8B=dahdi-fw-a8a-$(A8A_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-A4A=dahdi-fw-a4b-$(A4B_VERSION).tar.gz)
@@ -138,6 +140,7 @@ hotplug-install: $(DESTDIR)/usr/lib/hotplug/firmware $(DESTDIR)/lib/firmware $(F
@$(call RUN_INST,dahdi-fw-te133,$(TE133_VERSION))
@$(call RUN_INST,dahdi-fw-te134,$(TE134_VERSION))
@$(call RUN_INST,dahdi-fw-te435,$(TE435_VERSION))
@$(call RUN_INST,dahdi-fw-te436,$(TE436_VERSION))
@$(call RUN_INST,dahdi-fw-a8a,$(A8A_VERSION))
@$(call RUN_INST,dahdi-fw-a8b,$(A8B_VERSION))
@$(call RUN_INST,dahdi-fw-a4a,$(A4A_VERSION))

View File

@@ -207,7 +207,13 @@ int vb_net_register(struct voicebus *vb, const char *board_name)
struct voicebus_netdev_priv *priv;
const char our_mac[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
netdev = alloc_netdev(sizeof(*priv), board_name,
NET_NAME_UNKNOWN, ether_setup);
#else
netdev = alloc_netdev(sizeof(*priv), board_name, ether_setup);
#endif
if (!netdev)
return -ENOMEM;
priv = netdev_priv(netdev);

View File

@@ -3296,8 +3296,6 @@ static void t4_check_sigbits(struct t4 *wc, int span)
dev_notice(&wc->dev->dev, "Checking sigbits on span %d\n",
span + 1);
if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
return;
if (E1 == ts->linemode) {
for (i = 0; i < 15; i++) {
a = t4_framer_in(wc, span, 0x71 + i);
@@ -3687,6 +3685,7 @@ static inline void t4_framer_interrupt(struct t4 *wc, int span)
struct t4_span *ts = wc->tspans[span];
struct dahdi_chan *sigchan;
unsigned long flags;
bool recheck_sigbits = false;
/* 1st gen cards isn't used interrupts */
@@ -3712,6 +3711,8 @@ static inline void t4_framer_interrupt(struct t4 *wc, int span)
ts->span.count.ebit += __t4_framer_in(wc, span, EBCL_T);
ts->span.count.be += __t4_framer_in(wc, span, BECL_T);
ts->span.count.prbs = __t4_framer_in(wc, span, FRS1_T);
if (DAHDI_RXSIG_INITIAL == ts->span.chans[0]->rxhooksig)
recheck_sigbits = true;
}
spin_unlock_irqrestore(&wc->reglock, flags);
@@ -3720,7 +3721,7 @@ static inline void t4_framer_interrupt(struct t4 *wc, int span)
ts->span.count.errsec += 1;
}
if (isr0)
if (isr0 & 0x08 || recheck_sigbits)
t4_check_sigbits(wc, span);
if (E1 == ts->linemode) {

View File

@@ -657,7 +657,13 @@ wctc4xxp_net_register(struct wcdte *wc)
struct wcdte_netdev_priv *priv;
const char our_mac[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
netdev = alloc_netdev(sizeof(*priv), wc->board_name,
NET_NAME_UNKNOWN, ether_setup);
#else
netdev = alloc_netdev(sizeof(*priv), wc->board_name, ether_setup);
#endif
if (!netdev)
return -ENOMEM;
priv = netdev_priv(netdev);

View File

@@ -110,6 +110,7 @@ struct t13x {
struct vpm450m *vpm;
struct mutex lock;
struct wcxb xb;
u32 lineconfig_fingerprint;
};
static void te13x_handle_transmit(struct wcxb *xb, void *vfp);
@@ -1315,6 +1316,10 @@ static int t13x_startup(struct file *file, struct dahdi_span *span)
/* Reset framer with proper parameters and start */
t13x_framer_start(wc);
/* Reset span alarm state to RED to prevent false
* temporary GREEN state on span bringup */
span->alarms |= DAHDI_ALARM_RED;
/* Do we want to SYNC on receive or not. This must always happen after
* the framer is fully reset. */
wcxb_set_clksrc(&wc->xb,
@@ -1675,12 +1680,37 @@ static void t13x_chan_set_sigcap(struct dahdi_span *span, int x)
}
}
static bool t13x_lineconfig_changed(struct t13x *wc,
const struct dahdi_lineconfig *lc)
{
unsigned long flags;
bool result;
u32 crc = crc32(~0, lc, sizeof(*lc));
spin_lock_irqsave(&wc->reglock, flags);
result = (crc != wc->lineconfig_fingerprint);
spin_unlock_irqrestore(&wc->reglock, flags);
return result;
}
static void t13x_save_lineconfig(struct t13x *wc,
const struct dahdi_lineconfig *lc)
{
unsigned long flags;
u32 crc = crc32(~0, lc, sizeof(*lc));
spin_lock_irqsave(&wc->reglock, flags);
wc->lineconfig_fingerprint = crc;
spin_unlock_irqrestore(&wc->reglock, flags);
}
static int
t13x_spanconfig(struct file *file, struct dahdi_span *span,
struct dahdi_lineconfig *lc)
{
struct t13x *wc = container_of(span, struct t13x, span);
int i;
int res = 0;
if (file->f_flags & O_NONBLOCK)
return -EAGAIN;
@@ -1693,10 +1723,13 @@ t13x_spanconfig(struct file *file, struct dahdi_span *span,
t13x_chan_set_sigcap(span, i);
/* If already running, apply changes immediately */
if (test_bit(DAHDI_FLAGBIT_RUNNING, &span->flags))
return t13x_startup(file, span);
return 0;
if (test_bit(DAHDI_FLAGBIT_RUNNING, &span->flags) &&
t13x_lineconfig_changed(wc, lc)) {
res = t13x_startup(file, span);
if (!res)
t13x_save_lineconfig(wc, lc);
}
return res;
}
/**

View File

@@ -65,7 +65,9 @@ static inline int delayed_work_pending(struct work_struct *work)
#endif
static const char *TE435_FW_FILENAME = "dahdi-fw-te435.bin";
static const char *TE436_FW_FILENAME = "dahdi-fw-te436.bin";
static const u32 TE435_VERSION = 0xe0019;
static const u32 TE436_VERSION = 0x10017;
/* #define RPC_RCLK */
@@ -110,6 +112,7 @@ struct t43x_span {
bool debounce;
int syncpos;
int sync;
u32 lineconfig_fingerprint;
};
struct t43x_clksrc_work {
@@ -793,6 +796,8 @@ struct t43x_desc {
static const struct t43x_desc te435 = {"Wildcard TE435"}; /* pci express quad */
static const struct t43x_desc te235 = {"Wildcard TE235"}; /* pci express dual */
static const struct t43x_desc te436 = {"Wildcard TE436"}; /* pci quad */
static const struct t43x_desc te236 = {"Wildcard TE236"}; /* pci dual */
static int __t43x_pci_get(struct t43x *wc, unsigned int addr)
{
@@ -1761,6 +1766,10 @@ static void t43x_framer_start(struct t43x *wc)
t43x_set_cas_mode(wc, unit);
set_bit(DAHDI_FLAGBIT_RUNNING, &ts->span.flags);
/* Reset span alarm state to RED to prevent false
* temporary GREEN state on span bringup */
ts->span.alarms |= DAHDI_ALARM_RED;
}
for (unit = 0; unit < wc->numspans; unit++) {
@@ -2377,6 +2386,30 @@ static void t43x_chan_set_sigcap(struct dahdi_span *span, int x)
}
}
static bool t43x_lineconfig_changed(struct t43x_span *ts,
const struct dahdi_lineconfig *lc)
{
unsigned long flags;
bool result;
u32 crc = crc32(~0, lc, sizeof(*lc));
spin_lock_irqsave(&ts->owner->reglock, flags);
result = (crc != ts->lineconfig_fingerprint);
spin_unlock_irqrestore(&ts->owner->reglock, flags);
return result;
}
static void t43x_save_lineconfig(struct t43x_span *ts,
const struct dahdi_lineconfig *lc)
{
unsigned long flags;
u32 crc = crc32(~0, lc, sizeof(*lc));
spin_lock_irqsave(&ts->owner->reglock, flags);
ts->lineconfig_fingerprint = crc;
spin_unlock_irqrestore(&ts->owner->reglock, flags);
}
static int
t43x_spanconfig(struct file *file, struct dahdi_span *span,
struct dahdi_lineconfig *lc)
@@ -2384,6 +2417,7 @@ t43x_spanconfig(struct file *file, struct dahdi_span *span,
struct t43x_span *ts = container_of(span, struct t43x_span, span);
struct t43x *wc = ts->owner;
int i;
int res = 0;
if (debug)
dev_info(&wc->xb.pdev->dev, "%s\n", __func__);
@@ -2420,10 +2454,13 @@ t43x_spanconfig(struct file *file, struct dahdi_span *span,
t43x_chan_set_sigcap(span, i);
/* If already running, apply changes immediately */
if (test_bit(DAHDI_FLAGBIT_RUNNING, &span->flags))
return t43x_startup(file, span);
return 0;
if (test_bit(DAHDI_FLAGBIT_RUNNING, &span->flags) &&
t43x_lineconfig_changed(ts, lc)) {
res = t43x_startup(file, span);
if (!res)
t43x_save_lineconfig(ts, lc);
}
return res;
}
/*
@@ -3420,12 +3457,6 @@ static int __devinit t43x_init_one(struct pci_dev *pdev,
goto fail_exit;
}
/* Check for field updatable firmware */
res = wcxb_check_firmware(&wc->xb, TE435_VERSION,
TE435_FW_FILENAME, force_firmware, WCXB_RESET_NOW);
if (res)
goto fail_exit;
wc->ddev->hardware_id = t43x_read_serial(wc);
if (wc->ddev->hardware_id == NULL) {
@@ -3435,11 +3466,21 @@ static int __devinit t43x_init_one(struct pci_dev *pdev,
}
if (strncmp(wc->ddev->hardware_id, "1TE435F", 7) == 0) {
/* Quad-span PCIE */
wc->numspans = 4;
wc->devtype = &te435;
} else if (strncmp(wc->ddev->hardware_id, "1TE235F", 7) == 0) {
/* Dual-span PCIE */
wc->numspans = 2;
wc->devtype = &te235;
} else if (strncmp(wc->ddev->hardware_id, "1TE436F", 7) == 0) {
/* Quad-span PCI */
wc->numspans = 4;
wc->devtype = &te436;
} else if (strncmp(wc->ddev->hardware_id, "1TE236F", 7) == 0) {
/* Dual-span PCI */
wc->numspans = 2;
wc->devtype = &te236;
} else {
dev_info(&wc->xb.pdev->dev,
"Unable to identify board type from serial number %s\n",
@@ -3448,6 +3489,20 @@ static int __devinit t43x_init_one(struct pci_dev *pdev,
goto fail_exit;
}
/* Check for field updatable firmware */
if ((wc->devtype == &te435) || (wc->devtype == &te235)) {
res = wcxb_check_firmware(&wc->xb, TE435_VERSION,
TE435_FW_FILENAME, force_firmware, WCXB_RESET_NOW);
} else if ((wc->devtype == &te436) || (wc->devtype == &te236)) {
res = wcxb_check_firmware(&wc->xb, TE436_VERSION,
TE436_FW_FILENAME, force_firmware, WCXB_RESET_NOW);
} else {
res = -EIO;
}
if (res)
goto fail_exit;
for (x = 0; x < wc->numspans; x++) {
ts = kzalloc(sizeof(*wc->tspans[x]), GFP_KERNEL);
if (!ts) {
@@ -3566,6 +3621,7 @@ static void __devexit t43x_remove_one(struct pci_dev *pdev)
static DEFINE_PCI_DEVICE_TABLE(t43x_pci_tbl) = {
{ 0xd161, 0x800e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ 0xd161, 0x8013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ 0 }
};