summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/isdn/hardware/mISDN/hfc_multi.h15
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c582
-rw-r--r--drivers/isdn/mISDN/dsp.h4
-rw-r--r--drivers/isdn/mISDN/dsp_cmx.c19
-rw-r--r--drivers/isdn/mISDN/dsp_dtmf.c19
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c2
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_hw.c428
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_hw.h515
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_main.c243
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h5
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c93
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h8
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c2
-rw-r--r--drivers/net/ethernet/emulex/benet/be_hw.h74
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c221
-rw-r--r--include/linux/sock_diag.h4
-rw-r--r--include/linux/tcp.h5
-rw-r--r--net/core/sock_diag.c12
-rw-r--r--net/dcb/dcbnl.c2
-rw-r--r--net/ieee802154/6lowpan.c85
-rw-r--r--net/ieee802154/6lowpan.h3
-rw-r--r--net/ipv4/inet_diag.c4
-rw-r--r--net/ipv4/tcp.c60
-rw-r--r--net/ipv6/ip6_output.c4
-rw-r--r--net/ipv6/reassembly.c2
-rw-r--r--net/unix/diag.c2
26 files changed, 1452 insertions, 961 deletions
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h
index b0588acbb47d..c601f880141e 100644
--- a/drivers/isdn/hardware/mISDN/hfc_multi.h
+++ b/drivers/isdn/hardware/mISDN/hfc_multi.h
@@ -205,18 +205,22 @@ struct hfc_multi {
u_int slots; /* number of PCM slots */
u_int leds; /* type of leds */
- u_int ledcount; /* used to animate leds */
u_long ledstate; /* save last state of leds */
int opticalsupport; /* has the e1 board */
/* an optical Interface */
- int dslot; /* channel # of d-channel (E1) default 16 */
+
+ u_int bmask[32]; /* bitmask of bchannels for port */
+ u_char dnum[32]; /* array of used dchannel numbers for port */
+ u_char created[32]; /* what port is created */
+ u_int activity_tx; /* if there is data TX / RX */
+ u_int activity_rx; /* bitmask according to port number */
+ /* (will be cleared after */
+ /* showing led-states) */
+ u_int flash[8]; /* counter for flashing 8 leds on activity */
u_long wdcount; /* every 500 ms we need to */
/* send the watchdog a signal */
u_char wdbyte; /* watchdog toggle byte */
- u_int activity[8]; /* if there is any action on this */
- /* port (will be cleared after */
- /* showing led-states) */
int e1_state; /* keep track of last state */
int e1_getclock; /* if sync is retrieved from interface */
int syncronized; /* keep track of existing sync interface */
@@ -233,7 +237,6 @@ struct hfc_multi {
* the bch->channel is equvalent to the hfc-channel
*/
struct hfc_chan chan[32];
- u_char created[8]; /* what port is created */
signed char slot_owner[256]; /* owner channel of slot */
};
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index 033223180b55..43013316b9b0 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -103,14 +103,26 @@
* Omit this value, if all cards are interconnected or none is connected.
* If unsure, don't give this parameter.
*
- * dslot:
- * NOTE: only one dslot value must be given for every card.
- * Also this value must be given for non-E1 cards. If omitted, the E1
- * card has D-channel on time slot 16, which is default.
- * If 1..15 or 17..31, an alternate time slot is used for D-channel.
- * In this case, the application must be able to handle this.
- * If -1 is given, the D-channel is disabled and all 31 slots can be used
- * for B-channel. (only for specific applications)
+ * dmask and bmask:
+ * NOTE: One dmask value must be given for every HFC-E1 card.
+ * If omitted, the E1 card has D-channel on time slot 16, which is default.
+ * dmask is a 32 bit mask. The bit must be set for an alternate time slot.
+ * If multiple bits are set, multiple virtual card fragments are created.
+ * For each bit set, a bmask value must be given. Each bit on the bmask
+ * value stands for a B-channel. The bmask may not overlap with dmask or
+ * with other bmask values for that card.
+ * Example: dmask=0x00020002 bmask=0x0000fffc,0xfffc0000
+ * This will create one fragment with D-channel on slot 1 with
+ * B-channels on slots 2..15, and a second fragment with D-channel
+ * on slot 17 with B-channels on slot 18..31. Slot 16 is unused.
+ * If bit 0 is set (dmask=0x00000001) the D-channel is on slot 0 and will
+ * not function.
+ * Example: dmask=0x00000001 bmask=0xfffffffe
+ * This will create a port with all 31 usable timeslots as
+ * B-channels.
+ * If no bits are set on bmask, no B-channel is created for that fragment.
+ * Example: dmask=0xfffffffe bmask=0,0,0,0.... (31 0-values for bmask)
+ * This will create 31 ports with one D-channel only.
* If you don't know how to use it, you don't need it!
*
* iomode:
@@ -172,6 +184,7 @@
#define MAX_CARDS 8
#define MAX_PORTS (8 * MAX_CARDS)
+#define MAX_FRAGS (32 * MAX_CARDS)
static LIST_HEAD(HFClist);
static spinlock_t HFClock; /* global hfc list lock */
@@ -203,7 +216,8 @@ static int nt_t1_count[] = { 3840, 1920, 960, 480, 240, 120, 60, 30 };
static uint type[MAX_CARDS];
static int pcm[MAX_CARDS];
-static int dslot[MAX_CARDS];
+static uint dmask[MAX_CARDS];
+static uint bmask[MAX_FRAGS];
static uint iomode[MAX_CARDS];
static uint port[MAX_PORTS];
static uint debug;
@@ -218,7 +232,7 @@ static uint clockdelay_nt = CLKDEL_NT;
#define HWID_MINIP16 3
static uint hwid = HWID_NONE;
-static int HFC_cnt, Port_cnt, PCM_cnt = 99;
+static int HFC_cnt, E1_cnt, bmask_cnt, Port_cnt, PCM_cnt = 99;
MODULE_AUTHOR("Andreas Eversberg");
MODULE_LICENSE("GPL");
@@ -231,7 +245,8 @@ module_param(clockdelay_te, uint, S_IRUGO | S_IWUSR);
module_param(clockdelay_nt, uint, S_IRUGO | S_IWUSR);
module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR);
module_param_array(pcm, int, NULL, S_IRUGO | S_IWUSR);
-module_param_array(dslot, int, NULL, S_IRUGO | S_IWUSR);
+module_param_array(dmask, uint, NULL, S_IRUGO | S_IWUSR);
+module_param_array(bmask, uint, NULL, S_IRUGO | S_IWUSR);
module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR);
module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);
module_param(hwid, uint, S_IRUGO | S_IWUSR); /* The hardware ID */
@@ -1607,40 +1622,46 @@ hfcmulti_leds(struct hfc_multi *hc)
struct dchannel *dch;
int led[4];
- hc->ledcount += poll;
- if (hc->ledcount > 4096) {
- hc->ledcount -= 4096;
- hc->ledstate = 0xAFFEAFFE;
- }
-
switch (hc->leds) {
case 1: /* HFC-E1 OEM */
- /* 2 red blinking: NT mode deactivate
- * 2 red steady: TE mode deactivate
- * left green: L1 active
- * left red: frame sync, but no L1
- * right green: L2 active
+ /* 2 red steady: LOS
+ * 1 red steady: L1 not active
+ * 2 green steady: L1 active
+ * 1st green flashing: activity on TX
+ * 2nd green flashing: activity on RX
*/
- if (hc->chan[hc->dslot].sync != 2) { /* no frame sync */
- if (hc->chan[hc->dslot].dch->dev.D.protocol
- != ISDN_P_NT_E1) {
- led[0] = 1;
+ led[0] = 0;
+ led[1] = 0;
+ led[2] = 0;
+ led[3] = 0;
+ dch = hc->chan[hc->dnum[0]].dch;
+ if (dch) {
+ if (hc->chan[hc->dnum[0]].los)
led[1] = 1;
- } else if (hc->ledcount >> 11) {
+ if (hc->e1_state != 1) {
led[0] = 1;
- led[1] = 1;
+ hc->flash[2] = 0;
+ hc->flash[3] = 0;
} else {
- led[0] = 0;
- led[1] = 0;
+ led[2] = 1;
+ led[3] = 1;
+ if (!hc->flash[2] && hc->activity_tx)
+ hc->flash[2] = poll;
+ if (!hc->flash[3] && hc->activity_rx)
+ hc->flash[3] = poll;
+ if (hc->flash[2] && hc->flash[2] < 1024)
+ led[2] = 0;
+ if (hc->flash[3] && hc->flash[3] < 1024)
+ led[3] = 0;
+ if (hc->flash[2] >= 2048)
+ hc->flash[2] = 0;
+ if (hc->flash[3] >= 2048)
+ hc->flash[3] = 0;
+ if (hc->flash[2])
+ hc->flash[2] += poll;
+ if (hc->flash[3])
+ hc->flash[3] += poll;
}
- led[2] = 0;
- led[3] = 0;
- } else { /* with frame sync */
- /* TODO make it work */
- led[0] = 0;
- led[1] = 0;
- led[2] = 0;
- led[3] = 1;
}
leds = (led[0] | (led[1]<<2) | (led[2]<<1) | (led[3]<<3))^0xF;
/* leds are inverted */
@@ -1651,9 +1672,9 @@ hfcmulti_leds(struct hfc_multi *hc)
break;
case 2: /* HFC-4S OEM */
- /* red blinking = PH_DEACTIVATE NT Mode
- * red steady = PH_DEACTIVATE TE Mode
- * green steady = PH_ACTIVATE
+ /* red steady: PH_DEACTIVATE
+ * green steady: PH_ACTIVATE
+ * green flashing: activity on TX
*/
for (i = 0; i < 4; i++) {
state = 0;
@@ -1669,17 +1690,20 @@ hfcmulti_leds(struct hfc_multi *hc)
if (state) {
if (state == active) {
led[i] = 1; /* led green */
- } else
- if (dch->dev.D.protocol == ISDN_P_TE_S0)
- /* TE mode: led red */
- led[i] = 2;
- else
- if (hc->ledcount >> 11)
- /* led red */
- led[i] = 2;
- else
- /* led off */
- led[i] = 0;
+ hc->activity_tx |= hc->activity_rx;
+ if (!hc->flash[i] &&
+ (hc->activity_tx & (1 << i)))
+ hc->flash[i] = poll;
+ if (hc->flash[i] && hc->flash[i] < 1024)
+ led[i] = 0; /* led off */
+ if (hc->flash[i] >= 2048)
+ hc->flash[i] = 0;
+ if (hc->flash[i])
+ hc->flash[i] += poll;
+ } else {
+ led[i] = 2; /* led red */
+ hc->flash[i] = 0;
+ }
} else
led[i] = 0; /* led off */
}
@@ -1712,9 +1736,9 @@ hfcmulti_leds(struct hfc_multi *hc)
break;
case 3: /* HFC 1S/2S Beronet */
- /* red blinking = PH_DEACTIVATE NT Mode
- * red steady = PH_DEACTIVATE TE Mode
- * green steady = PH_ACTIVATE
+ /* red steady: PH_DEACTIVATE
+ * green steady: PH_ACTIVATE
+ * green flashing: activity on TX
*/
for (i = 0; i < 2; i++) {
state = 0;
@@ -1730,22 +1754,23 @@ hfcmulti_leds(struct hfc_multi *hc)
if (state) {
if (state == active) {
led[i] = 1; /* led green */
- } else
- if (dch->dev.D.protocol == ISDN_P_TE_S0)
- /* TE mode: led red */
- led[i] = 2;
- else
- if (hc->ledcount >> 11)
- /* led red */
- led[i] = 2;
- else
- /* led off */
- led[i] = 0;
+ hc->activity_tx |= hc->activity_rx;
+ if (!hc->flash[i] &&
+ (hc->activity_tx & (1 << i)))
+ hc->flash[i] = poll;
+ if (hc->flash[i] < 1024)
+ led[i] = 0; /* led off */
+ if (hc->flash[i] >= 2048)
+ hc->flash[i] = 0;
+ if (hc->flash[i])
+ hc->flash[i] += poll;
+ } else {
+ led[i] = 2; /* led red */
+ hc->flash[i] = 0;
+ }
} else
led[i] = 0; /* led off */
}
-
-
leds = (led[0] > 0) | ((led[1] > 0) << 1) | ((led[0]&1) << 2)
| ((led[1]&1) << 3);
if (leds != (int)hc->ledstate) {
@@ -1757,8 +1782,11 @@ hfcmulti_leds(struct hfc_multi *hc)
}
break;
case 8: /* HFC 8S+ Beronet */
- lled = 0;
-
+ /* off: PH_DEACTIVATE
+ * steady: PH_ACTIVATE
+ * flashing: activity on TX
+ */
+ lled = 0xff; /* leds off */
for (i = 0; i < 8; i++) {
state = 0;
active = -1;
@@ -1772,14 +1800,20 @@ hfcmulti_leds(struct hfc_multi *hc)
}
if (state) {
if (state == active) {
- lled |= 0 << i;
+ lled &= ~(1 << i); /* led on */
+ hc->activity_tx |= hc->activity_rx;
+ if (!hc->flash[i] &&
+ (hc->activity_tx & (1 << i)))
+ hc->flash[i] = poll;
+ if (hc->flash[i] < 1024)
+ lled |= 1 << i; /* led off */
+ if (hc->flash[i] >= 2048)
+ hc->flash[i] = 0;
+ if (hc->flash[i])
+ hc->flash[i] += poll;
} else
- if (hc->ledcount >> 11)
- lled |= 0 << i;
- else
- lled |= 1 << i;
- } else
- lled |= 1 << i;
+ hc->flash[i] = 0;
+ }
}
leddw = lled << 24 | lled << 16 | lled << 8 | lled;
if (leddw != hc->ledstate) {
@@ -1794,6 +1828,8 @@ hfcmulti_leds(struct hfc_multi *hc)
}
break;
}
+ hc->activity_tx = 0;
+ hc->activity_rx = 0;
}
/*
* read dtmf coefficients
@@ -2093,7 +2129,8 @@ next_frame:
*txpending = 1;
/* show activity */
- hc->activity[hc->chan[ch].port] = 1;
+ if (dch)
+ hc->activity_tx |= 1 << hc->chan[ch].port;
/* fill fifo to what we have left */
ii = len;
@@ -2236,7 +2273,8 @@ next_frame:
}
}
/* show activity */
- hc->activity[hc->chan[ch].port] = 1;
+ if (dch)
+ hc->activity_rx |= 1 << hc->chan[ch].port;
/* empty fifo with what we have */
if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
@@ -2430,55 +2468,55 @@ handle_timer_irq(struct hfc_multi *hc)
}
}
if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) {
- dch = hc->chan[hc->dslot].dch;
- if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
- /* LOS */
- temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;
- if (!temp && hc->chan[hc->dslot].los)
+ dch = hc->chan[hc->dnum[0]].dch;
+ /* LOS */
+ temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;
+ hc->chan[hc->dnum[0]].los = temp;
+ if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
+ if (!temp && hc->chan[hc->dnum[0]].los)
signal_state_up(dch, L1_SIGNAL_LOS_ON,
"LOS detected");
- if (temp && !hc->chan[hc->dslot].los)
+ if (temp && !hc->chan[hc->dnum[0]].los)
signal_state_up(dch, L1_SIGNAL_LOS_OFF,
"LOS gone");
- hc->chan[hc->dslot].los = temp;
}
- if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dslot].cfg)) {
+ if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dnum[0]].cfg)) {
/* AIS */
temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS;
- if (!temp && hc->chan[hc->dslot].ais)
+ if (!temp && hc->chan[hc->dnum[0]].ais)
signal_state_up(dch, L1_SIGNAL_AIS_ON,
"AIS detected");
- if (temp && !hc->chan[hc->dslot].ais)
+ if (temp && !hc->chan[hc->dnum[0]].ais)
signal_state_up(dch, L1_SIGNAL_AIS_OFF,
"AIS gone");
- hc->chan[hc->dslot].ais = temp;
+ hc->chan[hc->dnum[0]].ais = temp;
}
- if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dslot].cfg)) {
+ if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dnum[0]].cfg)) {
/* SLIP */
temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX;
- if (!temp && hc->chan[hc->dslot].slip_rx)
+ if (!temp && hc->chan[hc->dnum[0]].slip_rx)
signal_state_up(dch, L1_SIGNAL_SLIP_RX,
" bit SLIP detected RX");
- hc->chan[hc->dslot].slip_rx = temp;
+ hc->chan[hc->dnum[0]].slip_rx = temp;
temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX;
- if (!temp && hc->chan[hc->dslot].slip_tx)
+ if (!temp && hc->chan[hc->dnum[0]].slip_tx)
signal_state_up(dch, L1_SIGNAL_SLIP_TX,
" bit SLIP detected TX");
- hc->chan[hc->dslot].slip_tx = temp;
+ hc->chan[hc->dnum[0]].slip_tx = temp;
}
- if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dslot].cfg)) {
+ if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dnum[0]].cfg)) {
/* RDI */
temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A;
- if (!temp && hc->chan[hc->dslot].rdi)
+ if (!temp && hc->chan[hc->dnum[0]].rdi)
signal_state_up(dch, L1_SIGNAL_RDI_ON,
"RDI detected");
- if (temp && !hc->chan[hc->dslot].rdi)
+ if (temp && !hc->chan[hc->dnum[0]].rdi)
signal_state_up(dch, L1_SIGNAL_RDI_OFF,
"RDI gone");
- hc->chan[hc->dslot].rdi = temp;
+ hc->chan[hc->dnum[0]].rdi = temp;
}
temp = HFC_inb_nodebug(hc, R_JATT_DIR);
- switch (hc->chan[hc->dslot].sync) {
+ switch (hc->chan[hc->dnum[0]].sync) {
case 0:
if ((temp & 0x60) == 0x60) {
if (debug & DEBUG_HFCMULTI_SYNC)
@@ -2487,10 +2525,10 @@ handle_timer_irq(struct hfc_multi *hc)
"in clock sync\n",
__func__, hc->id);
HFC_outb(hc, R_RX_OFF,
- hc->chan[hc->dslot].jitter | V_RX_INIT);
+ hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
HFC_outb(hc, R_TX_OFF,
- hc->chan[hc->dslot].jitter | V_RX_INIT);
- hc->chan[hc->dslot].sync = 1;
+ hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
+ hc->chan[hc->dnum[0]].sync = 1;
goto check_framesync;
}
break;
@@ -2501,7 +2539,7 @@ handle_timer_irq(struct hfc_multi *hc)
"%s: (id=%d) E1 "
"lost clock sync\n",
__func__, hc->id);
- hc->chan[hc->dslot].sync = 0;
+ hc->chan[hc->dnum[0]].sync = 0;
break;
}
check_framesync:
@@ -2512,7 +2550,7 @@ handle_timer_irq(struct hfc_multi *hc)
"%s: (id=%d) E1 "
"now in frame sync\n",
__func__, hc->id);
- hc->chan[hc->dslot].sync = 2;
+ hc->chan[hc->dnum[0]].sync = 2;
}
break;
case 2:
@@ -2522,7 +2560,7 @@ handle_timer_irq(struct hfc_multi *hc)
"%s: (id=%d) E1 lost "
"clock & frame sync\n",
__func__, hc->id);
- hc->chan[hc->dslot].sync = 0;
+ hc->chan[hc->dnum[0]].sync = 0;
break;
}
temp = HFC_inb_nodebug(hc, R_SYNC_STA);
@@ -2532,7 +2570,7 @@ handle_timer_irq(struct hfc_multi *hc)
"%s: (id=%d) E1 "
"lost frame sync\n",
__func__, hc->id);
- hc->chan[hc->dslot].sync = 1;
+ hc->chan[hc->dnum[0]].sync = 1;
}
break;
}
@@ -2673,7 +2711,7 @@ hfcmulti_interrupt(int intno, void *dev_id)
int i;
void __iomem *plx_acc;
u_short wval;
- u_char e1_syncsta, temp;
+ u_char e1_syncsta, temp, temp2;
u_long flags;
if (!hc) {
@@ -2748,7 +2786,7 @@ hfcmulti_interrupt(int intno, void *dev_id)
if (r_irq_misc & V_STA_IRQ) {
if (hc->ctype == HFC_TYPE_E1) {
/* state machine */
- dch = hc->chan[hc->dslot].dch;
+ dch = hc->chan[hc->dnum[0]].dch;
e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA);
if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
&& hc->e1_getclock) {
@@ -2758,23 +2796,26 @@ hfcmulti_interrupt(int intno, void *dev_id)
hc->syncronized = 0;
}
/* undocumented: status changes during read */
- dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA);
- while (dch->state != (temp =
+ temp = HFC_inb_nodebug(hc, R_E1_RD_STA);
+ while (temp != (temp2 =
HFC_inb_nodebug(hc, R_E1_RD_STA))) {
if (debug & DEBUG_HFCMULTI_STATE)
printk(KERN_DEBUG "%s: reread "
"STATE because %d!=%d\n",
- __func__, temp,
- dch->state);
- dch->state = temp; /* repeat */
+ __func__, temp, temp2);
+ temp = temp2; /* repeat */
}
- dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)
- & 0x7;
- schedule_event(dch, FLG_PHCHANGE);
+ /* broadcast state change to all fragments */
if (debug & DEBUG_HFCMULTI_STATE)
printk(KERN_DEBUG
"%s: E1 (id=%d) newstate %x\n",
- __func__, hc->id, dch->state);
+ __func__, hc->id, temp & 0x7);
+ for (i = 0; i < hc->ports; i++) {
+ dch = hc->chan[hc->dnum[i]].dch;
+ dch->state = temp & 0x7;
+ schedule_event(dch, FLG_PHCHANGE);
+ }
+
if (test_bit(HFC_CHIP_PLXSD, &hc->chip))
plxsd_checksync(hc, 0);
}
@@ -3018,8 +3059,10 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF);
HFC_outb(hc, A_SUBCH_CFG, 0);
HFC_outb(hc, A_IRQ_MSK, 0);
- HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
- HFC_wait(hc);
+ if (hc->chan[ch].protocol != protocol) {
+ HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
+ HFC_wait(hc);
+ }
HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) +
((ch % 4) * 4) + 1) << 1) | 1);
HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1) | 1);
@@ -3039,8 +3082,10 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF);
HFC_outb(hc, A_SUBCH_CFG, 0);
HFC_outb(hc, A_IRQ_MSK, 0);
- HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
- HFC_wait(hc);
+ if (hc->chan[ch].protocol != protocol) {
+ HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
+ HFC_wait(hc);
+ }
/* tx silence */
HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +
@@ -3059,8 +3104,10 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
V_HDLC_TRP | V_IFF);
HFC_outb(hc, A_SUBCH_CFG, 0);
HFC_outb(hc, A_IRQ_MSK, 0);
- HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
- HFC_wait(hc);
+ if (hc->chan[ch].protocol != protocol) {
+ HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
+ HFC_wait(hc);
+ }
/* tx silence */
HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
/* enable RX fifo */
@@ -3075,8 +3122,10 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
V_HDLC_TRP);
HFC_outb(hc, A_SUBCH_CFG, 0);
HFC_outb(hc, A_IRQ_MSK, 0);
- HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
- HFC_wait(hc);
+ if (hc->chan[ch].protocol != protocol) {
+ HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
+ HFC_wait(hc);
+ }
}
if (hc->ctype != HFC_TYPE_E1) {
hc->hw.a_st_ctrl0[hc->chan[ch].port] |=
@@ -3839,31 +3888,37 @@ hfcmulti_initmode(struct dchannel *dch)
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: entered\n", __func__);
+ i = dch->slot;
+ pt = hc->chan[i].port;
if (hc->ctype == HFC_TYPE_E1) {
- hc->chan[hc->dslot].slot_tx = -1;
- hc->chan[hc->dslot].slot_rx = -1;
- hc->chan[hc->dslot].conf = -1;
- if (hc->dslot) {
- mode_hfcmulti(hc, hc->dslot, dch->dev.D.protocol,
+ /* E1 */
+ hc->chan[hc->dnum[pt]].slot_tx = -1;
+ hc->chan[hc->dnum[pt]].slot_rx = -1;
+ hc->chan[hc->dnum[pt]].conf = -1;
+ if (hc->dnum[pt]) {
+ mode_hfcmulti(hc, dch->slot, dch->dev.D.protocol,
-1, 0, -1, 0);
dch->timer.function = (void *) hfcmulti_dbusy_timer;
dch->timer.data = (long) dch;
init_timer(&dch->timer);
}
for (i = 1; i <= 31; i++) {
- if (i == hc->dslot)
+ if (!((1 << i) & hc->bmask[pt])) /* skip unused chan */
continue;
hc->chan[i].slot_tx = -1;
hc->chan[i].slot_rx = -1;
hc->chan[i].conf = -1;
mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0);
}
- /* E1 */
- if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
+ }
+ if (hc->ctype == HFC_TYPE_E1 && pt == 0) {
+ /* E1, port 0 */
+ dch = hc->chan[hc->dnum[0]].dch;
+ if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
HFC_outb(hc, R_LOS0, 255); /* 2 ms */
HFC_outb(hc, R_LOS1, 255); /* 512 ms */
}
- if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dslot].cfg)) {
+ if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dnum[0]].cfg)) {
HFC_outb(hc, R_RX0, 0);
hc->hw.r_tx0 = 0 | V_OUT_EN;
} else {
@@ -3876,12 +3931,12 @@ hfcmulti_initmode(struct dchannel *dch)
HFC_outb(hc, R_TX_FR0, 0x00);
HFC_outb(hc, R_TX_FR1, 0xf8);
- if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
+ if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg))
HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E);
HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0);
- if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
+ if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg))
HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC);
if (dch->dev.D.protocol == ISDN_P_NT_E1) {
@@ -3944,13 +3999,14 @@ hfcmulti_initmode(struct dchannel *dch)
hc->syncronized = 0;
plxsd_checksync(hc, 0);
}
- } else {
- i = dch->slot;
+ }
+ if (hc->ctype != HFC_TYPE_E1) {
+ /* ST */
hc->chan[i].slot_tx = -1;
hc->chan[i].slot_rx = -1;
hc->chan[i].conf = -1;
mode_hfcmulti(hc, i, dch->dev.D.protocol, -1, 0, -1, 0);
- dch->timer.function = (void *)hfcmulti_dbusy_timer;
+ dch->timer.function = (void *) hfcmulti_dbusy_timer;
dch->timer.data = (long) dch;
init_timer(&dch->timer);
hc->chan[i - 2].slot_tx = -1;
@@ -3961,8 +4017,6 @@ hfcmulti_initmode(struct dchannel *dch)
hc->chan[i - 1].slot_rx = -1;
hc->chan[i - 1].conf = -1;
mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0);
- /* ST */
- pt = hc->chan[i].port;
/* select interface */
HFC_outb(hc, R_ST_SEL, pt);
/* undocumented: delay after R_ST_SEL */
@@ -4054,14 +4108,9 @@ open_dchannel(struct hfc_multi *hc, struct dchannel *dch,
hfcmulti_initmode(dch);
spin_unlock_irqrestore(&hc->lock, flags);
}
-
- if (((rq->protocol == ISDN_P_NT_S0) && (dch->state == 3)) ||
- ((rq->protocol == ISDN_P_TE_S0) && (dch->state == 7)) ||
- ((rq->protocol == ISDN_P_NT_E1) && (dch->state == 1)) ||
- ((rq->protocol == ISDN_P_TE_E1) && (dch->state == 1))) {
+ if (test_bit(FLG_ACTIVE, &dch->Flags))
_queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY,
0, NULL, GFP_KERNEL);
- }
rq->ch = &dch->dev.D;
if (!try_module_get(THIS_MODULE))
printk(KERN_WARNING "%s:cannot get module\n", __func__);
@@ -4545,6 +4594,8 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
}
/* free channels */
for (i = 0; i <= 31; i++) {
+ if (!((1 << i) & hc->bmask[pt])) /* skip unused chan */
+ continue;
if (hc->chan[i].bch) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
@@ -4600,7 +4651,8 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
spin_unlock_irqrestore(&hc->lock, flags);
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_DEBUG "%s: free port %d channel D\n", __func__, pt);
+ printk(KERN_DEBUG "%s: free port %d channel D(%d)\n", __func__,
+ pt+1, ci);
mISDN_freedchannel(dch);
kfree(dch);
@@ -4622,15 +4674,19 @@ release_card(struct hfc_multi *hc)
if (hc->iclock)
mISDN_unregister_clock(hc->iclock);
- /* disable irq */
+ /* disable and free irq */
spin_lock_irqsave(&hc->lock, flags);
disable_hwirq(hc);
spin_unlock_irqrestore(&hc->lock, flags);
udelay(1000);
+ if (hc->irq) {
+ if (debug & DEBUG_HFCMULTI_INIT)
+ printk(KERN_DEBUG "%s: free irq %d (hc=%p)\n",
+ __func__, hc->irq, hc);
+ free_irq(hc->irq, hc);
+ hc->irq = 0;
- /* dimm leds */
- if (hc->leds)
- hfcmulti_leds(hc);
+ }
/* disable D-channels & B-channels */
if (debug & DEBUG_HFCMULTI_INIT)
@@ -4641,15 +4697,11 @@ release_card(struct hfc_multi *hc)
release_port(hc, hc->chan[ch].dch);
}
- /* release hardware & irq */
- if (hc->irq) {
- if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_DEBUG "%s: free irq %d\n",
- __func__, hc->irq);
- free_irq(hc->irq, hc);
- hc->irq = 0;
+ /* dimm leds */
+ if (hc->leds)
+ hfcmulti_leds(hc);
- }
+ /* release hardware */
release_io_hfcmulti(hc);
if (debug & DEBUG_HFCMULTI_INIT)
@@ -4667,61 +4719,9 @@ release_card(struct hfc_multi *hc)
__func__);
}
-static int
-init_e1_port(struct hfc_multi *hc, struct hm_map *m)
+static void
+init_e1_port_hw(struct hfc_multi *hc, struct hm_map *m)
{
- struct dchannel *dch;
- struct bchannel *bch;
- int ch, ret = 0;
- char name[MISDN_MAX_IDLEN];
-
- dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
- if (!dch)
- return -ENOMEM;
- dch->debug = debug;
- mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change);
- dch->hw = hc;
- dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1);
- dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
- (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
- dch->dev.D.send = handle_dmsg;
- dch->dev.D.ctrl = hfcm_dctrl;
- dch->dev.nrbchan = (hc->dslot) ? 30 : 31;
- dch->slot = hc->dslot;
- hc->chan[hc->dslot].dch = dch;
- hc->chan[hc->dslot].port = 0;
- hc->chan[hc->dslot].nt_timer = -1;
- for (ch = 1; ch <= 31; ch++) {
- if (ch == hc->dslot) /* skip dchannel */
- continue;
- bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
- if (!bch) {
- printk(KERN_ERR "%s: no memory for bchannel\n",
- __func__);
- ret = -ENOMEM;
- goto free_chan;
- }
- hc->chan[ch].coeff = kzalloc(512, GFP_KERNEL);
- if (!hc->chan[ch].coeff) {
- printk(KERN_ERR "%s: no memory for coeffs\n",
- __func__);
- ret = -ENOMEM;
- kfree(bch);
- goto free_chan;
- }
- bch->nr = ch;
- bch->slot = ch;
- bch->debug = debug;
- mISDN_initbchannel(bch, MAX_DATA_MEM);
- bch->hw = hc;
- bch->ch.send = handle_bmsg;
- bch->ch.ctrl = hfcm_bctrl;
- bch->ch.nr = ch;
- list_add(&bch->ch.list, &dch->dev.bchannels);
- hc->chan[ch].bch = bch;
- hc->chan[ch].port = 0;
- set_channelmap(bch->nr, dch->dev.channelmap);
- }
/* set optical line type */
if (port[Port_cnt] & 0x001) {
if (!m->opticalsupport) {
@@ -4737,7 +4737,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
__func__,
HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_OPTICAL,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[0]].cfg);
}
}
/* set LOS report */
@@ -4747,7 +4747,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
"LOS report: card(%d) port(%d)\n",
__func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_REPORT_LOS,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[0]].cfg);
}
/* set AIS report */
if (port[Port_cnt] & 0x008) {
@@ -4756,7 +4756,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
"AIS report: card(%d) port(%d)\n",
__func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_REPORT_AIS,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[0]].cfg);
}
/* set SLIP report */
if (port[Port_cnt] & 0x010) {
@@ -4766,7 +4766,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
"card(%d) port(%d)\n",
__func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_REPORT_SLIP,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[0]].cfg);
}
/* set RDI report */
if (port[Port_cnt] & 0x020) {
@@ -4776,7 +4776,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
"card(%d) port(%d)\n",
__func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_REPORT_RDI,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[0]].cfg);
}
/* set CRC-4 Mode */
if (!(port[Port_cnt] & 0x100)) {
@@ -4785,7 +4785,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
" card(%d) port(%d)\n",
__func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_CRC4,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[0]].cfg);
} else {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: PORT turn off CRC4"
@@ -4817,20 +4817,85 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
}
/* set elastic jitter buffer */
if (port[Port_cnt] & 0x3000) {
- hc->chan[hc->dslot].jitter = (port[Port_cnt]>>12) & 0x3;
+ hc->chan[hc->dnum[0]].jitter = (port[Port_cnt]>>12) & 0x3;
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
"%s: PORT set elastic "
"buffer to %d: card(%d) port(%d)\n",
- __func__, hc->chan[hc->dslot].jitter,
+ __func__, hc->chan[hc->dnum[0]].jitter,
HFC_cnt + 1, 1);
} else
- hc->chan[hc->dslot].jitter = 2; /* default */
- snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
+ hc->chan[hc->dnum[0]].jitter = 2; /* default */
+}
+
+static int
+init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt)
+{
+ struct dchannel *dch;
+ struct bchannel *bch;
+ int ch, ret = 0;
+ char name[MISDN_MAX_IDLEN];
+ int bcount = 0;
+
+ dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
+ if (!dch)
+ return -ENOMEM;
+ dch->debug = debug;
+ mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change);
+ dch->hw = hc;
+ dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1);
+ dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
+ (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
+ dch->dev.D.send = handle_dmsg;
+ dch->dev.D.ctrl = hfcm_dctrl;
+ dch->slot = hc->dnum[pt];
+ hc->chan[hc->dnum[pt]].dch = dch;
+ hc->chan[hc->dnum[pt]].port = pt;
+ hc->chan[hc->dnum[pt]].nt_timer = -1;
+ for (ch = 1; ch <= 31; ch++) {
+ if (!((1 << ch) & hc->bmask[pt])) /* skip unused channel */
+ continue;
+ bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
+ if (!bch) {
+ printk(KERN_ERR "%s: no memory for bchannel\n",
+ __func__);
+ ret = -ENOMEM;
+ goto free_chan;
+ }
+ hc->chan[ch].coeff = kzalloc(512, GFP_KERNEL);
+ if (!hc->chan[ch].coeff) {
+ printk(KERN_ERR "%s: no memory for coeffs\n",
+ __func__);
+ ret = -ENOMEM;
+ kfree(bch);
+ goto free_chan;
+ }
+ bch->nr = ch;
+ bch->slot = ch;
+ bch->debug = debug;
+ mISDN_initbchannel(bch, MAX_DATA_MEM);
+ bch->hw = hc;
+ bch->ch.send = handle_bmsg;
+ bch->ch.ctrl = hfcm_bctrl;
+ bch->ch.nr = ch;
+ list_add(&bch->ch.list, &dch->dev.bchannels);
+ hc->chan[ch].bch = bch;
+ hc->chan[ch].port = pt;
+ set_channelmap(bch->nr, dch->dev.channelmap);
+ bcount++;
+ }
+ dch->dev.nrbchan = bcount;
+ if (pt == 0)
+ init_e1_port_hw(hc, m);
+ if (hc->ports > 1)
+ snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d-%d",
+ HFC_cnt + 1, pt+1);
+ else
+ snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
if (ret)
goto free_chan;
- hc->created[0] = 1;
+ hc->created[pt] = 1;
return ret;
free_chan:
release_port(hc, dch);
@@ -4963,7 +5028,8 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
struct hfc_multi *hc;
u_long flags;
u_char dips = 0, pmj = 0; /* dip settings, port mode Jumpers */
- int i;
+ int i, ch;
+ u_int maskcheck;
if (HFC_cnt >= MAX_CARDS) {
printk(KERN_ERR "too many cards (max=%d).\n",
@@ -4997,18 +5063,36 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
hc->id = HFC_cnt;
hc->pcm = pcm[HFC_cnt];
hc->io_mode = iomode[HFC_cnt];
- if (dslot[HFC_cnt] < 0 && hc->ctype == HFC_TYPE_E1) {
- hc->dslot = 0;
- printk(KERN_INFO "HFC-E1 card has disabled D-channel, but "
- "31 B-channels\n");
- }
- if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32
- && hc->ctype == HFC_TYPE_E1) {
- hc->dslot = dslot[HFC_cnt];
- printk(KERN_INFO "HFC-E1 card has alternating D-channel on "
- "time slot %d\n", dslot[HFC_cnt]);
- } else
- hc->dslot = 16;
+ if (hc->ctype == HFC_TYPE_E1 && dmask[E1_cnt]) {
+ /* fragment card */
+ pt = 0;
+ maskcheck = 0;
+ for (ch = 0; ch <= 31; ch++) {
+ if (!((1 << ch) & dmask[E1_cnt]))
+ continue;
+ hc->dnum[pt] = ch;
+ hc->bmask[pt] = bmask[bmask_cnt++];
+ if ((maskcheck & hc->bmask[pt])
+ || (dmask[E1_cnt] & hc->bmask[pt])) {
+ printk(KERN_INFO
+ "HFC-E1 #%d has overlapping B-channels on fragment #%d\n",
+ E1_cnt + 1, pt);
+ return -EINVAL;
+ }
+ maskcheck |= hc->bmask[pt];
+ printk(KERN_INFO
+ "HFC-E1 #%d uses D-channel on slot %d and a B-channel map of 0x%08x\n",
+ E1_cnt + 1, ch, hc->bmask[pt]);
+ pt++;
+ }
+ hc->ports = pt;
+ }
+ if (hc->ctype == HFC_TYPE_E1 && !dmask[E1_cnt]) {
+ /* default card layout */
+ hc->dnum[0] = 16;
+ hc->bmask[0] = 0xfffefffe;
+ hc->ports = 1;
+ }
/* set chip specific features */
hc->masterclk = -1;
@@ -5091,23 +5175,33 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
goto free_card;
}
if (hc->ctype == HFC_TYPE_E1)
- ret_err = init_e1_port(hc, m);
+ ret_err = init_e1_port(hc, m, pt);
else
ret_err = init_multi_port(hc, pt);
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: Registering D-channel, card(%d) port(%d)"
+ "%s: Registering D-channel, card(%d) port(%d) "
"result %d\n",
- __func__, HFC_cnt + 1, pt, ret_err);
+ __func__, HFC_cnt + 1, pt + 1, ret_err);
if (ret_err) {
while (pt) { /* release already registered ports */
pt--;
- release_port(hc, hc->chan[(pt << 2) + 2].dch);
+ if (hc->ctype == HFC_TYPE_E1)
+ release_port(hc,
+ hc->chan[hc->dnum[pt]].dch);
+ else
+ release_port(hc,
+ hc->chan[(pt << 2) + 2].dch);
}
goto free_card;
}
- Port_cnt++;
+ if (hc->ctype != HFC_TYPE_E1)
+ Port_cnt++; /* for each S0 port */
+ }
+ if (hc->ctype == HFC_TYPE_E1) {
+ Port_cnt++; /* for each E1 port */
+ E1_cnt++;
}
/* disp switches */
diff --git a/drivers/isdn/mISDN/dsp.h b/drivers/isdn/mISDN/dsp.h
index afe4173ae007..fc1733a08845 100644
--- a/drivers/isdn/mISDN/dsp.h
+++ b/drivers/isdn/mISDN/dsp.h
@@ -76,7 +76,9 @@ extern u8 dsp_silence;
#define MAX_SECONDS_JITTER_CHECK 5
extern struct timer_list dsp_spl_tl;
-extern u32 dsp_spl_jiffies;
+
+/* the datatype need to match jiffies datatype */
+extern unsigned long dsp_spl_jiffies;
/* the structure of conferences:
*
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c
index 334feab060a1..a4f05c54c32b 100644
--- a/drivers/isdn/mISDN/dsp_cmx.c
+++ b/drivers/isdn/mISDN/dsp_cmx.c
@@ -742,8 +742,8 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
member->dsp->pcm_slot_tx,
member->dsp->pcm_bank_tx,
member->dsp->pcm_bank_rx);
- conf->hardware = 0;
- conf->software = 1;
+ conf->hardware = 1;
+ conf->software = tx_data;
return;
}
/* find a new slot */
@@ -834,8 +834,8 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
nextm->dsp->name,
member->dsp->pcm_slot_tx,
member->dsp->pcm_slot_rx);
- conf->hardware = 0;
- conf->software = 1;
+ conf->hardware = 1;
+ conf->software = tx_data;
return;
}
/* find two new slot */
@@ -939,8 +939,11 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
/* for more than two members.. */
/* if all members already have the same conference */
- if (all_conf)
+ if (all_conf) {
+ conf->hardware = 1;
+ conf->software = tx_data;
return;
+ }
/*
* if there is an existing conference, but not all members have joined
@@ -1013,6 +1016,8 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
dsp_cmx_hw_message(member->dsp,
MISDN_CTRL_HFC_CONF_JOIN, current_conf, 0, 0, 0);
}
+ conf->hardware = 1;
+ conf->software = tx_data;
return;
}
@@ -1328,7 +1333,7 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
}
if (dsp->conf && dsp->conf->software && dsp->conf->hardware)
tx_data_only = 1;
- if (dsp->conf->software && dsp->echo.hardware)
+ if (dsp->echo.software && dsp->echo.hardware)
tx_data_only = 1;
}
@@ -1619,7 +1624,7 @@ send_packet:
static u32 jittercount; /* counter for jitter check */
struct timer_list dsp_spl_tl;
-u32 dsp_spl_jiffies; /* calculate the next time to fire */
+unsigned long dsp_spl_jiffies; /* calculate the next time to fire */
static u16 dsp_count; /* last sample count */
static int dsp_count_valid; /* if we have last sample count */
diff --git a/drivers/isdn/mISDN/dsp_dtmf.c b/drivers/isdn/mISDN/dsp_dtmf.c
index 887860bdc63b..642f30be5ce2 100644
--- a/drivers/isdn/mISDN/dsp_dtmf.c
+++ b/drivers/isdn/mISDN/dsp_dtmf.c
@@ -222,16 +222,25 @@ coefficients:
goto storedigit;
}
- if (dsp_debug & DEBUG_DSP_DTMFCOEFF)
+ if (dsp_debug & DEBUG_DSP_DTMFCOEFF) {
+ s32 tresh_100 = tresh/100;
+
+ if (tresh_100 == 0) {
+ tresh_100 = 1;
+ printk(KERN_DEBUG
+ "tresh(%d) too small set tresh/100 to 1\n",
+ tresh);
+ }
printk(KERN_DEBUG "a %3d %3d %3d %3d %3d %3d %3d %3d"
" tr:%3d r %3d %3d %3d %3d %3d %3d %3d %3d\n",
result[0] / 10000, result[1] / 10000, result[2] / 10000,
result[3] / 10000, result[4] / 10000, result[5] / 10000,
result[6] / 10000, result[7] / 10000, tresh / 10000,
- result[0] / (tresh / 100), result[1] / (tresh / 100),
- result[2] / (tresh / 100), result[3] / (tresh / 100),
- result[4] / (tresh / 100), result[5] / (tresh / 100),
- result[6] / (tresh / 100), result[7] / (tresh / 100));
+ result[0] / (tresh_100), result[1] / (tresh_100),
+ result[2] / (tresh_100), result[3] / (tresh_100),
+ result[4] / (tresh_100), result[5] / (tresh_100),
+ result[6] / (tresh_100), result[7] / (tresh_100));
+ }
/* calc digit (lowgroup/highgroup) */
lowgroup = -1;
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c b/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c
index 3feb846d40e4..859ea844ba0f 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c
@@ -153,7 +153,7 @@ static void atl1c_get_regs(struct net_device *netdev,
AT_READ_REG(hw, REG_LINK_CTRL, p++);
AT_READ_REG(hw, REG_IDLE_STATUS, p++);
AT_READ_REG(hw, REG_MDIO_CTRL, p++);
- AT_READ_REG(hw, REG_SERDES_LOCK, p++);
+ AT_READ_REG(hw, REG_SERDES, p++);
AT_READ_REG(hw, REG_MAC_CTRL, p++);
AT_READ_REG(hw, REG_MAC_IPG_IFG, p++);
AT_READ_REG(hw, REG_MAC_STA_ADDR, p++);
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
index bd1667cbffa6..07f017f59b39 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
@@ -278,33 +278,158 @@ void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value)
}
/*
- * Reads the value from a PHY register
- * hw - Struct containing variables accessed by shared code
- * reg_addr - address of the PHY register to read
+ * wait mdio module be idle
+ * return true: idle
+ * false: still busy
*/
-int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
+bool atl1c_wait_mdio_idle(struct atl1c_hw *hw)
{
u32 val;
int i;
- val = ((u32)(reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT |
- MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW |
- MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
+ for (i = 0; i < MDIO_MAX_AC_TO; i++) {
+ AT_READ_REG(hw, REG_MDIO_CTRL, &val);
+ if (!(val & (MDIO_CTRL_BUSY | MDIO_CTRL_START)))
+ break;
+ udelay(10);
+ }
+
+ return i != MDIO_MAX_AC_TO;
+}
+
+void atl1c_stop_phy_polling(struct atl1c_hw *hw)
+{
+ if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
+ return;
+
+ AT_WRITE_REG(hw, REG_MDIO_CTRL, 0);
+ atl1c_wait_mdio_idle(hw);
+}
+
+void atl1c_start_phy_polling(struct atl1c_hw *hw, u16 clk_sel)
+{
+ u32 val;
+ if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
+ return;
+
+ val = MDIO_CTRL_SPRES_PRMBL |
+ FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
+ FIELDX(MDIO_CTRL_REG, 1) |
+ MDIO_CTRL_START |
+ MDIO_CTRL_OP_READ;
AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+ atl1c_wait_mdio_idle(hw);
+ val |= MDIO_CTRL_AP_EN;
+ val &= ~MDIO_CTRL_START;
+ AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+ udelay(30);
+}
- for (i = 0; i < MDIO_WAIT_TIMES; i++) {
- udelay(2);
- AT_READ_REG(hw, REG_MDIO_CTRL, &val);
- if (!(val & (MDIO_START | MDIO_BUSY)))
- break;
+
+/*
+ * atl1c_read_phy_core
+ * core funtion to read register in PHY via MDIO control regsiter.
+ * ext: extension register (see IEEE 802.3)
+ * dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0)
+ * reg: reg to read
+ */
+int atl1c_read_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
+ u16 reg, u16 *phy_data)
+{
+ u32 val;
+ u16 clk_sel = MDIO_CTRL_CLK_25_4;
+
+ atl1c_stop_phy_polling(hw);
+
+ *phy_data = 0;
+
+ /* only l2c_b2 & l1d_2 could use slow clock */
+ if ((hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) &&
+ hw->hibernate)
+ clk_sel = MDIO_CTRL_CLK_25_128;
+ if (ext) {
+ val = FIELDX(MDIO_EXTN_DEVAD, dev) | FIELDX(MDIO_EXTN_REG, reg);
+ AT_WRITE_REG(hw, REG_MDIO_EXTN, val);
+ val = MDIO_CTRL_SPRES_PRMBL |
+ FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
+ MDIO_CTRL_START |
+ MDIO_CTRL_MODE_EXT |
+ MDIO_CTRL_OP_READ;
+ } else {
+ val = MDIO_CTRL_SPRES_PRMBL |
+ FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
+ FIELDX(MDIO_CTRL_REG, reg) |
+ MDIO_CTRL_START |
+ MDIO_CTRL_OP_READ;
}
- if (!(val & (MDIO_START | MDIO_BUSY))) {
- *phy_data = (u16)val;
- return 0;
+ AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+
+ if (!atl1c_wait_mdio_idle(hw))
+ return -1;
+
+ AT_READ_REG(hw, REG_MDIO_CTRL, &val);
+ *phy_data = (u16)FIELD_GETX(val, MDIO_CTRL_DATA);
+
+ atl1c_start_phy_polling(hw, clk_sel);
+
+ return 0;
+}
+
+/*
+ * atl1c_write_phy_core
+ * core funtion to write to register in PHY via MDIO control regsiter.
+ * ext: extension register (see IEEE 802.3)
+ * dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0)
+ * reg: reg to write
+ */
+int atl1c_write_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
+ u16 reg, u16 phy_data)
+{
+ u32 val;
+ u16 clk_sel = MDIO_CTRL_CLK_25_4;
+
+ atl1c_stop_phy_polling(hw);
+
+
+ /* only l2c_b2 & l1d_2 could use slow clock */
+ if ((hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) &&
+ hw->hibernate)
+ clk_sel = MDIO_CTRL_CLK_25_128;
+
+ if (ext) {
+ val = FIELDX(MDIO_EXTN_DEVAD, dev) | FIELDX(MDIO_EXTN_REG, reg);
+ AT_WRITE_REG(hw, REG_MDIO_EXTN, val);
+ val = MDIO_CTRL_SPRES_PRMBL |
+ FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
+ FIELDX(MDIO_CTRL_DATA, phy_data) |
+ MDIO_CTRL_START |
+ MDIO_CTRL_MODE_EXT;
+ } else {
+ val = MDIO_CTRL_SPRES_PRMBL |
+ FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
+ FIELDX(MDIO_CTRL_DATA, phy_data) |
+ FIELDX(MDIO_CTRL_REG, reg) |
+ MDIO_CTRL_START;
}
+ AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
- return -1;
+ if (!atl1c_wait_mdio_idle(hw))
+ return -1;
+
+ atl1c_start_phy_polling(hw, clk_sel);
+
+ return 0;
+}
+
+/*
+ * Reads the value from a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to read
+ */
+int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
+{
+ return atl1c_read_phy_core(hw, false, 0, reg_addr, phy_data);
}
/*
@@ -315,27 +440,47 @@ int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
*/
int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data)
{
- int i;
- u32 val;
+ return atl1c_write_phy_core(hw, false, 0, reg_addr, phy_data);
+}
- val = ((u32)(phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT |
- (reg_addr & MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT |
- MDIO_SUP_PREAMBLE | MDIO_START |
- MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
+/* read from PHY extension register */
+int atl1c_read_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
+ u16 reg_addr, u16 *phy_data)
+{
+ return atl1c_read_phy_core(hw, true, dev_addr, reg_addr, phy_data);
+}
- AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+/* write to PHY extension register */
+int atl1c_write_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
+ u16 reg_addr, u16 phy_data)
+{
+ return atl1c_write_phy_core(hw, true, dev_addr, reg_addr, phy_data);
+}
- for (i = 0; i < MDIO_WAIT_TIMES; i++) {
- udelay(2);
- AT_READ_REG(hw, REG_MDIO_CTRL, &val);
- if (!(val & (MDIO_START | MDIO_BUSY)))
- break;
- }
+int atl1c_read_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
+{
+ int err;
- if (!(val & (MDIO_START | MDIO_BUSY)))
- return 0;
+ err = atl1c_write_phy_reg(hw, MII_DBG_ADDR, reg_addr);
+ if (unlikely(err))
+ return err;
+ else
+ err = atl1c_read_phy_reg(hw, MII_DBG_DATA, phy_data);
- return -1;
+ return err;
+}
+
+int atl1c_write_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 phy_data)
+{
+ int err;
+
+ err = atl1c_write_phy_reg(hw, MII_DBG_ADDR, reg_addr);
+ if (unlikely(err))
+ return err;
+ else
+ err = atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
+
+ return err;
}
/*
@@ -380,119 +525,100 @@ static int atl1c_phy_setup_adv(struct atl1c_hw *hw)
void atl1c_phy_disable(struct atl1c_hw *hw)
{
- AT_WRITE_REGW(hw, REG_GPHY_CTRL,
- GPHY_CTRL_PW_WOL_DIS | GPHY_CTRL_EXT_RESET);
+ atl1c_power_saving(hw, 0);
}
-static void atl1c_phy_magic_data(struct atl1c_hw *hw)
-{
- u16 data;
-
- data = ANA_LOOP_SEL_10BT | ANA_EN_MASK_TB | ANA_EN_10BT_IDLE |
- ((1 & ANA_INTERVAL_SEL_TIMER_MASK) <<
- ANA_INTERVAL_SEL_TIMER_SHIFT);
-
- atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_18);
- atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
-
- data = (2 & ANA_SERDES_CDR_BW_MASK) | ANA_MS_PAD_DBG |
- ANA_SERDES_EN_DEEM | ANA_SERDES_SEL_HSP | ANA_SERDES_EN_PLL |
- ANA_SERDES_EN_LCKDT;
-
- atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_5);
- atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
-
- data = (44 & ANA_LONG_CABLE_TH_100_MASK) |
- ((33 & ANA_SHORT_CABLE_TH_100_MASK) <<
- ANA_SHORT_CABLE_TH_100_SHIFT) | ANA_BP_BAD_LINK_ACCUM |
- ANA_BP_SMALL_BW;
-
- atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_54);
- atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
-
- data = (11 & ANA_IECHO_ADJ_MASK) | ((11 & ANA_IECHO_ADJ_MASK) <<
- ANA_IECHO_ADJ_2_SHIFT) | ((8 & ANA_IECHO_ADJ_MASK) <<
- ANA_IECHO_ADJ_1_SHIFT) | ((8 & ANA_IECHO_ADJ_MASK) <<
- ANA_IECHO_ADJ_0_SHIFT);
-
- atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_4);
- atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
-
- data = ANA_RESTART_CAL | ((7 & ANA_MANUL_SWICH_ON_MASK) <<
- ANA_MANUL_SWICH_ON_SHIFT) | ANA_MAN_ENABLE |
- ANA_SEL_HSP | ANA_EN_HB | ANA_OEN_125M;
-
- atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_0);
- atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
-
- if (hw->ctrl_flags & ATL1C_HIB_DISABLE) {
- atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_41);
- if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &data) != 0)
- return;
- data &= ~ANA_TOP_PS_EN;
- atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
-
- atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_11);
- if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &data) != 0)
- return;
- data &= ~ANA_PS_HIB_EN;
- atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
- }
-}
int atl1c_phy_reset(struct atl1c_hw *hw)
{
struct atl1c_adapter *adapter = hw->adapter;
struct pci_dev *pdev = adapter->pdev;
u16 phy_data;
- u32 phy_ctrl_data = GPHY_CTRL_DEFAULT;
- u32 mii_ier_data = IER_LINK_UP | IER_LINK_DOWN;
+ u32 phy_ctrl_data, lpi_ctrl;
int err;
- if (hw->ctrl_flags & ATL1C_HIB_DISABLE)
- phy_ctrl_data &= ~GPHY_CTRL_HIB_EN;
-
+ /* reset PHY core */
+ AT_READ_REG(hw, REG_GPHY_CTRL, &phy_ctrl_data);
+ phy_ctrl_data &= ~(GPHY_CTRL_EXT_RESET | GPHY_CTRL_PHY_IDDQ |
+ GPHY_CTRL_GATE_25M_EN | GPHY_CTRL_PWDOWN_HW | GPHY_CTRL_CLS);
+ phy_ctrl_data |= GPHY_CTRL_SEL_ANA_RST;
+ if (!(hw->ctrl_flags & ATL1C_HIB_DISABLE))
+ phy_ctrl_data |= (GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE);
+ else
+ phy_ctrl_data &= ~(GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE);
AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data);
AT_WRITE_FLUSH(hw);
- msleep(40);
- phy_ctrl_data |= GPHY_CTRL_EXT_RESET;
- AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data);
+ udelay(10);
+ AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data | GPHY_CTRL_EXT_RESET);
AT_WRITE_FLUSH(hw);
- msleep(10);
+ udelay(10 * GPHY_CTRL_EXT_RST_TO); /* delay 800us */
+ /* switch clock */
if (hw->nic_type == athr_l2c_b) {
- atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x0A);
- atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data);
- atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data & 0xDFFF);
+ atl1c_read_phy_dbg(hw, MIIDBG_CFGLPSPD, &phy_data);
+ atl1c_write_phy_dbg(hw, MIIDBG_CFGLPSPD,
+ phy_data & ~CFGLPSPD_RSTCNT_CLK125SW);
}
- if (hw->nic_type == athr_l2c_b ||
- hw->nic_type == athr_l2c_b2 ||
- hw->nic_type == athr_l1d ||
- hw->nic_type == athr_l1d_2) {
- atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B);
- atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data);
- atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data & 0xFFF7);
- msleep(20);
+ /* tx-half amplitude issue fix */
+ if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2) {
+ atl1c_read_phy_dbg(hw, MIIDBG_CABLE1TH_DET, &phy_data);
+ phy_data |= CABLE1TH_DET_EN;
+ atl1c_write_phy_dbg(hw, MIIDBG_CABLE1TH_DET, phy_data);
}
- if (hw->nic_type == athr_l1d) {
- atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x29);
- atl1c_write_phy_reg(hw, MII_DBG_DATA, 0x929D);
+
+ /* clear bit3 of dbgport 3B to lower voltage */
+ if (!(hw->ctrl_flags & ATL1C_HIB_DISABLE)) {
+ if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2) {
+ atl1c_read_phy_dbg(hw, MIIDBG_VOLT_CTRL, &phy_data);
+ phy_data &= ~VOLT_CTRL_SWLOWEST;
+ atl1c_write_phy_dbg(hw, MIIDBG_VOLT_CTRL, phy_data);
+ }
+ /* power saving config */
+ phy_data =
+ hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2 ?
+ L1D_LEGCYPS_DEF : L1C_LEGCYPS_DEF;
+ atl1c_write_phy_dbg(hw, MIIDBG_LEGCYPS, phy_data);
+ /* hib */
+ atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL,
+ SYSMODCTRL_IECHOADJ_DEF);
+ } else {
+ /* disable pws */
+ atl1c_read_phy_dbg(hw, MIIDBG_LEGCYPS, &phy_data);
+ atl1c_write_phy_dbg(hw, MIIDBG_LEGCYPS,
+ phy_data & ~LEGCYPS_EN);
+ /* disable hibernate */
+ atl1c_read_phy_dbg(hw, MIIDBG_HIBNEG, &phy_data);
+ atl1c_write_phy_dbg(hw, MIIDBG_HIBNEG,
+ phy_data & HIBNEG_PSHIB_EN);
}
- if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b2
- || hw->nic_type == athr_l2c) {
- atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x29);
- atl1c_write_phy_reg(hw, MII_DBG_DATA, 0xB6DD);
+ /* disable AZ(EEE) by default */
+ if (hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2 ||
+ hw->nic_type == athr_l2c_b2) {
+ AT_READ_REG(hw, REG_LPI_CTRL, &lpi_ctrl);
+ AT_WRITE_REG(hw, REG_LPI_CTRL, lpi_ctrl & ~LPI_CTRL_EN);
+ atl1c_write_phy_ext(hw, MIIEXT_ANEG, MIIEXT_LOCAL_EEEADV, 0);
+ atl1c_write_phy_ext(hw, MIIEXT_PCS, MIIEXT_CLDCTRL3,
+ L2CB_CLDCTRL3);
}
- err = atl1c_write_phy_reg(hw, MII_IER, mii_ier_data);
+
+ /* other debug port to set */
+ atl1c_write_phy_dbg(hw, MIIDBG_ANACTRL, ANACTRL_DEF);
+ atl1c_write_phy_dbg(hw, MIIDBG_SRDSYSMOD, SRDSYSMOD_DEF);
+ atl1c_write_phy_dbg(hw, MIIDBG_TST10BTCFG, TST10BTCFG_DEF);
+ /* UNH-IOL test issue, set bit7 */
+ atl1c_write_phy_dbg(hw, MIIDBG_TST100BTCFG,
+ TST100BTCFG_DEF | TST100BTCFG_LITCH_EN);
+
+ /* set phy interrupt mask */
+ phy_data = IER_LINK_UP | IER_LINK_DOWN;
+ err = atl1c_write_phy_reg(hw, MII_IER, phy_data);
if (err) {
if (netif_msg_hw(adapter))
dev_err(&pdev->dev,
"Error enable PHY linkChange Interrupt\n");
return err;
}
- if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
- atl1c_phy_magic_data(hw);
return 0;
}
@@ -589,7 +715,8 @@ int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex)
return 0;
}
-int atl1c_phy_power_saving(struct atl1c_hw *hw)
+/* select one link mode to get lower power consumption */
+int atl1c_phy_to_ps_link(struct atl1c_hw *hw)
{
struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
struct pci_dev *pdev = adapter->pdev;
@@ -660,3 +787,64 @@ int atl1c_restart_autoneg(struct atl1c_hw *hw)
return atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
}
+
+int atl1c_power_saving(struct atl1c_hw *hw, u32 wufc)
+{
+ struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
+ struct pci_dev *pdev = adapter->pdev;
+ u32 master_ctrl, mac_ctrl, phy_ctrl;
+ u32 wol_ctrl, speed;
+ u16 phy_data;
+
+ wol_ctrl = 0;
+ speed = adapter->link_speed == SPEED_1000 ?
+ MAC_CTRL_SPEED_1000 : MAC_CTRL_SPEED_10_100;
+
+ AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl);
+ AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl);
+ AT_READ_REG(hw, REG_GPHY_CTRL, &phy_ctrl);
+
+ master_ctrl &= ~MASTER_CTRL_CLK_SEL_DIS;
+ mac_ctrl = FIELD_SETX(mac_ctrl, MAC_CTRL_SPEED, speed);
+ mac_ctrl &= ~(MAC_CTRL_DUPLX | MAC_CTRL_RX_EN | MAC_CTRL_TX_EN);
+ if (adapter->link_duplex == FULL_DUPLEX)
+ mac_ctrl |= MAC_CTRL_DUPLX;
+ phy_ctrl &= ~(GPHY_CTRL_EXT_RESET | GPHY_CTRL_CLS);
+ phy_ctrl |= GPHY_CTRL_SEL_ANA_RST | GPHY_CTRL_HIB_PULSE |
+ GPHY_CTRL_HIB_EN;
+ if (!wufc) { /* without WoL */
+ master_ctrl |= MASTER_CTRL_CLK_SEL_DIS;
+ phy_ctrl |= GPHY_CTRL_PHY_IDDQ | GPHY_CTRL_PWDOWN_HW;
+ AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl);
+ AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl);
+ AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl);
+ AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
+ hw->phy_configured = false; /* re-init PHY when resume */
+ return 0;
+ }
+ phy_ctrl |= GPHY_CTRL_EXT_RESET;
+ if (wufc & AT_WUFC_MAG) {
+ mac_ctrl |= MAC_CTRL_RX_EN | MAC_CTRL_BC_EN;
+ wol_ctrl |= WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
+ if (hw->nic_type == athr_l2c_b && hw->revision_id == L2CB_V11)
+ wol_ctrl |= WOL_PATTERN_EN | WOL_PATTERN_PME_EN;
+ }
+ if (wufc & AT_WUFC_LNKC) {
+ wol_ctrl |= WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
+ if (atl1c_write_phy_reg(hw, MII_IER, IER_LINK_UP) != 0) {
+ dev_dbg(&pdev->dev, "%s: write phy MII_IER faild.\n",
+ atl1c_driver_name);
+ }
+ }
+ /* clear PHY interrupt */
+ atl1c_read_phy_reg(hw, MII_ISR, &phy_data);
+
+ dev_dbg(&pdev->dev, "%s: suspend MAC=%x,MASTER=%x,PHY=0x%x,WOL=%x\n",
+ atl1c_driver_name, mac_ctrl, master_ctrl, phy_ctrl, wol_ctrl);
+ AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl);
+ AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl);
+ AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl);
+ AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl);
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h
index cc7afa1a8fbe..0adb34131332 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h
@@ -48,7 +48,32 @@ bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value);
int atl1c_phy_init(struct atl1c_hw *hw);
int atl1c_check_eeprom_exist(struct atl1c_hw *hw);
int atl1c_restart_autoneg(struct atl1c_hw *hw);
-int atl1c_phy_power_saving(struct atl1c_hw *hw);
+int atl1c_phy_to_ps_link(struct atl1c_hw *hw);
+int atl1c_power_saving(struct atl1c_hw *hw, u32 wufc);
+bool atl1c_wait_mdio_idle(struct atl1c_hw *hw);
+void atl1c_stop_phy_polling(struct atl1c_hw *hw);
+void atl1c_start_phy_polling(struct atl1c_hw *hw, u16 clk_sel);
+int atl1c_read_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
+ u16 reg, u16 *phy_data);
+int atl1c_write_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
+ u16 reg, u16 phy_data);
+int atl1c_read_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
+ u16 reg_addr, u16 *phy_data);
+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);
+
+/* hw-ids */
+#define PCI_DEVICE_ID_ATTANSIC_L2C 0x1062
+#define PCI_DEVICE_ID_ATTANSIC_L1C 0x1063
+#define PCI_DEVICE_ID_ATHEROS_L2C_B 0x2060 /* AR8152 v1.1 Fast 10/100 */
+#define PCI_DEVICE_ID_ATHEROS_L2C_B2 0x2062 /* AR8152 v2.0 Fast 10/100 */
+#define PCI_DEVICE_ID_ATHEROS_L1D 0x1073 /* AR8151 v1.0 Gigabit 1000 */
+#define PCI_DEVICE_ID_ATHEROS_L1D_2_0 0x1083 /* AR8151 v2.0 Gigabit 1000 */
+#define L2CB_V10 0xc0
+#define L2CB_V11 0xc1
+
/* register definition */
#define REG_DEVICE_CAP 0x5C
#define DEVICE_CAP_MAX_PAYLOAD_MASK 0x7
@@ -211,41 +236,32 @@ int atl1c_phy_power_saving(struct atl1c_hw *hw);
#define IRQ_MODRT_RX_TIMER_SHIFT 16
#define REG_GPHY_CTRL 0x140C
-#define GPHY_CTRL_EXT_RESET 0x1
-#define GPHY_CTRL_RTL_MODE 0x2
-#define GPHY_CTRL_LED_MODE 0x4
-#define GPHY_CTRL_ANEG_NOW 0x8
-#define GPHY_CTRL_REV_ANEG 0x10
-#define GPHY_CTRL_GATE_25M_EN 0x20
-#define GPHY_CTRL_LPW_EXIT 0x40
-#define GPHY_CTRL_PHY_IDDQ 0x80
-#define GPHY_CTRL_PHY_IDDQ_DIS 0x100
-#define GPHY_CTRL_GIGA_DIS 0x200
-#define GPHY_CTRL_HIB_EN 0x400
-#define GPHY_CTRL_HIB_PULSE 0x800
-#define GPHY_CTRL_SEL_ANA_RST 0x1000
-#define GPHY_CTRL_PHY_PLL_ON 0x2000
-#define GPHY_CTRL_PWDOWN_HW 0x4000
-#define GPHY_CTRL_PHY_PLL_BYPASS 0x8000
-
-#define GPHY_CTRL_DEFAULT ( \
- GPHY_CTRL_SEL_ANA_RST |\
- GPHY_CTRL_HIB_PULSE |\
- GPHY_CTRL_HIB_EN)
-
-#define GPHY_CTRL_PW_WOL_DIS ( \
- GPHY_CTRL_SEL_ANA_RST |\
- GPHY_CTRL_HIB_PULSE |\
- GPHY_CTRL_HIB_EN |\
- GPHY_CTRL_PWDOWN_HW |\
- GPHY_CTRL_PHY_IDDQ)
-
-#define GPHY_CTRL_POWER_SAVING ( \
- GPHY_CTRL_SEL_ANA_RST |\
- GPHY_CTRL_HIB_EN |\
- GPHY_CTRL_HIB_PULSE |\
- GPHY_CTRL_PWDOWN_HW |\
- GPHY_CTRL_PHY_IDDQ)
+#define GPHY_CTRL_ADDR_MASK 0x1FUL
+#define GPHY_CTRL_ADDR_SHIFT 19
+#define GPHY_CTRL_BP_VLTGSW BIT(18)
+#define GPHY_CTRL_100AB_EN BIT(17)
+#define GPHY_CTRL_10AB_EN BIT(16)
+#define GPHY_CTRL_PHY_PLL_BYPASS BIT(15)
+#define GPHY_CTRL_PWDOWN_HW BIT(14) /* affect MAC&PHY, to low pw */
+#define GPHY_CTRL_PHY_PLL_ON BIT(13) /* 1:pll always on, 0:can sw */
+#define GPHY_CTRL_SEL_ANA_RST BIT(12)
+#define GPHY_CTRL_HIB_PULSE BIT(11)
+#define GPHY_CTRL_HIB_EN BIT(10)
+#define GPHY_CTRL_GIGA_DIS BIT(9)
+#define GPHY_CTRL_PHY_IDDQ_DIS BIT(8) /* pw on RST */
+#define GPHY_CTRL_PHY_IDDQ BIT(7) /* bit8 affect bit7 while rb */
+#define GPHY_CTRL_LPW_EXIT BIT(6)
+#define GPHY_CTRL_GATE_25M_EN BIT(5)
+#define GPHY_CTRL_REV_ANEG BIT(4)
+#define GPHY_CTRL_ANEG_NOW BIT(3)
+#define GPHY_CTRL_LED_MODE BIT(2)
+#define GPHY_CTRL_RTL_MODE BIT(1)
+#define GPHY_CTRL_EXT_RESET BIT(0) /* 1:out of DSP RST status */
+#define GPHY_CTRL_EXT_RST_TO 80 /* 800us atmost */
+#define GPHY_CTRL_CLS (\
+ GPHY_CTRL_LED_MODE |\
+ GPHY_CTRL_100AB_EN |\
+ GPHY_CTRL_PHY_PLL_ON)
/* Block IDLE Status Register */
#define REG_IDLE_STATUS 0x1410
@@ -268,38 +284,37 @@ int atl1c_phy_power_saving(struct atl1c_hw *hw);
/* MDIO Control Register */
#define REG_MDIO_CTRL 0x1414
-#define MDIO_DATA_MASK 0xffff /* On MDIO write, the 16-bit
- * control data to write to PHY
- * MII management register */
-#define MDIO_DATA_SHIFT 0 /* On MDIO read, the 16-bit
- * status data that was read
- * from the PHY MII management register */
-#define MDIO_REG_ADDR_MASK 0x1f /* MDIO register address */
-#define MDIO_REG_ADDR_SHIFT 16
-#define MDIO_RW 0x200000 /* 1: read, 0: write */
-#define MDIO_SUP_PREAMBLE 0x400000 /* Suppress preamble */
-#define MDIO_START 0x800000 /* Write 1 to initiate the MDIO
- * master. And this bit is self
- * cleared after one cycle */
-#define MDIO_CLK_SEL_SHIFT 24
-#define MDIO_CLK_25_4 0
-#define MDIO_CLK_25_6 2
-#define MDIO_CLK_25_8 3
-#define MDIO_CLK_25_10 4
-#define MDIO_CLK_25_14 5
-#define MDIO_CLK_25_20 6
-#define MDIO_CLK_25_28 7
-#define MDIO_BUSY 0x8000000
-#define MDIO_AP_EN 0x10000000
-#define MDIO_WAIT_TIMES 10
-
-/* MII PHY Status Register */
-#define REG_PHY_STATUS 0x1418
-#define PHY_GENERAL_STATUS_MASK 0xFFFF
-#define PHY_STATUS_RECV_ENABLE 0x0001
-#define PHY_OE_PWSP_STATUS_MASK 0x07FF
-#define PHY_OE_PWSP_STATUS_SHIFT 16
-#define PHY_STATUS_LPW_STATE 0x80000000
+#define MDIO_CTRL_MODE_EXT BIT(30)
+#define MDIO_CTRL_POST_READ BIT(29)
+#define MDIO_CTRL_AP_EN BIT(28)
+#define MDIO_CTRL_BUSY BIT(27)
+#define MDIO_CTRL_CLK_SEL_MASK 0x7UL
+#define MDIO_CTRL_CLK_SEL_SHIFT 24
+#define MDIO_CTRL_CLK_25_4 0 /* 25MHz divide 4 */
+#define MDIO_CTRL_CLK_25_6 2
+#define MDIO_CTRL_CLK_25_8 3
+#define MDIO_CTRL_CLK_25_10 4
+#define MDIO_CTRL_CLK_25_32 5
+#define MDIO_CTRL_CLK_25_64 6
+#define MDIO_CTRL_CLK_25_128 7
+#define MDIO_CTRL_START BIT(23)
+#define MDIO_CTRL_SPRES_PRMBL BIT(22)
+#define MDIO_CTRL_OP_READ BIT(21) /* 1:read, 0:write */
+#define MDIO_CTRL_REG_MASK 0x1FUL
+#define MDIO_CTRL_REG_SHIFT 16
+#define MDIO_CTRL_DATA_MASK 0xFFFFUL
+#define MDIO_CTRL_DATA_SHIFT 0
+#define MDIO_MAX_AC_TO 120 /* 1.2ms timeout for slow clk */
+
+/* for extension reg access */
+#define REG_MDIO_EXTN 0x1448
+#define MDIO_EXTN_PORTAD_MASK 0x1FUL
+#define MDIO_EXTN_PORTAD_SHIFT 21
+#define MDIO_EXTN_DEVAD_MASK 0x1FUL
+#define MDIO_EXTN_DEVAD_SHIFT 16
+#define MDIO_EXTN_REG_MASK 0xFFFFUL
+#define MDIO_EXTN_REG_SHIFT 0
+
/* BIST Control and Status Register0 (for the Packet Memory) */
#define REG_BIST0_CTRL 0x141c
#define BIST0_NOW 0x1
@@ -317,50 +332,81 @@ int atl1c_phy_power_saving(struct atl1c_hw *hw);
#define BIST1_FUSE_FLAG 0x4
/* SerDes Lock Detect Control and Status Register */
-#define REG_SERDES_LOCK 0x1424
-#define SERDES_LOCK_DETECT 0x1 /* SerDes lock detected. This signal
- * comes from Analog SerDes */
-#define SERDES_LOCK_DETECT_EN 0x2 /* 1: Enable SerDes Lock detect function */
-#define SERDES_LOCK_STS_SELFB_PLL_SHIFT 0xE
-#define SERDES_LOCK_STS_SELFB_PLL_MASK 0x3
-#define SERDES_OVCLK_18_25 0x0
-#define SERDES_OVCLK_12_18 0x1
-#define SERDES_OVCLK_0_4 0x2
-#define SERDES_OVCLK_4_12 0x3
-#define SERDES_MAC_CLK_SLOWDOWN 0x20000
-#define SERDES_PYH_CLK_SLOWDOWN 0x40000
+#define REG_SERDES 0x1424
+#define SERDES_PHY_CLK_SLOWDOWN BIT(18)
+#define SERDES_MAC_CLK_SLOWDOWN BIT(17)
+#define SERDES_SELFB_PLL_MASK 0x3UL
+#define SERDES_SELFB_PLL_SHIFT 14
+#define SERDES_PHYCLK_SEL_GTX BIT(13) /* 1:gtx_clk, 0:25M */
+#define SERDES_PCIECLK_SEL_SRDS BIT(12) /* 1:serdes,0:25M */
+#define SERDES_BUFS_RX_EN BIT(11)
+#define SERDES_PD_RX BIT(10)
+#define SERDES_PLL_EN BIT(9)
+#define SERDES_EN BIT(8)
+#define SERDES_SELFB_PLL_SEL_CSR BIT(6) /* 0:state-machine,1:csr */
+#define SERDES_SELFB_PLL_CSR_MASK 0x3UL
+#define SERDES_SELFB_PLL_CSR_SHIFT 4
+#define SERDES_SELFB_PLL_CSR_4 3 /* 4-12% OV-CLK */
+#define SERDES_SELFB_PLL_CSR_0 2 /* 0-4% OV-CLK */
+#define SERDES_SELFB_PLL_CSR_12 1 /* 12-18% OV-CLK */
+#define SERDES_SELFB_PLL_CSR_18 0 /* 18-25% OV-CLK */
+#define SERDES_VCO_SLOW BIT(3)
+#define SERDES_VCO_FAST BIT(2)
+#define SERDES_LOCK_DETECT_EN BIT(1)
+#define SERDES_LOCK_DETECT BIT(0)
+
+#define REG_LPI_DECISN_TIMER 0x143C
+#define L2CB_LPI_DESISN_TIMER 0x7D00
+
+#define REG_LPI_CTRL 0x1440
+#define LPI_CTRL_CHK_DA BIT(31)
+#define LPI_CTRL_ENH_TO_MASK 0x1FFFUL
+#define LPI_CTRL_ENH_TO_SHIFT 12
+#define LPI_CTRL_ENH_TH_MASK 0x1FUL
+#define LPI_CTRL_ENH_TH_SHIFT 6
+#define LPI_CTRL_ENH_EN BIT(5)
+#define LPI_CTRL_CHK_RX BIT(4)
+#define LPI_CTRL_CHK_STATE BIT(3)
+#define LPI_CTRL_GMII BIT(2)
+#define LPI_CTRL_TO_PHY BIT(1)
+#define LPI_CTRL_EN BIT(0)
+
+#define REG_LPI_WAIT 0x1444
+#define LPI_WAIT_TIMER_MASK 0xFFFFUL
+#define LPI_WAIT_TIMER_SHIFT 0
/* MAC Control Register */
#define REG_MAC_CTRL 0x1480
-#define MAC_CTRL_TX_EN 0x1
-#define MAC_CTRL_RX_EN 0x2
-#define MAC_CTRL_TX_FLOW 0x4
-#define MAC_CTRL_RX_FLOW 0x8
-#define MAC_CTRL_LOOPBACK 0x10
-#define MAC_CTRL_DUPLX 0x20
-#define MAC_CTRL_ADD_CRC 0x40
-#define MAC_CTRL_PAD 0x80
-#define MAC_CTRL_LENCHK 0x100
-#define MAC_CTRL_HUGE_EN 0x200
-#define MAC_CTRL_PRMLEN_SHIFT 10
-#define MAC_CTRL_PRMLEN_MASK 0xf
-#define MAC_CTRL_RMV_VLAN 0x4000
-#define MAC_CTRL_PROMIS_EN 0x8000
-#define MAC_CTRL_TX_PAUSE 0x10000
-#define MAC_CTRL_SCNT 0x20000
-#define MAC_CTRL_SRST_TX 0x40000
-#define MAC_CTRL_TX_SIMURST 0x80000
-#define MAC_CTRL_SPEED_SHIFT 20
-#define MAC_CTRL_SPEED_MASK 0x3
-#define MAC_CTRL_DBG_TX_BKPRESURE 0x400000
-#define MAC_CTRL_TX_HUGE 0x800000
-#define MAC_CTRL_RX_CHKSUM_EN 0x1000000
-#define MAC_CTRL_MC_ALL_EN 0x2000000
-#define MAC_CTRL_BC_EN 0x4000000
-#define MAC_CTRL_DBG 0x8000000
-#define MAC_CTRL_SINGLE_PAUSE_EN 0x10000000
-#define MAC_CTRL_HASH_ALG_CRC32 0x20000000
-#define MAC_CTRL_SPEED_MODE_SW 0x40000000
+#define MAC_CTRL_SPEED_MODE_SW BIT(30) /* 0:phy,1:sw */
+#define MAC_CTRL_HASH_ALG_CRC32 BIT(29) /* 1:legacy,0:lw_5b */
+#define MAC_CTRL_SINGLE_PAUSE_EN BIT(28)
+#define MAC_CTRL_DBG BIT(27)
+#define MAC_CTRL_BC_EN BIT(26)
+#define MAC_CTRL_MC_ALL_EN BIT(25)
+#define MAC_CTRL_RX_CHKSUM_EN BIT(24)
+#define MAC_CTRL_TX_HUGE BIT(23)
+#define MAC_CTRL_DBG_TX_BKPRESURE BIT(22)
+#define MAC_CTRL_SPEED_MASK 3UL
+#define MAC_CTRL_SPEED_SHIFT 20
+#define MAC_CTRL_SPEED_10_100 1
+#define MAC_CTRL_SPEED_1000 2
+#define MAC_CTRL_TX_SIMURST BIT(19)
+#define MAC_CTRL_SCNT BIT(17)
+#define MAC_CTRL_TX_PAUSE BIT(16)
+#define MAC_CTRL_PROMIS_EN BIT(15)
+#define MAC_CTRL_RMV_VLAN BIT(14)
+#define MAC_CTRL_PRMLEN_MASK 0xFUL
+#define MAC_CTRL_PRMLEN_SHIFT 10
+#define MAC_CTRL_HUGE_EN BIT(9)
+#define MAC_CTRL_LENCHK BIT(8)
+#define MAC_CTRL_PAD BIT(7)
+#define MAC_CTRL_ADD_CRC BIT(6)
+#define MAC_CTRL_DUPLX BIT(5)
+#define MAC_CTRL_LOOPBACK BIT(4)
+#define MAC_CTRL_RX_FLOW BIT(3)
+#define MAC_CTRL_TX_FLOW BIT(2)
+#define MAC_CTRL_RX_EN BIT(1)
+#define MAC_CTRL_TX_EN BIT(0)
/* MAC IPG/IFG Control Register */
#define REG_MAC_IPG_IFG 0x1484
@@ -793,73 +839,188 @@ int atl1c_phy_power_saving(struct atl1c_hw *hw);
#define MII_DBG_ADDR 0x1D
#define MII_DBG_DATA 0x1E
-#define MII_ANA_CTRL_0 0x0
-#define ANA_RESTART_CAL 0x0001
-#define ANA_MANUL_SWICH_ON_SHIFT 0x1
-#define ANA_MANUL_SWICH_ON_MASK 0xF
-#define ANA_MAN_ENABLE 0x0020
-#define ANA_SEL_HSP 0x0040
-#define ANA_EN_HB 0x0080
-#define ANA_EN_HBIAS 0x0100
-#define ANA_OEN_125M 0x0200
-#define ANA_EN_LCKDT 0x0400
-#define ANA_LCKDT_PHY 0x0800
-#define ANA_AFE_MODE 0x1000
-#define ANA_VCO_SLOW 0x2000
-#define ANA_VCO_FAST 0x4000
-#define ANA_SEL_CLK125M_DSP 0x8000
-
-#define MII_ANA_CTRL_4 0x4
-#define ANA_IECHO_ADJ_MASK 0xF
-#define ANA_IECHO_ADJ_3_SHIFT 0
-#define ANA_IECHO_ADJ_2_SHIFT 4
-#define ANA_IECHO_ADJ_1_SHIFT 8
-#define ANA_IECHO_ADJ_0_SHIFT 12
-
-#define MII_ANA_CTRL_5 0x5
-#define ANA_SERDES_CDR_BW_SHIFT 0
-#define ANA_SERDES_CDR_BW_MASK 0x3
-#define ANA_MS_PAD_DBG 0x0004
-#define ANA_SPEEDUP_DBG 0x0008
-#define ANA_SERDES_TH_LOS_SHIFT 4
-#define ANA_SERDES_TH_LOS_MASK 0x3
-#define ANA_SERDES_EN_DEEM 0x0040
-#define ANA_SERDES_TXELECIDLE 0x0080
-#define ANA_SERDES_BEACON 0x0100
-#define ANA_SERDES_HALFTXDR 0x0200
-#define ANA_SERDES_SEL_HSP 0x0400
-#define ANA_SERDES_EN_PLL 0x0800
-#define ANA_SERDES_EN 0x1000
-#define ANA_SERDES_EN_LCKDT 0x2000
-
-#define MII_ANA_CTRL_11 0xB
-#define ANA_PS_HIB_EN 0x8000
-
-#define MII_ANA_CTRL_18 0x12
-#define ANA_TEST_MODE_10BT_01SHIFT 0
-#define ANA_TEST_MODE_10BT_01MASK 0x3
-#define ANA_LOOP_SEL_10BT 0x0004
-#define ANA_RGMII_MODE_SW 0x0008
-#define ANA_EN_LONGECABLE 0x0010
-#define ANA_TEST_MODE_10BT_2 0x0020
-#define ANA_EN_10BT_IDLE 0x0400
-#define ANA_EN_MASK_TB 0x0800
-#define ANA_TRIGGER_SEL_TIMER_SHIFT 12
-#define ANA_TRIGGER_SEL_TIMER_MASK 0x3
-#define ANA_INTERVAL_SEL_TIMER_SHIFT 14
-#define ANA_INTERVAL_SEL_TIMER_MASK 0x3
-
-#define MII_ANA_CTRL_41 0x29
-#define ANA_TOP_PS_EN 0x8000
-
-#define MII_ANA_CTRL_54 0x36
-#define ANA_LONG_CABLE_TH_100_SHIFT 0
-#define ANA_LONG_CABLE_TH_100_MASK 0x3F
-#define ANA_DESERVED 0x0040
-#define ANA_EN_LIT_CH 0x0080
-#define ANA_SHORT_CABLE_TH_100_SHIFT 8
-#define ANA_SHORT_CABLE_TH_100_MASK 0x3F
-#define ANA_BP_BAD_LINK_ACCUM 0x4000
-#define ANA_BP_SMALL_BW 0x8000
+/***************************** debug port *************************************/
+
+#define MIIDBG_ANACTRL 0x00
+#define ANACTRL_CLK125M_DELAY_EN 0x8000
+#define ANACTRL_VCO_FAST 0x4000
+#define ANACTRL_VCO_SLOW 0x2000
+#define ANACTRL_AFE_MODE_EN 0x1000
+#define ANACTRL_LCKDET_PHY 0x800
+#define ANACTRL_LCKDET_EN 0x400
+#define ANACTRL_OEN_125M 0x200
+#define ANACTRL_HBIAS_EN 0x100
+#define ANACTRL_HB_EN 0x80
+#define ANACTRL_SEL_HSP 0x40
+#define ANACTRL_CLASSA_EN 0x20
+#define ANACTRL_MANUSWON_SWR_MASK 3U
+#define ANACTRL_MANUSWON_SWR_SHIFT 2
+#define ANACTRL_MANUSWON_SWR_2V 0
+#define ANACTRL_MANUSWON_SWR_1P9V 1
+#define ANACTRL_MANUSWON_SWR_1P8V 2
+#define ANACTRL_MANUSWON_SWR_1P7V 3
+#define ANACTRL_MANUSWON_BW3_4M 0x2
+#define ANACTRL_RESTART_CAL 0x1
+#define ANACTRL_DEF 0x02EF
+
+#define MIIDBG_SYSMODCTRL 0x04
+#define SYSMODCTRL_IECHOADJ_PFMH_PHY 0x8000
+#define SYSMODCTRL_IECHOADJ_BIASGEN 0x4000
+#define SYSMODCTRL_IECHOADJ_PFML_PHY 0x2000
+#define SYSMODCTRL_IECHOADJ_PS_MASK 3U
+#define SYSMODCTRL_IECHOADJ_PS_SHIFT 10
+#define SYSMODCTRL_IECHOADJ_PS_40 3
+#define SYSMODCTRL_IECHOADJ_PS_20 2
+#define SYSMODCTRL_IECHOADJ_PS_0 1
+#define SYSMODCTRL_IECHOADJ_10BT_100MV 0x40 /* 1:100mv, 0:200mv */
+#define SYSMODCTRL_IECHOADJ_HLFAP_MASK 3U
+#define SYSMODCTRL_IECHOADJ_HLFAP_SHIFT 4
+#define SYSMODCTRL_IECHOADJ_VDFULBW 0x8
+#define SYSMODCTRL_IECHOADJ_VDBIASHLF 0x4
+#define SYSMODCTRL_IECHOADJ_VDAMPHLF 0x2
+#define SYSMODCTRL_IECHOADJ_VDLANSW 0x1
+#define SYSMODCTRL_IECHOADJ_DEF 0x88BB /* ???? */
+
+/* for l1d & l2cb */
+#define SYSMODCTRL_IECHOADJ_CUR_ADD 0x8000
+#define SYSMODCTRL_IECHOADJ_CUR_MASK 7U
+#define SYSMODCTRL_IECHOADJ_CUR_SHIFT 12
+#define SYSMODCTRL_IECHOADJ_VOL_MASK 0xFU
+#define SYSMODCTRL_IECHOADJ_VOL_SHIFT 8
+#define SYSMODCTRL_IECHOADJ_VOL_17ALL 3
+#define SYSMODCTRL_IECHOADJ_VOL_100M15 1
+#define SYSMODCTRL_IECHOADJ_VOL_10M17 0
+#define SYSMODCTRL_IECHOADJ_BIAS1_MASK 0xFU
+#define SYSMODCTRL_IECHOADJ_BIAS1_SHIFT 4
+#define SYSMODCTRL_IECHOADJ_BIAS2_MASK 0xFU
+#define SYSMODCTRL_IECHOADJ_BIAS2_SHIFT 0
+#define L1D_SYSMODCTRL_IECHOADJ_DEF 0x4FBB
+
+#define MIIDBG_SRDSYSMOD 0x05
+#define SRDSYSMOD_LCKDET_EN 0x2000
+#define SRDSYSMOD_PLL_EN 0x800
+#define SRDSYSMOD_SEL_HSP 0x400
+#define SRDSYSMOD_HLFTXDR 0x200
+#define SRDSYSMOD_TXCLK_DELAY_EN 0x100
+#define SRDSYSMOD_TXELECIDLE 0x80
+#define SRDSYSMOD_DEEMP_EN 0x40
+#define SRDSYSMOD_MS_PAD 0x4
+#define SRDSYSMOD_CDR_ADC_VLTG 0x2
+#define SRDSYSMOD_CDR_DAC_1MA 0x1
+#define SRDSYSMOD_DEF 0x2C46
+
+#define MIIDBG_CFGLPSPD 0x0A
+#define CFGLPSPD_RSTCNT_MASK 3U
+#define CFGLPSPD_RSTCNT_SHIFT 14
+#define CFGLPSPD_RSTCNT_CLK125SW 0x2000
+
+#define MIIDBG_HIBNEG 0x0B
+#define HIBNEG_PSHIB_EN 0x8000
+#define HIBNEG_WAKE_BOTH 0x4000
+#define HIBNEG_ONOFF_ANACHG_SUDEN 0x2000
+#define HIBNEG_HIB_PULSE 0x1000
+#define HIBNEG_GATE_25M_EN 0x800
+#define HIBNEG_RST_80U 0x400
+#define HIBNEG_RST_TIMER_MASK 3U
+#define HIBNEG_RST_TIMER_SHIFT 8
+#define HIBNEG_GTX_CLK_DELAY_MASK 3U
+#define HIBNEG_GTX_CLK_DELAY_SHIFT 5
+#define HIBNEG_BYPSS_BRKTIMER 0x10
+#define HIBNEG_DEF 0xBC40
+
+#define MIIDBG_TST10BTCFG 0x12
+#define TST10BTCFG_INTV_TIMER_MASK 3U
+#define TST10BTCFG_INTV_TIMER_SHIFT 14
+#define TST10BTCFG_TRIGER_TIMER_MASK 3U
+#define TST10BTCFG_TRIGER_TIMER_SHIFT 12
+#define TST10BTCFG_DIV_MAN_MLT3_EN 0x800
+#define TST10BTCFG_OFF_DAC_IDLE 0x400
+#define TST10BTCFG_LPBK_DEEP 0x4 /* 1:deep,0:shallow */
+#define TST10BTCFG_DEF 0x4C04
+
+#define MIIDBG_AZ_ANADECT 0x15
+#define AZ_ANADECT_10BTRX_TH 0x8000
+#define AZ_ANADECT_BOTH_01CHNL 0x4000
+#define AZ_ANADECT_INTV_MASK 0x3FU
+#define AZ_ANADECT_INTV_SHIFT 8
+#define AZ_ANADECT_THRESH_MASK 0xFU
+#define AZ_ANADECT_THRESH_SHIFT 4
+#define AZ_ANADECT_CHNL_MASK 0xFU
+#define AZ_ANADECT_CHNL_SHIFT 0
+#define AZ_ANADECT_DEF 0x3220
+#define AZ_ANADECT_LONG 0xb210
+
+#define MIIDBG_MSE16DB 0x18 /* l1d */
+#define L1D_MSE16DB_UP 0x05EA
+#define L1D_MSE16DB_DOWN 0x02EA
+
+#define MIIDBG_LEGCYPS 0x29
+#define LEGCYPS_EN 0x8000
+#define LEGCYPS_DAC_AMP1000_MASK 7U
+#define LEGCYPS_DAC_AMP1000_SHIFT 12
+#define LEGCYPS_DAC_AMP100_MASK 7U
+#define LEGCYPS_DAC_AMP100_SHIFT 9
+#define LEGCYPS_DAC_AMP10_MASK 7U
+#define LEGCYPS_DAC_AMP10_SHIFT 6
+#define LEGCYPS_UNPLUG_TIMER_MASK 7U
+#define LEGCYPS_UNPLUG_TIMER_SHIFT 3
+#define LEGCYPS_UNPLUG_DECT_EN 0x4
+#define LEGCYPS_ECNC_PS_EN 0x1
+#define L1D_LEGCYPS_DEF 0x129D
+#define L1C_LEGCYPS_DEF 0x36DD
+
+#define MIIDBG_TST100BTCFG 0x36
+#define TST100BTCFG_NORMAL_BW_EN 0x8000
+#define TST100BTCFG_BADLNK_BYPASS 0x4000
+#define TST100BTCFG_SHORTCABL_TH_MASK 0x3FU
+#define TST100BTCFG_SHORTCABL_TH_SHIFT 8
+#define TST100BTCFG_LITCH_EN 0x80
+#define TST100BTCFG_VLT_SW 0x40
+#define TST100BTCFG_LONGCABL_TH_MASK 0x3FU
+#define TST100BTCFG_LONGCABL_TH_SHIFT 0
+#define TST100BTCFG_DEF 0xE12C
+
+#define MIIDBG_VOLT_CTRL 0x3B /* only for l2cb 1 & 2 */
+#define VOLT_CTRL_CABLE1TH_MASK 0x1FFU
+#define VOLT_CTRL_CABLE1TH_SHIFT 7
+#define VOLT_CTRL_AMPCTRL_MASK 3U
+#define VOLT_CTRL_AMPCTRL_SHIFT 5
+#define VOLT_CTRL_SW_BYPASS 0x10
+#define VOLT_CTRL_SWLOWEST 0x8
+#define VOLT_CTRL_DACAMP10_MASK 7U
+#define VOLT_CTRL_DACAMP10_SHIFT 0
+
+#define MIIDBG_CABLE1TH_DET 0x3E
+#define CABLE1TH_DET_EN 0x8000
+
+
+/******* dev 3 *********/
+#define MIIEXT_PCS 3
+
+#define MIIEXT_CLDCTRL3 0x8003
+#define CLDCTRL3_BP_CABLE1TH_DET_GT 0x8000
+#define CLDCTRL3_AZ_DISAMP 0x1000
+#define L2CB_CLDCTRL3 0x4D19
+#define L1D_CLDCTRL3 0xDD19
+
+#define MIIEXT_CLDCTRL6 0x8006
+#define CLDCTRL6_CAB_LEN_MASK 0x1FFU
+#define CLDCTRL6_CAB_LEN_SHIFT 0
+#define CLDCTRL6_CAB_LEN_SHORT 0x50
+
+/********* dev 7 **********/
+#define MIIEXT_ANEG 7
+
+#define MIIEXT_LOCAL_EEEADV 0x3C
+#define LOCAL_EEEADV_1000BT 0x4
+#define LOCAL_EEEADV_100BT 0x2
+
+#define MIIEXT_REMOTE_EEEADV 0x3D
+#define REMOTE_EEEADV_1000BT 0x4
+#define REMOTE_EEEADV_100BT 0x2
+
+#define MIIEXT_EEE_ANEG 0x8000
+#define EEE_ANEG_1000M 0x4
+#define EEE_ANEG_100M 0x2
#endif /*_ATL1C_HW_H_*/
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index df106370eb6d..25b7b0098496 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -24,14 +24,6 @@
#define ATL1C_DRV_VERSION "1.0.1.0-NAPI"
char atl1c_driver_name[] = "atl1c";
char atl1c_driver_version[] = ATL1C_DRV_VERSION;
-#define PCI_DEVICE_ID_ATTANSIC_L2C 0x1062
-#define PCI_DEVICE_ID_ATTANSIC_L1C 0x1063
-#define PCI_DEVICE_ID_ATHEROS_L2C_B 0x2060 /* AR8152 v1.1 Fast 10/100 */
-#define PCI_DEVICE_ID_ATHEROS_L2C_B2 0x2062 /* AR8152 v2.0 Fast 10/100 */
-#define PCI_DEVICE_ID_ATHEROS_L1D 0x1073 /* AR8151 v1.0 Gigabit 1000 */
-#define PCI_DEVICE_ID_ATHEROS_L1D_2_0 0x1083 /* AR8151 v2.0 Gigabit 1000 */
-#define L2CB_V10 0xc0
-#define L2CB_V11 0xc1
/*
* atl1c_pci_tbl - PCI Device ID Table
@@ -61,11 +53,9 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(ATL1C_DRV_VERSION);
static int atl1c_stop_mac(struct atl1c_hw *hw);
-static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw);
-static void atl1c_enable_tx_ctrl(struct atl1c_hw *hw);
static void atl1c_disable_l0s_l1(struct atl1c_hw *hw);
static void atl1c_set_aspm(struct atl1c_hw *hw, u16 link_speed);
-static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter);
+static void atl1c_start_mac(struct atl1c_adapter *adapter);
static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter,
int *work_done, int work_to_do);
static int atl1c_up(struct atl1c_adapter *adapter);
@@ -165,11 +155,6 @@ static void atl1c_reset_pcie(struct atl1c_hw *hw, u32 flag)
atl1c_pcie_patch(hw);
if (flag & ATL1C_PCIE_L0S_L1_DISABLE)
atl1c_disable_l0s_l1(hw);
- if (flag & ATL1C_PCIE_PHY_RESET)
- AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT);
- else
- AT_WRITE_REG(hw, REG_GPHY_CTRL,
- GPHY_CTRL_DEFAULT | GPHY_CTRL_EXT_RESET);
msleep(5);
}
@@ -275,8 +260,6 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter)
atl1c_set_aspm(hw, SPEED_0);
netif_carrier_off(netdev);
netif_stop_queue(netdev);
- atl1c_phy_reset(hw);
- atl1c_phy_init(&adapter->hw);
} else {
/* Link Up */
hw->hibernate = false;
@@ -291,9 +274,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_enable_tx_ctrl(hw);
- atl1c_enable_rx_ctrl(hw);
- atl1c_setup_mac_ctrl(adapter);
+ atl1c_start_mac(adapter);
if (netif_msg_link(adapter))
dev_info(&pdev->dev,
"%s: %s NIC Link is Up<%d Mbps %s>\n",
@@ -699,11 +680,9 @@ static void atl1c_set_mac_type(struct atl1c_hw *hw)
static int atl1c_setup_mac_funcs(struct atl1c_hw *hw)
{
- u32 phy_status_data;
u32 link_ctrl_data;
atl1c_set_mac_type(hw);
- AT_READ_REG(hw, REG_PHY_STATUS, &phy_status_data);
AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data);
hw->ctrl_flags = ATL1C_INTR_MODRT_ENABLE |
@@ -1015,7 +994,6 @@ static void atl1c_configure_des_ring(struct atl1c_adapter *adapter)
struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring;
struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *)
adapter->tpd_ring;
- u32 data;
/* TPD */
AT_WRITE_REG(hw, REG_TX_BASE_ADDR_HI,
@@ -1059,13 +1037,6 @@ static void atl1c_configure_des_ring(struct atl1c_adapter *adapter)
AT_WRITE_REG(hw, REG_TXF_WATER_MARK, 0); /* TX watermark, to enter l1 state.*/
AT_WRITE_REG(hw, REG_RXD_DMA_CTRL, 0); /* RXD threshold.*/
}
- if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l1d_2) {
- /* Power Saving for L2c_B */
- AT_READ_REG(hw, REG_SERDES_LOCK, &data);
- data |= SERDES_MAC_CLK_SLOWDOWN;
- data |= SERDES_PYH_CLK_SLOWDOWN;
- AT_WRITE_REG(hw, REG_SERDES_LOCK, data);
- }
/* Load all of base address above */
AT_WRITE_REG(hw, REG_LOAD_PTR, 1);
}
@@ -1157,22 +1128,36 @@ static int atl1c_stop_mac(struct atl1c_hw *hw)
IDLE_STATUS_TXMAC_BUSY | IDLE_STATUS_RXMAC_BUSY);
}
-static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw)
+static void atl1c_start_mac(struct atl1c_adapter *adapter)
{
- u32 data;
-
- AT_READ_REG(hw, REG_RXQ_CTRL, &data);
- data |= RXQ_CTRL_EN;
- AT_WRITE_REG(hw, REG_RXQ_CTRL, data);
-}
-
-static void atl1c_enable_tx_ctrl(struct atl1c_hw *hw)
-{
- u32 data;
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 mac, txq, rxq;
+
+ hw->mac_duplex = adapter->link_duplex == FULL_DUPLEX ? true : false;
+ hw->mac_speed = adapter->link_speed == SPEED_1000 ?
+ atl1c_mac_speed_1000 : atl1c_mac_speed_10_100;
+
+ AT_READ_REG(hw, REG_TXQ_CTRL, &txq);
+ AT_READ_REG(hw, REG_RXQ_CTRL, &rxq);
+ AT_READ_REG(hw, REG_MAC_CTRL, &mac);
+
+ txq |= TXQ_CTRL_EN;
+ rxq |= RXQ_CTRL_EN;
+ mac |= MAC_CTRL_TX_EN | MAC_CTRL_TX_FLOW |
+ MAC_CTRL_RX_EN | MAC_CTRL_RX_FLOW |
+ MAC_CTRL_ADD_CRC | MAC_CTRL_PAD |
+ MAC_CTRL_BC_EN | MAC_CTRL_SINGLE_PAUSE_EN |
+ MAC_CTRL_HASH_ALG_CRC32;
+ if (hw->mac_duplex)
+ mac |= MAC_CTRL_DUPLX;
+ else
+ mac &= ~MAC_CTRL_DUPLX;
+ mac = FIELD_SETX(mac, MAC_CTRL_SPEED, hw->mac_speed);
+ mac = FIELD_SETX(mac, MAC_CTRL_PRMLEN, hw->preamble_len);
- AT_READ_REG(hw, REG_TXQ_CTRL, &data);
- data |= TXQ_CTRL_EN;
- AT_WRITE_REG(hw, REG_TXQ_CTRL, data);
+ AT_WRITE_REG(hw, REG_TXQ_CTRL, txq);
+ AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq);
+ AT_WRITE_REG(hw, REG_MAC_CTRL, mac);
}
/*
@@ -1184,7 +1169,7 @@ static int atl1c_reset_mac(struct atl1c_hw *hw)
{
struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
struct pci_dev *pdev = adapter->pdev;
- u32 master_ctrl_data = 0;
+ u32 ctrl_data = 0;
AT_WRITE_REG(hw, REG_IMR, 0);
AT_WRITE_REG(hw, REG_ISR, ISR_DIS_INT);
@@ -1196,10 +1181,9 @@ static int atl1c_reset_mac(struct atl1c_hw *hw)
* the current PCI configuration. The global reset bit is self-
* clearing, and should clear within a microsecond.
*/
- AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl_data);
- master_ctrl_data |= MASTER_CTRL_OOB_DIS;
- AT_WRITE_REG(hw, REG_MASTER_CTRL,
- master_ctrl_data | MASTER_CTRL_SOFT_RST);
+ AT_READ_REG(hw, REG_MASTER_CTRL, &ctrl_data);
+ ctrl_data |= MASTER_CTRL_OOB_DIS;
+ AT_WRITE_REG(hw, REG_MASTER_CTRL, ctrl_data | MASTER_CTRL_SOFT_RST);
AT_WRITE_FLUSH(hw);
msleep(10);
@@ -1211,7 +1195,28 @@ static int atl1c_reset_mac(struct atl1c_hw *hw)
" disabled for 10ms second\n");
return -1;
}
- AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data);
+ AT_WRITE_REG(hw, REG_MASTER_CTRL, ctrl_data);
+
+ /* driver control speed/duplex */
+ AT_READ_REG(hw, REG_MAC_CTRL, &ctrl_data);
+ AT_WRITE_REG(hw, REG_MAC_CTRL, ctrl_data | MAC_CTRL_SPEED_MODE_SW);
+
+ /* clk switch setting */
+ AT_READ_REG(hw, REG_SERDES, &ctrl_data);
+ switch (hw->nic_type) {
+ case athr_l2c_b:
+ ctrl_data &= ~(SERDES_PHY_CLK_SLOWDOWN |
+ SERDES_MAC_CLK_SLOWDOWN);
+ AT_WRITE_REG(hw, REG_SERDES, ctrl_data);
+ break;
+ case athr_l2c_b2:
+ case athr_l1d_2:
+ ctrl_data |= SERDES_PHY_CLK_SLOWDOWN | SERDES_MAC_CLK_SLOWDOWN;
+ AT_WRITE_REG(hw, REG_SERDES, ctrl_data);
+ break;
+ default:
+ break;
+ }
return 0;
}
@@ -1301,49 +1306,6 @@ static void atl1c_set_aspm(struct atl1c_hw *hw, u16 link_speed)
return;
}
-static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter)
-{
- struct atl1c_hw *hw = &adapter->hw;
- struct net_device *netdev = adapter->netdev;
- u32 mac_ctrl_data;
-
- mac_ctrl_data = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN;
- mac_ctrl_data |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW);
-
- if (adapter->link_duplex == FULL_DUPLEX) {
- hw->mac_duplex = true;
- mac_ctrl_data |= MAC_CTRL_DUPLX;
- }
-
- if (adapter->link_speed == SPEED_1000)
- hw->mac_speed = atl1c_mac_speed_1000;
- else
- hw->mac_speed = atl1c_mac_speed_10_100;
-
- mac_ctrl_data |= (hw->mac_speed & MAC_CTRL_SPEED_MASK) <<
- MAC_CTRL_SPEED_SHIFT;
-
- mac_ctrl_data |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
- mac_ctrl_data |= ((hw->preamble_len & MAC_CTRL_PRMLEN_MASK) <<
- MAC_CTRL_PRMLEN_SHIFT);
-
- __atl1c_vlan_mode(netdev->features, &mac_ctrl_data);
-
- mac_ctrl_data |= MAC_CTRL_BC_EN;
- if (netdev->flags & IFF_PROMISC)
- mac_ctrl_data |= MAC_CTRL_PROMIS_EN;
- if (netdev->flags & IFF_ALLMULTI)
- mac_ctrl_data |= MAC_CTRL_MC_ALL_EN;
-
- mac_ctrl_data |= MAC_CTRL_SINGLE_PAUSE_EN;
- if (hw->nic_type == athr_l1d || hw->nic_type == athr_l2c_b2 ||
- hw->nic_type == athr_l1d_2) {
- mac_ctrl_data |= MAC_CTRL_SPEED_MODE_SW;
- mac_ctrl_data |= MAC_CTRL_HASH_ALG_CRC32;
- }
- AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
-}
-
/*
* atl1c_configure - Configure Transmit&Receive Unit after Reset
* @adapter: board private structure
@@ -2268,13 +2230,6 @@ static int atl1c_open(struct net_device *netdev)
if (unlikely(err))
goto err_up;
- if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) {
- u32 phy_data;
-
- AT_READ_REG(&adapter->hw, REG_MDIO_CTRL, &phy_data);
- phy_data |= MDIO_AP_EN;
- AT_WRITE_REG(&adapter->hw, REG_MDIO_CTRL, phy_data);
- }
return 0;
err_up:
@@ -2311,10 +2266,6 @@ static int atl1c_suspend(struct device *dev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct atl1c_adapter *adapter = netdev_priv(netdev);
struct atl1c_hw *hw = &adapter->hw;
- u32 mac_ctrl_data = 0;
- u32 master_ctrl_data = 0;
- u32 wol_ctrl_data = 0;
- u16 mii_intr_status_data = 0;
u32 wufc = adapter->wol;
atl1c_disable_l0s_l1(hw);
@@ -2325,80 +2276,10 @@ static int atl1c_suspend(struct device *dev)
netif_device_detach(netdev);
if (wufc)
- if (atl1c_phy_power_saving(hw) != 0)
+ if (atl1c_phy_to_ps_link(hw) != 0)
dev_dbg(&pdev->dev, "phy power saving failed");
- AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl_data);
- AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl_data);
-
- master_ctrl_data &= ~MASTER_CTRL_CLK_SEL_DIS;
- mac_ctrl_data &= ~(MAC_CTRL_PRMLEN_MASK << MAC_CTRL_PRMLEN_SHIFT);
- mac_ctrl_data |= (((u32)adapter->hw.preamble_len &
- MAC_CTRL_PRMLEN_MASK) <<
- MAC_CTRL_PRMLEN_SHIFT);
- mac_ctrl_data &= ~(MAC_CTRL_SPEED_MASK << MAC_CTRL_SPEED_SHIFT);
- mac_ctrl_data &= ~MAC_CTRL_DUPLX;
-
- if (wufc) {
- mac_ctrl_data |= MAC_CTRL_RX_EN;
- if (adapter->link_speed == SPEED_1000 ||
- adapter->link_speed == SPEED_0) {
- mac_ctrl_data |= atl1c_mac_speed_1000 <<
- MAC_CTRL_SPEED_SHIFT;
- mac_ctrl_data |= MAC_CTRL_DUPLX;
- } else
- mac_ctrl_data |= atl1c_mac_speed_10_100 <<
- MAC_CTRL_SPEED_SHIFT;
-
- if (adapter->link_duplex == DUPLEX_FULL)
- mac_ctrl_data |= MAC_CTRL_DUPLX;
-
- /* turn on magic packet wol */
- if (wufc & AT_WUFC_MAG) {
- wol_ctrl_data |= WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
- if (hw->nic_type == athr_l2c_b &&
- hw->revision_id == L2CB_V11) {
- wol_ctrl_data |=
- WOL_PATTERN_EN | WOL_PATTERN_PME_EN;
- }
- }
- if (wufc & AT_WUFC_LNKC) {
- wol_ctrl_data |= WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
- /* only link up can wake up */
- if (atl1c_write_phy_reg(hw, MII_IER, IER_LINK_UP) != 0) {
- dev_dbg(&pdev->dev, "%s: read write phy "
- "register failed.\n",
- atl1c_driver_name);
- }
- }
- /* clear phy interrupt */
- atl1c_read_phy_reg(hw, MII_ISR, &mii_intr_status_data);
- /* Config MAC Ctrl register */
- __atl1c_vlan_mode(netdev->features, &mac_ctrl_data);
-
- /* magic packet maybe Broadcast&multicast&Unicast frame */
- if (wufc & AT_WUFC_MAG)
- mac_ctrl_data |= MAC_CTRL_BC_EN;
-
- dev_dbg(&pdev->dev,
- "%s: suspend MAC=0x%x\n",
- atl1c_driver_name, mac_ctrl_data);
- AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data);
- AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data);
- AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
-
- AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT |
- GPHY_CTRL_EXT_RESET);
- } else {
- AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_POWER_SAVING);
- master_ctrl_data |= MASTER_CTRL_CLK_SEL_DIS;
- mac_ctrl_data |= atl1c_mac_speed_10_100 << MAC_CTRL_SPEED_SHIFT;
- mac_ctrl_data |= MAC_CTRL_DUPLX;
- AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data);
- AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
- AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
- hw->phy_configured = false; /* re-init PHY when resume */
- }
+ atl1c_power_saving(hw, wufc);
return 0;
}
@@ -2411,8 +2292,7 @@ static int atl1c_resume(struct device *dev)
struct atl1c_adapter *adapter = netdev_priv(netdev);
AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
- atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE |
- ATL1C_PCIE_PHY_RESET);
+ atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE);
atl1c_phy_reset(&adapter->hw);
atl1c_reset_mac(&adapter->hw);
@@ -2560,7 +2440,7 @@ static int __devinit atl1c_probe(struct pci_dev *pdev,
adapter->mii.mdio_read = atl1c_mdio_read;
adapter->mii.mdio_write = atl1c_mdio_write;
adapter->mii.phy_id_mask = 0x1f;
- adapter->mii.reg_num_mask = MDIO_REG_ADDR_MASK;
+ adapter->mii.reg_num_mask = MDIO_CTRL_REG_MASK;
netif_napi_add(netdev, &adapter->napi, atl1c_clean, 64);
setup_timer(&adapter->phy_config_timer, atl1c_phy_config,
(unsigned long)adapter);
@@ -2570,8 +2450,7 @@ static int __devinit atl1c_probe(struct pci_dev *pdev,
dev_err(&pdev->dev, "net device private data init failed\n");
goto err_sw_init;
}
- atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE |
- ATL1C_PCIE_PHY_RESET);
+ atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE);
/* Init GPHY as early as possible due to power saving issue */
atl1c_phy_reset(&adapter->hw);
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index ad69cf89491c..4bc18efb7053 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -162,6 +162,11 @@ static inline void queue_head_inc(struct be_queue_info *q)
index_inc(&q->head, q->len);
}
+static inline void index_dec(u16 *index, u16 limit)
+{
+ *index = MODULO((*index - 1), limit);
+}
+
static inline void queue_tail_inc(struct be_queue_info *q)
{
index_inc(&q->tail, q->len);
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 22be08c03594..43167e863955 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -61,10 +61,21 @@ static inline void be_mcc_compl_use(struct be_mcc_compl *compl)
compl->flags = 0;
}
+static struct be_cmd_resp_hdr *be_decode_resp_hdr(u32 tag0, u32 tag1)
+{
+ unsigned long addr;
+
+ addr = tag1;
+ addr = ((addr << 16) << 16) | tag0;
+ return (void *)addr;
+}
+
static int be_mcc_compl_process(struct be_adapter *adapter,
- struct be_mcc_compl *compl)
+ struct be_mcc_compl *compl)
{
u16 compl_status, extd_status;
+ struct be_cmd_resp_hdr *resp_hdr;
+ u8 opcode = 0, subsystem = 0;
/* Just swap the status to host endian; mcc tag is opaquely copied
* from mcc_wrb */
@@ -73,32 +84,36 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
CQE_STATUS_COMPL_MASK;
- if (((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) ||
- (compl->tag0 == OPCODE_COMMON_WRITE_OBJECT)) &&
- (compl->tag1 == CMD_SUBSYSTEM_COMMON)) {
+ resp_hdr = be_decode_resp_hdr(compl->tag0, compl->tag1);
+
+ if (resp_hdr) {
+ opcode = resp_hdr->opcode;
+ subsystem = resp_hdr->subsystem;
+ }
+
+ if (((opcode == OPCODE_COMMON_WRITE_FLASHROM) ||
+ (opcode == OPCODE_COMMON_WRITE_OBJECT)) &&
+ (subsystem == CMD_SUBSYSTEM_COMMON)) {
adapter->flash_status = compl_status;
complete(&adapter->flash_compl);
}
if (compl_status == MCC_STATUS_SUCCESS) {
- if (((compl->tag0 == OPCODE_ETH_GET_STATISTICS) ||
- (compl->tag0 == OPCODE_ETH_GET_PPORT_STATS)) &&
- (compl->tag1 == CMD_SUBSYSTEM_ETH)) {
+ if (((opcode == OPCODE_ETH_GET_STATISTICS) ||
+ (opcode == OPCODE_ETH_GET_PPORT_STATS)) &&
+ (subsystem == CMD_SUBSYSTEM_ETH)) {
be_parse_stats(adapter);
adapter->stats_cmd_sent = false;
}
- if (compl->tag0 ==
- OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES) {
- struct be_mcc_wrb *mcc_wrb =
- queue_index_node(&adapter->mcc_obj.q,
- compl->tag1);
+ if (opcode == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES &&
+ subsystem == CMD_SUBSYSTEM_COMMON) {
struct be_cmd_resp_get_cntl_addnl_attribs *resp =
- embedded_payload(mcc_wrb);
+ (void *)resp_hdr;
adapter->drv_stats.be_on_die_temperature =
resp->on_die_temperature;
}
} else {
- if (compl->tag0 == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES)
+ if (opcode == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES)
be_get_temp_freq = 0;
if (compl_status == MCC_STATUS_NOT_SUPPORTED ||
@@ -108,13 +123,13 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
if (compl_status == MCC_STATUS_UNAUTHORIZED_REQUEST) {
dev_warn(&adapter->pdev->dev, "This domain(VM) is not "
"permitted to execute this cmd (opcode %d)\n",
- compl->tag0);
+ opcode);
} else {
extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
CQE_STATUS_EXTD_MASK;
dev_err(&adapter->pdev->dev, "Cmd (opcode %d) failed:"
"status %d, extd-status %d\n",
- compl->tag0, compl_status, extd_status);
+ opcode, compl_status, extd_status);
}
}
done:
@@ -286,7 +301,7 @@ static int be_mcc_wait_compl(struct be_adapter *adapter)
if (i == mcc_timeout) {
dev_err(&adapter->pdev->dev, "FW not responding\n");
adapter->fw_timeout = true;
- return -1;
+ return -EIO;
}
return status;
}
@@ -294,8 +309,26 @@ static int be_mcc_wait_compl(struct be_adapter *adapter)
/* Notify MCC requests and wait for completion */
static int be_mcc_notify_wait(struct be_adapter *adapter)
{
+ int status;
+ struct be_mcc_wrb *wrb;
+ struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
+ u16 index = mcc_obj->q.head;
+ struct be_cmd_resp_hdr *resp;
+
+ index_dec(&index, mcc_obj->q.len);
+ wrb = queue_index_node(&mcc_obj->q, index);
+
+ resp = be_decode_resp_hdr(wrb->tag0, wrb->tag1);
+
be_mcc_notify(adapter);
- return be_mcc_wait_compl(adapter);
+
+ status = be_mcc_wait_compl(adapter);
+ if (status == -EIO)
+ goto out;
+
+ status = resp->status;
+out:
+ return status;
}
static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
@@ -435,14 +468,17 @@ static void be_wrb_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
struct be_mcc_wrb *wrb, struct be_dma_mem *mem)
{
struct be_sge *sge;
+ unsigned long addr = (unsigned long)req_hdr;
+ u64 req_addr = addr;
req_hdr->opcode = opcode;
req_hdr->subsystem = subsystem;
req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
req_hdr->version = 0;
- wrb->tag0 = opcode;
- wrb->tag1 = subsystem;
+ wrb->tag0 = req_addr & 0xFFFFFFFF;
+ wrb->tag1 = upper_32_bits(req_addr);
+
wrb->payload_length = cmd_len;
if (mem) {
wrb->embedded |= (1 & MCC_WRB_SGE_CNT_MASK) <<
@@ -1221,7 +1257,7 @@ int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
OPCODE_ETH_GET_PPORT_STATS, nonemb_cmd->size, wrb,
nonemb_cmd);
- req->cmd_params.params.pport_num = cpu_to_le16(adapter->port_num);
+ req->cmd_params.params.pport_num = cpu_to_le16(adapter->hba_port_num);
req->cmd_params.params.reset_stats = 0;
be_mcc_notify(adapter);
@@ -1283,13 +1319,10 @@ int be_cmd_get_die_temperature(struct be_adapter *adapter)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_get_cntl_addnl_attribs *req;
- u16 mccq_index;
int status;
spin_lock_bh(&adapter->mcc_lock);
- mccq_index = adapter->mcc_obj.q.head;
-
wrb = wrb_from_mccq(adapter);
if (!wrb) {
status = -EBUSY;
@@ -1301,8 +1334,6 @@ int be_cmd_get_die_temperature(struct be_adapter *adapter)
OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES, sizeof(*req),
wrb, NULL);
- wrb->tag1 = mccq_index;
-
be_mcc_notify(adapter);
err:
@@ -1824,18 +1855,16 @@ int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
spin_unlock_bh(&adapter->mcc_lock);
if (!wait_for_completion_timeout(&adapter->flash_compl,
- msecs_to_jiffies(12000)))
+ msecs_to_jiffies(30000)))
status = -1;
else
status = adapter->flash_status;
resp = embedded_payload(wrb);
- if (!status) {
+ if (!status)
*data_written = le32_to_cpu(resp->actual_write_len);
- } else {
+ else
*addn_status = resp->additional_status;
- status = resp->status;
- }
return status;
@@ -1950,7 +1979,7 @@ int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_READ_FLASHROM, sizeof(*req)+4, wrb, NULL);
- req->params.op_type = cpu_to_le32(IMG_TYPE_REDBOOT);
+ req->params.op_type = cpu_to_le32(OPTYPE_REDBOOT);
req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT);
req->params.offset = cpu_to_le32(offset);
req->params.data_buf_size = cpu_to_le32(0x4);
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 3c543610906a..944f031bd31e 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -225,8 +225,12 @@ struct be_cmd_req_hdr {
#define RESP_HDR_INFO_OPCODE_SHIFT 0 /* bits 0 - 7 */
#define RESP_HDR_INFO_SUBSYS_SHIFT 8 /* bits 8 - 15 */
struct be_cmd_resp_hdr {
- u32 info; /* dword 0 */
- u32 status; /* dword 1 */
+ u8 opcode; /* dword 0 */
+ u8 subsystem; /* dword 0 */
+ u8 rsvd[2]; /* dword 0 */
+ u8 status; /* dword 1 */
+ u8 add_status; /* dword 1 */
+ u8 rsvd1[2]; /* dword 1 */
u32 response_length; /* dword 2 */
u32 actual_resp_len; /* dword 3 */
};
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index dc9f74c69c40..0c6f06efce12 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -793,7 +793,7 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
}
}
- if (be_test_ddr_dma(adapter) != 0) {
+ if (!lancer_chip(adapter) && be_test_ddr_dma(adapter) != 0) {
data[3] = 1;
test->flags |= ETH_TEST_FL_FAILED;
}
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h
index f2c89e3ccabd..0949aa609164 100644
--- a/drivers/net/ethernet/emulex/benet/be_hw.h
+++ b/drivers/net/ethernet/emulex/benet/be_hw.h
@@ -162,22 +162,23 @@
#define QUERY_FAT 1
/* Flashrom related descriptors */
+#define MAX_FLASH_COMP 32
#define IMAGE_TYPE_FIRMWARE 160
#define IMAGE_TYPE_BOOTCODE 224
#define IMAGE_TYPE_OPTIONROM 32
#define NUM_FLASHDIR_ENTRIES 32
-#define IMG_TYPE_ISCSI_ACTIVE 0
-#define IMG_TYPE_REDBOOT 1
-#define IMG_TYPE_BIOS 2
-#define IMG_TYPE_PXE_BIOS 3
-#define IMG_TYPE_FCOE_BIOS 8
-#define IMG_TYPE_ISCSI_BACKUP 9
-#define IMG_TYPE_FCOE_FW_ACTIVE 10
-#define IMG_TYPE_FCOE_FW_BACKUP 11
-#define IMG_TYPE_NCSI_FW 13
-#define IMG_TYPE_PHY_FW 99
+#define OPTYPE_ISCSI_ACTIVE 0
+#define OPTYPE_REDBOOT 1
+#define OPTYPE_BIOS 2
+#define OPTYPE_PXE_BIOS 3
+#define OPTYPE_FCOE_BIOS 8
+#define OPTYPE_ISCSI_BACKUP 9
+#define OPTYPE_FCOE_FW_ACTIVE 10
+#define OPTYPE_FCOE_FW_BACKUP 11
+#define OPTYPE_NCSI_FW 13
+#define OPTYPE_PHY_FW 99
#define TN_8022 13
#define ILLEGAL_IOCTL_REQ 2
@@ -223,6 +224,24 @@
#define FLASH_REDBOOT_START_g3 (262144)
#define FLASH_PHY_FW_START_g3 1310720
+#define IMAGE_NCSI 16
+#define IMAGE_OPTION_ROM_PXE 32
+#define IMAGE_OPTION_ROM_FCoE 33
+#define IMAGE_OPTION_ROM_ISCSI 34
+#define IMAGE_FLASHISM_JUMPVECTOR 48
+#define IMAGE_FLASH_ISM 49
+#define IMAGE_JUMP_VECTOR 50
+#define IMAGE_FIRMWARE_iSCSI 160
+#define IMAGE_FIRMWARE_COMP_iSCSI 161
+#define IMAGE_FIRMWARE_FCoE 162
+#define IMAGE_FIRMWARE_COMP_FCoE 163
+#define IMAGE_FIRMWARE_BACKUP_iSCSI 176
+#define IMAGE_FIRMWARE_BACKUP_COMP_iSCSI 177
+#define IMAGE_FIRMWARE_BACKUP_FCoE 178
+#define IMAGE_FIRMWARE_BACKUP_COMP_FCoE 179
+#define IMAGE_FIRMWARE_PHY 192
+#define IMAGE_BOOT_CODE 224
+
/************* Rx Packet Type Encoding **************/
#define BE_UNICAST_PACKET 0
#define BE_MULTICAST_PACKET 1
@@ -445,6 +464,7 @@ struct flash_comp {
unsigned long offset;
int optype;
int size;
+ int img_type;
};
struct image_hdr {
@@ -481,17 +501,19 @@ struct flash_section_hdr {
u32 format_rev;
u32 cksum;
u32 antidote;
- u32 build_no;
- u8 id_string[64];
- u32 active_entry_mask;
- u32 valid_entry_mask;
- u32 org_content_mask;
- u32 rsvd0;
- u32 rsvd1;
- u32 rsvd2;
- u32 rsvd3;
- u32 rsvd4;
-};
+ u32 num_images;
+ u8 id_string[128];
+ u32 rsvd[4];
+} __packed;
+
+struct flash_section_hdr_g2 {
+ u32 format_rev;
+ u32 cksum;
+ u32 antidote;
+ u32 build_num;
+ u8 id_string[128];
+ u32 rsvd[8];
+} __packed;
struct flash_section_entry {
u32 type;
@@ -503,10 +525,16 @@ struct flash_section_entry {
u32 rsvd0;
u32 rsvd1;
u8 ver_data[32];
-};
+} __packed;
struct flash_section_info {
u8 cookie[32];
struct flash_section_hdr fsec_hdr;
struct flash_section_entry fsec_entry[32];
-};
+} __packed;
+
+struct flash_section_info_g2 {
+ u8 cookie[32];
+ struct flash_section_hdr_g2 fsec_hdr;
+ struct flash_section_entry fsec_entry[32];
+} __packed;
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index a5bc6084be05..c9f757c10fdc 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -421,6 +421,9 @@ void be_parse_stats(struct be_adapter *adapter)
populate_be2_stats(adapter);
}
+ if (lancer_chip(adapter))
+ goto done;
+
/* as erx_v1 is longer than v0, ok to use v1 defn for v0 access */
for_all_rx_queues(adapter, rxo, i) {
/* below erx HW counter can actually wrap around after
@@ -429,6 +432,8 @@ void be_parse_stats(struct be_adapter *adapter)
accumulate_16bit_val(&rx_stats(rxo)->rx_drops_no_frags,
(u16)erx->rx_drops_no_fragments[rxo->q.id]);
}
+done:
+ return;
}
static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev,
@@ -797,22 +802,30 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
if (adapter->promiscuous)
return 0;
- if (adapter->vlans_added <= adapter->max_vlans) {
- /* Construct VLAN Table to give to HW */
- for (i = 0; i < VLAN_N_VID; i++) {
- if (adapter->vlan_tag[i]) {
- vtag[ntags] = cpu_to_le16(i);
- ntags++;
- }
- }
- status = be_cmd_vlan_config(adapter, adapter->if_handle,
- vtag, ntags, 1, 0);
- } else {
- status = be_cmd_vlan_config(adapter, adapter->if_handle,
- NULL, 0, 1, 1);
+ if (adapter->vlans_added > adapter->max_vlans)
+ goto set_vlan_promisc;
+
+ /* Construct VLAN Table to give to HW */
+ for (i = 0; i < VLAN_N_VID; i++)
+ if (adapter->vlan_tag[i])
+ vtag[ntags++] = cpu_to_le16(i);
+
+ status = be_cmd_vlan_config(adapter, adapter->if_handle,
+ vtag, ntags, 1, 0);
+
+ /* Set to VLAN promisc mode as setting VLAN filter failed */
+ if (status) {
+ dev_info(&adapter->pdev->dev, "Exhausted VLAN HW filters.\n");
+ dev_info(&adapter->pdev->dev, "Disabling HW VLAN filtering.\n");
+ goto set_vlan_promisc;
}
return status;
+
+set_vlan_promisc:
+ status = be_cmd_vlan_config(adapter, adapter->if_handle,
+ NULL, 0, 1, 1);
+ return status;
}
static int be_vlan_add_vid(struct net_device *netdev, u16 vid)
@@ -862,6 +875,7 @@ ret:
static void be_set_rx_mode(struct net_device *netdev)
{
struct be_adapter *adapter = netdev_priv(netdev);
+ int status;
if (netdev->flags & IFF_PROMISC) {
be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
@@ -908,7 +922,14 @@ static void be_set_rx_mode(struct net_device *netdev)
}
}
- be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
+ status = be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
+
+ /* Set to MCAST promisc mode if setting MULTICAST address fails */
+ if (status) {
+ dev_info(&adapter->pdev->dev, "Exhausted multicast HW filters.\n");
+ dev_info(&adapter->pdev->dev, "Disabling HW multicast filtering.\n");
+ be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON);
+ }
done:
return;
}
@@ -1555,7 +1576,9 @@ static int event_handle(struct be_eq_obj *eqo)
if (!num)
rearm = true;
- be_eq_notify(eqo->adapter, eqo->q.id, rearm, true, num);
+ if (num || msix_enabled(eqo->adapter))
+ be_eq_notify(eqo->adapter, eqo->q.id, rearm, true, num);
+
if (num)
napi_schedule(&eqo->napi);
@@ -2736,6 +2759,8 @@ static void be_netpoll(struct net_device *netdev)
#endif
#define FW_FILE_HDR_SIGN "ServerEngines Corp. "
+char flash_cookie[2][16] = {"*** SE FLAS", "H DIRECTORY *** "};
+
static bool be_flash_redboot(struct be_adapter *adapter,
const u8 *p, u32 img_start, int image_size,
int hdr_size)
@@ -2769,58 +2794,101 @@ static bool phy_flashing_required(struct be_adapter *adapter)
adapter->phy.interface_type == PHY_TYPE_BASET_10GB);
}
+static bool is_comp_in_ufi(struct be_adapter *adapter,
+ struct flash_section_info *fsec, int type)
+{
+ int i = 0, img_type = 0;
+ struct flash_section_info_g2 *fsec_g2 = NULL;
+
+ if (adapter->generation != BE_GEN3)
+ fsec_g2 = (struct flash_section_info_g2 *)fsec;
+
+ for (i = 0; i < MAX_FLASH_COMP; i++) {
+ if (fsec_g2)
+ img_type = le32_to_cpu(fsec_g2->fsec_entry[i].type);
+ else
+ img_type = le32_to_cpu(fsec->fsec_entry[i].type);
+
+ if (img_type == type)
+ return true;
+ }
+ return false;
+
+}
+
+struct flash_section_info *get_fsec_info(struct be_adapter *adapter,
+ int header_size,
+ const struct firmware *fw)
+{
+ struct flash_section_info *fsec = NULL;
+ const u8 *p = fw->data;
+
+ p += header_size;
+ while (p < (fw->data + fw->size)) {
+ fsec = (struct flash_section_info *)p;
+ if (!memcmp(flash_cookie, fsec->cookie, sizeof(flash_cookie)))
+ return fsec;
+ p += 32;
+ }
+ return NULL;
+}
+
static int be_flash_data(struct be_adapter *adapter,
- const struct firmware *fw,
- struct be_dma_mem *flash_cmd, int num_of_images)
+ const struct firmware *fw,
+ struct be_dma_mem *flash_cmd,
+ int num_of_images)
{
int status = 0, i, filehdr_size = 0;
+ int img_hdrs_size = (num_of_images * sizeof(struct image_hdr));
u32 total_bytes = 0, flash_op;
int num_bytes;
const u8 *p = fw->data;
struct be_cmd_write_flashrom *req = flash_cmd->va;
const struct flash_comp *pflashcomp;
- int num_comp;
-
- static const struct flash_comp gen3_flash_types[10] = {
- { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE,
- FLASH_IMAGE_MAX_SIZE_g3},
- { FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT,
- FLASH_REDBOOT_IMAGE_MAX_SIZE_g3},
- { FLASH_iSCSI_BIOS_START_g3, IMG_TYPE_BIOS,
- FLASH_BIOS_IMAGE_MAX_SIZE_g3},
- { FLASH_PXE_BIOS_START_g3, IMG_TYPE_PXE_BIOS,
- FLASH_BIOS_IMAGE_MAX_SIZE_g3},
- { FLASH_FCoE_BIOS_START_g3, IMG_TYPE_FCOE_BIOS,
- FLASH_BIOS_IMAGE_MAX_SIZE_g3},
- { FLASH_iSCSI_BACKUP_IMAGE_START_g3, IMG_TYPE_ISCSI_BACKUP,
- FLASH_IMAGE_MAX_SIZE_g3},
- { FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE,
- FLASH_IMAGE_MAX_SIZE_g3},
- { FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP,
- FLASH_IMAGE_MAX_SIZE_g3},
- { FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW,
- FLASH_NCSI_IMAGE_MAX_SIZE_g3},
- { FLASH_PHY_FW_START_g3, IMG_TYPE_PHY_FW,
- FLASH_PHY_FW_IMAGE_MAX_SIZE_g3}
+ int num_comp, hdr_size;
+ struct flash_section_info *fsec = NULL;
+
+ struct flash_comp gen3_flash_types[] = {
+ { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, OPTYPE_ISCSI_ACTIVE,
+ FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_iSCSI},
+ { FLASH_REDBOOT_START_g3, OPTYPE_REDBOOT,
+ FLASH_REDBOOT_IMAGE_MAX_SIZE_g3, IMAGE_BOOT_CODE},
+ { FLASH_iSCSI_BIOS_START_g3, OPTYPE_BIOS,
+ FLASH_BIOS_IMAGE_MAX_SIZE_g3, IMAGE_OPTION_ROM_ISCSI},
+ { FLASH_PXE_BIOS_START_g3, OPTYPE_PXE_BIOS,
+ FLASH_BIOS_IMAGE_MAX_SIZE_g3, IMAGE_OPTION_ROM_PXE},
+ { FLASH_FCoE_BIOS_START_g3, OPTYPE_FCOE_BIOS,
+ FLASH_BIOS_IMAGE_MAX_SIZE_g3, IMAGE_OPTION_ROM_FCoE},
+ { FLASH_iSCSI_BACKUP_IMAGE_START_g3, OPTYPE_ISCSI_BACKUP,
+ FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_BACKUP_iSCSI},
+ { FLASH_FCoE_PRIMARY_IMAGE_START_g3, OPTYPE_FCOE_FW_ACTIVE,
+ FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_FCoE},
+ { FLASH_FCoE_BACKUP_IMAGE_START_g3, OPTYPE_FCOE_FW_BACKUP,
+ FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_BACKUP_FCoE},
+ { FLASH_NCSI_START_g3, OPTYPE_NCSI_FW,
+ FLASH_NCSI_IMAGE_MAX_SIZE_g3, IMAGE_NCSI},
+ { FLASH_PHY_FW_START_g3, OPTYPE_PHY_FW,
+ FLASH_PHY_FW_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_PHY}
};
- static const struct flash_comp gen2_flash_types[8] = {
- { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE,
- FLASH_IMAGE_MAX_SIZE_g2},
- { FLASH_REDBOOT_START_g2, IMG_TYPE_REDBOOT,
- FLASH_REDBOOT_IMAGE_MAX_SIZE_g2},
- { FLASH_iSCSI_BIOS_START_g2, IMG_TYPE_BIOS,
- FLASH_BIOS_IMAGE_MAX_SIZE_g2},
- { FLASH_PXE_BIOS_START_g2, IMG_TYPE_PXE_BIOS,
- FLASH_BIOS_IMAGE_MAX_SIZE_g2},
- { FLASH_FCoE_BIOS_START_g2, IMG_TYPE_FCOE_BIOS,
- FLASH_BIOS_IMAGE_MAX_SIZE_g2},
- { FLASH_iSCSI_BACKUP_IMAGE_START_g2, IMG_TYPE_ISCSI_BACKUP,
- FLASH_IMAGE_MAX_SIZE_g2},
- { FLASH_FCoE_PRIMARY_IMAGE_START_g2, IMG_TYPE_FCOE_FW_ACTIVE,
- FLASH_IMAGE_MAX_SIZE_g2},
- { FLASH_FCoE_BACKUP_IMAGE_START_g2, IMG_TYPE_FCOE_FW_BACKUP,
- FLASH_IMAGE_MAX_SIZE_g2}
+
+ struct flash_comp gen2_flash_types[] = {
+ { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, OPTYPE_ISCSI_ACTIVE,
+ FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_iSCSI},
+ { FLASH_REDBOOT_START_g2, OPTYPE_REDBOOT,
+ FLASH_REDBOOT_IMAGE_MAX_SIZE_g2, IMAGE_BOOT_CODE},
+ { FLASH_iSCSI_BIOS_START_g2, OPTYPE_BIOS,
+ FLASH_BIOS_IMAGE_MAX_SIZE_g2, IMAGE_OPTION_ROM_ISCSI},
+ { FLASH_PXE_BIOS_START_g2, OPTYPE_PXE_BIOS,
+ FLASH_BIOS_IMAGE_MAX_SIZE_g2, IMAGE_OPTION_ROM_PXE},
+ { FLASH_FCoE_BIOS_START_g2, OPTYPE_FCOE_BIOS,
+ FLASH_BIOS_IMAGE_MAX_SIZE_g2, IMAGE_OPTION_ROM_FCoE},
+ { FLASH_iSCSI_BACKUP_IMAGE_START_g2, OPTYPE_ISCSI_BACKUP,
+ FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_BACKUP_iSCSI},
+ { FLASH_FCoE_PRIMARY_IMAGE_START_g2, OPTYPE_FCOE_FW_ACTIVE,
+ FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_FCoE},
+ { FLASH_FCoE_BACKUP_IMAGE_START_g2, OPTYPE_FCOE_FW_BACKUP,
+ FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_BACKUP_FCoE}
};
if (adapter->generation == BE_GEN3) {
@@ -2832,22 +2900,37 @@ static int be_flash_data(struct be_adapter *adapter,
filehdr_size = sizeof(struct flash_file_hdr_g2);
num_comp = ARRAY_SIZE(gen2_flash_types);
}
+ /* Get flash section info*/
+ fsec = get_fsec_info(adapter, filehdr_size + img_hdrs_size, fw);
+ if (!fsec) {
+ dev_err(&adapter->pdev->dev,
+ "Invalid Cookie. UFI corrupted ?\n");
+ return -1;
+ }
for (i = 0; i < num_comp; i++) {
- if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) &&
- memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
+ if (!is_comp_in_ufi(adapter, fsec, pflashcomp[i].img_type))
continue;
- if (pflashcomp[i].optype == IMG_TYPE_PHY_FW) {
+
+ if ((pflashcomp[i].optype == OPTYPE_NCSI_FW) &&
+ memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
+ continue;
+
+ if (pflashcomp[i].optype == OPTYPE_PHY_FW) {
if (!phy_flashing_required(adapter))
continue;
}
- if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) &&
- (!be_flash_redboot(adapter, fw->data,
- pflashcomp[i].offset, pflashcomp[i].size, filehdr_size +
- (num_of_images * sizeof(struct image_hdr)))))
+
+ hdr_size = filehdr_size +
+ (num_of_images * sizeof(struct image_hdr));
+
+ if ((pflashcomp[i].optype == OPTYPE_REDBOOT) &&
+ (!be_flash_redboot(adapter, fw->data, pflashcomp[i].offset,
+ pflashcomp[i].size, hdr_size)))
continue;
+
+ /* Flash the component */
p = fw->data;
- p += filehdr_size + pflashcomp[i].offset
- + (num_of_images * sizeof(struct image_hdr));
+ p += filehdr_size + pflashcomp[i].offset + img_hdrs_size;
if (p + pflashcomp[i].size > fw->data + fw->size)
return -1;
total_bytes = pflashcomp[i].size;
@@ -2858,12 +2941,12 @@ static int be_flash_data(struct be_adapter *adapter,
num_bytes = total_bytes;
total_bytes -= num_bytes;
if (!total_bytes) {
- if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
+ if (pflashcomp[i].optype == OPTYPE_PHY_FW)
flash_op = FLASHROM_OPER_PHY_FLASH;
else
flash_op = FLASHROM_OPER_FLASH;
} else {
- if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
+ if (pflashcomp[i].optype == OPTYPE_PHY_FW)
flash_op = FLASHROM_OPER_PHY_SAVE;
else
flash_op = FLASHROM_OPER_SAVE;
@@ -2875,7 +2958,7 @@ static int be_flash_data(struct be_adapter *adapter,
if (status) {
if ((status == ILLEGAL_IOCTL_REQ) &&
(pflashcomp[i].optype ==
- IMG_TYPE_PHY_FW))
+ OPTYPE_PHY_FW))
break;
dev_err(&adapter->pdev->dev,
"cmd to write to flash rom failed.\n");
diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h
index 251729a47880..db4bae78bda9 100644
--- a/include/linux/sock_diag.h
+++ b/include/linux/sock_diag.h
@@ -32,8 +32,8 @@ struct sock_diag_handler {
int (*dump)(struct sk_buff *skb, struct nlmsghdr *nlh);
};
-int sock_diag_register(struct sock_diag_handler *h);
-void sock_diag_unregister(struct sock_diag_handler *h);
+int sock_diag_register(const struct sock_diag_handler *h);
+void sock_diag_unregister(const struct sock_diag_handler *h);
void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh));
void sock_diag_unregister_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh));
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 986593685566..278af9ea42d4 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -111,6 +111,11 @@ enum {
#define TCP_QUEUE_SEQ 21
#define TCP_REPAIR_OPTIONS 22
+struct tcp_repair_opt {
+ __u32 opt_code;
+ __u32 opt_val;
+};
+
enum {
TCP_NO_QUEUE,
TCP_RECV_QUEUE,
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c
index b9868e1fd62c..5fd146720f39 100644
--- a/net/core/sock_diag.c
+++ b/net/core/sock_diag.c
@@ -10,7 +10,7 @@
#include <linux/inet_diag.h>
#include <linux/sock_diag.h>
-static struct sock_diag_handler *sock_diag_handlers[AF_MAX];
+static const struct sock_diag_handler *sock_diag_handlers[AF_MAX];
static int (*inet_rcv_compat)(struct sk_buff *skb, struct nlmsghdr *nlh);
static DEFINE_MUTEX(sock_diag_table_mutex);
@@ -70,7 +70,7 @@ void sock_diag_unregister_inet_compat(int (*fn)(struct sk_buff *skb, struct nlms
}
EXPORT_SYMBOL_GPL(sock_diag_unregister_inet_compat);
-int sock_diag_register(struct sock_diag_handler *hndl)
+int sock_diag_register(const struct sock_diag_handler *hndl)
{
int err = 0;
@@ -88,7 +88,7 @@ int sock_diag_register(struct sock_diag_handler *hndl)
}
EXPORT_SYMBOL_GPL(sock_diag_register);
-void sock_diag_unregister(struct sock_diag_handler *hnld)
+void sock_diag_unregister(const struct sock_diag_handler *hnld)
{
int family = hnld->family;
@@ -102,7 +102,7 @@ void sock_diag_unregister(struct sock_diag_handler *hnld)
}
EXPORT_SYMBOL_GPL(sock_diag_unregister);
-static inline struct sock_diag_handler *sock_diag_lock_handler(int family)
+static const inline struct sock_diag_handler *sock_diag_lock_handler(int family)
{
if (sock_diag_handlers[family] == NULL)
request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
@@ -112,7 +112,7 @@ static inline struct sock_diag_handler *sock_diag_lock_handler(int family)
return sock_diag_handlers[family];
}
-static inline void sock_diag_unlock_handler(struct sock_diag_handler *h)
+static inline void sock_diag_unlock_handler(const struct sock_diag_handler *h)
{
mutex_unlock(&sock_diag_table_mutex);
}
@@ -121,7 +121,7 @@ static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
int err;
struct sock_diag_req *req = NLMSG_DATA(nlh);
- struct sock_diag_handler *hndl;
+ const struct sock_diag_handler *hndl;
if (nlmsg_len(nlh) < sizeof(*req))
return -EINVAL;
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index 8dfa1da7c40d..656c7c75b192 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -704,6 +704,7 @@ static int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb,
ret = dcbnl_reply(err, RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP,
pid, seq, flags);
+ dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SAPP, seq, 0);
out:
return ret;
}
@@ -936,6 +937,7 @@ static int dcbnl_setall(struct net_device *netdev, struct nlattr **tb,
ret = dcbnl_reply(netdev->dcbnl_ops->setall(netdev), RTM_SETDCB,
DCB_CMD_SET_ALL, DCB_ATTR_SET_ALL, pid, seq, flags);
+ dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SET_ALL, seq, 0);
return ret;
}
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
index 58c8895716ff..4b5701c8bf97 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -196,7 +196,7 @@ lowpan_compress_addr_64(u8 **hc06_ptr, u8 shift, const struct in6_addr *ipaddr,
static void
lowpan_uip_ds6_set_addr_iid(struct in6_addr *ipaddr, unsigned char *lladdr)
{
- memcpy(&ipaddr->s6_addr[8], lladdr, IEEE802154_ALEN);
+ memcpy(&ipaddr->s6_addr[8], lladdr, IEEE802154_ADDR_LEN);
/* second bit-flip (Universe/Local) is done according RFC2464 */
ipaddr->s6_addr[8] ^= 0x02;
}
@@ -221,7 +221,7 @@ lowpan_uncompress_addr(struct sk_buff *skb, struct in6_addr *ipaddr,
if (lladdr)
lowpan_raw_dump_inline(__func__, "linklocal address",
- lladdr, IEEE802154_ALEN);
+ lladdr, IEEE802154_ADDR_LEN);
if (prefcount > 0)
memcpy(ipaddr, prefix, prefcount);
@@ -650,6 +650,53 @@ static void lowpan_fragment_timer_expired(unsigned long entry_addr)
kfree(entry);
}
+static struct lowpan_fragment *
+lowpan_alloc_new_frame(struct sk_buff *skb, u8 iphc0, u8 len, u8 tag)
+{
+ struct lowpan_fragment *frame;
+
+ frame = kzalloc(sizeof(struct lowpan_fragment),
+ GFP_ATOMIC);
+ if (!frame)
+ goto frame_err;
+
+ INIT_LIST_HEAD(&frame->list);
+
+ frame->length = (iphc0 & 7) | (len << 3);
+ frame->tag = tag;
+
+ /* allocate buffer for frame assembling */
+ frame->skb = alloc_skb(frame->length +
+ sizeof(struct ipv6hdr), GFP_ATOMIC);
+
+ if (!frame->skb)
+ goto skb_err;
+
+ frame->skb->priority = skb->priority;
+ frame->skb->dev = skb->dev;
+
+ /* reserve headroom for uncompressed ipv6 header */
+ skb_reserve(frame->skb, sizeof(struct ipv6hdr));
+ skb_put(frame->skb, frame->length);
+
+ init_timer(&frame->timer);
+ /* time out is the same as for ipv6 - 60 sec */
+ frame->timer.expires = jiffies + LOWPAN_FRAG_TIMEOUT;
+ frame->timer.data = (unsigned long)frame;
+ frame->timer.function = lowpan_fragment_timer_expired;
+
+ add_timer(&frame->timer);
+
+ list_add_tail(&frame->list, &lowpan_fragments);
+
+ return frame;
+
+skb_err:
+ kfree(frame);
+frame_err:
+ return NULL;
+}
+
static int
lowpan_process_data(struct sk_buff *skb)
{
@@ -692,41 +739,9 @@ lowpan_process_data(struct sk_buff *skb)
/* alloc new frame structure */
if (!found) {
- frame = kzalloc(sizeof(struct lowpan_fragment),
- GFP_ATOMIC);
+ frame = lowpan_alloc_new_frame(skb, iphc0, len, tag);
if (!frame)
goto unlock_and_drop;
-
- INIT_LIST_HEAD(&frame->list);
-
- frame->length = (iphc0 & 7) | (len << 3);
- frame->tag = tag;
-
- /* allocate buffer for frame assembling */
- frame->skb = alloc_skb(frame->length +
- sizeof(struct ipv6hdr), GFP_ATOMIC);
-
- if (!frame->skb) {
- kfree(frame);
- goto unlock_and_drop;
- }
-
- frame->skb->priority = skb->priority;
- frame->skb->dev = skb->dev;
-
- /* reserve headroom for uncompressed ipv6 header */
- skb_reserve(frame->skb, sizeof(struct ipv6hdr));
- skb_put(frame->skb, frame->length);
-
- init_timer(&frame->timer);
- /* time out is the same as for ipv6 - 60 sec */
- frame->timer.expires = jiffies + LOWPAN_FRAG_TIMEOUT;
- frame->timer.data = (unsigned long)frame;
- frame->timer.function = lowpan_fragment_timer_expired;
-
- add_timer(&frame->timer);
-
- list_add_tail(&frame->list, &lowpan_fragments);
}
if ((iphc0 & LOWPAN_DISPATCH_MASK) == LOWPAN_DISPATCH_FRAG1)
diff --git a/net/ieee802154/6lowpan.h b/net/ieee802154/6lowpan.h
index aeff3f310482..8c2251fb0a3f 100644
--- a/net/ieee802154/6lowpan.h
+++ b/net/ieee802154/6lowpan.h
@@ -53,9 +53,6 @@
#ifndef __6LOWPAN_H__
#define __6LOWPAN_H__
-/* need to know address length to manipulate with it */
-#define IEEE802154_ALEN 8
-
#define UIP_802154_SHORTADDR_LEN 2 /* compressed ipv6 address length */
#define UIP_IPH_LEN 40 /* ipv6 fixed header size */
#define UIP_PROTO_UDP 17 /* ipv6 next header value for UDP */
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 8d25a1c557eb..9f24028a3ba7 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -999,12 +999,12 @@ static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
return inet_diag_get_exact(skb, h, (struct inet_diag_req_v2 *)NLMSG_DATA(h));
}
-static struct sock_diag_handler inet_diag_handler = {
+static const struct sock_diag_handler inet_diag_handler = {
.family = AF_INET,
.dump = inet_diag_handler_dump,
};
-static struct sock_diag_handler inet6_diag_handler = {
+static const struct sock_diag_handler inet6_diag_handler = {
.family = AF_INET6,
.dump = inet_diag_handler_dump,
};
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index de6a238f0e1d..9670af341931 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2283,60 +2283,40 @@ static inline int tcp_can_repair_sock(struct sock *sk)
((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_ESTABLISHED));
}
-static int tcp_repair_options_est(struct tcp_sock *tp, char __user *optbuf, unsigned int len)
+static int tcp_repair_options_est(struct tcp_sock *tp,
+ struct tcp_repair_opt __user *optbuf, unsigned int len)
{
- /*
- * Options are stored in CODE:VALUE form where CODE is 8bit and VALUE
- * fits the respective TCPOLEN_ size
- */
+ struct tcp_repair_opt opt;
- while (len > 0) {
- u8 opcode;
-
- if (get_user(opcode, optbuf))
+ while (len >= sizeof(opt)) {
+ if (copy_from_user(&opt, optbuf, sizeof(opt)))
return -EFAULT;
optbuf++;
- len--;
-
- switch (opcode) {
- case TCPOPT_MSS: {
- u16 in_mss;
+ len -= sizeof(opt);
- if (len < sizeof(in_mss))
- return -ENODATA;
- if (get_user(in_mss, optbuf))
- return -EFAULT;
-
- tp->rx_opt.mss_clamp = in_mss;
-
- optbuf += sizeof(in_mss);
- len -= sizeof(in_mss);
+ switch (opt.opt_code) {
+ case TCPOPT_MSS:
+ tp->rx_opt.mss_clamp = opt.opt_val;
break;
- }
- case TCPOPT_WINDOW: {
- u8 wscale;
-
- if (len < sizeof(wscale))
- return -ENODATA;
- if (get_user(wscale, optbuf))
- return -EFAULT;
-
- if (wscale > 14)
+ case TCPOPT_WINDOW:
+ if (opt.opt_val > 14)
return -EFBIG;
- tp->rx_opt.snd_wscale = wscale;
-
- optbuf += sizeof(wscale);
- len -= sizeof(wscale);
+ tp->rx_opt.snd_wscale = opt.opt_val;
break;
- }
case TCPOPT_SACK_PERM:
+ if (opt.opt_val != 0)
+ return -EINVAL;
+
tp->rx_opt.sack_ok |= TCP_SACK_SEEN;
if (sysctl_tcp_fack)
tcp_enable_fack(tp);
break;
case TCPOPT_TIMESTAMP:
+ if (opt.opt_val != 0)
+ return -EINVAL;
+
tp->rx_opt.tstamp_ok = 1;
break;
}
@@ -2557,7 +2537,9 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
if (!tp->repair)
err = -EINVAL;
else if (sk->sk_state == TCP_ESTABLISHED)
- err = tcp_repair_options_est(tp, optval, optlen);
+ err = tcp_repair_options_est(tp,
+ (struct tcp_repair_opt __user *)optval,
+ optlen);
else
err = -EPERM;
break;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index b7ca46161cb9..b347062aa809 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -210,7 +210,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
kfree_skb(skb);
return -ENOBUFS;
}
- kfree_skb(skb);
+ consume_skb(skb);
skb = skb2;
skb_set_owner_w(skb, sk);
}
@@ -889,7 +889,7 @@ slow_path:
}
IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
IPSTATS_MIB_FRAGOKS);
- kfree_skb(skb);
+ consume_skb(skb);
return err;
fail:
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 36e04cff1a85..54c5d2b704df 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -433,7 +433,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
skb_morph(head, fq->q.fragments);
head->next = fq->q.fragments->next;
- kfree_skb(fq->q.fragments);
+ consume_skb(fq->q.fragments);
fq->q.fragments = head;
}
diff --git a/net/unix/diag.c b/net/unix/diag.c
index f0486ae9ebe6..47d3002737f5 100644
--- a/net/unix/diag.c
+++ b/net/unix/diag.c
@@ -310,7 +310,7 @@ static int unix_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
return unix_diag_get_exact(skb, h, (struct unix_diag_req *)NLMSG_DATA(h));
}
-static struct sock_diag_handler unix_diag_handler = {
+static const struct sock_diag_handler unix_diag_handler = {
.family = AF_UNIX,
.dump = unix_diag_handler_dump,
};