* [PATCH 5/8] mISDN: Make layer1 timer 3 value configurable
From: Karsten Keil @ 2012-04-28 11:43 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Karsten Keil
In-Reply-To: <1335613404-10187-1-git-send-email-kkeil@linux-pingi.de>
From: Karsten Keil <isdn@linux-pingi.de>
For certification test it is very useful to change the layer1
timer3 value on runtime.
Signed-off-by: Karsten Keil <kkeil@linux-pingi.de>
---
drivers/isdn/mISDN/layer1.c | 16 ++++++++++++++--
include/linux/mISDNhw.h | 3 +++
include/linux/mISDNif.h | 3 ++-
3 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/isdn/mISDN/layer1.c b/drivers/isdn/mISDN/layer1.c
index 0fc49b3..ff05153 100644
--- a/drivers/isdn/mISDN/layer1.c
+++ b/drivers/isdn/mISDN/layer1.c
@@ -30,11 +30,12 @@ struct layer1 {
struct FsmInst l1m;
struct FsmTimer timer;
int delay;
+ int t3_value;
struct dchannel *dch;
dchannel_l1callback *dcb;
};
-#define TIMER3_VALUE 7000
+#define TIMER3_DEFAULT_VALUE 7000
static
struct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL};
@@ -233,7 +234,7 @@ l1_activate_s(struct FsmInst *fi, int event, void *arg)
{
struct layer1 *l1 = fi->userdata;
- mISDN_FsmRestartTimer(&l1->timer, TIMER3_VALUE, EV_TIMER3, NULL, 2);
+ mISDN_FsmRestartTimer(&l1->timer, l1->t3_value, EV_TIMER3, NULL, 2);
test_and_set_bit(FLG_L1_T3RUN, &l1->Flags);
l1->dcb(l1->dch, HW_RESET_REQ);
}
@@ -356,6 +357,16 @@ l1_event(struct layer1 *l1, u_int event)
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);
@@ -377,6 +388,7 @@ create_l1(struct dchannel *dch, dchannel_l1callback *dcb) {
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;
diff --git a/include/linux/mISDNhw.h b/include/linux/mISDNhw.h
index 74d5734..7075753 100644
--- a/include/linux/mISDNhw.h
+++ b/include/linux/mISDNhw.h
@@ -136,6 +136,9 @@ extern int create_l1(struct dchannel *, dchannel_l1callback *);
#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);
diff --git a/include/linux/mISDNif.h b/include/linux/mISDNif.h
index b7457e8..322d316 100644
--- a/include/linux/mISDNif.h
+++ b/include/linux/mISDNif.h
@@ -37,7 +37,7 @@
*/
#define MISDN_MAJOR_VERSION 1
#define MISDN_MINOR_VERSION 1
-#define MISDN_RELEASE 26
+#define MISDN_RELEASE 27
/* primitives for information exchange
* generell format
@@ -374,6 +374,7 @@ clear_channelmap(u_int nr, u_char *map)
#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
--
1.7.3.4
^ permalink raw reply related
* [PATCH 2/8] mISDN: Fix refcounting bug
From: Karsten Keil @ 2012-04-28 11:43 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Karsten Keil
In-Reply-To: <1335613404-10187-1-git-send-email-kkeil@linux-pingi.de>
From: Karsten Keil <isdn@linux-pingi.de>
Under some configs it was still not possible to unload the driver,
because the module use count was srewed up.
Signed-off-by: Karsten Keil <keil@b1-systems.de>
---
drivers/isdn/mISDN/tei.c | 52 +++++++++++++++++++++++++++++++++------------
1 files changed, 38 insertions(+), 14 deletions(-)
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
index 969766f..25ed826 100644
--- a/drivers/isdn/mISDN/tei.c
+++ b/drivers/isdn/mISDN/tei.c
@@ -790,18 +790,22 @@ tei_ph_data_ind(struct teimgr *tm, u_int mt, u_char *dp, int len)
static struct layer2 *
create_new_tei(struct manager *mgr, int tei, int sapi)
{
- u_long opt = 0;
- u_long flags;
- int id;
- struct layer2 *l2;
+ u_long opt = 0;
+ u_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)))
+ 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__);
@@ -836,6 +840,14 @@ create_new_tei(struct manager *mgr, int tei, int sapi)
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;
}
@@ -978,10 +990,11 @@ TEIrelease(struct layer2 *l2)
static int
create_teimgr(struct manager *mgr, struct channel_req *crq)
{
- struct layer2 *l2;
- u_long opt = 0;
- u_long flags;
- int id;
+ struct layer2 *l2;
+ u_long opt = 0;
+ u_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",
@@ -1016,6 +1029,7 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
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);
@@ -1055,24 +1069,34 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
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.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
- } else {
+ if (id >= 0) {
l2->ch.nr = id;
l2->up->nr = id;
crq->ch = &l2->ch;
- id = 0;
+ /* 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;
}
--
1.7.3.4
^ permalink raw reply related
* [PATCH 8/8] mISDN: Add 2MBit mode for HFC E1 card
From: Karsten Keil @ 2012-04-28 11:43 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Karsten Keil
In-Reply-To: <1335613404-10187-1-git-send-email-kkeil@linux-pingi.de>
From: Karsten Keil <isdn@linux-pingi.de>
The new mode allows to receive and transmit full transparent
or HDLC data of all timeslots via one FIFO.
Change some register names to match the latest manual for
the E1 chip.
Signed-off-by: Karsten Keil <kkeil@linux-pingi.de>
---
drivers/isdn/hardware/mISDN/hfc_multi.h | 79 +++---
drivers/isdn/hardware/mISDN/hfcmulti.c | 426 ++++++++++++++++++++++++++-----
include/linux/mISDNif.h | 57 +++--
3 files changed, 440 insertions(+), 122 deletions(-)
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h
index c601f88..9dc0543 100644
--- a/drivers/isdn/hardware/mISDN/hfc_multi.h
+++ b/drivers/isdn/hardware/mISDN/hfc_multi.h
@@ -12,6 +12,7 @@
#define DEBUG_HFCMULTI_FILL 0x00800000
#define DEBUG_HFCMULTI_SYNC 0x01000000
#define DEBUG_HFCMULTI_DTMF 0x02000000
+#define DEBUG_HFCMULTI_TIMER 0x04000000
#define DEBUG_HFCMULTI_LOCK 0x80000000
#define PCI_ENA_REGIO 0x01
@@ -71,7 +72,10 @@ struct hfcm_hw {
u_char r_dtmf;
u_char r_st_sync;
u_char r_sci_msk;
- u_char r_tx0, r_tx1;
+ u_char r_tx0;
+ u_char r_tx1;
+ u_char r_rx_sl0_cfg0;
+ u_char r_tx_sl0_cfg1;
u_char a_st_ctrl0[8];
u_char r_bert_wd_md;
timer_t timer;
@@ -114,6 +118,7 @@ struct hfcm_hw {
/* 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_CHIP_2MBITRAW 16 /* mode to access full 32 byte data */
#define HFC_IO_MODE_PCIMEM 0x00 /* normal memory mapped IO */
#define HFC_IO_MODE_REGIO 0x01 /* PCI io access */
@@ -334,24 +339,23 @@ struct hfc_multi {
#define R_LOS0 0x22
#define R_LOS1 0x23
#define R_RX0 0x24
-#define R_RX_FR0 0x25
-#define R_RX_FR1 0x26
+#define R_RX_SL0_CFG0 0x25
+#define R_RX_SL0_CFG1 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 R_TX_SL0_CFG0 0x2C
+#define R_TX_SL0 0x2D
+#define R_TX_SL0_CFG1 0x2E
+#define R_JATT_CFG 0x2F
#define A_ST_RD_STATE 0x30
#define A_ST_WR_STATE 0x30
-#define R_RX_OFF 0x30
+#define R_RX_OFFS 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_TX_OFFS 0x34
#define R_SYNC_CTRL 0x35
#define A_ST_CLK_DLY 0x37
#define R_PWM0 0x38
@@ -414,8 +418,8 @@ struct hfc_multi {
#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 R_JATT_STA 0x2B
+#define R_SLIP 0x2C
#define A_ST_RD_STA 0x30
#define R_FAS_EC 0x30
#define R_FAS_ECL 0x30
@@ -430,12 +434,12 @@ struct hfc_multi {
#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 R_SA6_VAL13_EC 0x38
+#define R_SA6_VAL13_ECL 0x38
+#define R_SA6_VAL13_ECH 0x39
+#define R_SA6_VAL23_EC 0x3A
+#define R_SA6_VAL23_ECL 0x3A
+#define R_SA6_VAL23_ECH 0x3B
#define A_ST_B1_RX 0x3C
#define A_ST_B2_RX 0x3D
#define A_ST_D_RX 0x3E
@@ -624,7 +628,7 @@ struct hfc_multi {
#define V_RX_INV_CLK 0x20
#define V_RX_INV_DATA 0x40
#define V_AIS_ITU 0x80
-/* R_RX_FR0 */
+/* R_RX_SL0_CFG0 */
#define V_NO_INSYNC 0x01
#define V_AUTO_RESYNC 0x02
#define V_AUTO_RECO 0x04
@@ -633,7 +637,7 @@ struct hfc_multi {
#define V_XCRC_SYNC 0x20
#define V_MF_RESYNC 0x40
#define V_RESYNC 0x80
-/* R_RX_FR1 */
+/* R_RX_SL0_CFG1 */
#define V_RX_MF 0x01
#define V_RX_MF_SYNC 0x02
#define V_RX_SL0_RAM 0x04
@@ -654,17 +658,17 @@ struct hfc_multi {
#define V_ATX 0x20
#define V_NTRI 0x40
#define V_AUTO_ERR_RES 0x80
-/* R_TX_FR0 */
+/* R_TX_SL0_CFG0 */
#define V_TRP_FAS 0x01
#define V_TRP_NFAS 0x02
#define V_TRP_RAL 0x04
#define V_TRP_SA 0x08
-/* R_TX_FR1 */
+/* R_TX_SL0 */
#define V_TX_FAS 0x01
#define V_TX_NFAS 0x02
#define V_TX_RAL 0x04
#define V_TX_SA 0x08
-/* R_TX_FR2 */
+/* R_TX_SL0_CFG1 */
#define V_TX_MF 0x01
#define V_TRP_SL0 0x02
#define V_TX_SL0_RAM 0x04
@@ -672,7 +676,7 @@ struct hfc_multi {
#define V_NEG_E 0x20
#define V_XS12_ON 0x40
#define V_XS15_ON 0x80
-/* R_RX_OFF */
+/* R_RX_OFFS */
#define V_RX_SZ 0x01
#define V_RX_INIT 0x04
/* R_SYNC_OUT */
@@ -680,7 +684,7 @@ struct hfc_multi {
#define V_IPATS0 0x20
#define V_IPATS1 0x40
#define V_IPATS2 0x80
-/* R_TX_OFF */
+/* R_TX_OFFS */
#define V_TX_SZ 0x01
#define V_TX_INIT 0x04
/* R_SYNC_CTRL */
@@ -1119,20 +1123,20 @@ struct hfc_register_names {
{"R_LOS0", 0x22},
{"R_LOS1", 0x23},
{"R_RX0", 0x24},
- {"R_RX_FR0", 0x25},
- {"R_RX_FR1", 0x26},
+ {"R_RX_SL0_CFG0", 0x25},
+ {"R_RX_SL0_CFG1", 0x26},
{"R_TX0", 0x28},
{"R_TX1", 0x29},
- {"R_TX_FR0", 0x2C},
- {"R_TX_FR1", 0x2D},
- {"R_TX_FR2", 0x2E},
+ {"R_TX_SL0_CFG0", 0x2C},
+ {"R_TX_SL0", 0x2D},
+ {"R_TX_SL0_CFG1", 0x2E},
{"R_JATT_ATT", 0x2F},
- {"A_ST_xx_STA/R_RX_OFF", 0x30},
+ {"A_ST_xx_STA/R_RX_OFFS", 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_TX_OFFS", 0x34},
{"R_SYNC_CTRL", 0x35},
{"A_ST_CLK_DLY", 0x37},
{"R_PWM0", 0x38},
@@ -1194,8 +1198,9 @@ struct hfc_register_names {
{"R_RX_SL0_0", 0x25},
{"R_RX_SL0_1", 0x26},
{"R_RX_SL0_2", 0x27},
- {"R_JATT_DIR", 0x2b},
+ {"R_JATT_STA", 0x2b},
{"R_SLIP", 0x2c},
+ {"R_JATT_CFG", 0x2f},
{"A_ST_RD_STA", 0x30},
{"R_FAS_ECL", 0x30},
{"R_FAS_ECH", 0x31},
@@ -1205,10 +1210,10 @@ struct hfc_register_names {
{"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},
+ {"R_SA6_VAL13_ECL", 0x38},
+ {"R_SA6_VAL13_ECH", 0x39},
+ {"R_SA6_VAL23_ECL", 0x3A},
+ {"R_SA6_VAL23_ECH", 0x3B},
{"A_ST_B1_RX", 0x3C},
{"A_ST_B2_RX", 0x3D},
{"A_ST_D_RX", 0x3E},
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index 4301331..06be60c 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -64,7 +64,7 @@
*
* HFC-E1 only bits:
* Bit 0 = 0x0001 = interface: 0=copper, 1=optical
- * Bit 1 = 0x0002 = reserved (later for 32 B-channels transparent mode)
+ * Bit 1 = 0x0002 = 32 B-channels bundle mode (one channel)
* Bit 2 = 0x0004 = Report LOS
* Bit 3 = 0x0008 = Report AIS
* Bit 4 = 0x0010 = Report SLIP
@@ -1269,11 +1269,10 @@ init_chip(struct hfc_multi *hc)
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) {
+ } 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__);
+ __func__);
hc->hw.r_pcm_md0 |= V_PCM_MD;
} else {
if (debug & DEBUG_HFCMULTI_INIT)
@@ -1288,7 +1287,18 @@ init_chip(struct hfc_multi *hc)
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 (test_bit(HFC_CHIP_2MBITRAW, &hc->chip) &&
+ (hc->ctype == HFC_TYPE_E1)) {
+ if (debug & DEBUG_HFCMULTI_INIT)
+ printk(KERN_DEBUG "%s: setting 2MBit raw mode\n",
+ __func__);
+ HFC_outb(hc, R_FIFO_MD, 0x0c);
+ hc->Flen = 0x10;
+ hc->Zmin = 0x80;
+ hc->Zlen = 384;
+
+ } else
+ 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
@@ -1334,7 +1344,8 @@ init_chip(struct hfc_multi *hc)
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))
+ if (test_bit(HFC_CHIP_PLXSD, &hc->chip) ||
+ test_bit(HFC_CHIP_PCM_MASTER, &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 */
@@ -1956,7 +1967,10 @@ hfcmulti_tx(struct hfc_multi *hc, int ch)
int *idxp;
bch = hc->chan[ch].bch;
- dch = hc->chan[ch].dch;
+ if (!bch)
+ dch = hc->chan[ch].dch;
+ else
+ dch = NULL;
if ((!dch) && (!bch))
return;
@@ -2205,7 +2219,11 @@ hfcmulti_rx(struct hfc_multi *hc, int ch)
int maxlen;
bch = hc->chan[ch].bch;
- dch = hc->chan[ch].dch;
+ if (!bch)
+ dch = hc->chan[ch].dch;
+ else
+ dch = NULL;
+
if ((!dch) && (!bch))
return;
if (dch) {
@@ -2264,20 +2282,20 @@ next_frame:
if (Zsize <= 0)
return;
- if (*sp == NULL) {
- *sp = mI_alloc_skb(maxlen + 3, GFP_ATOMIC);
- if (*sp == NULL) {
- printk(KERN_DEBUG "%s: No mem for rx_skb\n",
- __func__);
- 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 (*sp == NULL) {
+ *sp = mI_alloc_skb(maxlen + 3, GFP_ATOMIC);
+ if (*sp == NULL) {
+ printk(KERN_DEBUG "%s: No mem for rx_skb\n",
+ __func__);
+ return;
+ }
+ }
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) "
@@ -2355,24 +2373,18 @@ next_frame:
/* there is an incomplete frame */
} else {
/* transparent */
+ if (*sp == NULL) {
+ *sp = mI_alloc_skb(Zsize, GFP_ATOMIC);
+ if (*sp == NULL) {
+ printk(KERN_DEBUG "%s: No mem for rx_skb\n",
+ __func__);
+ return;
+ }
+ }
if (Zsize > skb_tailroom(*sp))
Zsize = skb_tailroom(*sp);
hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize);
- if (((*sp)->len) < MISDN_COPY_SIZE) {
- skb = *sp;
- *sp = mI_alloc_skb(skb->len, GFP_ATOMIC);
- if (*sp) {
- memcpy(skb_put(*sp, skb->len),
- skb->data, skb->len);
- skb_trim(skb, 0);
- } else {
- printk(KERN_DEBUG "%s: No mem\n", __func__);
- *sp = skb;
- skb = NULL;
- }
- } else {
- skb = NULL;
- }
+ skb = NULL;
if (debug & DEBUG_HFCMULTI_FIFO)
printk(KERN_DEBUG
"%s(card %d): fifo(%d) reading %d bytes "
@@ -2409,7 +2421,7 @@ signal_state_up(struct dchannel *dch, int info, char *msg)
static inline void
handle_timer_irq(struct hfc_multi *hc)
{
- int ch, temp;
+ int ch, temp, ch_activ = 0;
struct dchannel *dch;
u_long flags;
@@ -2443,10 +2455,33 @@ handle_timer_irq(struct hfc_multi *hc)
hc->e1_resync = 0;
spin_unlock_irqrestore(&HFClock, flags);
}
-
- if (hc->ctype != HFC_TYPE_E1 || hc->e1_state == 1)
+ if (test_bit(HFC_CHIP_2MBITRAW, &hc->chip)) {
+ ch = 0;
+ if (hc->created[hc->chan[ch].port] && hc->chan[ch].bch &&
+ test_bit(FLG_ACTIVE, &hc->chan[ch].bch->Flags)) {
+ ch_activ++;
+ hfcmulti_tx(hc, ch);
+ 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);
+ }
+ }
+ }
+ } else if (hc->ctype != HFC_TYPE_E1 || hc->e1_state == 1) {
for (ch = 0; ch <= 31; ch++) {
if (hc->created[hc->chan[ch].port]) {
+ ch_activ++;
hfcmulti_tx(hc, ch);
/* fifo is started when switching to rx-fifo */
hfcmulti_rx(hc, ch);
@@ -2467,6 +2502,11 @@ handle_timer_irq(struct hfc_multi *hc)
}
}
}
+ }
+ if (debug & DEBUG_HFCMULTI_TIMER)
+ printk(KERN_DEBUG "Timer IRQ id%dp%d st%d activ %d\n",
+ hc->id, hc->ports, hc->e1_state, ch_activ);
+
if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) {
dch = hc->chan[hc->dnum[0]].dch;
/* LOS */
@@ -2515,7 +2555,7 @@ handle_timer_irq(struct hfc_multi *hc)
"RDI gone");
hc->chan[hc->dnum[0]].rdi = temp;
}
- temp = HFC_inb_nodebug(hc, R_JATT_DIR);
+ temp = HFC_inb_nodebug(hc, R_JATT_STA);
switch (hc->chan[hc->dnum[0]].sync) {
case 0:
if ((temp & 0x60) == 0x60) {
@@ -2524,9 +2564,9 @@ handle_timer_irq(struct hfc_multi *hc)
"%s: (id=%d) E1 now "
"in clock sync\n",
__func__, hc->id);
- HFC_outb(hc, R_RX_OFF,
+ HFC_outb(hc, R_RX_OFFS,
hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
- HFC_outb(hc, R_TX_OFF,
+ HFC_outb(hc, R_TX_OFFS,
hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
hc->chan[hc->dnum[0]].sync = 1;
goto check_framesync;
@@ -2660,6 +2700,8 @@ fifo_irq(struct hfc_multi *hc, int block)
r_irq_fifo_bl = HFC_inb_nodebug(hc, R_IRQ_FIFO_BL0 + block);
j = 0;
+ printk(KERN_DEBUG "%s: block %d fifo_bl %02x\n", __func__,
+ block, r_irq_fifo_bl);
while (j < 8) {
ch = (block << 2) + (j >> 1);
dch = hc->chan[ch].dch;
@@ -2870,6 +2912,52 @@ hfcmulti_dbusy_timer(struct hfc_multi *hc)
{
}
+/* special mode to transmit/revceive full frame (all timeslots) in fifo 0 */
+
+static int set_2MBit_mode(struct hfc_multi *hc, int prot)
+{
+ u8 ch, lim;
+
+ for (ch = 0; ch < 64; ch++) {
+ /* Reset all fifo */
+ HFC_outb(hc, R_FIFO, ch);
+ HFC_wait(hc);
+ HFC_outb(hc, R_INC_RES_FIFO, 6);
+ }
+
+ HFC_outb(hc, R_FIRST_FIFO, 0x0);
+ lim = 63;
+ for (ch = 0; ch < 64; ch++) {
+ HFC_outb(hc, R_FSM_IDX, ch);
+ HFC_wait(hc);
+ HFC_outb(hc, A_CHANNEL, ch);
+ HFC_outb(hc, A_FIFO_SEQ, (ch + 1) % 2);
+ if (prot == ISDN_P_B_HDLC)
+ HFC_outb(hc, A_CON_HDLC, 0x4);
+ else
+ HFC_outb(hc, A_CON_HDLC, 0x6);
+ HFC_outb(hc, A_SUBCH_CFG, 0);
+ if (ch == lim)
+ break;
+ }
+ HFC_outb(hc, A_FIFO_SEQ, 0x40);
+
+ for (ch = 0; ch < 64; ch++) {
+ u8 ach, asc, ac, afs, ais, af1, af2;
+ HFC_outb(hc, R_FIFO, ch);
+ HFC_wait(hc);
+ ach = HFC_inb(hc, A_CON_HDLC);
+ asc = HFC_inb(hc, A_SUBCH_CFG);
+ ac = HFC_inb(hc, A_CHANNEL);
+ afs = HFC_inb(hc, A_FIFO_SEQ);
+ ais = HFC_inb(hc, A_IRQ_MSK);
+ af1 = HFC_inb(hc, A_F1);
+ af2 = HFC_inb(hc, A_F2);
+ printk(KERN_DEBUG "R_FIFO %02d: %02x/%02x/%02x/%02x/%02x %d/%d\n",
+ ch, ach, asc, ac, afs, ais, af1, af2);
+ }
+ return 0;
+}
/*
* activate/deactivate hardware for selected channels and mode
@@ -3514,12 +3602,24 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
/* 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 (test_bit(HFC_CHIP_2MBITRAW, &hc->chip)) {
+ ret = set_2MBit_mode(hc, ch->protocol);
+ /* The default content for these registers can
+ * be changed via a MISDN_CTRL_L1_TS0_MODE ctrl
+ * request
+ */
+ HFC_outb(hc, R_RX_SL0_CFG0,
+ hc->hw.r_rx_sl0_cfg0);
+ HFC_outb(hc, R_TX_SL0_CFG1,
+ hc->hw.r_tx_sl0_cfg1);
+ } else {
+ 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)) {
@@ -3591,11 +3691,13 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
int slot_rx;
int bank_rx;
int num;
+ u8 v1, v2;
switch (cq->op) {
case MISDN_CTRL_GETOP:
- cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP
- | MISDN_CTRL_RX_OFF | MISDN_CTRL_FILL_EMPTY;
+ cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP |
+ MISDN_CTRL_RX_OFF | MISDN_CTRL_FILL_EMPTY |
+ MISDN_CTRL_L1_TESTS;
break;
case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */
hc->chan[bch->slot].rx_off = !!cq->p1;
@@ -3702,6 +3804,38 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
else
ret = -EINVAL;
break;
+ case MISDN_CTRL_L1_TS0_MODE:
+ if (hc->ctype == HFC_TYPE_E1) {
+ v1 = hc->hw.r_rx_sl0_cfg0;
+ v2 = hc->hw.r_tx_sl0_cfg1;
+ if (cq->p1 > -1) {
+ hc->hw.r_rx_sl0_cfg0 = cq->p1 & 0xff;
+ HFC_outb(hc, R_RX_SL0_CFG0, cq->p1 & 0xff);
+ printk(KERN_DEBUG "RX_SL0_CFG0 = %x\n", cq->p1);
+ } else
+ printk(KERN_DEBUG "RX_SL0_CFG0 not modified\n");
+ if (cq->p2 > -1) {
+ hc->hw.r_tx_sl0_cfg1 = cq->p2 & 0xff;
+ HFC_outb(hc, R_TX_SL0_CFG1, cq->p2 & 0xff);
+ printk(KERN_DEBUG "TX_SL0_CFG1 = %x\n", cq->p2);
+ } else
+ printk(KERN_DEBUG "TX_SL0_CFG1 not modified\n");
+ cq->p1 = v1;
+ cq->p2 = v2;
+ } else {
+ printk(KERN_DEBUG "Not E1\n");
+ ret = -EINVAL;
+ }
+ break;
+ case MISDN_CTRL_L1_GET_SYNC_INFO:
+ cq->p1 = HFC_inb(hc, R_E1_RD_STA);
+ cq->p1 |= (HFC_inb(hc, R_SYNC_STA) << 8);
+ cq->p2 = HFC_inb(hc, R_RX_SL0_0);
+ cq->p2 |= (HFC_inb(hc, R_RX_SL0_1) << 8);
+ cq->p2 |= (HFC_inb(hc, R_RX_SL0_2) << 16);
+ cq->p3 = HFC_inb(hc, R_JATT_STA);
+ cq->p3 |= (HFC_inb(hc, R_SLIP) << 8);
+ break;
default:
printk(KERN_WARNING "%s: unknown Op %x\n",
__func__, cq->op);
@@ -3776,6 +3910,12 @@ ph_state_change(struct dchannel *dch)
}
switch (dch->state) {
case (1):
+ if (test_bit(HFC_CHIP_2MBITRAW, &hc->chip)) {
+ if (debug & DEBUG_HFCMULTI_STATE)
+ printk(KERN_DEBUG
+ "2 MBIT Raw state 1 reached\n");
+ break;
+ }
if (hc->e1_state != 1) {
for (i = 1; i <= 31; i++) {
/* reset fifos on e1 activation */
@@ -3874,6 +4014,113 @@ ph_state_change(struct dchannel *dch)
}
}
+int init_2MBit_mode(struct hfc_multi *hc, int nr)
+{
+ u_char r_e1_wr_sta;
+ int pt;
+
+ if (debug & DEBUG_HFCMULTI_INIT)
+ printk(KERN_DEBUG "%s: ch%d entered\n", __func__, nr);
+
+ if (nr != 0) {
+ printk(KERN_ERR "Only ch0 supports 2MBit card%d\n", hc->id);
+ return -EINVAL;
+ }
+
+ pt = hc->chan[nr].port;
+ if (pt != 0) {
+ printk(KERN_ERR "Only port 0 in 2MBit mode %d\n", hc->id);
+ return -EINVAL;
+ }
+
+ hc->chan[nr].slot_tx = -1;
+ hc->chan[nr].slot_rx = -1;
+ hc->chan[nr].conf = -1;
+ mode_hfcmulti(hc, nr, ISDN_P_NONE, -1, 0, -1, 0);
+
+ if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[nr].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[nr].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_SL0_CFG0, 0x00);
+ HFC_outb(hc, R_TX_SL0, 0xf8);
+
+ HFC_outb(hc, R_TX_SL0_CFG1, V_TX_MF | V_TX_E | V_NEG_E);
+ /* set transparent SL0 is set on ACTIVATE */
+ hc->hw.r_tx_sl0_cfg1 = V_TX_MF | V_TRP_SL0;
+
+ HFC_outb(hc, R_RX_SL0_CFG0, V_AUTO_RESYNC | V_AUTO_RECO | 0);
+
+ hc->hw.r_rx_sl0_cfg0 = 0x1;
+
+ if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg))
+ HFC_outb(hc, R_RX_SL0_CFG1, V_RX_MF | V_RX_MF_SYNC);
+
+ /* Default TE mode and clock from interface */
+ r_e1_wr_sta = 1;
+ 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, 0);
+ } 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_CFG, 0x9c);
+ 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(10); /* wait at least 5,21us */
+ if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
+ hc->syncronized = 0;
+ plxsd_checksync(hc, 0);
+ }
+ if (debug & DEBUG_HFCMULTI_INIT)
+ printk("%s: done\n", __func__);
+ return 0;
+}
+
/*
* called for card mode init message
*/
@@ -3928,16 +4175,19 @@ hfcmulti_initmode(struct dchannel *dch)
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);
+ HFC_outb(hc, R_TX_SL0_CFG0, 0x00);
+ HFC_outb(hc, R_TX_SL0, 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);
+ if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg)) {
+ hc->hw.r_tx_sl0_cfg1 = V_TX_MF | V_TX_E | V_NEG_E;
+ HFC_outb(hc, R_TX_SL0_CFG1, hc->hw.r_tx_sl0_cfg1);
+ }
- HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0);
+ hc->hw.r_rx_sl0_cfg0 = V_AUTO_RESYNC | V_AUTO_RECO;
+ HFC_outb(hc, R_RX_SL0_CFG0, hc->hw.r_rx_sl0_cfg0);
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);
+ HFC_outb(hc, R_RX_SL0_CFG1, V_RX_MF | V_RX_MF_SYNC);
if (dch->dev.D.protocol == ISDN_P_NT_E1) {
if (debug & DEBUG_HFCMULTI_INIT)
@@ -3987,7 +4237,7 @@ hfcmulti_initmode(struct dchannel *dch)
HFC_outb(hc, R_SYNC_OUT, 0);
}
}
- HFC_outb(hc, R_JATT_ATT, 0x9c); /* undoc register */
+ HFC_outb(hc, R_JATT_CFG, 0x9c); /* undoc register */
HFC_outb(hc, R_PWM_MD, V_PWM0_MD);
HFC_outb(hc, R_PWM0, 0x50);
HFC_outb(hc, R_PWM1, 0xff);
@@ -4086,6 +4336,9 @@ open_dchannel(struct hfc_multi *hc, struct dchannel *dch,
if (debug & DEBUG_HW_OPEN)
printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,
dch->dev.id, __builtin_return_address(0));
+ if (test_bit(HFC_CHIP_2MBITRAW, &hc->chip) &&
+ (hc->ctype == HFC_TYPE_E1)) /* No Dchannel in this mode */
+ return -EINVAL;
if (rq->protocol == ISDN_P_NONE)
return -EINVAL;
if ((dch->dev.D.protocol != ISDN_P_NONE) &&
@@ -4122,15 +4375,20 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
struct channel_req *rq)
{
struct bchannel *bch;
- int ch;
+ int ret, 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)
+ if (hc->ctype == HFC_TYPE_E1) {
ch = rq->adr.channel;
- else
+ if (test_bit(HFC_CHIP_2MBITRAW, &hc->chip)) {
+ ret = init_2MBit_mode(hc, ch);
+ if (ret)
+ return ret;
+ }
+ } else
ch = (rq->adr.channel - 1) + (dch->slot - 2);
bch = hc->chan[ch].bch;
if (!bch) {
@@ -4141,6 +4399,7 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
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;
hc->chan[ch].rx_off = 0;
rq->ch = &bch->ch;
@@ -4158,10 +4417,11 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
struct hfc_multi *hc = dch->hw;
int ret = 0;
int wd_mode, wd_cnt;
+ u_char reg, reg1;
switch (cq->op) {
case MISDN_CTRL_GETOP:
- cq->op = MISDN_CTRL_HFC_OP;
+ cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_L1_TESTS;
break;
case MISDN_CTRL_HFC_WD_INIT: /* init the watchdog */
wd_cnt = cq->p1 & 0xf;
@@ -4191,6 +4451,42 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
__func__);
HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);
break;
+ case MISDN_CTRL_L1_STATE_TEST:
+ if (hc->ctype == HFC_TYPE_E1) {
+ /* undocumented: status changes during read */
+ reg = HFC_inb_nodebug(hc, R_E1_RD_STA);
+ while (reg != (reg1 =
+ HFC_inb_nodebug(hc, R_E1_RD_STA))) {
+ if (debug & DEBUG_HFCMULTI_STATE)
+ printk(KERN_DEBUG
+ "%s: reread STATE because %d!=%d\n",
+ __func__, reg, reg1);
+ reg = reg1; /* repeat */
+ }
+ printk(KERN_DEBUG "Old L1 state %02x\n", reg);
+ reg &= 0x07;
+ if (cq->p1 < 0 || cq->p1 > 6) /* reset auto mode */
+ HFC_outb(hc, R_E1_WR_STA, reg);
+ else {/* force new state state */
+ reg = cq->p1 & 0x07;
+ HFC_outb(hc, R_E1_WR_STA, reg | V_E1_LD_STA);
+ printk(KERN_DEBUG "New L1 state %02x\n", reg);
+ }
+ } else
+ ret = -EINVAL;
+ break;
+ case MISDN_CTRL_L1_AIS_TEST:
+ if (hc->ctype == HFC_TYPE_E1) {
+ printk(KERN_DEBUG "Old AIS state %02x\n", hc->hw.r_tx1);
+ if (cq->p1)
+ hc->hw.r_tx1 |= V_AIS_OUT;
+ else
+ hc->hw.r_tx1 &= ~V_AIS_OUT;
+ HFC_outb(hc, R_TX1, hc->hw.r_tx1);
+ printk(KERN_DEBUG "New AIS state %02x\n", hc->hw.r_tx1);
+ } else
+ ret = -EINVAL;
+ break;
default:
printk(KERN_WARNING "%s: unknown Op %x\n",
__func__, cq->op);
@@ -4843,7 +5139,18 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt)
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);
+ if (port[Port_cnt] & 0x0002) {
+ if (debug & DEBUG_HFCMULTI_INIT)
+ printk(KERN_DEBUG
+ "%s: PORT 2MBit raw mode E1: card(%d) port(%d)\n",
+ __func__, HFC_cnt + 1, 1);
+ test_and_set_bit(HFC_CHIP_2MBITRAW, &hc->chip);
+ dch->dev.Dprotocols = (1 << ISDN_P_NONE);
+ hc->dnum[pt] = 0;
+ hc->bmask[pt] = 1;
+ } else
+ 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;
@@ -4852,8 +5159,9 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m, int 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 */
+ for (ch = 0; ch <= 31; ch++) {
+ /* skip unused channel */
+ if (!((1 << ch) & hc->bmask[pt]))
continue;
bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
if (!bch) {
diff --git a/include/linux/mISDNif.h b/include/linux/mISDNif.h
index f474f40..850fe1f 100644
--- a/include/linux/mISDNif.h
+++ b/include/linux/mISDNif.h
@@ -37,7 +37,7 @@
*/
#define MISDN_MAJOR_VERSION 1
#define MISDN_MINOR_VERSION 1
-#define MISDN_RELEASE 28
+#define MISDN_RELEASE 29
/* primitives for information exchange
* generell format
@@ -363,31 +363,36 @@ clear_channelmap(u_int nr, u_char *map)
}
/* 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_GET_PCM_SLOTS 0x0010
-#define MISDN_CTRL_SET_PCM_SLOTS 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
+#define MISDN_CTRL_GETOP 0x00000000
+#define MISDN_CTRL_LOOP 0x00000001
+#define MISDN_CTRL_CONNECT 0x00000002
+#define MISDN_CTRL_DISCONNECT 0x00000004
+#define MISDN_CTRL_GET_PCM_SLOTS 0x00000010
+#define MISDN_CTRL_SET_PCM_SLOTS 0x00000020
+#define MISDN_CTRL_SETPEER 0x00000040
+#define MISDN_CTRL_UNSETPEER 0x00000080
+#define MISDN_CTRL_RX_OFF 0x00000100
+#define MISDN_CTRL_FILL_EMPTY 0x00000200
+#define MISDN_CTRL_GETPEER 0x00000400
+#define MISDN_CTRL_L1_TIMER3 0x00000800
+#define MISDN_CTRL_HW_FEATURES_OP 0x00002000
+#define MISDN_CTRL_HW_FEATURES 0x00002001
+#define MISDN_CTRL_HFC_OP 0x00004000
+#define MISDN_CTRL_HFC_PCM_CONN 0x00004001
+#define MISDN_CTRL_HFC_PCM_DISC 0x00004002
+#define MISDN_CTRL_HFC_CONF_JOIN 0x00004003
+#define MISDN_CTRL_HFC_CONF_SPLIT 0x00004004
+#define MISDN_CTRL_HFC_RECEIVE_OFF 0x00004005
+#define MISDN_CTRL_HFC_RECEIVE_ON 0x00004006
+#define MISDN_CTRL_HFC_ECHOCAN_ON 0x00004007
+#define MISDN_CTRL_HFC_ECHOCAN_OFF 0x00004008
+#define MISDN_CTRL_HFC_WD_INIT 0x00004009
+#define MISDN_CTRL_HFC_WD_RESET 0x0000400A
+#define MISDN_CTRL_L1_TESTS 0x00010000
+#define MISDN_CTRL_L1_STATE_TEST 0x00010001
+#define MISDN_CTRL_L1_AIS_TEST 0x00010002
+#define MISDN_CTRL_L1_TS0_MODE 0x00010003
+#define MISDN_CTRL_L1_GET_SYNC_INFO 0x00010004
/* special PCM slot numbers */
#define MISDN_PCM_SLOT_DISABLE -1 /* PCM disabled */
--
1.7.3.4
^ permalink raw reply related
* [PATCH 7/8] mISDN: Help to identify the card
From: Karsten Keil @ 2012-04-28 11:43 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Karsten Keil
In-Reply-To: <1335613404-10187-1-git-send-email-kkeil@linux-pingi.de>
From: Karsten Keil <isdn@linux-pingi.de>
With multiple cards is hard to figure out which port caused trouble
int the layer2 routines (e.g. got a timeout).
Now we have the informations in the log output.
Signed-off-by: Karsten Keil <kkeil@linux-pingi.de>
---
drivers/isdn/mISDN/core.c | 16 +++++++++
drivers/isdn/mISDN/layer2.c | 75 ++++++++++++++++++++++++------------------
include/linux/mISDNif.h | 3 +-
3 files changed, 61 insertions(+), 33 deletions(-)
diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c
index a24530f..c401634 100644
--- a/drivers/isdn/mISDN/core.c
+++ b/drivers/isdn/mISDN/core.c
@@ -355,6 +355,22 @@ mISDN_unregister_Bprotocol(struct Bprotocol *bp)
}
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)
{
diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c
index d421495..2829d93 100644
--- a/drivers/isdn/mISDN/layer2.c
+++ b/drivers/isdn/mISDN/layer2.c
@@ -110,8 +110,8 @@ l2m_debug(struct FsmInst *fi, char *fmt, ...)
vaf.fmt = fmt;
vaf.va = &va;
- printk(KERN_DEBUG "l2 (sapi %d tei %d): %pV\n",
- l2->sapi, l2->tei, &vaf);
+ printk(KERN_DEBUG "%s l2 (sapi %d tei %d): %pV\n",
+ mISDNDevName4ch(&l2->ch), l2->sapi, l2->tei, &vaf);
va_end(va);
}
@@ -154,7 +154,8 @@ l2up(struct layer2 *l2, u_int prim, struct sk_buff *skb)
mISDN_HEAD_ID(skb) = (l2->ch.nr << 16) | l2->ch.addr;
err = l2->up->send(l2->up, skb);
if (err) {
- printk(KERN_WARNING "%s: err=%d\n", __func__, err);
+ printk(KERN_WARNING "%s: dev %s err=%d\n", __func__,
+ mISDNDevName4ch(&l2->ch), err);
dev_kfree_skb(skb);
}
}
@@ -178,7 +179,8 @@ l2up_create(struct layer2 *l2, u_int prim, int len, void *arg)
memcpy(skb_put(skb, len), arg, len);
err = l2->up->send(l2->up, skb);
if (err) {
- printk(KERN_WARNING "%s: err=%d\n", __func__, err);
+ printk(KERN_WARNING "%s: dev %s err=%d\n", __func__,
+ mISDNDevName4ch(&l2->ch), err);
dev_kfree_skb(skb);
}
}
@@ -189,7 +191,8 @@ l2down_skb(struct layer2 *l2, struct sk_buff *skb) {
ret = l2->ch.recv(l2->ch.peer, skb);
if (ret && (*debug & DEBUG_L2_RECV))
- printk(KERN_DEBUG "l2down_skb: ret(%d)\n", ret);
+ printk(KERN_DEBUG "l2down_skb: dev %s ret(%d)\n",
+ mISDNDevName4ch(&l2->ch), ret);
return ret;
}
@@ -289,18 +292,18 @@ l2_timeout(struct FsmInst *fi, int event, void *arg)
skb = mI_alloc_skb(0, GFP_ATOMIC);
if (!skb) {
- printk(KERN_WARNING "L2(%d,%d) nr:%x timer %s lost - no skb\n",
- l2->sapi, l2->tei, l2->ch.nr, event == EV_L2_T200 ?
- "T200" : "T203");
+ 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 "L2(%d,%d) nr:%x timer %s expired\n",
- l2->sapi, l2->tei, l2->ch.nr, event == EV_L2_T200 ?
- "T200" : "T203");
+ 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);
}
@@ -309,8 +312,8 @@ static int
l2mgr(struct layer2 *l2, u_int prim, void *arg) {
long c = (long)arg;
- printk(KERN_WARNING
- "l2mgr: addr:%x prim %x %c\n", l2->id, prim, (char)c);
+ 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) {
@@ -632,8 +635,8 @@ send_uframe(struct layer2 *l2, struct sk_buff *skb, u_char cmd, u_char cr)
else {
skb = mI_alloc_skb(i, GFP_ATOMIC);
if (!skb) {
- printk(KERN_WARNING "%s: can't alloc skbuff\n",
- __func__);
+ printk(KERN_WARNING "%s: can't alloc skbuff in %s\n",
+ mISDNDevName4ch(&l2->ch), __func__);
return;
}
}
@@ -1118,8 +1121,8 @@ enquiry_cr(struct layer2 *l2, u_char typ, u_char cr, u_char pf)
tmp[i++] = (l2->vr << 5) | typ | (pf ? 0x10 : 0);
skb = mI_alloc_skb(i, GFP_ATOMIC);
if (!skb) {
- printk(KERN_WARNING
- "isdnl2 can't alloc sbbuff for enquiry_cr\n");
+ printk(KERN_WARNING "%s: isdnl2 can't alloc sbbuff in %s\n",
+ mISDNDevName4ch(&l2->ch), __func__);
return;
}
memcpy(skb_put(skb, i), tmp, i);
@@ -1179,7 +1182,7 @@ invoke_retransmission(struct layer2 *l2, unsigned int nr)
else
printk(KERN_WARNING
"%s: windowar[%d] is NULL\n",
- __func__, p1);
+ mISDNDevName4ch(&l2->ch), p1);
l2->windowar[p1] = NULL;
}
mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);
@@ -1490,8 +1493,8 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
p1 = (l2->vs - l2->va) % 8;
p1 = (p1 + l2->sow) % l2->window;
if (l2->windowar[p1]) {
- printk(KERN_WARNING "isdnl2 try overwrite ack queue entry %d\n",
- 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;
@@ -1511,12 +1514,14 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
memcpy(skb_push(nskb, i), header, i);
else {
printk(KERN_WARNING
- "isdnl2 pull_iqueue skb header(%d/%d) too short\n", i, p1);
+ "%s: L2 pull_iqueue skb header(%d/%d) too short\n",
+ mISDNDevName4ch(&l2->ch), i, p1);
oskb = nskb;
nskb = mI_alloc_skb(oskb->len + i, GFP_ATOMIC);
if (!nskb) {
dev_kfree_skb(oskb);
- printk(KERN_WARNING "%s: no skb mem\n", __func__);
+ printk(KERN_WARNING "%s: no skb mem in %s\n",
+ mISDNDevName4ch(&l2->ch), __func__);
return;
}
memcpy(skb_put(nskb, i), header, i);
@@ -1892,7 +1897,8 @@ ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
ptei = *datap++;
if ((psapi & 1) || !(ptei & 1)) {
printk(KERN_WARNING
- "l2 D-channel frame wrong EA0/EA1\n");
+ "%s l2 D-channel frame wrong EA0/EA1\n",
+ mISDNDevName4ch(&l2->ch));
return ret;
}
psapi >>= 2;
@@ -1901,7 +1907,7 @@ ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
/* not our business */
if (*debug & DEBUG_L2)
printk(KERN_DEBUG "%s: sapi %d/%d mismatch\n",
- __func__, psapi, l2->sapi);
+ mISDNDevName4ch(&l2->ch), psapi, l2->sapi);
dev_kfree_skb(skb);
return 0;
}
@@ -1909,7 +1915,7 @@ ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
/* not our business */
if (*debug & DEBUG_L2)
printk(KERN_DEBUG "%s: tei %d/%d mismatch\n",
- __func__, ptei, l2->tei);
+ mISDNDevName4ch(&l2->ch), ptei, l2->tei);
dev_kfree_skb(skb);
return 0;
}
@@ -1950,7 +1956,8 @@ ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
} else
c = 'L';
if (c) {
- printk(KERN_WARNING "l2 D-channel frame error %c\n", 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;
@@ -1964,15 +1971,16 @@ l2_send(struct mISDNchannel *ch, struct sk_buff *skb)
int ret = -EINVAL;
if (*debug & DEBUG_L2_RECV)
- printk(KERN_DEBUG "%s: prim(%x) id(%x) sapi(%d) tei(%d)\n",
- __func__, hh->prim, hh->id, l2->sapi, l2->tei);
+ 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",
- __func__, hh->prim, hh->id);
+ mISDNDevName4ch(&l2->ch), hh->prim, hh->id);
}
switch (hh->prim) {
case PH_DATA_IND:
@@ -2053,7 +2061,8 @@ 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)\n", __func__, cmd);
+ 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);
@@ -2066,7 +2075,8 @@ tei_l2(struct layer2 *l2, u_int cmd, u_long arg)
break;
case (MDL_ERROR_RSP):
/* ETS 300-125 5.3.2.1 Test: TC13010 */
- printk(KERN_NOTICE "MDL_ERROR|REQ (tei_l2)\n");
+ printk(KERN_NOTICE "%s: MDL_ERROR|REQ (tei_l2)\n",
+ mISDNDevName4ch(&l2->ch));
ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, NULL);
break;
}
@@ -2098,7 +2108,8 @@ l2_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
u_int info;
if (*debug & DEBUG_L2_CTRL)
- printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);
+ printk(KERN_DEBUG "%s: %s cmd(%x)\n",
+ mISDNDevName4ch(ch), __func__, cmd);
switch (cmd) {
case OPEN_CHANNEL:
diff --git a/include/linux/mISDNif.h b/include/linux/mISDNif.h
index 322d316..f474f40 100644
--- a/include/linux/mISDNif.h
+++ b/include/linux/mISDNif.h
@@ -37,7 +37,7 @@
*/
#define MISDN_MAJOR_VERSION 1
#define MISDN_MINOR_VERSION 1
-#define MISDN_RELEASE 27
+#define MISDN_RELEASE 28
/* primitives for information exchange
* generell format
@@ -598,6 +598,7 @@ static inline struct mISDNdevice *dev_to_mISDN(struct device *dev)
extern void set_channel_address(struct mISDNchannel *, u_int, u_int);
extern void mISDN_clock_update(struct mISDNclock *, int, struct timeval *);
extern unsigned short mISDN_clock_get(void);
+extern const char *mISDNDevName4ch(struct mISDNchannel *);
#endif /* __KERNEL__ */
#endif /* mISDNIF_H */
--
1.7.3.4
^ permalink raw reply related
* [PATCH 3/8] Sometimes the ISDN chip only controls the D-channel
From: Karsten Keil @ 2012-04-28 11:43 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <1335613404-10187-1-git-send-email-kkeil@linux-pingi.de>
The B-channels are only accessed via the PCM backplane.
Add infrastruckture for this special mode.
Signed-off-by: Karsten Keil <kkeil@linux-pingi.de>
---
drivers/isdn/mISDN/socket.c | 3 +++
include/linux/mISDNhw.h | 3 +++
include/linux/mISDNif.h | 13 +++++++++----
3 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index abe2d69..502bcf1 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -270,6 +270,7 @@ data_sock_release(struct socket *sock)
break;
case ISDN_P_LAPD_TE:
case ISDN_P_LAPD_NT:
+ case ISDN_P_B_PCM:
case ISDN_P_B_RAW:
case ISDN_P_B_HDLC:
case ISDN_P_B_X75SLP:
@@ -544,6 +545,7 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
err = create_l2entity(_pms(sk)->dev, &_pms(sk)->ch,
sk->sk_protocol, maddr);
break;
+ case ISDN_P_B_PCM:
case ISDN_P_B_RAW:
case ISDN_P_B_HDLC:
case ISDN_P_B_X75SLP:
@@ -800,6 +802,7 @@ mISDN_sock_create(struct net *net, struct socket *sock, int proto, int kern)
case ISDN_P_NT_E1:
case ISDN_P_LAPD_TE:
case ISDN_P_LAPD_NT:
+ case ISDN_P_B_PCM:
case ISDN_P_B_RAW:
case ISDN_P_B_HDLC:
case ISDN_P_B_X75SLP:
diff --git a/include/linux/mISDNhw.h b/include/linux/mISDNhw.h
index 4af8414..74d5734 100644
--- a/include/linux/mISDNhw.h
+++ b/include/linux/mISDNhw.h
@@ -5,6 +5,7 @@
* Basic declarations for the mISDN HW channels
*
* Copyright 2008 by Karsten Keil <kkeil@novell.com>
+ * Copyright 2009-2012 by Karsten Keil <kkeil@linux-pingi.de>
*
* 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
@@ -148,6 +149,8 @@ struct bchannel {
u_int state;
void *hw;
int slot; /* multiport card channel slot */
+ int pcm_tx; /* PCM tx slot nr */
+ int pcm_rx; /* PCM rx slot nr */
struct timer_list timer;
/* receive data */
struct sk_buff *rx_skb;
diff --git a/include/linux/mISDNif.h b/include/linux/mISDNif.h
index b5e7f22..bdda647 100644
--- a/include/linux/mISDNif.h
+++ b/include/linux/mISDNif.h
@@ -37,7 +37,7 @@
*/
#define MISDN_MAJOR_VERSION 1
#define MISDN_MINOR_VERSION 1
-#define MISDN_RELEASE 21
+#define MISDN_RELEASE 24
/* primitives for information exchange
* generell format
@@ -229,7 +229,7 @@
#define ISDN_P_B_MASK 0x1f
#define ISDN_P_B_START 0x20
-
+#define ISDN_P_B_PCM 0x20
#define ISDN_P_B_RAW 0x21
#define ISDN_P_B_HDLC 0x22
#define ISDN_P_B_X75SLP 0x23
@@ -360,8 +360,8 @@ clear_channelmap(u_int nr, u_char *map)
#define MISDN_CTRL_LOOP 0x0001
#define MISDN_CTRL_CONNECT 0x0002
#define MISDN_CTRL_DISCONNECT 0x0004
-#define MISDN_CTRL_PCMCONNECT 0x0010
-#define MISDN_CTRL_PCMDISCONNECT 0x0020
+#define MISDN_CTRL_GET_PCM_SLOTS 0x0010
+#define MISDN_CTRL_SET_PCM_SLOTS 0x0020
#define MISDN_CTRL_SETPEER 0x0040
#define MISDN_CTRL_UNSETPEER 0x0080
#define MISDN_CTRL_RX_OFF 0x0100
@@ -381,6 +381,10 @@ clear_channelmap(u_int nr, u_char *map)
#define MISDN_CTRL_HFC_WD_INIT 0x4009
#define MISDN_CTRL_HFC_WD_RESET 0x400A
+/* special PCM slot numbers */
+#define MISDN_PCM_SLOT_DISABLE -1 /* PCM disabled */
+#define MISDN_PCM_SLOT_IGNORE -2 /* PCM setting will be not changed */
+
/* socket options */
#define MISDN_TIME_STAMP 0x0001
@@ -389,6 +393,7 @@ struct mISDN_ctrl_req {
int channel;
int p1;
int p2;
+ int p3;
};
/* muxer options */
--
1.7.3.4
^ permalink raw reply related
* [PATCH 1/8] mISDN: Added PH_* state info to tei manager.
From: Karsten Keil @ 2012-04-28 11:43 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Andreas Eversberg
In-Reply-To: <1335613404-10187-1-git-send-email-kkeil@linux-pingi.de>
From: Andreas Eversberg <andreas@eversberg.eu>
Tei manager reports current layer 1 state on creation.
On state change it reports it to the socket interface.
Signed-off-by: Andreas Eversberg <andreas@eversberg.eu>
Signed-off-by: Karsten Keil <keil@b1-systems.de>
---
drivers/isdn/mISDN/tei.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
index ba2bc0c..969766f 100644
--- a/drivers/isdn/mISDN/tei.c
+++ b/drivers/isdn/mISDN/tei.c
@@ -1023,6 +1023,8 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
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);
@@ -1096,12 +1098,16 @@ mgr_send(struct mISDNchannel *ch, struct sk_buff *skb)
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;
--
1.7.3.4
^ permalink raw reply related
* [PATCH 6/8] mISDN: Layer1 statemachine fix
From: Karsten Keil @ 2012-04-28 11:43 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Karsten Keil
In-Reply-To: <1335613404-10187-1-git-send-email-kkeil@linux-pingi.de>
From: Karsten Keil <isdn@linux-pingi.de>
The timer3 and the activation delay timer need to be
independent.
Now layer1 pass TBR3 again.
Signed-off-by: Karsten Keil <kkeil@linux-pingi.de>
---
drivers/isdn/mISDN/layer1.c | 23 ++++++++++++++---------
1 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/drivers/isdn/mISDN/layer1.c b/drivers/isdn/mISDN/layer1.c
index ff05153..ee16e03 100644
--- a/drivers/isdn/mISDN/layer1.c
+++ b/drivers/isdn/mISDN/layer1.c
@@ -28,7 +28,8 @@ static u_int *debug;
struct layer1 {
u_long Flags;
struct FsmInst l1m;
- struct FsmTimer timer;
+ struct FsmTimer timer3;
+ struct FsmTimer timerX;
int delay;
int t3_value;
struct dchannel *dch;
@@ -135,7 +136,7 @@ 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->timer, 550, EV_TIMER_DEACT, NULL, 2);
+ mISDN_FsmRestartTimer(&l1->timerX, 550, EV_TIMER_DEACT, NULL, 2);
test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags);
}
@@ -180,11 +181,11 @@ l1_info4_ind(struct FsmInst *fi, int event, void *arg)
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->timer, 4);
+ 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->timer, 3);
- mISDN_FsmRestartTimer(&l1->timer, 110, EV_TIMER_ACT, NULL, 2);
+ mISDN_FsmDelTimer(&l1->timer3, 3);
+ mISDN_FsmRestartTimer(&l1->timerX, 110, EV_TIMER_ACT, NULL, 2);
test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags);
}
}
@@ -201,8 +202,9 @@ l1_timer3(struct FsmInst *fi, int event, void *arg)
l1->dcb(l1->dch, PH_DEACTIVATE_IND);
}
if (l1->l1m.state != ST_L1_F6) {
+ /* keep in F6 */
mISDN_FsmChangeState(fi, ST_L1_F3);
- l1->dcb(l1->dch, HW_POWERUP_REQ);
+ /* do not force anything here, we need send INFO 0 */
}
}
@@ -234,8 +236,9 @@ l1_activate_s(struct FsmInst *fi, int event, void *arg)
{
struct layer1 *l1 = fi->userdata;
- mISDN_FsmRestartTimer(&l1->timer, l1->t3_value, EV_TIMER3, NULL, 2);
+ 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);
}
@@ -303,7 +306,8 @@ static struct FsmNode L1SFnList[] =
static void
release_l1(struct layer1 *l1) {
- mISDN_FsmDelTimer(&l1->timer, 0);
+ mISDN_FsmDelTimer(&l1->timerX, 0);
+ mISDN_FsmDelTimer(&l1->timer3, 0);
if (l1->dch)
l1->dch->l1 = NULL;
module_put(THIS_MODULE);
@@ -395,7 +399,8 @@ create_l1(struct dchannel *dch, dchannel_l1callback *dcb) {
nl1->l1m.printdebug = l1m_debug;
nl1->dch = dch;
nl1->dcb = dcb;
- mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer);
+ mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer3);
+ mISDN_FsmInitTimer(&nl1->l1m, &nl1->timerX);
__module_get(THIS_MODULE);
dch->l1 = nl1;
return 0;
--
1.7.3.4
^ permalink raw reply related
* Re: [PATCH] RPS: Sparse connection optimizations
From: Eric Dumazet @ 2012-04-28 11:55 UTC (permalink / raw)
To: Deng-Cheng Zhu; +Cc: davem, therbert, netdev
In-Reply-To: <1335607805-735-1-git-send-email-dczhu@mips.com>
On Sat, 2012-04-28 at 18:10 +0800, Deng-Cheng Zhu wrote:
> From: Deng-Cheng Zhu <dczhu@mips.com>
>
> Currently, choosing target CPU to process the incoming packet is based on
> skb->rxhash. In the case of sparse connections, this could lead to
> relatively low and inconsistent bandwidth while doing network throughput
> tests -- CPU selection in the RPS map is imbalanced. Even with the same
> hash value, 2 packets could come from different devices. Besides, on
> architectures like MIPS with multi-threaded cores, siblings of CPU0 should
> not be selected when others are not saturated.
What CPU0 is doing so special you have to mention it in this changelog ?
>
> This patch introduces a feature that allows some flows to select their CPUs
> by looping the RPS CPU maps. Some tests were performed on the MIPS Malta
> 1004K platform (2 cores, each with 2 VPEs) at 25Mhz with 2 Intel Pro/1000
> NICs. The Malta board works as a router between 2 PCs. Using iperf, here
> are results:
RPS on a router ? Thats not very good, unless you perform a crazy amount
of work in iptables rules maybe ?
One packet comes, its better to handle it right now and send it right
now on the same cpu. No IPI cost, no cache line misses...
RPS is something more suitable to TCP handling in local host because
stack has big memory footprint and latencies, not for forwarding
workload.
I suspect you can reach more throughput using appropriate tunings
(correct interrupt affinities). This sounds like a bad config from the
very beginning.
> +};
> +
> +static struct cpu_flow flow[CONFIG_NR_RPS_MAP_LOOPS][NR_CPUS];
Thats absolutely not allowed to add a [NR_CPUS] array anywhere in linux
kernel in 2012.
> +/*
> + * We've got CONFIG_SMP to do RPS, so only arch define is needed here to access
> + * sibling specific information.
> + */
> +#if defined(CONFIG_MIPS)
Thats not allowed to add a CONFIG_somearch in net/core/dev.c
^ permalink raw reply
* Re: [PATCH v2 1/2] drop_monitor: fix sleeping in invalid context warning
From: Neil Horman @ 2012-04-28 14:30 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, David Miller
In-Reply-To: <1335593473.2900.0.camel@edumazet-glaptop>
On Sat, Apr 28, 2012 at 08:11:13AM +0200, Eric Dumazet wrote:
> On Fri, 2012-04-27 at 16:11 -0400, Neil Horman wrote:
> > Eric Dumazet pointed out this warning in the drop_monitor protocol to me:
> >
>
> > It stems from holding a spinlock (trace_state_lock) while attempting to register
> > or unregister tracepoint hooks, making in_atomic() true in this context, leading
> > to the warning when the tracepoint calls might_sleep() while its taking a mutex.
> > Since we only use the trace_state_lock to prevent trace protocol state races, as
> > well as hardware stat list updates on an rcu write side, we can just convert the
> > spinlock to a mutex to avoid this problem.
> >
> > Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> > Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
> > CC: David Miller <davem@davemloft.net>
> > ---
>
> Acked-by: Eric Dumazet <edumazet@google.com>
>
> Thanks Neil
>
Anytmie, thanks for reporting it.
Neil
>
>
>
^ permalink raw reply
* From 27/04/2012
From: From Director's Desk Hang Seng Bank @ 2012-04-28 5:16 UTC (permalink / raw)
To: Recipients
Dear friend 27/04/2012
I am Dr Raymond Chien Independent Non-executive Director of Hang Seng
Bank Hong Kong I have a business transaction of $44.5 million USD
to share with you,If interested contact me for more details via my
personal email: draymndch8@yahoo.co.jp
Full names:
Address:
Age:
Occupation:
Phone/Fax
Regards
Dr Raymond Chien Kuo Fung
^ permalink raw reply
* URGENT FAMILY NEED ASSISTANCE(KINDLY CONTACT ME FOR MORE DETAILS )
From: EDWARD SYLVESTER @ 2012-04-28 16:16 UTC (permalink / raw)
[-- Attachment #1: Type: text/plain, Size: 0 bytes --]
[-- Attachment #2: EDWARD SYLVESTER.doc --]
[-- Type: application/msword, Size: 25600 bytes --]
^ permalink raw reply
* Re: [PATCH net-next] pch_gbe: reprogram multicast address register on reset
From: Richard Cochran @ 2012-04-28 16:41 UTC (permalink / raw)
To: roy.qing.li; +Cc: netdev, tshimizu818
In-Reply-To: <1335592421-31406-1-git-send-email-roy.qing.li@gmail.com>
On Sat, Apr 28, 2012 at 01:53:41PM +0800, roy.qing.li@gmail.com wrote:
> From: RongQing.Li <roy.qing.li@gmail.com>
>
> The reset logic after a Rx FIFO overrun will clear the programmed
> multicast addresses. This patch fixes the issue by reprogramming the
> registers after the reset.
>
> The commit eefc48b tried to fix this problem, but it introduces
> unnecessary codes. In fact, all multicast addresses have been saved
> in netdev->mc, So we can call pch_gbe_set_multi() directly after
> reset_hw and reset_rx.
>
> This commit kills 50+ line codes
Looks good to me.
Acked-by: Richard Cochran <richardcochran@gmail.com>
^ permalink raw reply
* Re: [PATCH 01/10] atl1c: add workaround for issue of bit INTX-disable for MSI interrupt
From: Luis R. Rodriguez @ 2012-04-28 17:21 UTC (permalink / raw)
To: Huang, Xiong
Cc: davem@davemloft.net, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, qca-linux-team, nic-devel
In-Reply-To: <157393863283F442885425D2C454285623D5F96D@nasanexd02a.na.qualcomm.com>
On Sat, Apr 28, 2012 at 2:53 AM, Huang, Xiong <xiong@qca.qualcomm.com> wrote:
> Thanks Luis, just one question:
>
> I don't know which kernel version contains the updated pci/quirks.c, so,
> if I write the patch file (a 58-drivers-pci-quirks.patch) as:
>
> --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
>
> +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
> + pdev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG;
> +#endif
>
>
> It seems not good for the kernel with updated pci/quirks.c
>
> Any better suggestion ? thanks
That looks good for the backport, you would just ifdef around <
KERNEL_VERSION(3,5,0)
Luis
^ permalink raw reply
* Re: [PATCH 02/10] atl1c: add PHY link event(up/down) patch
From: Florian Fainelli @ 2012-04-28 17:24 UTC (permalink / raw)
To: xiong; +Cc: davem, netdev, linux-kernel, qca-linux-team, nic-devel
In-Reply-To: <1335578325-21326-3-git-send-email-xiong@qca.qualcomm.com>
Hi Xiong,
Le samedi 28 avril 2012 03:58:37, xiong a écrit :
> On some platforms the PHY settings need to change depending on the
> cable link status to get better stability.
>
> Signed-off-by: xiong <xiong@qca.qualcomm.com>
> Tested-by: Liu David <dwliu@qca.qualcomm.com>
> ---
> drivers/net/ethernet/atheros/atl1c/atl1c.h | 1 +
> drivers/net/ethernet/atheros/atl1c/atl1c_hw.c | 37 +++++++++++++++
> drivers/net/ethernet/atheros/atl1c/atl1c_hw.h | 1 +
> drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 55
> +++++++++++++++++++++++ 4 files changed, 94 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c.h
> b/drivers/net/ethernet/atheros/atl1c/atl1c.h index acc2956..b2bf324 100644
> --- a/drivers/net/ethernet/atheros/atl1c/atl1c.h
> +++ b/drivers/net/ethernet/atheros/atl1c/atl1c.h
> @@ -436,6 +436,7 @@ struct atl1c_hw {
> bool phy_configured;
> bool re_autoneg;
> bool emi_ca;
> + bool msi_lnkpatch; /* link patch for specific platforms */
> };
>
> /*
> diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
> b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c index 07f017f..209c179
> 100644
> --- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
> +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
> @@ -848,3 +848,40 @@ int atl1c_power_saving(struct atl1c_hw *hw, u32 wufc)
>
> return 0;
> }
> +
> +
> +/* configure phy after Link change Event */
> +void atl1c_post_phy_linkchg(struct atl1c_hw *hw, u16 link_speed)
> +{
> + u16 phy_val;
> + bool adj_thresh = false;
> +
> + if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2 ||
> + hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2)
> + adj_thresh = true;
> +
> + if (link_speed != SPEED_0) { /* link up */
> + /* az with brcm, half-amp */
> + if (hw->nic_type == athr_l1d_2) {
> + atl1c_read_phy_ext(hw, MIIEXT_PCS, MIIEXT_CLDCTRL6,
> + &phy_val);
> + phy_val = FIELD_GETX(phy_val, CLDCTRL6_CAB_LEN);
> + phy_val = phy_val > CLDCTRL6_CAB_LEN_SHORT ?
> + AZ_ANADECT_LONG : AZ_ANADECT_DEF;
> + atl1c_write_phy_dbg(hw, MIIDBG_AZ_ANADECT, phy_val);
> + }
> + /* threshold adjust */
> + if (adj_thresh && link_speed == SPEED_100 && hw->msi_lnkpatch) {
> + atl1c_write_phy_dbg(hw, MIIDBG_MSE16DB, L1D_MSE16DB_UP);
> + atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL,
> + L1D_SYSMODCTRL_IECHOADJ_DEF);
> + }
> + } else { /* link down */
> + if (adj_thresh && hw->msi_lnkpatch) {
> + atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL,
> + SYSMODCTRL_IECHOADJ_DEF);
> + atl1c_write_phy_dbg(hw, MIIDBG_MSE16DB,
> + L1D_MSE16DB_DOWN);
> + }
> + }
> +}
> diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h
> b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h index 0adb341..ea3f520
> 100644
> --- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h
> +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h
> @@ -63,6 +63,7 @@ int atl1c_write_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
> u16 reg_addr, u16 phy_data);
> int atl1c_read_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data);
> int atl1c_write_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 phy_data);
> +void atl1c_post_phy_linkchg(struct atl1c_hw *hw, u16 link_speed);
>
> /* hw-ids */
> #define PCI_DEVICE_ID_ATTANSIC_L2C 0x1062
> diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 25b7b00..50df437
> 100644
> --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> @@ -258,6 +258,7 @@ static void atl1c_check_link_status(struct
> atl1c_adapter *adapter) if (netif_msg_hw(adapter))
> dev_warn(&pdev->dev, "stop mac failed\n");
> atl1c_set_aspm(hw, SPEED_0);
> + atl1c_post_phy_linkchg(hw, SPEED_0);
> netif_carrier_off(netdev);
> netif_stop_queue(netdev);
> } else {
> @@ -274,6 +275,7 @@ static void atl1c_check_link_status(struct
> atl1c_adapter *adapter) adapter->link_speed = speed;
> adapter->link_duplex = duplex;
> atl1c_set_aspm(hw, speed);
> + atl1c_post_phy_linkchg(hw, speed);
> atl1c_start_mac(adapter);
> if (netif_msg_link(adapter))
> dev_info(&pdev->dev,
> @@ -697,6 +699,57 @@ static int atl1c_setup_mac_funcs(struct atl1c_hw *hw)
> hw->link_cap_flags |= ATL1C_LINK_CAP_1000M;
> return 0;
> }
> +
> +struct atl1c_platform_patch {
> + u16 pci_vid;
> + u16 pci_did;
> + u8 pci_revid;
> + u16 subsystem_vid;
> + u16 subsystem_did;
> + u32 patch_flag;
> +#define ATL1C_LINK_PATCH 0x1
> +};
> +static struct atl1c_platform_patch plats[] = {
This should be static const.
> +{0x1969, 0x2060, 0xC1, 0x1019, 0x8152, 0x1},
> +{0x1969, 0x2060, 0xC1, 0x1019, 0x2060, 0x1},
> +{0x1969, 0x2060, 0xC1, 0x1019, 0xE000, 0x1},
> +{0x1969, 0x2062, 0xC0, 0x1019, 0x8152, 0x1},
> +{0x1969, 0x2062, 0xC0, 0x1019, 0x2062, 0x1},
> +{0x1969, 0x2062, 0xC0, 0x1458, 0xE000, 0x1},
> +{0x1969, 0x2062, 0xC1, 0x1019, 0x8152, 0x1},
> +{0x1969, 0x2062, 0xC1, 0x1019, 0x2062, 0x1},
> +{0x1969, 0x2062, 0xC1, 0x1458, 0xE000, 0x1},
> +{0x1969, 0x2062, 0xC1, 0x1565, 0x2802, 0x1},
> +{0x1969, 0x2062, 0xC1, 0x1565, 0x2801, 0x1},
> +{0x1969, 0x1073, 0xC0, 0x1019, 0x8151, 0x1},
> +{0x1969, 0x1073, 0xC0, 0x1019, 0x1073, 0x1},
> +{0x1969, 0x1073, 0xC0, 0x1458, 0xE000, 0x1},
> +{0x1969, 0x1083, 0xC0, 0x1458, 0xE000, 0x1},
> +{0x1969, 0x1083, 0xC0, 0x1019, 0x8151, 0x1},
> +{0x1969, 0x1083, 0xC0, 0x1019, 0x1083, 0x1},
> +{0x1969, 0x1083, 0xC0, 0x1462, 0x7680, 0x1},
> +{0x1969, 0x1083, 0xC0, 0x1565, 0x2803, 0x1},
> +{0},
Since patch_flag is always set to 0x1, just remove it, if you find a matching
entry, apply the patch. Vendor ID is always the same, remove it as well.
Looking at the supported PCI devices table, this patching table is applicable
to all Atheros PCI device id and none of the Attansic PCI device id, this
suggests that your table should be reversed, and you should only list the
devices *not* needing the patch, this should make the lookup code smaller.
> +};
> +
> +static void __devinit atl1c_patch_assign(struct atl1c_hw *hw)
> +{
> + int i = 0;
> +
> + hw->msi_lnkpatch = false;
> +
> + while (plats[i].pci_vid != 0) {
> + if (plats[i].pci_vid == hw->vendor_id &&
> + plats[i].pci_did == hw->device_id &&
> + plats[i].pci_revid == hw->revision_id &&
> + plats[i].subsystem_vid == hw->subsystem_vendor_id &&
> + plats[i].subsystem_did == hw->subsystem_id) {
> + if (plats[i].patch_flag & ATL1C_LINK_PATCH)
> + hw->msi_lnkpatch = true;
> + }
> + i++;
> + }
> +}
> /*
> * atl1c_sw_init - Initialize general software structures (struct
> atl1c_adapter) * @adapter: board private structure to initialize
> @@ -732,6 +785,8 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter
> *adapter) dev_err(&pdev->dev, "set mac function pointers failed\n");
> return -1;
> }
> + atl1c_patch_assign(hw);
> +
> hw->intr_mask = IMR_NORMAL_MASK;
> hw->phy_configured = false;
> hw->preamble_len = 7;
--
Florian
^ permalink raw reply
* Re: [PATCH] 9p: disconnect channel when PCI device is removed
From: Aneesh Kumar K.V @ 2012-04-28 18:16 UTC (permalink / raw)
To: Sasha Levin; +Cc: davem, ericvh, jvrao, rusty, netdev, linux-kernel, davej
In-Reply-To: <CA+1xoqfQ0Cj5pibxN8ZTXbksezH4NqOERaiYav=D7BA+v86m3A@mail.gmail.com>
Sasha Levin <levinsasha928@gmail.com> writes:
> On Mon, Apr 16, 2012 at 12:59 PM, Aneesh Kumar K.V
> <aneesh.kumar@linux.vnet.ibm.com> wrote:
>> Sasha Levin <levinsasha928@gmail.com> writes:
>>
>>> On Sun, Apr 15, 2012 at 2:27 PM, Aneesh Kumar K.V
>>> <aneesh.kumar@linux.vnet.ibm.com> wrote:
>>>> Sasha Levin <levinsasha928@gmail.com> writes:
>>>>
>>>>> When a virtio_9p pci device is being removed, we should close down any
>>>>> active channels and free up resources, we're not supposed to BUG() if there's
>>>>> still an open channel since it's a valid case when removing the PCI device.
>>>>>
>>>>> Otherwise, removing the PCI device with an open channel would cause the
>>>>> following BUG():
>>>>>
>>>> ...
>>>>
>>>>> diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
>>>>> index 3d43206..5af18d1 100644
>>>>> --- a/net/9p/trans_virtio.c
>>>>> +++ b/net/9p/trans_virtio.c
>>>>> @@ -615,7 +615,8 @@ static void p9_virtio_remove(struct virtio_device *vdev)
>>>>> {
>>>>> struct virtio_chan *chan = vdev->priv;
>>>>>
>>>>> - BUG_ON(chan->inuse);
>>>>> + if (chan->inuse)
>>>>> + p9_virtio_close(chan->client);
>>>>> vdev->config->del_vqs(vdev);
>>>>>
>>>>> mutex_lock(&virtio_9p_lock);
>>>>
>>>> But an umount should have resulted in p9_virtio_close ? How are you
>>>> removing the device ? Are you removing the device with file system
>>>> mounted ?. In that case may be we should return EBUSY ?
>>>
>>> I signal the underlying PCI device to remove (echo 1 >
>>> /sys/devices/pci0000\:00/[...]/remove), we can't really prevent that
>>> thing so we must clean up ourselves.
>>
>> What does that mean for the mounted file system ? What would happen to
>> the pending fs operations in that case ?
>
> I'm guessing that all of them should be canceled.
Pending operation we can cancel, but what about dirty pages in cached
mode ? Also how does virtio-blk handle this ?
> virtio-pci simulates
> a PCI device, if the PCI device is unplugged there's not much to do
> about the filesystem or pending requests.
Ideal thing to do would be to make remove return -EBUSY; let the user
umount. But looking at the code, I guess there is no easy way to return
error from remove callback ?
-aneesh
^ permalink raw reply
* [PATCH v2 3/3] RFC tcp: early retransmit: delayed fast retransmit
From: Yuchung Cheng @ 2012-04-28 18:46 UTC (permalink / raw)
To: davem, ilpo.jarvinen; +Cc: ncardwell, nanditad, edumazet, netdev, Yuchung Cheng
In-Reply-To: <1335638781-960-1-git-send-email-ycheng@google.com>
Implementing the advanced early retransmit (sysctl_tcp_early_retrans==2).
Delays the fast retransmit by an interval of RTT/4. We borrow the
RTO timer to implement the delay. If we receive another ACK or send
a new packet, the timer is cancelled and restored to original RTO
value offset by time elapsed. When the delayed-ER timer fires,
we enter fast recovery and perform fast retransmit.
Signed-off-by: Yuchung Cheng <ycheng@google.com>
---
include/linux/tcp.h | 4 +-
include/net/tcp.h | 3 ++
net/ipv4/tcp_input.c | 69 ++++++++++++++++++++++++++++++++++++++++++++-----
net/ipv4/tcp_output.c | 5 +--
net/ipv4/tcp_timer.c | 5 +++
5 files changed, 74 insertions(+), 12 deletions(-)
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 7d08a79..da5b659 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -369,8 +369,8 @@ struct tcp_sock {
thin_lto : 1,/* Use linear timeouts for thin streams */
thin_dupack : 1,/* Fast retransmit on first dupack */
repair : 1,
- do_early_retrans: 1;/* Enable RFC5827 early-retransmit */
-
+ do_early_retrans: 1,/* Enable RFC5827 early retransmit (ER) */
+ early_retrans_delayed: 1; /* Delayed ER timer installed */
u8 frto_counter; /* Number of new acks after RTO */
u8 repair_queue;
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 685437a..5283aa4 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -500,6 +500,8 @@ extern void tcp_send_delayed_ack(struct sock *sk);
/* tcp_input.c */
extern void tcp_cwnd_application_limited(struct sock *sk);
+extern void tcp_resume_early_retransmit(struct sock *sk);
+extern void tcp_rearm_rto(struct sock *sk);
/* tcp_timer.c */
extern void tcp_init_xmit_timers(struct sock *);
@@ -805,6 +807,7 @@ static inline void tcp_enable_early_retrans(struct tcp_sock *tp)
{
tp->do_early_retrans = sysctl_tcp_early_retrans &&
!sysctl_tcp_thin_dupack && sysctl_tcp_reordering == 3;
+ tp->early_retrans_delayed = 0;
}
static inline void tcp_disable_early_retrans(struct tcp_sock *tp)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 98c586d..8abf63b 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2342,6 +2342,27 @@ static inline int tcp_dupack_heuristics(const struct tcp_sock *tp)
return tcp_is_fack(tp) ? tp->fackets_out : tp->sacked_out + 1;
}
+static bool tcp_pause_early_retransmit(struct sock *sk, int flag)
+{
+ struct tcp_sock *tp = tcp_sk(sk);
+ unsigned long delay;
+
+ /* Delay early retransmit and entering fast recovery for
+ * max(RTT/4, 2msec) unless ack has ECE mark, no RTT samples
+ * available, or RTO is scheduled to fire first.
+ */
+ if (sysctl_tcp_early_retrans < 2 || (flag & FLAG_ECE) || !tp->srtt)
+ return false;
+
+ delay = max_t(unsigned long, (tp->srtt >> 5), msecs_to_jiffies(2));
+ if (!time_after(inet_csk(sk)->icsk_timeout, (jiffies + delay)))
+ return false;
+
+ inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, delay, TCP_RTO_MAX);
+ tp->early_retrans_delayed = 1;
+ return true;
+}
+
static inline int tcp_skb_timedout(const struct sock *sk,
const struct sk_buff *skb)
{
@@ -2449,7 +2470,7 @@ static inline int tcp_head_timedout(const struct sock *sk)
* Main question: may we further continue forward transmission
* with the same cwnd?
*/
-static int tcp_time_to_recover(struct sock *sk)
+static int tcp_time_to_recover(struct sock *sk, int flag)
{
struct tcp_sock *tp = tcp_sk(sk);
__u32 packets_out;
@@ -2503,7 +2524,7 @@ static int tcp_time_to_recover(struct sock *sk)
if (tp->do_early_retrans && !tp->retrans_out && tp->sacked_out &&
(tp->packets_out == (tp->sacked_out + 1) && tp->packets_out < 4) &&
!tcp_may_send_now(sk))
- return 1;
+ return !tcp_pause_early_retransmit(sk, flag);
return 0;
}
@@ -3170,7 +3191,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
if (icsk->icsk_ca_state <= TCP_CA_Disorder)
tcp_try_undo_dsack(sk);
- if (!tcp_time_to_recover(sk)) {
+ if (!tcp_time_to_recover(sk, flag)) {
tcp_try_to_open(sk, flag);
return;
}
@@ -3269,16 +3290,47 @@ static void tcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
/* Restart timer after forward progress on connection.
* RFC2988 recommends to restart timer to now+rto.
*/
-static void tcp_rearm_rto(struct sock *sk)
+void tcp_rearm_rto(struct sock *sk)
{
- const struct tcp_sock *tp = tcp_sk(sk);
+ struct tcp_sock *tp = tcp_sk(sk);
if (!tp->packets_out) {
inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
} else {
- inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
- inet_csk(sk)->icsk_rto, TCP_RTO_MAX);
+ u32 rto = inet_csk(sk)->icsk_rto;
+ /* Offset the time elapsed after installing regular RTO */
+ if (tp->early_retrans_delayed) {
+ struct sk_buff *skb = tcp_write_queue_head(sk);
+ const u32 rto_time_stamp = TCP_SKB_CB(skb)->when + rto;
+ s32 delta = (s32)(rto_time_stamp - tcp_time_stamp);
+ /* delta may not be positive if the socket is locked
+ * when the delayed ER timer fires and is rescheduled.
+ */
+ if (delta > 0)
+ rto = delta;
+ }
+ inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, rto,
+ TCP_RTO_MAX);
}
+ tp->early_retrans_delayed = 0;
+}
+
+/* This function is called when the delayed ER timer fires. TCP enters
+ * fast recovery and performs fast-retransmit.
+ */
+void tcp_resume_early_retransmit(struct sock *sk)
+{
+ struct tcp_sock *tp = tcp_sk(sk);
+
+ tcp_rearm_rto(sk);
+
+ /* Stop if ER is disabled after the delayed ER timer is scheduled */
+ if (!tp->do_early_retrans)
+ return;
+
+ tcp_enter_recovery(sk, false);
+ tcp_update_scoreboard(sk, 1);
+ tcp_xmit_retransmit_queue(sk);
}
/* If we get here, the whole TSO packet has not been acked. */
@@ -3727,6 +3779,9 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
if (after(ack, tp->snd_nxt))
goto invalid_ack;
+ if (tp->early_retrans_delayed)
+ tcp_rearm_rto(sk);
+
if (after(ack, prior_snd_una))
flag |= FLAG_SND_UNA_ADVANCED;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 834e89f..d947330 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -78,9 +78,8 @@ static void tcp_event_new_data_sent(struct sock *sk, const struct sk_buff *skb)
tp->frto_counter = 3;
tp->packets_out += tcp_skb_pcount(skb);
- if (!prior_packets)
- inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
- inet_csk(sk)->icsk_rto, TCP_RTO_MAX);
+ if (!prior_packets || tp->early_retrans_delayed)
+ tcp_rearm_rto(sk);
}
/* SND.NXT, if window was not shrunk.
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 34d4a02..e911e6c 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -319,6 +319,11 @@ void tcp_retransmit_timer(struct sock *sk)
struct tcp_sock *tp = tcp_sk(sk);
struct inet_connection_sock *icsk = inet_csk(sk);
+ if (tp->early_retrans_delayed) {
+ tcp_resume_early_retransmit(sk);
+ return;
+ }
+
if (!tp->packets_out)
goto out;
--
1.7.7.3
^ permalink raw reply related
* [PATCH v2 2/3] RFC tcp: early retransmit
From: Yuchung Cheng @ 2012-04-28 18:46 UTC (permalink / raw)
To: davem, ilpo.jarvinen; +Cc: ncardwell, nanditad, edumazet, netdev, Yuchung Cheng
In-Reply-To: <1335638781-960-1-git-send-email-ycheng@google.com>
This patch implements RFC 5827 early retransmit (ER) for TCP.
It reduces DUPACK threshold (dupthresh) if outstanding packets are
less than 4 to recover losses by fast recovery instead of timeout.
While the algorithm is simple, small but frequent network reordering
makes this feature dangerous: the connection repeatedly enter
false recovery and degrade performance. Therefore we implement
a mitigation suggested in the appendix of the RFC that delays
entering fast recovery by a small interval, i.e., RTT/4. But when
the network reordering degree is too large, i.e., 3 packets,
ER is disabled to avoid false fast recoveries for the rest of
the connection. The performance impact of ER is summarized in
section 6 of the paper "Proportional Rate Reduction for TCP”,
IMC 2011. http://conferences.sigcomm.org/imc/2011/docs/p155.pdf
Note that Linux has a similar feature called THIN_DUPACK. The
differences are THIN_DUPACK do not mitigate reorderings and is only
used after slow start. Currently ER is disabled if THIN_DUPACK is
enabled. I would be happy to merge THIN_DUPACK feature with ER if
people think it's a good idea.
ER is enabled by sysctl_tcp_early_retrans:
0: Disables ER
1: Reduce dupthresh to packets_out - 1 when outstanding packets < 4.
2: (Default) reduce dupthresh like mode 1. In addition, delay
entering fast recovery by RTT/4.
Note: mode 2 is implemented in the third part of this patch series.
Signed-off-by: Yuchung Cheng <ycheng@google.com>
---
Documentation/networking/ip-sysctl.txt | 14 ++++++++++++++
include/linux/tcp.h | 7 ++++---
include/net/tcp.h | 15 +++++++++++++++
net/ipv4/sysctl_net_ipv4.c | 10 ++++++++++
net/ipv4/tcp.c | 3 +++
net/ipv4/tcp_input.c | 13 +++++++++++++
net/ipv4/tcp_minisocks.c | 1 +
7 files changed, 60 insertions(+), 3 deletions(-)
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 9b569a2..23ebeae 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -202,6 +202,20 @@ tcp_ecn - INTEGER
not support ECN, behavior is like with ECN disabled.
Default: 2
+tcp_early_retrans - INTEGER
+ Enable Early Retransmit (ER), per RFC 5827. ER lowers the threshold
+ for triggering fast retransmit when the amount of outstanding data is
+ small and when no previously unsent data can be transmitted (such
+ that limited transmit could be used).
+ Possible values:
+ 0 disables ER
+ 1 enables ER
+ 2 enables ER but delays fast recovery and fast retransmit
+ by a fourth of RTT. This mitigates connection falsely
+ recovers when network has a small degree of reordering
+ (less than 3 packets).
+ Default: 2
+
tcp_fack - BOOLEAN
Enable FACK congestion avoidance and fast retransmission.
The value is not used, if tcp_sack is not enabled.
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 278af9e..7d08a79 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -365,12 +365,13 @@ struct tcp_sock {
u32 frto_highmark; /* snd_nxt when RTO occurred */
u16 advmss; /* Advertised MSS */
- u8 frto_counter; /* Number of new acks after RTO */
- u8 nonagle : 4,/* Disable Nagle algorithm? */
+ u16 nonagle : 4,/* Disable Nagle algorithm? */
thin_lto : 1,/* Use linear timeouts for thin streams */
thin_dupack : 1,/* Fast retransmit on first dupack */
repair : 1,
- unused : 1;
+ do_early_retrans: 1;/* Enable RFC5827 early-retransmit */
+
+ u8 frto_counter; /* Number of new acks after RTO */
u8 repair_queue;
/* RTT measurement */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 0fb84de..685437a 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -252,6 +252,7 @@ extern int sysctl_tcp_max_ssthresh;
extern int sysctl_tcp_cookie_size;
extern int sysctl_tcp_thin_linear_timeouts;
extern int sysctl_tcp_thin_dupack;
+extern int sysctl_tcp_early_retrans;
extern atomic_long_t tcp_memory_allocated;
extern struct percpu_counter tcp_sockets_allocated;
@@ -797,6 +798,20 @@ static inline void tcp_enable_fack(struct tcp_sock *tp)
tp->rx_opt.sack_ok |= TCP_FACK_ENABLED;
}
+/* TCP early-retransmit (ER) is similar to but more conservative than
+ * the thin-dupack feature. Enable ER only if thin-dupack is disabled.
+ */
+static inline void tcp_enable_early_retrans(struct tcp_sock *tp)
+{
+ tp->do_early_retrans = sysctl_tcp_early_retrans &&
+ !sysctl_tcp_thin_dupack && sysctl_tcp_reordering == 3;
+}
+
+static inline void tcp_disable_early_retrans(struct tcp_sock *tp)
+{
+ tp->do_early_retrans = 0;
+}
+
static inline unsigned int tcp_left_out(const struct tcp_sock *tp)
{
return tp->sacked_out + tp->lost_out;
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 33417f8..ef32956 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -27,6 +27,7 @@
#include <net/tcp_memcontrol.h>
static int zero;
+static int two = 2;
static int tcp_retr1_max = 255;
static int ip_local_port_range_min[] = { 1, 1 };
static int ip_local_port_range_max[] = { 65535, 65535 };
@@ -677,6 +678,15 @@ static struct ctl_table ipv4_table[] = {
.proc_handler = proc_dointvec
},
{
+ .procname = "tcp_early_retrans",
+ .data = &sysctl_tcp_early_retrans,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &zero,
+ .extra2 = &two,
+ },
+ {
.procname = "udp_mem",
.data = &sysctl_udp_mem,
.maxlen = sizeof(sysctl_udp_mem),
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 9670af3..6802c89 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -395,6 +395,7 @@ void tcp_init_sock(struct sock *sk)
tp->mss_cache = TCP_MSS_DEFAULT;
tp->reordering = sysctl_tcp_reordering;
+ tcp_enable_early_retrans(tp);
icsk->icsk_ca_ops = &tcp_init_congestion_ops;
sk->sk_state = TCP_CLOSE;
@@ -2495,6 +2496,8 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
err = -EINVAL;
else
tp->thin_dupack = val;
+ if (tp->thin_dupack)
+ tcp_disable_early_retrans(tp);
break;
case TCP_REPAIR:
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 22df826..98c586d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -99,6 +99,7 @@ int sysctl_tcp_thin_dupack __read_mostly;
int sysctl_tcp_moderate_rcvbuf __read_mostly = 1;
int sysctl_tcp_abc __read_mostly;
+int sysctl_tcp_early_retrans __read_mostly = 2;
#define FLAG_DATA 0x01 /* Incoming frame contained data. */
#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */
@@ -906,6 +907,7 @@ static void tcp_init_metrics(struct sock *sk)
if (dst_metric(dst, RTAX_REORDERING) &&
tp->reordering != dst_metric(dst, RTAX_REORDERING)) {
tcp_disable_fack(tp);
+ tcp_disable_early_retrans(tp);
tp->reordering = dst_metric(dst, RTAX_REORDERING);
}
@@ -987,6 +989,7 @@ static void tcp_update_reordering(struct sock *sk, const int metric,
tp->undo_marker ? tp->undo_retrans : 0);
#endif
tcp_disable_fack(tp);
+ tcp_disable_early_retrans(tp);
}
}
@@ -2492,6 +2495,16 @@ static int tcp_time_to_recover(struct sock *sk)
tcp_is_sack(tp) && !tcp_send_head(sk))
return 1;
+ /* Trick#6: TCP early retransmit, per RFC5827. To avoid spurious
+ * retransmissions due to small network reorderings, we implement
+ * Mitigation A.3 in the RFC and delay the retransmission for a short
+ * interval if appropriate.
+ */
+ if (tp->do_early_retrans && !tp->retrans_out && tp->sacked_out &&
+ (tp->packets_out == (tp->sacked_out + 1) && tp->packets_out < 4) &&
+ !tcp_may_send_now(sk))
+ return 1;
+
return 0;
}
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 3cabafb..6f6a918 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -482,6 +482,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
newtp->sacked_out = 0;
newtp->fackets_out = 0;
newtp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
+ tcp_enable_early_retrans(newtp);
/* So many TCP implementations out there (incorrectly) count the
* initial SYN frame in their delayed-ACK and congestion control
--
1.7.7.3
^ permalink raw reply related
* [PATCH] sungem: Fix WakeOnLan
From: Gerard Lledo @ 2012-04-28 18:52 UTC (permalink / raw)
To: netdev; +Cc: davem, Gerard Lledo
From: Gerard Lledo <gerard.lledo@gmail.com>
WakeOnLan was broken in this driver because gp->asleep_wol is a 1-bit
bitfield and it was being assigned WAKE_MAGIC, which is (1 << 5).
gp->asleep_wol remains 0 and the machine never wakes up. Fixed by casting
gp->wake_on_lan to bool. Tested on an iBook G4.
Signed-off-by: Gerard Lledo <gerard.lledo@gmail.com>
---
drivers/net/ethernet/sun/sungem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c
index 558409f..4ba9690 100644
--- a/drivers/net/ethernet/sun/sungem.c
+++ b/drivers/net/ethernet/sun/sungem.c
@@ -2339,7 +2339,7 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
netif_device_detach(dev);
/* Switch off chip, remember WOL setting */
- gp->asleep_wol = gp->wake_on_lan;
+ gp->asleep_wol = !!gp->wake_on_lan;
gem_do_stop(dev, gp->asleep_wol);
/* Unlock the network stack */
--
1.7.10
^ permalink raw reply related
* [PATCH v2 1/3] RFC tcp: early retransmit: tcp_enter_recovery()
From: Yuchung Cheng @ 2012-04-28 18:46 UTC (permalink / raw)
To: davem, ilpo.jarvinen; +Cc: ncardwell, nanditad, edumazet, netdev, Yuchung Cheng
This a prepartion patch that refactors the code to enter recovery
into a new function tcp_enter_recovery(). It's needed to implement
the delayed fast retransmit in ER.
Signed-off-by: Yuchung Cheng <ycheng@google.com>
---
ChangeLog in v2:
Fix sysctl_tcp_early_retrans default to 2
Re-arrange the patch parts so they are individually compilable and functional.
net/ipv4/tcp_input.c | 61 +++++++++++++++++++++++++++----------------------
1 files changed, 34 insertions(+), 27 deletions(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index c93b0cb..22df826 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3022,6 +3022,38 @@ static void tcp_update_cwnd_in_recovery(struct sock *sk, int newly_acked_sacked,
tp->snd_cwnd = tcp_packets_in_flight(tp) + sndcnt;
}
+static void tcp_enter_recovery(struct sock *sk, bool ece_ack)
+{
+ struct tcp_sock *tp = tcp_sk(sk);
+ int mib_idx;
+
+ if (tcp_is_reno(tp))
+ mib_idx = LINUX_MIB_TCPRENORECOVERY;
+ else
+ mib_idx = LINUX_MIB_TCPSACKRECOVERY;
+
+ NET_INC_STATS_BH(sock_net(sk), mib_idx);
+
+ tp->high_seq = tp->snd_nxt;
+ tp->prior_ssthresh = 0;
+ tp->undo_marker = tp->snd_una;
+ tp->undo_retrans = tp->retrans_out;
+
+ if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) {
+ if (!ece_ack)
+ tp->prior_ssthresh = tcp_current_ssthresh(sk);
+ tp->snd_ssthresh = inet_csk(sk)->icsk_ca_ops->ssthresh(sk);
+ TCP_ECN_queue_cwr(tp);
+ }
+
+ tp->bytes_acked = 0;
+ tp->snd_cwnd_cnt = 0;
+ tp->prior_cwnd = tp->snd_cwnd;
+ tp->prr_delivered = 0;
+ tp->prr_out = 0;
+ tcp_set_ca_state(sk, TCP_CA_Recovery);
+}
+
/* Process an event, which can update packets-in-flight not trivially.
* Main goal of this function is to calculate new estimate for left_out,
* taking into account both packets sitting in receiver's buffer and
@@ -3041,7 +3073,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
struct tcp_sock *tp = tcp_sk(sk);
int do_lost = is_dupack || ((flag & FLAG_DATA_SACKED) &&
(tcp_fackets_out(tp) > tp->reordering));
- int fast_rexmit = 0, mib_idx;
+ int fast_rexmit = 0;
if (WARN_ON(!tp->packets_out && tp->sacked_out))
tp->sacked_out = 0;
@@ -3142,32 +3174,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
}
/* Otherwise enter Recovery state */
-
- if (tcp_is_reno(tp))
- mib_idx = LINUX_MIB_TCPRENORECOVERY;
- else
- mib_idx = LINUX_MIB_TCPSACKRECOVERY;
-
- NET_INC_STATS_BH(sock_net(sk), mib_idx);
-
- tp->high_seq = tp->snd_nxt;
- tp->prior_ssthresh = 0;
- tp->undo_marker = tp->snd_una;
- tp->undo_retrans = tp->retrans_out;
-
- if (icsk->icsk_ca_state < TCP_CA_CWR) {
- if (!(flag & FLAG_ECE))
- tp->prior_ssthresh = tcp_current_ssthresh(sk);
- tp->snd_ssthresh = icsk->icsk_ca_ops->ssthresh(sk);
- TCP_ECN_queue_cwr(tp);
- }
-
- tp->bytes_acked = 0;
- tp->snd_cwnd_cnt = 0;
- tp->prior_cwnd = tp->snd_cwnd;
- tp->prr_delivered = 0;
- tp->prr_out = 0;
- tcp_set_ca_state(sk, TCP_CA_Recovery);
+ tcp_enter_recovery(sk, (flag & FLAG_ECE));
fast_rexmit = 1;
}
--
1.7.7.3
^ permalink raw reply related
* [PATCH] tcp: fix infinite cwnd in tcp_complete_cwr()
From: Yuchung Cheng @ 2012-04-28 19:04 UTC (permalink / raw)
To: davem, ilpo.jarvinen; +Cc: ncardwell, nanditad, netdev, Yuchung Cheng
When the cwnd reduction is done, ssthresh may be infinite
if TCP enters CWR via ECN or F-RTO. If cwnd is not undone, i.e.,
undo_marker is set, tcp_complete_cwr() falsely set cwnd to the
infinite ssthresh value. The correct operation is to keep cwnd
intact because it has been updated in ECN or F-RTO.
Signed-off-by: Yuchung Cheng <ycheng@google.com>
---
net/ipv4/tcp_input.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index c93b0cb..ac417de 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2868,11 +2868,13 @@ static inline void tcp_complete_cwr(struct sock *sk)
/* Do not moderate cwnd if it's already undone in cwr or recovery. */
if (tp->undo_marker) {
- if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR)
+ if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR) {
tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
- else /* PRR */
+ } else if (tp->snd_ssthresh < TCP_INFINITE_SSTHRESH) {
+ /* PRR algorithm. */
tp->snd_cwnd = tp->snd_ssthresh;
- tp->snd_cwnd_stamp = tcp_time_stamp;
+ tp->snd_cwnd_stamp = tcp_time_stamp;
+ }
}
tcp_ca_event(sk, CA_EVENT_COMPLETE_CWR);
}
--
1.7.7.3
^ permalink raw reply related
* kernel panic, inconsistent lock, vanilla 3.3.4, 32bit, tcp
From: Denys Fedoryshchenko @ 2012-04-28 21:45 UTC (permalink / raw)
To: netdev
Hi
Just got repeatable kernel panic on loaded proxy server
Here is the log:
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.903868]
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.903880]
=================================
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.903890] [ INFO: inconsistent
lock state ]
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.903903] 3.3.4-build-0061 #8
Not tainted
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904133]
---------------------------------
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904344] inconsistent
{IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage.
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] squid/1603
[HC0[0]:SC0[0]:HE1:SE1] takes:
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] (key#3){+.?...}, at:
[<c0232cc4>] __percpu_counter_sum+0xd/0x58
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] {IN-SOFTIRQ-W} state
was registered at:
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0158b84>]
__lock_acquire+0x284/0xc26
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c01598e8>]
lock_acquire+0x71/0x85
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0349765>]
_raw_spin_lock+0x33/0x40
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0232c93>]
__percpu_counter_add+0x58/0x7c
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c02cfde1>]
sk_clone_lock+0x1e5/0x200
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0303ee4>]
inet_csk_clone_lock+0xe/0x78
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0315778>]
tcp_create_openreq_child+0x1b/0x404
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c031339c>]
tcp_v4_syn_recv_sock+0x32/0x1c1
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c031615a>]
tcp_check_req+0x1fd/0x2d7
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0313f77>]
tcp_v4_do_rcv+0xab/0x194
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c03153bb>]
tcp_v4_rcv+0x3b3/0x5cc
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c02fc0c4>]
ip_local_deliver_finish+0x13a/0x1e9
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c02fc539>]
NF_HOOK.clone.11+0x46/0x4d
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c02fc652>]
ip_local_deliver+0x41/0x45
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c02fc4d1>]
ip_rcv_finish+0x31a/0x33c
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c02fc539>]
NF_HOOK.clone.11+0x46/0x4d
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c02fc857>]
ip_rcv+0x201/0x23e
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c02daa3a>]
__netif_receive_skb+0x319/0x368
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c02dac07>]
netif_receive_skb+0x4e/0x7d
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c02dacf6>]
napi_skb_finish+0x1e/0x34
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c02db122>]
napi_gro_receive+0x20/0x24
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<f85d1743>]
e1000_receive_skb+0x3f/0x45 [e1000e]
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<f85d3464>]
e1000_clean_rx_irq+0x1f9/0x284 [e1000e]
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<f85d3926>]
e1000_clean+0x62/0x1f4 [e1000e]
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c02db228>]
net_rx_action+0x90/0x160
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c012a445>]
__do_softirq+0x7b/0x118
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] irq event stamp:
156915469
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] hardirqs last enabled
at (156915469): [<c019b4f4>] __slab_alloc.clone.58.clone.63+0xc4/0x2de
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] hardirqs last disabled
at (156915468): [<c019b452>] __slab_alloc.clone.58.clone.63+0x22/0x2de
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] softirqs last enabled
at (156915466): [<c02ce677>] lock_sock_nested+0x64/0x6c
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] softirqs last disabled
at (156915464): [<c0349914>] _raw_spin_lock_bh+0xe/0x45
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542]
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] other info that might
help us debug this:
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] Possible unsafe
locking scenario:
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542]
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] CPU0
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] ----
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] lock(key#3);
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] <Interrupt>
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] lock(key#3);
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542]
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] *** DEADLOCK ***
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542]
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] 1 lock held by
squid/1603:
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] #0:
(sk_lock-AF_INET){+.+.+.}, at: [<c03055c0>] lock_sock+0xa/0xc
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542]
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] stack backtrace:
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] Pid: 1603, comm: squid
Not tainted 3.3.4-build-0061 #8
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] Call Trace:
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0347b73>] ?
printk+0x18/0x1d
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c015873a>]
valid_state+0x1f6/0x201
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0158816>]
mark_lock+0xd1/0x1bb
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c015876b>] ?
mark_lock+0x26/0x1bb
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c015805d>] ?
check_usage_forwards+0x77/0x77
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0158bf8>]
__lock_acquire+0x2f8/0xc26
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0159b8e>] ?
mark_held_locks+0x5d/0x7b
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0159cf6>] ?
trace_hardirqs_on+0xb/0xd
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0158dd4>] ?
__lock_acquire+0x4d4/0xc26
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c01598e8>]
lock_acquire+0x71/0x85
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0232cc4>] ?
__percpu_counter_sum+0xd/0x58
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0349765>]
_raw_spin_lock+0x33/0x40
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0232cc4>] ?
__percpu_counter_sum+0xd/0x58
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0232cc4>]
__percpu_counter_sum+0xd/0x58
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c02cebc4>]
__sk_mem_schedule+0xdd/0x1c7
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c02d178d>] ?
__alloc_skb+0x76/0x100
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0305e8e>]
sk_wmem_schedule+0x21/0x2d
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0306370>]
sk_stream_alloc_skb+0x42/0xaa
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0306567>]
tcp_sendmsg+0x18f/0x68b
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c031f3dc>] ?
ip_fast_csum+0x30/0x30
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0320193>]
inet_sendmsg+0x53/0x5a
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c02cb633>]
sock_aio_write+0xd2/0xda
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c015876b>] ?
mark_lock+0x26/0x1bb
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c01a1017>]
do_sync_write+0x9f/0xd9
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c01a2111>] ?
file_free_rcu+0x2f/0x2f
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c01a17a1>]
vfs_write+0x8f/0xab
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c01a284d>] ?
fget_light+0x75/0x7c
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c01a1900>]
sys_write+0x3d/0x5e
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0349ec9>]
syscall_call+0x7/0xb
Apr 29 00:38:17 10.0.15.2 kernel: [ 762.904542] [<c0340000>] ?
rp_sidt+0x41/0x83
---
Denys Fedoryshchenko
^ permalink raw reply
* Re: [PATCH 6/6] tilegx network driver: initial support
From: Chris Metcalf @ 2012-04-28 22:07 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linux-kernel, netdev
In-Reply-To: <201204131034.03544.arnd@arndb.de>
On 4/13/2012 6:34 AM, Arnd Bergmann wrote:
> On Thursday 12 April 2012, Chris Metcalf wrote:
>> On 4/10/2012 6:42 AM, Arnd Bergmann wrote:
>>> Ok, but please remove tile_net_devs then.
>>> I think a better abstraction for tile_net_devs_for_channel would be
>>> some interface that lets you add private data to a channel so when
>>> you get data from a channel, you can extract that pointer from the driver
>>> using the channel.
>> I think what would be clearer is to document how and why we are using this
>> additional data structure. We do access via both arrays where it is
>> efficient to do so, so getting rid of either of them doesn't seem right.
In the latest round of changes (to be mailed shortly), we eliminated one of
the arrays entirely. We now just have an array of net_device pointers
indexed by channel, which we need since we get packets from the hardware
and are only given the channel. To get the device, we have to look it up
in the array.
Since this is now the only array of net_device pointers, I eliminated the
bychannel*() API I discussed in the previous email, since its use didn't
seem as compelling any more.
>> Let's keep the "normal" tile_net_devs[] as is, indexed by devno, and make
>> the tile_net_devs_for_channel[] more abstracted by using the following code:
> The tile_net_devs still feels dirty. You basically only
> use it in tile_net_handle_egress_timer(), but there you don't
> actually take the mutex that protects addition and removal from
> the array, so it's racy in case of hotplug.
We don't free the net_device structures themselves, so it's safe to do a
lookup in the array and then dereference the net_device pointer even if we
are doing an "ifconfig down" in another thread. The only way you could
imagine the net_device getting structures getting freed was via module
unload, but it turns out that was pretty broken anyway, so I've just
removed it altogether in the latest version of the patch. So once you have
a net_device pointer, it remains valid.
--
Chris Metcalf, Tilera Corp.
http://www.tilera.com
^ permalink raw reply
* Re: [PATCH] mwl8k: Add 0x2a02 PCI device-id (Marvell 88W8361)
From: Sedat Dilek @ 2012-04-28 22:25 UTC (permalink / raw)
To: Lennert Buytenhek
Cc: John W. Linville, linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, lautriv, Jim Cromie
In-Reply-To: <CA+icZUWQmCRdjucb4+Nf24_zbJ4fzzp7zjqhKjXE6U01rppDfA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 6958 bytes --]
On Fri, Apr 27, 2012 at 11:53 PM, Sedat Dilek
<sedat.dilek-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:
> On Fri, Apr 27, 2012 at 8:58 PM, Lennert Buytenhek
> <buytenh-OLH4Qvv75CYX/NnBR394Jw@public.gmane.org> wrote:
>> On Fri, Apr 27, 2012 at 03:29:26PM +0200, Sedat Dilek wrote:
>>
>>> >>> >> >> >> Are you planning to or even working on support (for) 8361 devices?
>>> >>> >> >> >
>>> >>> >> >> > I don't have any such plans, and I don't know of anyone who does.
>>> >>> >> >>
>>> >>> >> >> Does 8361 require firmware support?
>>> >>> >> >
>>> >>> >> > What do you mean by that?
>>> >>> >>
>>> >>> >> IIRC ath5k for example needs no external firmware file.
>>> >>> >
>>> >>> > The 8361 requires firmware to be loaded into it before it'll do
>>> >>> > anything useful.
>>> >>> >
>>> >>> >
>>> >>> >> >> Does a firmware file exist (name?)?
>>> >>> >> >
>>> >>> >> > There's firmware for the 8361 out there, however, that version of
>>> >>> >> > the firmware implements a firmware API that is different from the
>>> >>> >> > one that mwl8k currently implements.
>>> >>> >> >
>>> >>> >> > You could add 8361 support to mwl8k, but then you'd have to go over
>>> >>> >> > all the firmware command invocations in mwl8k and make sure that they
>>> >>> >> > will work on the 8361 firmware that you're trying to support as well.
>>> >>> >>
>>> >>> >> Without having a 8361 this will be even harder to walk through.
>>> >>> >>
>>> >>> >> Anyway, thanks for your detailed explanations.
>>> >>> >>
>>> >>> >> What's the alternative for such affected users?
>>> >>> >> Use ndis-wrapper?
>>> >>> >
>>> >>> > I'm not sure. I've never tried to get a 8361 work under Linux.
>>> >>>
>>> >>> Just found on [1] this same wrong patch in [2] :-).
>>> >>> Dunno if [3] worked and from where they have stolen fw-files.
>>> >>>
>>> >>> - Sedat -
>>> >>>
>>> >>> [1] https://dev.openwrt.org/ticket/7209
>>> >>> [2] https://dev.openwrt.org/attachment/ticket/7209/mwl8k_fix_pci_id.patch
>>> >>> [3] https://dev.openwrt.org/attachment/ticket/7209/mwl8k_8361p.patch
>>> >>
>>> >> I doubt that [3] is really all that's needed to make it work. But if
>>> >> there's someone for whom it works, I'd like them to run some tests on
>>> >> mwl8k + [3] on 88w8361p.
>>> >
>>> > Just asked lautriv to do so (he will do against linux-3.3.3), lets' see.
>>> > Also, I refreshed and adapted a bit the instructions (see attachment).
>>> >
>>> > - Sedat -
>>>
>>> [ CC Jim Cromie ]
>>>
>>> Now, with extracted firmware files renamed & copied to
>>> /lib/firmware/mwl8k/ and applied patch (see attachment) against
>>> Linux-3.4-rc4+ I am seeing with modinfo:
>>>
>>> $ sudo modinfo mwl8k
>>> filename:
>>> /lib/modules/3.4.0-rc4-5-generic/kernel/drivers/net/wireless/mwl8k.ko
>>> license: GPL
>>> author: Lennert Buytenhek <buytenh@marvell.com>
>>> version: 0.13
>>> description: Marvell TOPDOG(R) 802.11 Wireless Network Driver
>>> firmware: mwl8k/fmimage_8366_ap-2.fw
>>> firmware: mwl8k/fmimage_8366.fw
>>> firmware: mwl8k/helper_8366.fw
>>> firmware: mwl8k/fmimage_8687.fw
>>> firmware: mwl8k/helper_8687.fw
>>> firmware: mwl8k/fmimage_8363.fw
>>> firmware: mwl8k/helper_8363.fw
>>> firmware: mwl8k/fmimage_8361p.fw
>>> firmware: mwl8k/helper_8361p.fw
>>> srcversion: 9E1479A05C8D67E6AE90746
>>> alias: pci:v000011ABd00002A43sv*sd*bc*sc*i*
>>> alias: pci:v000011ABd00002A40sv*sd*bc*sc*i*
>>> alias: pci:v000011ABd00002A30sv*sd*bc*sc*i*
>>> alias: pci:v000011ABd00002A2Bsv*sd*bc*sc*i*
>>> alias: pci:v000011ABd00002A24sv*sd*bc*sc*i*
>>> alias: pci:v000011ABd00002A0Csv*sd*bc*sc*i*
>>> alias: pci:v000011ABd00002A0Asv*sd*bc*sc*i*
>>> alias: pci:v000011ABd00002A02sv*sd*bc*sc*i* <--- 8361P:
>>> 0x2a02 PCI device-id
>>> depends: mac80211,cfg80211
>>> vermagic: 3.4.0-rc4-5-generic SMP mod_unload modversions
>>> parm: ap_mode_default:Set to 1 to make ap mode the default
>>> instead of sta mode (bool)
>>>
>>> $ ls -l /lib/firmware/mwl8k/
>>> insgesamt 456
>>> -rw-r--r-- 1 root root 75848 Apr 27 13:49 fmimage_8361p.fw <---
>>> 8361P: Firmware image
>>> -rw-r--r-- 1 root root 101780 Mär 19 19:32 fmimage_8366_ap-1.fw
>>> -rw-r--r-- 1 root root 101976 Mär 19 19:32 fmimage_8366_ap-2.fw
>>> -rw-r--r-- 1 root root 96664 Mär 19 19:32 fmimage_8366.fw
>>> -rw-r--r-- 1 root root 73252 Feb 23 20:07 fmimage_8687.fw
>>> -rw-r--r-- 1 root root 2476 Apr 27 13:49 helper_8361p.fw <--- 8361P:
>>> Helper image
>>> -rw-r--r-- 1 root root 2476 Mär 19 19:32 helper_8366.fw
>>> -rw-r--r-- 1 root root 2476 Feb 23 20:07 helper_8687.fw
>>>
>>> As said... ***compile-tested*** only here.
>>
>> Which doesn't say much at all, but..
>>
>
> As already pointed out, no Marwell WLAN hardware here. Marvell comics
> of course :-).
>
>>
>>> I had a short query with lautriv on #linux-wireless this afternoon:
>>> * mwl8k kernel-module was autoloaded
>>> * wlan0 interface got fired up
>>> * ESSID was accepted
>>> * logs reported 802.11bgn support is active
>>> * (he tested on Linux-3.3.3)
>>>
>>> With WPA/WPA2 lautriv had some problems as his installation was
>>> missing wpasupplicant.
>>> He setup a classic /etc/network/interfaces.
>>> After resetting his router mwl8k worked nicely.
>>>
>>> Unfortunately, he was on the run and promised me to send logs and do
>>> more testing this evening.
>>
>> ..but this is pretty interesting. I thought that the only available
>> 8361p firmware used an incompatible firmware API, and I didn't know
>> of the existence of an apparently compatible firmware.
>>
>>
>>> So, Lennert if you want more testing - What? How? etc.
>>
>> For one, the output of 'iw phy', please.
>>
>> Also, does monitor mode work? Do you get plausible channel/rxpower
>> values in tcpdump in monitor mode?
>>
>> Are there any messages in the syslog about failing commands?
>>
>>
>> thanks,
>> Lennert
>
> On 1st sight, logs look fine:
>
> [21:52:52] <lautriv> [ 6.050967] ieee80211 phy0: 88w8361p v4,
> 00173f3bdde3, STA firmware 2.1.4.25
>
> But WLAN connection is not that fast and stable as lautriv reports
> (several abnormalities were observed).
>
> I requested a tarball which includes:
> * dmesg (Linux-3.3.3)
> * e_n_a (/etc/network/interfaces)
> * ifconfig output
> * iwconfig output
> * iw_phy output
> * ps_axu (WPA) output
>
> lautriv will be so kind to be around on #linux-wireless/Freenode the
> next days (UTC+2: German/Swiss local-time).
> Just ping him.
>
> Hope you have fun, together!
>
> - Sedat -
A new tarball from lautriv with same outputs as before, but now tested
with Linux-3.4-rc4.
- Sedat -
[-- Attachment #2: 8361p_3.4.0-rc4.tar.xz --]
[-- Type: application/octet-stream, Size: 9944 bytes --]
^ permalink raw reply
* Re: [PATCH] mwl8k: Add 0x2a02 PCI device-id (Marvell 88W8361)
From: Jim Cromie @ 2012-04-28 22:36 UTC (permalink / raw)
To: sedat.dilek-Re5JQEeQqe8AvxtiuMwx3w
Cc: Lennert Buytenhek, John W. Linville,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, lautriv
In-Reply-To: <CA+icZUXSaEMA=KbQP9UQcU6ZMBh8QD2sv-O=6r_Ly8is==gvSA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 8916 bytes --]
[dropped lkml from cc]
On Sat, Apr 28, 2012 at 4:25 PM, Sedat Dilek <sedat.dilek-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:
> On Fri, Apr 27, 2012 at 11:53 PM, Sedat Dilek
> <sedat.dilek-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:
>> On Fri, Apr 27, 2012 at 8:58 PM, Lennert Buytenhek
>> <buytenh-OLH4Qvv75CYX/NnBR394Jw@public.gmane.org> wrote:
>>> On Fri, Apr 27, 2012 at 03:29:26PM +0200, Sedat Dilek wrote:
>>>
>>>> >>> >> >> >> Are you planning to or even working on support (for) 8361 devices?
>>>> >>> >> >> >
>>>> >>> >> >> > I don't have any such plans, and I don't know of anyone who does.
>>>> >>> >> >>
>>>> >>> >> >> Does 8361 require firmware support?
>>>> >>> >> >
>>>> >>> >> > What do you mean by that?
>>>> >>> >>
>>>> >>> >> IIRC ath5k for example needs no external firmware file.
>>>> >>> >
>>>> >>> > The 8361 requires firmware to be loaded into it before it'll do
>>>> >>> > anything useful.
>>>> >>> >
>>>> >>> >
>>>> >>> >> >> Does a firmware file exist (name?)?
>>>> >>> >> >
>>>> >>> >> > There's firmware for the 8361 out there, however, that version of
>>>> >>> >> > the firmware implements a firmware API that is different from the
>>>> >>> >> > one that mwl8k currently implements.
>>>> >>> >> >
>>>> >>> >> > You could add 8361 support to mwl8k, but then you'd have to go over
>>>> >>> >> > all the firmware command invocations in mwl8k and make sure that they
>>>> >>> >> > will work on the 8361 firmware that you're trying to support as well.
>>>> >>> >>
>>>> >>> >> Without having a 8361 this will be even harder to walk through.
>>>> >>> >>
>>>> >>> >> Anyway, thanks for your detailed explanations.
>>>> >>> >>
>>>> >>> >> What's the alternative for such affected users?
>>>> >>> >> Use ndis-wrapper?
>>>> >>> >
>>>> >>> > I'm not sure. I've never tried to get a 8361 work under Linux.
>>>> >>>
>>>> >>> Just found on [1] this same wrong patch in [2] :-).
>>>> >>> Dunno if [3] worked and from where they have stolen fw-files.
>>>> >>>
>>>> >>> - Sedat -
>>>> >>>
>>>> >>> [1] https://dev.openwrt.org/ticket/7209
>>>> >>> [2] https://dev.openwrt.org/attachment/ticket/7209/mwl8k_fix_pci_id.patch
>>>> >>> [3] https://dev.openwrt.org/attachment/ticket/7209/mwl8k_8361p.patch
>>>> >>
>>>> >> I doubt that [3] is really all that's needed to make it work. But if
>>>> >> there's someone for whom it works, I'd like them to run some tests on
>>>> >> mwl8k + [3] on 88w8361p.
>>>> >
>>>> > Just asked lautriv to do so (he will do against linux-3.3.3), lets' see.
>>>> > Also, I refreshed and adapted a bit the instructions (see attachment).
>>>> >
>>>> > - Sedat -
>>>>
>>>> [ CC Jim Cromie ]
>>>>
>>>> Now, with extracted firmware files renamed & copied to
>>>> /lib/firmware/mwl8k/ and applied patch (see attachment) against
>>>> Linux-3.4-rc4+ I am seeing with modinfo:
>>>>
>>>> $ sudo modinfo mwl8k
>>>> filename:
>>>> /lib/modules/3.4.0-rc4-5-generic/kernel/drivers/net/wireless/mwl8k.ko
>>>> license: GPL
>>>> author: Lennert Buytenhek <buytenh-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
>>>> version: 0.13
>>>> description: Marvell TOPDOG(R) 802.11 Wireless Network Driver
>>>> firmware: mwl8k/fmimage_8366_ap-2.fw
>>>> firmware: mwl8k/fmimage_8366.fw
>>>> firmware: mwl8k/helper_8366.fw
>>>> firmware: mwl8k/fmimage_8687.fw
>>>> firmware: mwl8k/helper_8687.fw
>>>> firmware: mwl8k/fmimage_8363.fw
>>>> firmware: mwl8k/helper_8363.fw
>>>> firmware: mwl8k/fmimage_8361p.fw
>>>> firmware: mwl8k/helper_8361p.fw
>>>> srcversion: 9E1479A05C8D67E6AE90746
>>>> alias: pci:v000011ABd00002A43sv*sd*bc*sc*i*
>>>> alias: pci:v000011ABd00002A40sv*sd*bc*sc*i*
>>>> alias: pci:v000011ABd00002A30sv*sd*bc*sc*i*
>>>> alias: pci:v000011ABd00002A2Bsv*sd*bc*sc*i*
>>>> alias: pci:v000011ABd00002A24sv*sd*bc*sc*i*
>>>> alias: pci:v000011ABd00002A0Csv*sd*bc*sc*i*
>>>> alias: pci:v000011ABd00002A0Asv*sd*bc*sc*i*
>>>> alias: pci:v000011ABd00002A02sv*sd*bc*sc*i* <--- 8361P:
>>>> 0x2a02 PCI device-id
>>>> depends: mac80211,cfg80211
>>>> vermagic: 3.4.0-rc4-5-generic SMP mod_unload modversions
>>>> parm: ap_mode_default:Set to 1 to make ap mode the default
>>>> instead of sta mode (bool)
>>>>
>>>> $ ls -l /lib/firmware/mwl8k/
>>>> insgesamt 456
>>>> -rw-r--r-- 1 root root 75848 Apr 27 13:49 fmimage_8361p.fw <---
>>>> 8361P: Firmware image
>>>> -rw-r--r-- 1 root root 101780 Mär 19 19:32 fmimage_8366_ap-1.fw
>>>> -rw-r--r-- 1 root root 101976 Mär 19 19:32 fmimage_8366_ap-2.fw
>>>> -rw-r--r-- 1 root root 96664 Mär 19 19:32 fmimage_8366.fw
>>>> -rw-r--r-- 1 root root 73252 Feb 23 20:07 fmimage_8687.fw
>>>> -rw-r--r-- 1 root root 2476 Apr 27 13:49 helper_8361p.fw <--- 8361P:
>>>> Helper image
>>>> -rw-r--r-- 1 root root 2476 Mär 19 19:32 helper_8366.fw
>>>> -rw-r--r-- 1 root root 2476 Feb 23 20:07 helper_8687.fw
>>>>
>>>> As said... ***compile-tested*** only here.
>>>
>>> Which doesn't say much at all, but..
>>>
>>
>> As already pointed out, no Marwell WLAN hardware here. Marvell comics
>> of course :-).
>>
>>>
>>>> I had a short query with lautriv on #linux-wireless this afternoon:
>>>> * mwl8k kernel-module was autoloaded
>>>> * wlan0 interface got fired up
>>>> * ESSID was accepted
>>>> * logs reported 802.11bgn support is active
>>>> * (he tested on Linux-3.3.3)
>>>>
>>>> With WPA/WPA2 lautriv had some problems as his installation was
>>>> missing wpasupplicant.
>>>> He setup a classic /etc/network/interfaces.
>>>> After resetting his router mwl8k worked nicely.
>>>>
>>>> Unfortunately, he was on the run and promised me to send logs and do
>>>> more testing this evening.
>>>
>>> ..but this is pretty interesting. I thought that the only available
>>> 8361p firmware used an incompatible firmware API, and I didn't know
>>> of the existence of an apparently compatible firmware.
>>>
>>>
>>>> So, Lennert if you want more testing - What? How? etc.
>>>
>>> For one, the output of 'iw phy', please.
>>>
>>> Also, does monitor mode work? Do you get plausible channel/rxpower
>>> values in tcpdump in monitor mode?
>>>
>>> Are there any messages in the syslog about failing commands?
>>>
>>>
>>> thanks,
>>> Lennert
>>
>> On 1st sight, logs look fine:
>>
>> [21:52:52] <lautriv> [ 6.050967] ieee80211 phy0: 88w8361p v4,
>> 00173f3bdde3, STA firmware 2.1.4.25
>>
>> But WLAN connection is not that fast and stable as lautriv reports
>> (several abnormalities were observed).
>>
>> I requested a tarball which includes:
>> * dmesg (Linux-3.3.3)
>> * e_n_a (/etc/network/interfaces)
>> * ifconfig output
>> * iwconfig output
>> * iw_phy output
>> * ps_axu (WPA) output
>>
>> lautriv will be so kind to be around on #linux-wireless/Freenode the
>> next days (UTC+2: German/Swiss local-time).
>> Just ping him.
>>
>> Hope you have fun, together!
>>
>> - Sedat -
>
> A new tarball from lautriv with same outputs as before, but now tested
> with Linux-3.4-rc4.
>
> - Sedat -
heres my logs, using firmware extracted by Sedat's script,
and the patch on mwl8k.c
bottom-line, it appears to be working.
its contents are a bit more pedantic, and includes data for
another wifi card (rtl8180 based) also in the box.
It was obtained by this script:
#!/bin/bash
# dmesg (Linux-3.3.3)
# e_n_a (/etc/network/interfaces)
# ifconfig output
# iwconfig output
# iw_phy output
# ps_axu (WPA) output
devs="wlan0 wlan1"
apmac=00:14:d1:e8:65:0a
loudly () {
echo "# $@"
fname=`echo $@ | sed -e 's/ /-/g'`
$@ 2> $fname-err | tee $fname
[ $? != 0 ] && echo non-zero exit on $fname: $?
[ -s $fname-err ] || rm $fname-err
}
( iw --debug event -f > iw-event-f )&
pid_event=$!
for N in 0 1 ; do
loudly iw dev wlan$N interface add fish$N type monitor # flags none
loudly iw dev fish$N set channel 8
loudly ifconfig fish$N up
( tcpdump -i fish$N -s 65000 -p -U -w fish$N.dump )&
pid_dump_fish$N=$!
done
loudly iw list
#loudly iwspy
# gives: Interface doesn't support wireless statistic collection
for dev in $devs ; do
loudly ifconfig $dev
loudly iwconfig $dev
loudly iwlist $dev scan
loudly iw dev $dev info
loudly iw dev $dev link
loudly iw dev $dev scan
loudly iw dev $dev survey dump
done
for phy in $phys ; do
loudly iw phy $phy info
done
# these are unsupported on wlan0
loudly iw dev wlan1 survey dump
loudly iw dev wlan1 station dump
loudly iw dev wlan1 station get $apmac
for N in 0 1 ; do
loudly iw dev fish$N del
done
kill $pid_dump_fish0 $pid_dump_fish0
kill $pid_event
dmesg > dmesg
grep -vE '^#|key' /etc/network/interfaces > e_n_a
exit
[-- Attachment #2: mwl8k-8361p-logs.tgz --]
[-- Type: application/x-gzip, Size: 32883 bytes --]
^ permalink raw reply
* Re: [PATCH] mwl8k: Add 0x2a02 PCI device-id (Marvell 88W8361)
From: Sedat Dilek @ 2012-04-28 22:49 UTC (permalink / raw)
To: Jim Cromie
Cc: Lennert Buytenhek, John W. Linville, linux-wireless, netdev,
lautriv
In-Reply-To: <CAJfuBxw7YFAC9CLAGNmg3nM_g2xH2vuiz07D-3xOcyn2XuP5vA@mail.gmail.com>
On Sun, Apr 29, 2012 at 12:36 AM, Jim Cromie <jim.cromie@gmail.com> wrote:
> [dropped lkml from cc]
>
> On Sat, Apr 28, 2012 at 4:25 PM, Sedat Dilek <sedat.dilek@googlemail.com> wrote:
>> On Fri, Apr 27, 2012 at 11:53 PM, Sedat Dilek
>> <sedat.dilek@googlemail.com> wrote:
>>> On Fri, Apr 27, 2012 at 8:58 PM, Lennert Buytenhek
>>> <buytenh@wantstofly.org> wrote:
>>>> On Fri, Apr 27, 2012 at 03:29:26PM +0200, Sedat Dilek wrote:
>>>>
>>>>> >>> >> >> >> Are you planning to or even working on support (for) 8361 devices?
>>>>> >>> >> >> >
>>>>> >>> >> >> > I don't have any such plans, and I don't know of anyone who does.
>>>>> >>> >> >>
>>>>> >>> >> >> Does 8361 require firmware support?
>>>>> >>> >> >
>>>>> >>> >> > What do you mean by that?
>>>>> >>> >>
>>>>> >>> >> IIRC ath5k for example needs no external firmware file.
>>>>> >>> >
>>>>> >>> > The 8361 requires firmware to be loaded into it before it'll do
>>>>> >>> > anything useful.
>>>>> >>> >
>>>>> >>> >
>>>>> >>> >> >> Does a firmware file exist (name?)?
>>>>> >>> >> >
>>>>> >>> >> > There's firmware for the 8361 out there, however, that version of
>>>>> >>> >> > the firmware implements a firmware API that is different from the
>>>>> >>> >> > one that mwl8k currently implements.
>>>>> >>> >> >
>>>>> >>> >> > You could add 8361 support to mwl8k, but then you'd have to go over
>>>>> >>> >> > all the firmware command invocations in mwl8k and make sure that they
>>>>> >>> >> > will work on the 8361 firmware that you're trying to support as well.
>>>>> >>> >>
>>>>> >>> >> Without having a 8361 this will be even harder to walk through.
>>>>> >>> >>
>>>>> >>> >> Anyway, thanks for your detailed explanations.
>>>>> >>> >>
>>>>> >>> >> What's the alternative for such affected users?
>>>>> >>> >> Use ndis-wrapper?
>>>>> >>> >
>>>>> >>> > I'm not sure. I've never tried to get a 8361 work under Linux.
>>>>> >>>
>>>>> >>> Just found on [1] this same wrong patch in [2] :-).
>>>>> >>> Dunno if [3] worked and from where they have stolen fw-files.
>>>>> >>>
>>>>> >>> - Sedat -
>>>>> >>>
>>>>> >>> [1] https://dev.openwrt.org/ticket/7209
>>>>> >>> [2] https://dev.openwrt.org/attachment/ticket/7209/mwl8k_fix_pci_id.patch
>>>>> >>> [3] https://dev.openwrt.org/attachment/ticket/7209/mwl8k_8361p.patch
>>>>> >>
>>>>> >> I doubt that [3] is really all that's needed to make it work. But if
>>>>> >> there's someone for whom it works, I'd like them to run some tests on
>>>>> >> mwl8k + [3] on 88w8361p.
>>>>> >
>>>>> > Just asked lautriv to do so (he will do against linux-3.3.3), lets' see.
>>>>> > Also, I refreshed and adapted a bit the instructions (see attachment).
>>>>> >
>>>>> > - Sedat -
>>>>>
>>>>> [ CC Jim Cromie ]
>>>>>
>>>>> Now, with extracted firmware files renamed & copied to
>>>>> /lib/firmware/mwl8k/ and applied patch (see attachment) against
>>>>> Linux-3.4-rc4+ I am seeing with modinfo:
>>>>>
>>>>> $ sudo modinfo mwl8k
>>>>> filename:
>>>>> /lib/modules/3.4.0-rc4-5-generic/kernel/drivers/net/wireless/mwl8k.ko
>>>>> license: GPL
>>>>> author: Lennert Buytenhek <buytenh@marvell.com>
>>>>> version: 0.13
>>>>> description: Marvell TOPDOG(R) 802.11 Wireless Network Driver
>>>>> firmware: mwl8k/fmimage_8366_ap-2.fw
>>>>> firmware: mwl8k/fmimage_8366.fw
>>>>> firmware: mwl8k/helper_8366.fw
>>>>> firmware: mwl8k/fmimage_8687.fw
>>>>> firmware: mwl8k/helper_8687.fw
>>>>> firmware: mwl8k/fmimage_8363.fw
>>>>> firmware: mwl8k/helper_8363.fw
>>>>> firmware: mwl8k/fmimage_8361p.fw
>>>>> firmware: mwl8k/helper_8361p.fw
>>>>> srcversion: 9E1479A05C8D67E6AE90746
>>>>> alias: pci:v000011ABd00002A43sv*sd*bc*sc*i*
>>>>> alias: pci:v000011ABd00002A40sv*sd*bc*sc*i*
>>>>> alias: pci:v000011ABd00002A30sv*sd*bc*sc*i*
>>>>> alias: pci:v000011ABd00002A2Bsv*sd*bc*sc*i*
>>>>> alias: pci:v000011ABd00002A24sv*sd*bc*sc*i*
>>>>> alias: pci:v000011ABd00002A0Csv*sd*bc*sc*i*
>>>>> alias: pci:v000011ABd00002A0Asv*sd*bc*sc*i*
>>>>> alias: pci:v000011ABd00002A02sv*sd*bc*sc*i* <--- 8361P:
>>>>> 0x2a02 PCI device-id
>>>>> depends: mac80211,cfg80211
>>>>> vermagic: 3.4.0-rc4-5-generic SMP mod_unload modversions
>>>>> parm: ap_mode_default:Set to 1 to make ap mode the default
>>>>> instead of sta mode (bool)
>>>>>
>>>>> $ ls -l /lib/firmware/mwl8k/
>>>>> insgesamt 456
>>>>> -rw-r--r-- 1 root root 75848 Apr 27 13:49 fmimage_8361p.fw <---
>>>>> 8361P: Firmware image
>>>>> -rw-r--r-- 1 root root 101780 Mär 19 19:32 fmimage_8366_ap-1.fw
>>>>> -rw-r--r-- 1 root root 101976 Mär 19 19:32 fmimage_8366_ap-2.fw
>>>>> -rw-r--r-- 1 root root 96664 Mär 19 19:32 fmimage_8366.fw
>>>>> -rw-r--r-- 1 root root 73252 Feb 23 20:07 fmimage_8687.fw
>>>>> -rw-r--r-- 1 root root 2476 Apr 27 13:49 helper_8361p.fw <--- 8361P:
>>>>> Helper image
>>>>> -rw-r--r-- 1 root root 2476 Mär 19 19:32 helper_8366.fw
>>>>> -rw-r--r-- 1 root root 2476 Feb 23 20:07 helper_8687.fw
>>>>>
>>>>> As said... ***compile-tested*** only here.
>>>>
>>>> Which doesn't say much at all, but..
>>>>
>>>
>>> As already pointed out, no Marwell WLAN hardware here. Marvell comics
>>> of course :-).
>>>
>>>>
>>>>> I had a short query with lautriv on #linux-wireless this afternoon:
>>>>> * mwl8k kernel-module was autoloaded
>>>>> * wlan0 interface got fired up
>>>>> * ESSID was accepted
>>>>> * logs reported 802.11bgn support is active
>>>>> * (he tested on Linux-3.3.3)
>>>>>
>>>>> With WPA/WPA2 lautriv had some problems as his installation was
>>>>> missing wpasupplicant.
>>>>> He setup a classic /etc/network/interfaces.
>>>>> After resetting his router mwl8k worked nicely.
>>>>>
>>>>> Unfortunately, he was on the run and promised me to send logs and do
>>>>> more testing this evening.
>>>>
>>>> ..but this is pretty interesting. I thought that the only available
>>>> 8361p firmware used an incompatible firmware API, and I didn't know
>>>> of the existence of an apparently compatible firmware.
>>>>
>>>>
>>>>> So, Lennert if you want more testing - What? How? etc.
>>>>
>>>> For one, the output of 'iw phy', please.
>>>>
>>>> Also, does monitor mode work? Do you get plausible channel/rxpower
>>>> values in tcpdump in monitor mode?
>>>>
>>>> Are there any messages in the syslog about failing commands?
>>>>
>>>>
>>>> thanks,
>>>> Lennert
>>>
>>> On 1st sight, logs look fine:
>>>
>>> [21:52:52] <lautriv> [ 6.050967] ieee80211 phy0: 88w8361p v4,
>>> 00173f3bdde3, STA firmware 2.1.4.25
>>>
>>> But WLAN connection is not that fast and stable as lautriv reports
>>> (several abnormalities were observed).
>>>
>>> I requested a tarball which includes:
>>> * dmesg (Linux-3.3.3)
>>> * e_n_a (/etc/network/interfaces)
>>> * ifconfig output
>>> * iwconfig output
>>> * iw_phy output
>>> * ps_axu (WPA) output
>>>
>>> lautriv will be so kind to be around on #linux-wireless/Freenode the
>>> next days (UTC+2: German/Swiss local-time).
>>> Just ping him.
>>>
>>> Hope you have fun, together!
>>>
>>> - Sedat -
>>
>> A new tarball from lautriv with same outputs as before, but now tested
>> with Linux-3.4-rc4.
>>
>> - Sedat -
>
>
> heres my logs, using firmware extracted by Sedat's script,
> and the patch on mwl8k.c
>
> bottom-line, it appears to be working.
>
> its contents are a bit more pedantic, and includes data for
> another wifi card (rtl8180 based) also in the box.
> It was obtained by this script:
>
> #!/bin/bash
>
> # dmesg (Linux-3.3.3)
> # e_n_a (/etc/network/interfaces)
> # ifconfig output
> # iwconfig output
> # iw_phy output
> # ps_axu (WPA) output
>
> devs="wlan0 wlan1"
> apmac=00:14:d1:e8:65:0a
>
> loudly () {
> echo "# $@"
> fname=`echo $@ | sed -e 's/ /-/g'`
> $@ 2> $fname-err | tee $fname
> [ $? != 0 ] && echo non-zero exit on $fname: $?
> [ -s $fname-err ] || rm $fname-err
> }
>
> ( iw --debug event -f > iw-event-f )&
> pid_event=$!
>
> for N in 0 1 ; do
> loudly iw dev wlan$N interface add fish$N type monitor # flags none
> loudly iw dev fish$N set channel 8
> loudly ifconfig fish$N up
> ( tcpdump -i fish$N -s 65000 -p -U -w fish$N.dump )&
> pid_dump_fish$N=$!
> done
>
> loudly iw list
>
> #loudly iwspy
> # gives: Interface doesn't support wireless statistic collection
>
> for dev in $devs ; do
> loudly ifconfig $dev
> loudly iwconfig $dev
> loudly iwlist $dev scan
> loudly iw dev $dev info
> loudly iw dev $dev link
> loudly iw dev $dev scan
> loudly iw dev $dev survey dump
> done
>
> for phy in $phys ; do
> loudly iw phy $phy info
> done
>
> # these are unsupported on wlan0
> loudly iw dev wlan1 survey dump
> loudly iw dev wlan1 station dump
> loudly iw dev wlan1 station get $apmac
>
>
> for N in 0 1 ; do
> loudly iw dev fish$N del
> done
>
> kill $pid_dump_fish0 $pid_dump_fish0
> kill $pid_event
>
> dmesg > dmesg
>
> grep -vE '^#|key' /etc/network/interfaces > e_n_a
>
> exit
Hi Jim,
thanks for your testing and the nice testcase-script!
lautriv you wanna run some more tests with Jim's script?
Jim, how stable/fast/reliable is your WLAN connection?
Suspend/resume tested?
Hope this helps to get native Linux support for 8361p.
Regards,
- Sedat -
P.S.: BTW, only to clarify it should be "e_n_i" as short-form for
/etc/network/interfaces file, but e_n_a sounds more female and nicer
:-).
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox