From 0008641bd40be7abc9040f99f62622f54be76911 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 14 Sep 2009 18:11:03 +0400 Subject: [PATCH] --- yaml --- r: 171252 b: refs/heads/master c: 69d9ab96f983720b7794e91437bd9c5f83bae9f7 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/MAINTAINERS | 1 - trunk/drivers/isdn/hardware/eicon/maintidi.c | 5 +- trunk/drivers/isdn/hardware/eicon/message.c | 18 +- trunk/drivers/isdn/hisax/amd7930_fn.c | 1 - trunk/drivers/isdn/hisax/diva.c | 2 +- trunk/drivers/isdn/hisax/hfc_usb.c | 4 +- trunk/drivers/isdn/hisax/hscx_irq.c | 2 +- trunk/drivers/isdn/hisax/icc.c | 1 - trunk/drivers/isdn/mISDN/socket.c | 2 +- trunk/drivers/isdn/mISDN/stack.c | 2 +- trunk/drivers/net/benet/be_cmds.h | 2 +- trunk/drivers/net/bnx2x_hsi.h | 1 - trunk/drivers/net/bnx2x_link.c | 317 +++---- trunk/drivers/net/bnx2x_link.h | 3 +- trunk/drivers/net/bnx2x_main.c | 20 +- trunk/drivers/net/bnx2x_reg.h | 23 +- trunk/drivers/net/davinci_emac.c | 2 +- trunk/drivers/net/e100.c | 26 +- trunk/drivers/net/e1000e/defines.h | 2 - trunk/drivers/net/e1000e/e1000.h | 14 - trunk/drivers/net/e1000e/hw.h | 1 - trunk/drivers/net/e1000e/ich8lan.c | 482 ++-------- trunk/drivers/net/e1000e/phy.c | 15 +- trunk/drivers/net/pcmcia/pcnet_cs.c | 2 +- trunk/drivers/net/pppox.c | 3 +- trunk/drivers/net/r8169.c | 2 +- trunk/drivers/net/sky2.c | 2 - trunk/drivers/net/tokenring/ibmtr.c | 11 +- trunk/drivers/net/usb/Kconfig | 2 +- trunk/drivers/net/usb/cdc_ether.c | 42 +- trunk/drivers/net/virtio_net.c | 6 +- trunk/drivers/net/wimax/i2400m/control.c | 16 +- trunk/drivers/net/wimax/i2400m/debugfs.c | 2 +- trunk/drivers/net/wimax/i2400m/driver.c | 500 +++------- trunk/drivers/net/wimax/i2400m/fw.c | 886 ++++-------------- trunk/drivers/net/wimax/i2400m/i2400m-sdio.h | 16 +- trunk/drivers/net/wimax/i2400m/i2400m-usb.h | 16 +- trunk/drivers/net/wimax/i2400m/i2400m.h | 209 ++--- trunk/drivers/net/wimax/i2400m/netdev.c | 127 +-- trunk/drivers/net/wimax/i2400m/rx.c | 170 +--- trunk/drivers/net/wimax/i2400m/sdio-fw.c | 11 +- trunk/drivers/net/wimax/i2400m/sdio-rx.c | 42 +- trunk/drivers/net/wimax/i2400m/sdio-tx.c | 5 +- trunk/drivers/net/wimax/i2400m/sdio.c | 205 ++-- trunk/drivers/net/wimax/i2400m/tx.c | 20 +- trunk/drivers/net/wimax/i2400m/usb-fw.c | 37 +- trunk/drivers/net/wimax/i2400m/usb-notif.c | 35 +- trunk/drivers/net/wimax/i2400m/usb-rx.c | 60 +- trunk/drivers/net/wimax/i2400m/usb-tx.c | 61 +- trunk/drivers/net/wimax/i2400m/usb.c | 189 +--- trunk/drivers/net/wireless/ath/ath9k/rc.c | 2 +- trunk/drivers/net/wireless/b43/dma.c | 15 +- trunk/drivers/net/wireless/ipw2x00/ipw2100.c | 5 +- trunk/drivers/net/wireless/ipw2x00/ipw2200.c | 2 - trunk/drivers/net/wireless/ipw2x00/libipw.h | 1 - .../net/wireless/ipw2x00/libipw_module.c | 14 +- trunk/drivers/net/wireless/libertas/if_usb.c | 2 +- trunk/drivers/net/wireless/rt2x00/rt73usb.c | 5 - trunk/drivers/serial/serial_cs.c | 8 +- trunk/firmware/Makefile | 6 +- trunk/firmware/WHENCE | 4 - trunk/firmware/cis/PE-200.cis.ihex | 9 - trunk/firmware/cis/SW_555_SER.cis.ihex | 12 - trunk/firmware/cis/SW_7xx_SER.cis.ihex | 13 - trunk/firmware/cis/SW_8xx_SER.cis.ihex | 13 - trunk/include/linux/can/core.h | 2 + trunk/include/linux/mmc/sdio_ids.h | 1 - trunk/include/linux/net.h | 3 +- trunk/include/linux/skbuff.h | 6 +- trunk/include/linux/wimax/debug.h | 72 -- trunk/include/linux/wimax/i2400m.h | 13 +- trunk/include/net/ip_fib.h | 3 +- trunk/include/net/netfilter/nf_conntrack.h | 8 +- trunk/include/net/netfilter/nf_nat_helper.h | 4 - trunk/include/net/protocol.h | 4 + trunk/include/net/wimax.h | 6 - trunk/include/net/wpan-phy.h | 6 + trunk/net/appletalk/ddp.c | 3 +- trunk/net/atm/pvc.c | 3 +- trunk/net/atm/svc.c | 7 +- trunk/net/ax25/af_ax25.c | 3 +- trunk/net/bluetooth/af_bluetooth.c | 5 +- trunk/net/bluetooth/bnep/sock.c | 3 +- trunk/net/bluetooth/cmtp/sock.c | 3 +- trunk/net/bluetooth/hci_sock.c | 3 +- trunk/net/bluetooth/hidp/sock.c | 3 +- trunk/net/bluetooth/l2cap.c | 5 +- trunk/net/bluetooth/rfcomm/sock.c | 3 +- trunk/net/bluetooth/sco.c | 3 +- trunk/net/bridge/br_if.c | 6 +- trunk/net/bridge/br_ioctl.c | 4 +- trunk/net/can/af_can.c | 8 +- trunk/net/can/bcm.c | 1 + trunk/net/can/raw.c | 1 + trunk/net/core/datagram.c | 10 +- trunk/net/core/pktgen.c | 5 +- trunk/net/core/sock.c | 17 +- trunk/net/dccp/ipv4.c | 1 + trunk/net/dccp/ipv6.c | 1 + trunk/net/decnet/af_decnet.c | 3 +- trunk/net/decnet/sysctl_net_decnet.c | 7 +- trunk/net/econet/af_econet.c | 3 +- trunk/net/ieee802154/af_ieee802154.c | 2 +- trunk/net/ipv4/af_inet.c | 8 +- trunk/net/ipv4/fib_frontend.c | 5 +- trunk/net/ipv4/ip_fragment.c | 7 +- trunk/net/ipv4/ip_gre.c | 28 +- trunk/net/ipv4/netfilter/nf_nat_core.c | 3 - trunk/net/ipv4/netfilter/nf_nat_helper.c | 34 +- trunk/net/ipv4/route.c | 8 +- trunk/net/ipv4/udp.c | 4 +- trunk/net/ipv4/udplite.c | 1 + trunk/net/ipv6/af_inet6.c | 5 +- trunk/net/ipv6/raw.c | 1 + trunk/net/ipv6/reassembly.c | 13 +- trunk/net/ipv6/tcp_ipv6.c | 1 + trunk/net/ipv6/udp.c | 5 +- trunk/net/ipv6/udplite.c | 1 + trunk/net/ipx/af_ipx.c | 3 +- trunk/net/irda/af_irda.c | 7 +- trunk/net/iucv/af_iucv.c | 3 +- trunk/net/key/af_key.c | 3 +- trunk/net/llc/af_llc.c | 5 +- trunk/net/mac80211/agg-tx.c | 19 +- trunk/net/mac80211/cfg.c | 6 +- trunk/net/mac80211/ht.c | 2 +- trunk/net/mac80211/ibss.c | 6 +- trunk/net/netfilter/nf_conntrack_core.c | 8 - trunk/net/netfilter/nf_conntrack_proto_tcp.c | 64 +- trunk/net/netlabel/netlabel_unlabeled.c | 6 +- trunk/net/netlink/af_netlink.c | 3 +- trunk/net/netrom/af_netrom.c | 3 +- trunk/net/packet/af_packet.c | 3 +- trunk/net/phonet/af_phonet.c | 3 +- trunk/net/rds/af_rds.c | 3 +- trunk/net/rose/af_rose.c | 3 +- trunk/net/rose/rose_route.c | 16 +- trunk/net/rxrpc/af_rxrpc.c | 3 +- trunk/net/sched/cls_api.c | 4 +- trunk/net/sctp/ipv6.c | 21 +- trunk/net/sctp/protocol.c | 2 + trunk/net/socket.c | 2 +- trunk/net/sunrpc/svcsock.c | 10 +- trunk/net/tipc/socket.c | 6 +- trunk/net/unix/af_unix.c | 3 +- trunk/net/wimax/op-msg.c | 2 - trunk/net/wimax/op-rfkill.c | 10 +- trunk/net/wimax/stack.c | 11 - trunk/net/wireless/sme.c | 7 +- trunk/net/x25/af_x25.c | 3 +- 151 files changed, 1138 insertions(+), 3213 deletions(-) delete mode 100644 trunk/firmware/cis/PE-200.cis.ihex delete mode 100644 trunk/firmware/cis/SW_555_SER.cis.ihex delete mode 100644 trunk/firmware/cis/SW_7xx_SER.cis.ihex delete mode 100644 trunk/firmware/cis/SW_8xx_SER.cis.ihex diff --git a/[refs] b/[refs] index 217ef646c4be..80b6dd45cccf 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 62d83681e53fd87c91927018cfe5ba9f9e8109a3 +refs/heads/master: 69d9ab96f983720b7794e91437bd9c5f83bae9f7 diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 0350ace39e6c..e1cf7314a24c 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -3655,7 +3655,6 @@ L: netdev@vger.kernel.org W: http://www.linuxfoundation.org/en/Net W: http://patchwork.ozlabs.org/project/netdev/list/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git -T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6.git S: Maintained F: net/ F: include/net/ diff --git a/trunk/drivers/isdn/hardware/eicon/maintidi.c b/trunk/drivers/isdn/hardware/eicon/maintidi.c index 41c26e756452..23960cb6eaab 100644 --- a/trunk/drivers/isdn/hardware/eicon/maintidi.c +++ b/trunk/drivers/isdn/hardware/eicon/maintidi.c @@ -959,9 +959,8 @@ static int process_idi_event (diva_strace_context_t* pLib, } if (!strncmp("State\\Layer2 No1", path, pVar->path_length)) { char* tmp = &pLib->lines[0].pInterface->Layer2[0]; - dword l2_state; - if (diva_strace_read_uint(pVar, &l2_state)) - return -1; + dword l2_state; + diva_strace_read_uint (pVar, &l2_state); switch (l2_state) { case 0: diff --git a/trunk/drivers/isdn/hardware/eicon/message.c b/trunk/drivers/isdn/hardware/eicon/message.c index ae89fb89da64..27d5dd68f4fb 100644 --- a/trunk/drivers/isdn/hardware/eicon/message.c +++ b/trunk/drivers/isdn/hardware/eicon/message.c @@ -2692,7 +2692,7 @@ static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, if (!(fax_control_bits & T30_CONTROL_BIT_MORE_DOCUMENTS) || (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS)) { - len = offsetof(T30_INFO, universal_6); + len = (byte)(&(((T30_INFO *) 0)->universal_6)); fax_info_change = false; if (ncpi->length >= 4) { @@ -2754,7 +2754,7 @@ static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, for (i = 0; i < w; i++) ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1+i]; ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0; - len = offsetof(T30_INFO, station_id) + 20; + len = (byte)(((T30_INFO *) 0)->station_id + 20); w = fax_parms[5].length; if (w > 20) w = 20; @@ -2788,7 +2788,7 @@ static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, } else { - len = offsetof(T30_INFO, universal_6); + len = (byte)(&(((T30_INFO *) 0)->universal_6)); } fax_info_change = true; @@ -2892,7 +2892,7 @@ static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF) && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)) { - len = offsetof(T30_INFO, station_id) + 20; + len = ((byte)(((T30_INFO *) 0)->station_id + 20)); if (plci->fax_connect_info_length < len) { ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0; @@ -3802,7 +3802,7 @@ static byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, break; } ncpi = &m_parms[1]; - len = offsetof(T30_INFO, station_id) + 20; + len = ((byte)(((T30_INFO *) 0)->station_id + 20)); if (plci->fax_connect_info_length < len) { ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0; @@ -6844,7 +6844,7 @@ static void nl_ind(PLCI *plci) if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1]) & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) { - i = offsetof(T30_INFO, station_id) + 20 + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len; + i = ((word)(((T30_INFO *) 0)->station_id + 20)) + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len; while (i < plci->NL.RBuffer->length) plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++]; } @@ -7236,7 +7236,7 @@ static void nl_ind(PLCI *plci) { plci->RData[1].P = plci->RData[0].P; plci->RData[1].PLength = plci->RData[0].PLength; - plci->RData[0].P = v120_header_buffer + (-((unsigned long)v120_header_buffer) & 3); + plci->RData[0].P = v120_header_buffer + (-((int) v120_header_buffer) & 3); if ((plci->NL.RBuffer->P[0] & V120_HEADER_EXTEND_BIT) || (plci->NL.RLength == 1)) plci->RData[0].PLength = 1; else @@ -8473,7 +8473,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp) fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING; } len = nlc[0]; - pos = offsetof(T30_INFO, station_id) + 20; + pos = ((byte)(((T30_INFO *) 0)->station_id + 20)); if (pos < plci->fax_connect_info_length) { for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--) @@ -8525,7 +8525,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp) } PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits); - len = offsetof(T30_INFO, station_id) + 20; + len = ((byte)(((T30_INFO *) 0)->station_id + 20)); for (i = 0; i < len; i++) plci->fax_connect_info_buffer[i] = nlc[1+i]; ((T30_INFO *) plci->fax_connect_info_buffer)->head_line_len = 0; diff --git a/trunk/drivers/isdn/hisax/amd7930_fn.c b/trunk/drivers/isdn/hisax/amd7930_fn.c index d6fdf1f66754..bf526a7a63af 100644 --- a/trunk/drivers/isdn/hisax/amd7930_fn.c +++ b/trunk/drivers/isdn/hisax/amd7930_fn.c @@ -594,7 +594,6 @@ Amd7930_l1hw(struct PStack *st, int pr, void *arg) if (cs->debug & L1_DEB_WARN) debugl1(cs, "Amd7930: l1hw: l2l1 tx_skb exist this shouldn't happen"); skb_queue_tail(&cs->sq, skb); - spin_unlock_irqrestore(&cs->lock, flags); break; } if (cs->debug & DEB_DLOG_HEX) diff --git a/trunk/drivers/isdn/hisax/diva.c b/trunk/drivers/isdn/hisax/diva.c index 0b0c2e5d806b..018bd293e580 100644 --- a/trunk/drivers/isdn/hisax/diva.c +++ b/trunk/drivers/isdn/hisax/diva.c @@ -382,7 +382,7 @@ MemwaitforXFW(struct IsdnCardState *cs, int hscx) { int to = 50; - while (((MemReadHSCX(cs, hscx, HSCX_STAR) & 0x44) != 0x40) && to) { + while ((!(MemReadHSCX(cs, hscx, HSCX_STAR) & 0x44) == 0x40) && to) { udelay(1); to--; } diff --git a/trunk/drivers/isdn/hisax/hfc_usb.c b/trunk/drivers/isdn/hisax/hfc_usb.c index a420b64472e3..9de54202c90c 100644 --- a/trunk/drivers/isdn/hisax/hfc_usb.c +++ b/trunk/drivers/isdn/hisax/hfc_usb.c @@ -817,8 +817,8 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) } /* we have a complete hdlc packet */ if (finish) { - if (fifo->skbuff->len > 3 && - !fifo->skbuff->data[fifo->skbuff->len - 1]) { + if ((!fifo->skbuff->data[fifo->skbuff->len - 1]) + && (fifo->skbuff->len > 3)) { if (fifon == HFCUSB_D_RX) { DBG(HFCUSB_DBG_DCHANNEL, diff --git a/trunk/drivers/isdn/hisax/hscx_irq.c b/trunk/drivers/isdn/hisax/hscx_irq.c index 2387d76c721a..7b1ad5e4ecda 100644 --- a/trunk/drivers/isdn/hisax/hscx_irq.c +++ b/trunk/drivers/isdn/hisax/hscx_irq.c @@ -32,7 +32,7 @@ waitforXFW(struct IsdnCardState *cs, int hscx) { int to = 50; - while (((READHSCX(cs, hscx, HSCX_STAR) & 0x44) != 0x40) && to) { + while ((!(READHSCX(cs, hscx, HSCX_STAR) & 0x44) == 0x40) && to) { udelay(1); to--; } diff --git a/trunk/drivers/isdn/hisax/icc.c b/trunk/drivers/isdn/hisax/icc.c index c80cbb8a2ef9..9aba646ba221 100644 --- a/trunk/drivers/isdn/hisax/icc.c +++ b/trunk/drivers/isdn/hisax/icc.c @@ -468,7 +468,6 @@ ICC_l1hw(struct PStack *st, int pr, void *arg) if (cs->debug & L1_DEB_WARN) debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); skb_queue_tail(&cs->sq, skb); - spin_unlock_irqrestore(&cs->lock, flags); break; } if (cs->debug & DEB_DLOG_HEX) diff --git a/trunk/drivers/isdn/mISDN/socket.c b/trunk/drivers/isdn/mISDN/socket.c index fcfe17a19a61..28182ed8dea1 100644 --- a/trunk/drivers/isdn/mISDN/socket.c +++ b/trunk/drivers/isdn/mISDN/socket.c @@ -779,7 +779,7 @@ base_sock_create(struct net *net, struct socket *sock, int protocol) } static int -mISDN_sock_create(struct net *net, struct socket *sock, int proto, int kern) +mISDN_sock_create(struct net *net, struct socket *sock, int proto) { int err = -EPROTONOSUPPORT; diff --git a/trunk/drivers/isdn/mISDN/stack.c b/trunk/drivers/isdn/mISDN/stack.c index 0d05ec43012c..3e1532a180ff 100644 --- a/trunk/drivers/isdn/mISDN/stack.c +++ b/trunk/drivers/isdn/mISDN/stack.c @@ -364,7 +364,7 @@ add_layer2(struct mISDNchannel *ch, struct mISDNstack *st) static int st_own_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg) { - if (!ch->st || !ch->st->layer1) + if (!ch->st || ch->st->layer1) return -EINVAL; return ch->st->layer1->ctrl(ch->st->layer1, cmd, arg); } diff --git a/trunk/drivers/net/benet/be_cmds.h b/trunk/drivers/net/benet/be_cmds.h index 69dc017c814b..76410c1d5669 100644 --- a/trunk/drivers/net/benet/be_cmds.h +++ b/trunk/drivers/net/benet/be_cmds.h @@ -68,7 +68,7 @@ enum { #define CQE_STATUS_COMPL_MASK 0xFFFF #define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */ #define CQE_STATUS_EXTD_MASK 0xFFFF -#define CQE_STATUS_EXTD_SHIFT 16 /* bits 16 - 31 */ +#define CQE_STATUS_EXTD_SHIFT 0 /* bits 0 - 15 */ struct be_mcc_compl { u32 status; /* dword 0 */ diff --git a/trunk/drivers/net/bnx2x_hsi.h b/trunk/drivers/net/bnx2x_hsi.h index 52585338ada8..dc2f8ed5fd07 100644 --- a/trunk/drivers/net/bnx2x_hsi.h +++ b/trunk/drivers/net/bnx2x_hsi.h @@ -264,7 +264,6 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101 0x00000800 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727 0x00000900 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC 0x00000a00 -#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823 0x00000b00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN 0x0000ff00 diff --git a/trunk/drivers/net/bnx2x_link.c b/trunk/drivers/net/bnx2x_link.c index 41b9b7bd3d8e..e32d3370862e 100644 --- a/trunk/drivers/net/bnx2x_link.c +++ b/trunk/drivers/net/bnx2x_link.c @@ -1107,21 +1107,18 @@ static void bnx2x_set_parallel_detection(struct link_params *params, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, &control2); - if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) - control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; - else - control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; - DP(NETIF_MSG_LINK, "params->speed_cap_mask = 0x%x, control2 = 0x%x\n", - params->speed_cap_mask, control2); + + + control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; + + CL45_WR_OVER_CL22(bp, params->port, params->phy_addr, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, control2); - if ((phy_flags & PHY_XGXS_FLAG) && - (params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { + if (phy_flags & PHY_XGXS_FLAG) { DP(NETIF_MSG_LINK, "XGXS\n"); CL45_WR_OVER_CL22(bp, params->port, @@ -1228,7 +1225,7 @@ static void bnx2x_set_autoneg(struct link_params *params, params->phy_addr, MDIO_REG_BANK_CL73_USERB0, MDIO_CL73_USERB0_CL73_UCTRL, - 0xe); + MDIO_CL73_USERB0_CL73_UCTRL_USTAT1_MUXSEL); /* Enable BAM Station Manager*/ CL45_WR_OVER_CL22(bp, params->port, @@ -1239,25 +1236,29 @@ static void bnx2x_set_autoneg(struct link_params *params, MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN | MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN); - /* Advertise CL73 link speeds */ + /* Merge CL73 and CL37 aneg resolution */ + CL45_RD_OVER_CL22(bp, params->port, + params->phy_addr, + MDIO_REG_BANK_CL73_USERB0, + MDIO_CL73_USERB0_CL73_BAM_CTRL3, + ®_val); + + if (params->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) { + /* Set the CL73 AN speed */ CL45_RD_OVER_CL22(bp, params->port, params->phy_addr, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV2, ®_val); - if (params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) - reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4; - if (params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) - reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX; CL45_WR_OVER_CL22(bp, params->port, params->phy_addr, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV2, - reg_val); + reg_val | MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4); + } /* CL73 Autoneg Enabled */ reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN; @@ -1350,7 +1351,6 @@ static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params) static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc) { - struct bnx2x *bp = params->bp; *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX; /* resolve pause mode and advertisement * Please refer to Table 28B-3 of the 802.3ab-1999 spec */ @@ -1380,30 +1380,18 @@ static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc) *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; break; } - DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc); } static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params, u16 ieee_fc) { struct bnx2x *bp = params->bp; - u16 val; /* for AN, we are always publishing full duplex */ CL45_WR_OVER_CL22(bp, params->port, params->phy_addr, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc); - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, - MDIO_REG_BANK_CL73_IEEEB1, - MDIO_CL73_IEEEB1_AN_ADV1, &val); - val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH; - val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, - MDIO_REG_BANK_CL73_IEEEB1, - MDIO_CL73_IEEEB1_AN_ADV1, val); } static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73) @@ -1621,39 +1609,6 @@ static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params, return ret; } -static u8 bnx2x_direct_parallel_detect_used(struct link_params *params) -{ - struct bnx2x *bp = params->bp; - u16 pd_10g, status2_1000x; - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, - MDIO_REG_BANK_SERDES_DIGITAL, - MDIO_SERDES_DIGITAL_A_1000X_STATUS2, - &status2_1000x); - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, - MDIO_REG_BANK_SERDES_DIGITAL, - MDIO_SERDES_DIGITAL_A_1000X_STATUS2, - &status2_1000x); - if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) { - DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n", - params->port); - return 1; - } - - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, - MDIO_REG_BANK_10G_PARALLEL_DETECT, - MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS, - &pd_10g); - - if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) { - DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n", - params->port); - return 1; - } - return 0; -} static void bnx2x_flow_ctrl_resolve(struct link_params *params, struct link_vars *vars, @@ -1672,53 +1627,21 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params, (!(vars->phy_flags & PHY_SGMII_FLAG)) && (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) { - if (bnx2x_direct_parallel_detect_used(params)) { - vars->flow_ctrl = params->req_fc_auto_adv; - return; - } - if ((gp_status & - (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | - MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) == - (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | - MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) { - - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, - MDIO_REG_BANK_CL73_IEEEB1, - MDIO_CL73_IEEEB1_AN_ADV1, - &ld_pause); - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, - MDIO_REG_BANK_CL73_IEEEB1, - MDIO_CL73_IEEEB1_AN_LP_ADV1, - &lp_pause); - pause_result = (ld_pause & - MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK) - >> 8; - pause_result |= (lp_pause & - MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK) - >> 10; - DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n", - pause_result); - } else { - - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_AUTO_NEG_ADV, - &ld_pause); - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1, - &lp_pause); - pause_result = (ld_pause & + CL45_RD_OVER_CL22(bp, params->port, + params->phy_addr, + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_AUTO_NEG_ADV, + &ld_pause); + CL45_RD_OVER_CL22(bp, params->port, + params->phy_addr, + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1, + &lp_pause); + pause_result = (ld_pause & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5; - pause_result |= (lp_pause & + pause_result |= (lp_pause & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7; - DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n", - pause_result); - } + DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result); bnx2x_pause_resolve(vars, pause_result); } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) && (bnx2x_ext_phy_resolve_fc(params, vars))) { @@ -1929,8 +1852,6 @@ static u8 bnx2x_link_settings_status(struct link_params *params, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) || (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || - (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) || (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) { vars->autoneg = AUTO_NEG_ENABLED; @@ -2066,7 +1987,8 @@ static u8 bnx2x_emac_program(struct link_params *params, GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE, mode); - bnx2x_set_led(params, LED_MODE_OPER, line_speed); + bnx2x_set_led(bp, params->port, LED_MODE_OPER, + line_speed, params->hw_led_mode, params->chip_id); return 0; } @@ -2200,8 +2122,6 @@ static void bnx2x_ext_phy_reset(struct link_params *params, MDIO_PMA_REG_CTRL, 1<<15); break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: - break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n"); break; @@ -2592,11 +2512,16 @@ static void bnx2x_bcm8726_external_rom_boot(struct link_params *params) /* Need to wait 100ms after reset */ msleep(100); + /* Set serial boot control for external load */ + bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_MISC_CTRL1, 0x0001); + /* Micro controller re-boot */ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, - 0x018B); + MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); /* Set soft reset */ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, @@ -2604,10 +2529,14 @@ static void bnx2x_bcm8726_external_rom_boot(struct link_params *params) MDIO_PMA_REG_GEN_CTRL, MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); + /* Set PLL register value to be same like in P13 ver */ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0001); + MDIO_PMA_REG_PLL_CTRL, + 0x73A0); + /* Clear soft reset. + Will automatically reset micro-controller re-boot */ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, @@ -3533,8 +3462,8 @@ static void bnx2x_8481_set_10G_led_mode(struct link_params *params, MDIO_PMA_REG_8481_LINK_SIGNAL, &val1); /* Set bit 2 to 0, and bits [1:0] to 10 */ - val1 &= ~((1<<0) | (1<<2) | (1<<7)); /* Clear bits 0,2,7*/ - val1 |= ((1<<1) | (1<<6)); /* Set bit 1, 6 */ + val1 &= ~((1<<0) | (1<<2)); /* Clear bits 0,2*/ + val1 |= (1<<1); /* Set bit 1 */ bnx2x_cl45_write(bp, params->port, ext_phy_type, @@ -3568,19 +3497,36 @@ static void bnx2x_8481_set_10G_led_mode(struct link_params *params, MDIO_PMA_REG_8481_LED2_MASK, 0); - /* Unmask LED3 for 10G link */ + /* LED3 (10G/1G/100/10G Activity) */ + bnx2x_cl45_read(bp, params->port, + ext_phy_type, + ext_phy_addr, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, + &val1); + /* Enable blink based on source 4(Activity) */ + val1 &= ~((1<<7) | (1<<8)); /* Clear bits 7,8 */ + val1 |= (1<<6); /* Set only bit 6 */ bnx2x_cl45_write(bp, params->port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, + val1); + + bnx2x_cl45_read(bp, params->port, + ext_phy_type, + ext_phy_addr, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED3_MASK, - 0x6); + &val1); + val1 |= (1<<4); /* Unmask LED3 for 10G link */ bnx2x_cl45_write(bp, params->port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED3_BLINK, - 0); + MDIO_PMA_REG_8481_LED3_MASK, + val1); } @@ -3598,10 +3544,7 @@ static void bnx2x_init_internal_phy(struct link_params *params, bnx2x_set_preemphasis(params); /* forced speed requested? */ - if (vars->line_speed != SPEED_AUTO_NEG || - ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && - params->loopback_mode == LOOPBACK_EXT)) { + if (vars->line_speed != SPEED_AUTO_NEG) { DP(NETIF_MSG_LINK, "not SGMII, no AN\n"); /* disable autoneg */ @@ -3750,6 +3693,19 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) } } /* Force speed */ + /* First enable LASI */ + bnx2x_cl45_write(bp, params->port, + ext_phy_type, + ext_phy_addr, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_RX_ALARM_CTRL, + 0x0400); + bnx2x_cl45_write(bp, params->port, + ext_phy_type, + ext_phy_addr, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_LASI_CTRL, 0x0004); + if (params->req_line_speed == SPEED_10000) { DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n"); @@ -3759,9 +3715,6 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, 0x400); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, 1); } else { /* Force 1Gbps using autoneg with 1G advertisment */ @@ -3803,17 +3756,6 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, - 0x0400); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, 0x0004); } bnx2x_save_bcm_spirom_ver(bp, params->port, @@ -4349,7 +4291,6 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) break; } case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: /* This phy uses the NIG latch mechanism since link indication arrives through its LED4 and not via its LASI signal, so we get steady signal @@ -4357,12 +4298,6 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, 1 << NIG_LATCH_BC_ENABLE_MI_INT); - bnx2x_cl45_write(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 0x0000); - bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr); if (params->req_line_speed == SPEED_AUTO_NEG) { @@ -4459,12 +4394,17 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) { DP(NETIF_MSG_LINK, "Advertising 10G\n"); /* Restart autoneg for 10G*/ - + bnx2x_cl45_read(bp, params->port, + ext_phy_type, + ext_phy_addr, + MDIO_AN_DEVAD, + MDIO_AN_REG_CTRL, &val); + val |= 0x200; bnx2x_cl45_write(bp, params->port, ext_phy_type, ext_phy_addr, MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, 0x3200); + MDIO_AN_REG_CTRL, val); } } else { /* Force speed */ @@ -5208,7 +5148,6 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, } break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: /* Check 10G-BaseT link status */ /* Check PMD signal ok */ bnx2x_cl45_read(bp, params->port, ext_phy_type, @@ -5424,10 +5363,8 @@ static void bnx2x_link_int_ack(struct link_params *params, (NIG_STATUS_XGXS0_LINK10G | NIG_STATUS_XGXS0_LINK_STATUS | NIG_STATUS_SERDES0_LINK_STATUS)); - if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) - == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) || - (XGXS_EXT_PHY_TYPE(params->ext_phy_config) - == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) { + if (XGXS_EXT_PHY_TYPE(params->ext_phy_config) + == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) { bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int); } if (vars->phy_link_up) { @@ -5540,7 +5477,6 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, status = bnx2x_format_ver(spirom_ver, version, len); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: spirom_ver = ((spirom_ver & 0xF80) >> 7) << 16 | (spirom_ver & 0x7F); status = bnx2x_format_ver(spirom_ver, version, len); @@ -5792,15 +5728,13 @@ u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, } -u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed) +u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed, + u16 hw_led_mode, u32 chip_id) { - u8 port = params->port; - u16 hw_led_mode = params->hw_led_mode; u8 rc = 0; u32 tmp; u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode); DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n", speed, hw_led_mode); @@ -5815,14 +5749,7 @@ u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed) break; case LED_MODE_OPER: - if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) { - REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); - REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); - } else { - REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, - hw_led_mode); - } - + REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode); REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0); /* Set blinking rate to ~15.9Hz */ @@ -5834,7 +5761,7 @@ u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed) EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp & (~EMAC_LED_OVERRIDE))); - if (CHIP_IS_E1(bp) && + if (!CHIP_IS_E1H(bp) && ((speed == SPEED_2500) || (speed == SPEED_1000) || (speed == SPEED_100) || @@ -5937,7 +5864,6 @@ static u8 bnx2x_link_initialize(struct link_params *params, if (non_ext_phy || (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || - (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) || (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) || (params->loopback_mode == LOOPBACK_EXT_PHY)) { if (params->req_line_speed == SPEED_AUTO_NEG) @@ -6104,7 +6030,10 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); - bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed); + bnx2x_set_led(bp, params->port, LED_MODE_OPER, + vars->line_speed, params->hw_led_mode, + params->chip_id); + } else /* No loopback */ { @@ -6162,13 +6091,15 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, { struct bnx2x *bp = params->bp; u32 ext_phy_config = params->ext_phy_config; + u16 hw_led_mode = params->hw_led_mode; + u32 chip_id = params->chip_id; u8 port = params->port; u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); u32 val = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. port_feature_config[params->port]. config)); - DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); + /* disable attentions */ vars->link_status = 0; bnx2x_update_mng(params, vars->link_status); @@ -6196,7 +6127,7 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, * Hold it as vars low */ /* clear link led */ - bnx2x_set_led(params, LED_MODE_OFF, 0); + bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id); if (reset_ext_phy) { switch (ext_phy_type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: @@ -6232,22 +6163,6 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr); break; } - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: - { - u8 ext_phy_addr = - XGXS_EXT_PHY_ADDR(params->ext_phy_config); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, 0x0000); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 1); - break; - } default: /* HW reset */ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, @@ -6283,7 +6198,9 @@ static u8 bnx2x_update_link_down(struct link_params *params, u8 port = params->port; DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port); - bnx2x_set_led(params, LED_MODE_OFF, 0); + bnx2x_set_led(bp, port, LED_MODE_OFF, + 0, params->hw_led_mode, + params->chip_id); /* indicate no mac active */ vars->mac_type = MAC_TYPE_NONE; @@ -6320,13 +6237,15 @@ static u8 bnx2x_update_link_up(struct link_params *params, vars->link_status |= LINK_STATUS_LINK_UP; if (link_10g) { bnx2x_bmac_enable(params, vars, 0); - bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000); + bnx2x_set_led(bp, port, LED_MODE_OPER, + SPEED_10000, params->hw_led_mode, + params->chip_id); + } else { + bnx2x_emac_enable(params, vars, 0); rc = bnx2x_emac_program(params, vars->line_speed, vars->duplex); - bnx2x_emac_enable(params, vars, 0); - /* AN complete? */ if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { if (!(vars->phy_flags & @@ -6424,7 +6343,6 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) && (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) && (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) && (ext_phy_link_up && !vars->phy_link_up)) bnx2x_init_internal_phy(params, vars, 0); @@ -6660,13 +6578,6 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) return 0; } - -static u8 bnx2x_84823_common_init_phy(struct bnx2x *bp, u32 shmem_base) -{ - /* HW reset */ - bnx2x_ext_phy_hw_reset(bp, 1); - return 0; -} u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base) { u8 rc = 0; @@ -6696,9 +6607,7 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base) /* GPIO1 affects both ports, so there's need to pull it for single port alone */ rc = bnx2x_8726_common_init_phy(bp, shmem_base); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: - rc = bnx2x_84823_common_init_phy(bp, shmem_base); + break; default: DP(NETIF_MSG_LINK, diff --git a/trunk/drivers/net/bnx2x_link.h b/trunk/drivers/net/bnx2x_link.h index 40c2981de8ed..f3e252264e1b 100644 --- a/trunk/drivers/net/bnx2x_link.h +++ b/trunk/drivers/net/bnx2x_link.h @@ -178,7 +178,8 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, Basically, the CLC takes care of the led for the link, but in case one needs to set/unset the led unnaturally, set the "mode" to LED_MODE_OPER to blink the led, and LED_MODE_OFF to set the led off.*/ -u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed); +u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed, + u16 hw_led_mode, u32 chip_id); #define LED_MODE_OFF 0 #define LED_MODE_OPER 2 diff --git a/trunk/drivers/net/bnx2x_main.c b/trunk/drivers/net/bnx2x_main.c index 61974b74909a..59b58d8f0fa8 100644 --- a/trunk/drivers/net/bnx2x_main.c +++ b/trunk/drivers/net/bnx2x_main.c @@ -56,8 +56,8 @@ #include "bnx2x_init_ops.h" #include "bnx2x_dump.h" -#define DRV_MODULE_VERSION "1.52.1-3" -#define DRV_MODULE_RELDATE "2009/11/05" +#define DRV_MODULE_VERSION "1.52.1-1" +#define DRV_MODULE_RELDATE "2009/10/13" #define BNX2X_BC_VER 0x040200 #include @@ -10855,6 +10855,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev, static int bnx2x_phys_id(struct net_device *dev, u32 data) { struct bnx2x *bp = netdev_priv(dev); + int port = BP_PORT(bp); int i; if (!netif_running(dev)) @@ -10868,10 +10869,13 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data) for (i = 0; i < (data * 2); i++) { if ((i % 2) == 0) - bnx2x_set_led(&bp->link_params, LED_MODE_OPER, - SPEED_1000); + bnx2x_set_led(bp, port, LED_MODE_OPER, SPEED_1000, + bp->link_params.hw_led_mode, + bp->link_params.chip_id); else - bnx2x_set_led(&bp->link_params, LED_MODE_OFF, 0); + bnx2x_set_led(bp, port, LED_MODE_OFF, 0, + bp->link_params.hw_led_mode, + bp->link_params.chip_id); msleep_interruptible(500); if (signal_pending(current)) @@ -10879,8 +10883,10 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data) } if (bp->link_vars.link_up) - bnx2x_set_led(&bp->link_params, LED_MODE_OPER, - bp->link_vars.line_speed); + bnx2x_set_led(bp, port, LED_MODE_OPER, + bp->link_vars.line_speed, + bp->link_params.hw_led_mode, + bp->link_params.chip_id); return 0; } diff --git a/trunk/drivers/net/bnx2x_reg.h b/trunk/drivers/net/bnx2x_reg.h index b668173ffcb4..aa76cbada5e2 100644 --- a/trunk/drivers/net/bnx2x_reg.h +++ b/trunk/drivers/net/bnx2x_reg.h @@ -4772,28 +4772,18 @@ #define PCI_ID_VAL2 0x438 -#define MDIO_REG_BANK_CL73_IEEEB0 0x0 -#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL 0x0 +#define MDIO_REG_BANK_CL73_IEEEB0 0x0 +#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL 0x0 #define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN 0x0200 #define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN 0x1000 #define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_MAIN_RST 0x8000 -#define MDIO_REG_BANK_CL73_IEEEB1 0x10 -#define MDIO_CL73_IEEEB1_AN_ADV1 0x00 -#define MDIO_CL73_IEEEB1_AN_ADV1_PAUSE 0x0400 -#define MDIO_CL73_IEEEB1_AN_ADV1_ASYMMETRIC 0x0800 -#define MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH 0x0C00 -#define MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK 0x0C00 -#define MDIO_CL73_IEEEB1_AN_ADV2 0x01 +#define MDIO_REG_BANK_CL73_IEEEB1 0x10 +#define MDIO_CL73_IEEEB1_AN_ADV2 0x01 #define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M 0x0000 #define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX 0x0020 #define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 0x0040 #define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR 0x0080 -#define MDIO_CL73_IEEEB1_AN_LP_ADV1 0x03 -#define MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE 0x0400 -#define MDIO_CL73_IEEEB1_AN_LP_ADV1_ASYMMETRIC 0x0800 -#define MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_BOTH 0x0C00 -#define MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK 0x0C00 #define MDIO_REG_BANK_RX0 0x80b0 #define MDIO_RX0_RX_STATUS 0x10 @@ -4920,8 +4910,6 @@ #define MDIO_REG_BANK_10G_PARALLEL_DETECT 0x8130 -#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS 0x10 -#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK 0x8000 #define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL 0x11 #define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN 0x1 #define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK 0x13 @@ -4946,8 +4934,6 @@ #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_1G 0x0010 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_100M 0x0008 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_10M 0x0000 -#define MDIO_SERDES_DIGITAL_A_1000X_STATUS2 0x15 -#define MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED 0x0002 #define MDIO_SERDES_DIGITAL_MISC1 0x18 #define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_MASK 0xE000 #define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_25M 0x0000 @@ -5129,7 +5115,6 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_PMA_REG_8481_LED1_MASK 0xa82c #define MDIO_PMA_REG_8481_LED2_MASK 0xa82f #define MDIO_PMA_REG_8481_LED3_MASK 0xa832 -#define MDIO_PMA_REG_8481_LED3_BLINK 0xa834 #define MDIO_PMA_REG_8481_SIGNAL_MASK 0xa835 #define MDIO_PMA_REG_8481_LINK_SIGNAL 0xa83b diff --git a/trunk/drivers/net/davinci_emac.c b/trunk/drivers/net/davinci_emac.c index 79ce8e857eab..f1b09c0992b4 100644 --- a/trunk/drivers/net/davinci_emac.c +++ b/trunk/drivers/net/davinci_emac.c @@ -2217,7 +2217,7 @@ void emac_poll_controller(struct net_device *ndev) struct emac_priv *priv = netdev_priv(ndev); emac_int_disable(priv); - emac_irq(ndev->irq, ndev); + emac_irq(ndev->irq, priv); emac_int_enable(priv); } #endif diff --git a/trunk/drivers/net/e100.c b/trunk/drivers/net/e100.c index 7462fdfd7f92..f428c5f72f18 100644 --- a/trunk/drivers/net/e100.c +++ b/trunk/drivers/net/e100.c @@ -1438,31 +1438,19 @@ static int e100_phy_init(struct nic *nic) } else DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id); + /* Isolate all the PHY ids */ + for (addr = 0; addr < 32; addr++) + mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE); + /* Select the discovered PHY */ + bmcr &= ~BMCR_ISOLATE; + mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr); + /* Get phy ID */ id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1); id_hi = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID2); nic->phy = (u32)id_hi << 16 | (u32)id_lo; DPRINTK(HW, DEBUG, "phy ID = 0x%08X\n", nic->phy); - /* Select the phy and isolate the rest */ - for (addr = 0; addr < 32; addr++) { - if (addr != nic->mii.phy_id) { - mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE); - } else if (nic->phy != phy_82552_v) { - bmcr = mdio_read(netdev, addr, MII_BMCR); - mdio_write(netdev, addr, MII_BMCR, - bmcr & ~BMCR_ISOLATE); - } - } - /* - * Workaround for 82552: - * Clear the ISOLATE bit on selected phy_id last (mirrored on all - * other phy_id's) using bmcr value from addr discovery loop above. - */ - if (nic->phy == phy_82552_v) - mdio_write(netdev, nic->mii.phy_id, MII_BMCR, - bmcr & ~BMCR_ISOLATE); - /* Handle National tx phys */ #define NCS_PHY_MODEL_MASK 0xFFF0FFFF if ((nic->phy & NCS_PHY_MODEL_MASK) == phy_nsc_tx) { diff --git a/trunk/drivers/net/e1000e/defines.h b/trunk/drivers/net/e1000e/defines.h index 1190167a8b3d..c0f185beb8bc 100644 --- a/trunk/drivers/net/e1000e/defines.h +++ b/trunk/drivers/net/e1000e/defines.h @@ -76,7 +76,6 @@ /* Extended Device Control */ #define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */ #define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ -#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */ #define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */ #define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clock Gating */ #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000 @@ -348,7 +347,6 @@ /* Extended Configuration Control and Size */ #define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020 #define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001 -#define E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE 0x00000008 #define E1000_EXTCNF_CTRL_SWFLAG 0x00000020 #define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000 #define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16 diff --git a/trunk/drivers/net/e1000e/e1000.h b/trunk/drivers/net/e1000e/e1000.h index 00989c5534c1..08a4f9dd20e9 100644 --- a/trunk/drivers/net/e1000e/e1000.h +++ b/trunk/drivers/net/e1000e/e1000.h @@ -141,20 +141,6 @@ struct e1000_info; #define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */ #define HV_TNCRS_LOWER PHY_REG(778, 30) -/* BM PHY Copper Specific Status */ -#define BM_CS_STATUS 17 -#define BM_CS_STATUS_LINK_UP 0x0400 -#define BM_CS_STATUS_RESOLVED 0x0800 -#define BM_CS_STATUS_SPEED_MASK 0xC000 -#define BM_CS_STATUS_SPEED_1000 0x8000 - -/* 82577 Mobile Phy Status Register */ -#define HV_M_STATUS 26 -#define HV_M_STATUS_AUTONEG_COMPLETE 0x1000 -#define HV_M_STATUS_SPEED_MASK 0x0300 -#define HV_M_STATUS_SPEED_1000 0x0200 -#define HV_M_STATUS_LINK_UP 0x0040 - enum e1000_boards { board_82571, board_82572, diff --git a/trunk/drivers/net/e1000e/hw.h b/trunk/drivers/net/e1000e/hw.h index aaea41ef794d..7b05cf47f7f5 100644 --- a/trunk/drivers/net/e1000e/hw.h +++ b/trunk/drivers/net/e1000e/hw.h @@ -903,7 +903,6 @@ struct e1000_shadow_ram { struct e1000_dev_spec_ich8lan { bool kmrn_lock_loss_workaround_enabled; struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS]; - bool nvm_k1_enabled; }; struct e1000_hw { diff --git a/trunk/drivers/net/e1000e/ich8lan.c b/trunk/drivers/net/e1000e/ich8lan.c index 51ddb04ab195..b6388b9535fd 100644 --- a/trunk/drivers/net/e1000e/ich8lan.c +++ b/trunk/drivers/net/e1000e/ich8lan.c @@ -124,25 +124,11 @@ #define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in milliseconds */ -/* SMBus Address Phy Register */ -#define HV_SMB_ADDR PHY_REG(768, 26) -#define HV_SMB_ADDR_PEC_EN 0x0200 -#define HV_SMB_ADDR_VALID 0x0080 - -/* Strapping Option Register - RO */ -#define E1000_STRAP 0x0000C -#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000 -#define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17 - /* OEM Bits Phy Register */ #define HV_OEM_BITS PHY_REG(768, 25) #define HV_OEM_BITS_LPLU 0x0004 /* Low Power Link Up */ -#define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */ #define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */ -#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */ -#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */ - /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ /* Offset 04h HSFSTS */ union ich8_hws_flash_status { @@ -222,9 +208,6 @@ static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw); static s32 e1000_led_on_pchlan(struct e1000_hw *hw); static s32 e1000_led_off_pchlan(struct e1000_hw *hw); static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); -static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); -static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); -static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable); static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) { @@ -500,6 +483,14 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) goto out; } + if (hw->mac.type == e1000_pchlan) { + ret_val = e1000e_write_kmrn_reg(hw, + E1000_KMRNCTRLSTA_K1_CONFIG, + E1000_KMRNCTRLSTA_K1_ENABLE); + if (ret_val) + goto out; + } + /* * First we want to see if the MII Status Register reports * link. If so, then we want to get the current speed/duplex @@ -509,12 +500,6 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) if (ret_val) goto out; - if (hw->mac.type == e1000_pchlan) { - ret_val = e1000_k1_gig_workaround_hv(hw, link); - if (ret_val) - goto out; - } - if (!link) goto out; /* No link detected */ @@ -808,326 +793,6 @@ static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw) return 0; } -/** - * e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration - * @hw: pointer to the HW structure - * - * SW should configure the LCD from the NVM extended configuration region - * as a workaround for certain parts. - **/ -static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) -{ - struct e1000_phy_info *phy = &hw->phy; - u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; - s32 ret_val; - u16 word_addr, reg_data, reg_addr, phy_page = 0; - - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - return ret_val; - - /* - * Initialize the PHY from the NVM on ICH platforms. This - * is needed due to an issue where the NVM configuration is - * not properly autoloaded after power transitions. - * Therefore, after each PHY reset, we will load the - * configuration data out of the NVM manually. - */ - if ((hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) || - (hw->mac.type == e1000_pchlan)) { - struct e1000_adapter *adapter = hw->adapter; - - /* Check if SW needs to configure the PHY */ - if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) || - (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M) || - (hw->mac.type == e1000_pchlan)) - sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; - else - sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; - - data = er32(FEXTNVM); - if (!(data & sw_cfg_mask)) - goto out; - - /* Wait for basic configuration completes before proceeding */ - e1000_lan_init_done_ich8lan(hw); - - /* - * Make sure HW does not configure LCD from PHY - * extended configuration before SW configuration - */ - data = er32(EXTCNF_CTRL); - if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) - goto out; - - cnf_size = er32(EXTCNF_SIZE); - cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; - cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; - if (!cnf_size) - goto out; - - cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; - cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; - - if (!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) && - (hw->mac.type == e1000_pchlan)) { - /* - * HW configures the SMBus address and LEDs when the - * OEM and LCD Write Enable bits are set in the NVM. - * When both NVM bits are cleared, SW will configure - * them instead. - */ - data = er32(STRAP); - data &= E1000_STRAP_SMBUS_ADDRESS_MASK; - reg_data = data >> E1000_STRAP_SMBUS_ADDRESS_SHIFT; - reg_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID; - ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, - reg_data); - if (ret_val) - goto out; - - data = er32(LEDCTL); - ret_val = e1000_write_phy_reg_hv_locked(hw, - HV_LED_CONFIG, - (u16)data); - if (ret_val) - goto out; - } - /* Configure LCD from extended configuration region. */ - - /* cnf_base_addr is in DWORD */ - word_addr = (u16)(cnf_base_addr << 1); - - for (i = 0; i < cnf_size; i++) { - ret_val = e1000_read_nvm(hw, (word_addr + i * 2), 1, - ®_data); - if (ret_val) - goto out; - - ret_val = e1000_read_nvm(hw, (word_addr + i * 2 + 1), - 1, ®_addr); - if (ret_val) - goto out; - - /* Save off the PHY page for future writes. */ - if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { - phy_page = reg_data; - continue; - } - - reg_addr &= PHY_REG_MASK; - reg_addr |= phy_page; - - ret_val = phy->ops.write_phy_reg_locked(hw, - (u32)reg_addr, - reg_data); - if (ret_val) - goto out; - } - } - -out: - hw->phy.ops.release_phy(hw); - return ret_val; -} - -/** - * e1000_k1_gig_workaround_hv - K1 Si workaround - * @hw: pointer to the HW structure - * @link: link up bool flag - * - * If K1 is enabled for 1Gbps, the MAC might stall when transitioning - * from a lower speed. This workaround disables K1 whenever link is at 1Gig - * If link is down, the function will restore the default K1 setting located - * in the NVM. - **/ -static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link) -{ - s32 ret_val = 0; - u16 status_reg = 0; - bool k1_enable = hw->dev_spec.ich8lan.nvm_k1_enabled; - - if (hw->mac.type != e1000_pchlan) - goto out; - - /* Wrap the whole flow with the sw flag */ - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - goto out; - - /* Disable K1 when link is 1Gbps, otherwise use the NVM setting */ - if (link) { - if (hw->phy.type == e1000_phy_82578) { - ret_val = hw->phy.ops.read_phy_reg_locked(hw, - BM_CS_STATUS, - &status_reg); - if (ret_val) - goto release; - - status_reg &= BM_CS_STATUS_LINK_UP | - BM_CS_STATUS_RESOLVED | - BM_CS_STATUS_SPEED_MASK; - - if (status_reg == (BM_CS_STATUS_LINK_UP | - BM_CS_STATUS_RESOLVED | - BM_CS_STATUS_SPEED_1000)) - k1_enable = false; - } - - if (hw->phy.type == e1000_phy_82577) { - ret_val = hw->phy.ops.read_phy_reg_locked(hw, - HV_M_STATUS, - &status_reg); - if (ret_val) - goto release; - - status_reg &= HV_M_STATUS_LINK_UP | - HV_M_STATUS_AUTONEG_COMPLETE | - HV_M_STATUS_SPEED_MASK; - - if (status_reg == (HV_M_STATUS_LINK_UP | - HV_M_STATUS_AUTONEG_COMPLETE | - HV_M_STATUS_SPEED_1000)) - k1_enable = false; - } - - /* Link stall fix for link up */ - ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19), - 0x0100); - if (ret_val) - goto release; - - } else { - /* Link stall fix for link down */ - ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19), - 0x4100); - if (ret_val) - goto release; - } - - ret_val = e1000_configure_k1_ich8lan(hw, k1_enable); - -release: - hw->phy.ops.release_phy(hw); -out: - return ret_val; -} - -/** - * e1000_configure_k1_ich8lan - Configure K1 power state - * @hw: pointer to the HW structure - * @enable: K1 state to configure - * - * Configure the K1 power state based on the provided parameter. - * Assumes semaphore already acquired. - * - * Success returns 0, Failure returns -E1000_ERR_PHY (-2) - **/ -static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable) -{ - s32 ret_val = 0; - u32 ctrl_reg = 0; - u32 ctrl_ext = 0; - u32 reg = 0; - u16 kmrn_reg = 0; - - ret_val = e1000e_read_kmrn_reg_locked(hw, - E1000_KMRNCTRLSTA_K1_CONFIG, - &kmrn_reg); - if (ret_val) - goto out; - - if (k1_enable) - kmrn_reg |= E1000_KMRNCTRLSTA_K1_ENABLE; - else - kmrn_reg &= ~E1000_KMRNCTRLSTA_K1_ENABLE; - - ret_val = e1000e_write_kmrn_reg_locked(hw, - E1000_KMRNCTRLSTA_K1_CONFIG, - kmrn_reg); - if (ret_val) - goto out; - - udelay(20); - ctrl_ext = er32(CTRL_EXT); - ctrl_reg = er32(CTRL); - - reg = ctrl_reg & ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100); - reg |= E1000_CTRL_FRCSPD; - ew32(CTRL, reg); - - ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_SPD_BYPS); - udelay(20); - ew32(CTRL, ctrl_reg); - ew32(CTRL_EXT, ctrl_ext); - udelay(20); - -out: - return ret_val; -} - -/** - * e1000_oem_bits_config_ich8lan - SW-based LCD Configuration - * @hw: pointer to the HW structure - * @d0_state: boolean if entering d0 or d3 device state - * - * SW will configure Gbe Disable and LPLU based on the NVM. The four bits are - * collectively called OEM bits. The OEM Write Enable bit and SW Config bit - * in NVM determines whether HW should configure LPLU and Gbe Disable. - **/ -static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) -{ - s32 ret_val = 0; - u32 mac_reg; - u16 oem_reg; - - if (hw->mac.type != e1000_pchlan) - return ret_val; - - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - return ret_val; - - mac_reg = er32(EXTCNF_CTRL); - if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) - goto out; - - mac_reg = er32(FEXTNVM); - if (!(mac_reg & E1000_FEXTNVM_SW_CONFIG_ICH8M)) - goto out; - - mac_reg = er32(PHY_CTRL); - - ret_val = hw->phy.ops.read_phy_reg_locked(hw, HV_OEM_BITS, &oem_reg); - if (ret_val) - goto out; - - oem_reg &= ~(HV_OEM_BITS_GBE_DIS | HV_OEM_BITS_LPLU); - - if (d0_state) { - if (mac_reg & E1000_PHY_CTRL_GBE_DISABLE) - oem_reg |= HV_OEM_BITS_GBE_DIS; - - if (mac_reg & E1000_PHY_CTRL_D0A_LPLU) - oem_reg |= HV_OEM_BITS_LPLU; - } else { - if (mac_reg & E1000_PHY_CTRL_NOND0A_GBE_DISABLE) - oem_reg |= HV_OEM_BITS_GBE_DIS; - - if (mac_reg & E1000_PHY_CTRL_NOND0A_LPLU) - oem_reg |= HV_OEM_BITS_LPLU; - } - /* Restart auto-neg to activate the bits */ - oem_reg |= HV_OEM_BITS_RESTART_AN; - ret_val = hw->phy.ops.write_phy_reg_locked(hw, HV_OEM_BITS, oem_reg); - -out: - hw->phy.ops.release_phy(hw); - - return ret_val; -} - - /** * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be * done after every PHY reset. @@ -1168,20 +833,10 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) ret_val = hw->phy.ops.acquire_phy(hw); if (ret_val) return ret_val; - hw->phy.addr = 1; - ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); - if (ret_val) - goto out; + e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); hw->phy.ops.release_phy(hw); - /* - * Configure the K1 Si workaround during phy reset assuming there is - * link so that it disables K1 if link is in 1Gbps. - */ - ret_val = e1000_k1_gig_workaround_hv(hw, true); - -out: return ret_val; } @@ -1227,8 +882,11 @@ static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw) **/ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) { - s32 ret_val = 0; - u16 reg; + struct e1000_phy_info *phy = &hw->phy; + u32 i; + u32 data, cnf_size, cnf_base_addr, sw_cfg_mask; + s32 ret_val; + u16 reg, word_addr, reg_data, reg_addr, phy_page = 0; ret_val = e1000e_phy_hw_reset_generic(hw); if (ret_val) @@ -1247,16 +905,81 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) if (hw->mac.type == e1000_pchlan) e1e_rphy(hw, BM_WUC, ®); - /* Configure the LCD with the extended configuration region in NVM */ - ret_val = e1000_sw_lcd_config_ich8lan(hw); - if (ret_val) - goto out; + /* + * Initialize the PHY from the NVM on ICH platforms. This + * is needed due to an issue where the NVM configuration is + * not properly autoloaded after power transitions. + * Therefore, after each PHY reset, we will load the + * configuration data out of the NVM manually. + */ + if (hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) { + struct e1000_adapter *adapter = hw->adapter; - /* Configure the LCD with the OEM bits in NVM */ - if (hw->mac.type == e1000_pchlan) - ret_val = e1000_oem_bits_config_ich8lan(hw, true); + /* Check if SW needs configure the PHY */ + if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) || + (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M)) + sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; + else + sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; + + data = er32(FEXTNVM); + if (!(data & sw_cfg_mask)) + return 0; + + /* Wait for basic configuration completes before proceeding */ + e1000_lan_init_done_ich8lan(hw); + + /* + * Make sure HW does not configure LCD from PHY + * extended configuration before SW configuration + */ + data = er32(EXTCNF_CTRL); + if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) + return 0; + + cnf_size = er32(EXTCNF_SIZE); + cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; + cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; + if (!cnf_size) + return 0; + + cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; + cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; + + /* Configure LCD from extended configuration region. */ + + /* cnf_base_addr is in DWORD */ + word_addr = (u16)(cnf_base_addr << 1); + + for (i = 0; i < cnf_size; i++) { + ret_val = e1000_read_nvm(hw, + (word_addr + i * 2), + 1, + ®_data); + if (ret_val) + return ret_val; + + ret_val = e1000_read_nvm(hw, + (word_addr + i * 2 + 1), + 1, + ®_addr); + if (ret_val) + return ret_val; + + /* Save off the PHY page for future writes. */ + if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { + phy_page = reg_data; + continue; + } + + reg_addr |= phy_page; + + ret_val = e1e_wphy(hw, (u32)reg_addr, reg_data); + if (ret_val) + return ret_val; + } + } -out: return 0; } @@ -2583,7 +2306,6 @@ static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw) **/ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) { - struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; u16 reg; u32 ctrl, icr, kab; s32 ret_val; @@ -2619,18 +2341,6 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) ew32(PBS, E1000_PBS_16K); } - if (hw->mac.type == e1000_pchlan) { - /* Save the NVM K1 bit setting*/ - ret_val = e1000_read_nvm(hw, E1000_NVM_K1_CONFIG, 1, ®); - if (ret_val) - return ret_val; - - if (reg & E1000_NVM_K1_ENABLE) - dev_spec->nvm_k1_enabled = true; - else - dev_spec->nvm_k1_enabled = false; - } - ctrl = er32(CTRL); if (!e1000_check_reset_block(hw)) { @@ -2676,15 +2386,6 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) if (hw->mac.type == e1000_pchlan) e1e_rphy(hw, BM_WUC, ®); - ret_val = e1000_sw_lcd_config_ich8lan(hw); - if (ret_val) - goto out; - - if (hw->mac.type == e1000_pchlan) { - ret_val = e1000_oem_bits_config_ich8lan(hw, true); - if (ret_val) - goto out; - } /* * For PCH, this write will make sure that any noise * will be detected as a CRC error and be dropped rather than show up @@ -2703,7 +2404,6 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) if (hw->mac.type == e1000_pchlan) ret_val = e1000_hv_phy_workarounds_ich8lan(hw); -out: return ret_val; } @@ -3008,6 +2708,14 @@ static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, if (ret_val) return ret_val; + if ((hw->mac.type == e1000_pchlan) && (*speed == SPEED_1000)) { + ret_val = e1000e_write_kmrn_reg(hw, + E1000_KMRNCTRLSTA_K1_CONFIG, + E1000_KMRNCTRLSTA_K1_DISABLE); + if (ret_val) + return ret_val; + } + if ((hw->mac.type == e1000_ich8lan) && (hw->phy.type == e1000_phy_igp_3) && (*speed == SPEED_1000)) { diff --git a/trunk/drivers/net/e1000e/phy.c b/trunk/drivers/net/e1000e/phy.c index 03175b3a2c9e..f9d33ab05e97 100644 --- a/trunk/drivers/net/e1000e/phy.c +++ b/trunk/drivers/net/e1000e/phy.c @@ -95,6 +95,13 @@ static const u16 e1000_igp_2_cable_length_table[] = /* BM PHY Copper Specific Control 1 */ #define BM_CS_CTRL1 16 +/* BM PHY Copper Specific Status */ +#define BM_CS_STATUS 17 +#define BM_CS_STATUS_LINK_UP 0x0400 +#define BM_CS_STATUS_RESOLVED 0x0800 +#define BM_CS_STATUS_SPEED_MASK 0xC000 +#define BM_CS_STATUS_SPEED_1000 0x8000 + #define HV_MUX_DATA_CTRL PHY_REG(776, 16) #define HV_MUX_DATA_CTRL_GEN_TO_MAC 0x0400 #define HV_MUX_DATA_CTRL_FORCE_SPEED 0x0004 @@ -556,7 +563,7 @@ s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data) } /** - * e1000e_read_kmrn_reg_locked - Read kumeran register + * e1000_read_kmrn_reg_locked - Read kumeran register * @hw: pointer to the HW structure * @offset: register offset to be read * @data: pointer to the read data @@ -565,7 +572,7 @@ s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data) * information retrieved is stored in data. * Assumes semaphore already acquired. **/ -s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data) +s32 e1000_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data) { return __e1000_read_kmrn_reg(hw, offset, data, true); } @@ -624,7 +631,7 @@ s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data) } /** - * e1000e_write_kmrn_reg_locked - Write kumeran register + * e1000_write_kmrn_reg_locked - Write kumeran register * @hw: pointer to the HW structure * @offset: register offset to write to * @data: data to write at register offset @@ -632,7 +639,7 @@ s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data) * Write the data to PHY register at the offset using the kumeran interface. * Assumes semaphore already acquired. **/ -s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data) +s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data) { return __e1000_write_kmrn_reg(hw, offset, data, true); } diff --git a/trunk/drivers/net/pcmcia/pcnet_cs.c b/trunk/drivers/net/pcmcia/pcnet_cs.c index 94c9ad2746bc..bd3447f04902 100644 --- a/trunk/drivers/net/pcmcia/pcnet_cs.c +++ b/trunk/drivers/net/pcmcia/pcnet_cs.c @@ -1760,7 +1760,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"), - PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"), + PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"), PCMCIA_DEVICE_PROD_ID12("Ethernet", "CF Size PC Card", 0x00b2e941, 0x43ac239b), PCMCIA_DEVICE_PROD_ID123("Fast Ethernet", "CF Size PC Card", "1.0", diff --git a/trunk/drivers/net/pppox.c b/trunk/drivers/net/pppox.c index ac806b27c658..c14ee24c05a8 100644 --- a/trunk/drivers/net/pppox.c +++ b/trunk/drivers/net/pppox.c @@ -104,8 +104,7 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) EXPORT_SYMBOL(pppox_ioctl); -static int pppox_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int pppox_create(struct net *net, struct socket *sock, int protocol) { int rc = -EPROTOTYPE; diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index 1b0aa4cf89bc..1f7946c7d4e8 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -3379,7 +3379,7 @@ static u16 rtl_rw_cpluscmd(void __iomem *ioaddr) static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz) { /* Low hurts. Let's disable the filtering. */ - RTL_W16(RxMaxSize, rx_buf_sz + 1); + RTL_W16(RxMaxSize, rx_buf_sz); } static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index a3d99913f184..1729ebf5de9c 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -4651,8 +4651,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, goto err_out_free_netdev; } - netif_carrier_off(dev); - netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT); err = request_irq(pdev->irq, sky2_intr, diff --git a/trunk/drivers/net/tokenring/ibmtr.c b/trunk/drivers/net/tokenring/ibmtr.c index 6a3c7510afd9..525bbc5b9c9d 100644 --- a/trunk/drivers/net/tokenring/ibmtr.c +++ b/trunk/drivers/net/tokenring/ibmtr.c @@ -1143,16 +1143,9 @@ static void dir_open_adapter (struct net_device *dev) } else { char **prphase = printphase; char **prerror = printerror; - int pnr = err / 16 - 1; - int enr = err % 16 - 1; DPRINTK("TR Adapter misc open failure, error code = "); - if (pnr < 0 || pnr >= ARRAY_SIZE(printphase) || - enr < 0 || - enr >= ARRAY_SIZE(printerror)) - printk("0x%x, invalid Phase/Error.", err); - else - printk("0x%x, Phase: %s, Error: %s\n", err, - prphase[pnr], prerror[enr]); + printk("0x%x, Phase: %s, Error: %s\n", + err, prphase[err/16 -1], prerror[err%16 -1]); printk(" retrying after %ds delay...\n", TR_RETRY_INTERVAL/HZ); } diff --git a/trunk/drivers/net/usb/Kconfig b/trunk/drivers/net/usb/Kconfig index 32d93564a74d..c47237c2d638 100644 --- a/trunk/drivers/net/usb/Kconfig +++ b/trunk/drivers/net/usb/Kconfig @@ -174,7 +174,7 @@ config USB_NET_CDCETHER * Ericsson Mobile Broadband Module (all variants) * Motorola (DM100 and SB4100) * Broadcom Cable Modem (reference design) - * Toshiba (PCX1100U and F3507g/F3607gw) + * Toshiba (PCX1100U and F3507g) * ... This driver creates an interface named "ethX", where X depends on diff --git a/trunk/drivers/net/usb/cdc_ether.c b/trunk/drivers/net/usb/cdc_ether.c index 71d7ff3de99f..71e65fc10e6f 100644 --- a/trunk/drivers/net/usb/cdc_ether.c +++ b/trunk/drivers/net/usb/cdc_ether.c @@ -551,29 +551,9 @@ static const struct usb_device_id products [] = { USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1904, USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), .driver_info = (unsigned long) &mbm_info, -}, { - /* Ericsson F3607gw ver 2 */ - USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1905, USB_CLASS_COMM, - USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &mbm_info, -}, { - /* Ericsson F3607gw ver 3 */ - USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1906, USB_CLASS_COMM, - USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &mbm_info, }, { /* Ericsson F3307 */ - USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190a, USB_CLASS_COMM, - USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &mbm_info, -}, { - /* Ericsson F3307 ver 2 */ - USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1909, USB_CLASS_COMM, - USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &mbm_info, -}, { - /* Ericsson C3607w */ - USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1049, USB_CLASS_COMM, + USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1906, USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), .driver_info = (unsigned long) &mbm_info, }, { @@ -581,31 +561,11 @@ static const struct usb_device_id products [] = { USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), .driver_info = (unsigned long) &mbm_info, -}, { - /* Toshiba F3607gw */ - USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130c, USB_CLASS_COMM, - USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &mbm_info, -}, { - /* Toshiba F3607gw ver 2 */ - USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x1311, USB_CLASS_COMM, - USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &mbm_info, }, { /* Dell F3507g */ USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8147, USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), .driver_info = (unsigned long) &mbm_info, -}, { - /* Dell F3607gw */ - USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8183, USB_CLASS_COMM, - USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &mbm_info, -}, { - /* Dell F3607gw ver 2 */ - USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8184, USB_CLASS_COMM, - USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &mbm_info, }, { }, // END }; diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index 22a8ca5d67d5..95274678fe45 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -996,7 +996,7 @@ static unsigned int features[] = { VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, }; -static struct virtio_driver virtio_net_driver = { +static struct virtio_driver virtio_net = { .feature_table = features, .feature_table_size = ARRAY_SIZE(features), .driver.name = KBUILD_MODNAME, @@ -1009,12 +1009,12 @@ static struct virtio_driver virtio_net_driver = { static int __init init(void) { - return register_virtio_driver(&virtio_net_driver); + return register_virtio_driver(&virtio_net); } static void __exit fini(void) { - unregister_virtio_driver(&virtio_net_driver); + unregister_virtio_driver(&virtio_net); } module_init(init); module_exit(fini); diff --git a/trunk/drivers/net/wimax/i2400m/control.c b/trunk/drivers/net/wimax/i2400m/control.c index 944945540391..07308686dbcf 100644 --- a/trunk/drivers/net/wimax/i2400m/control.c +++ b/trunk/drivers/net/wimax/i2400m/control.c @@ -54,7 +54,7 @@ * i2400m_set_init_config() * i2400m_cmd_get_state() * i2400m_dev_shutdown() Called by i2400m_dev_stop() - * i2400m_reset() + * i2400m->bus_reset() * * i2400m_{cmd,get,set}_*() * i2400m_msg_to_dev() @@ -82,13 +82,6 @@ #define D_SUBMODULE control #include "debug-levels.h" -int i2400m_passive_mode; /* 0 (passive mode disabled) by default */ -module_param_named(passive_mode, i2400m_passive_mode, int, 0644); -MODULE_PARM_DESC(passive_mode, - "If true, the driver will not do any device setup " - "and leave it up to user space, who must be properly " - "setup."); - /* * Return if a TLV is of a give type and size @@ -270,7 +263,7 @@ int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *l3l4_hdr, if (status == 0) return 0; - if (status >= ARRAY_SIZE(ms_to_errno)) { + if (status > ARRAY_SIZE(ms_to_errno)) { str = "unknown status code"; result = -EBADR; } else { @@ -343,7 +336,7 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m, /* Huh? just in case, shut it down */ dev_err(dev, "HW BUG? unknown state %u: shutting down\n", i2400m_state); - i2400m_reset(i2400m, I2400M_RT_WARM); + i2400m->bus_reset(i2400m, I2400M_RT_WARM); break; }; d_fnend(3, dev, "(i2400m %p ss %p [%u]) = void\n", @@ -1342,8 +1335,6 @@ int i2400m_dev_initialize(struct i2400m *i2400m) unsigned argc = 0; d_fnstart(3, dev, "(i2400m %p)\n", i2400m); - if (i2400m_passive_mode) - goto out_passive; /* Disable idle mode? (enabled by default) */ if (i2400m_idle_mode_disabled) { if (i2400m_le_v1_3(i2400m)) { @@ -1386,7 +1377,6 @@ int i2400m_dev_initialize(struct i2400m *i2400m) result = i2400m_set_init_config(i2400m, args, argc); if (result < 0) goto error; -out_passive: /* * Update state: Here it just calls a get state; parsing the * result (System State TLV and RF Status TLV [done in the rx diff --git a/trunk/drivers/net/wimax/i2400m/debugfs.c b/trunk/drivers/net/wimax/i2400m/debugfs.c index b1aec3e1892f..9b81af3f80a9 100644 --- a/trunk/drivers/net/wimax/i2400m/debugfs.c +++ b/trunk/drivers/net/wimax/i2400m/debugfs.c @@ -214,7 +214,7 @@ int debugfs_i2400m_reset_set(void *data, u64 val) case I2400M_RT_WARM: case I2400M_RT_COLD: case I2400M_RT_BUS: - result = i2400m_reset(i2400m, rt); + result = i2400m->bus_reset(i2400m, rt); if (result >= 0) result = 0; default: diff --git a/trunk/drivers/net/wimax/i2400m/driver.c b/trunk/drivers/net/wimax/i2400m/driver.c index 96a615fe09de..304f0443ca4b 100644 --- a/trunk/drivers/net/wimax/i2400m/driver.c +++ b/trunk/drivers/net/wimax/i2400m/driver.c @@ -41,10 +41,8 @@ * __i2400m_dev_start() * * i2400m_setup() - * i2400m->bus_setup() * i2400m_bootrom_init() * register_netdev() - * wimax_dev_add() * i2400m_dev_start() * __i2400m_dev_start() * i2400m_dev_bootstrap() @@ -52,15 +50,15 @@ * i2400m->bus_dev_start() * i2400m_firmware_check() * i2400m_check_mac_addr() + * wimax_dev_add() * * i2400m_release() + * wimax_dev_rm() * i2400m_dev_stop() * __i2400m_dev_stop() * i2400m_dev_shutdown() * i2400m->bus_dev_stop() * i2400m_tx_release() - * i2400m->bus_release() - * wimax_dev_rm() * unregister_netdev() */ #include "i2400m.h" @@ -68,7 +66,6 @@ #include #include #include -#include #define D_SUBMODULE driver #include "debug-levels.h" @@ -93,39 +90,76 @@ MODULE_PARM_DESC(power_save_disabled, "False by default (so the device is told to do power " "saving)."); -static char i2400m_debug_params[128]; -module_param_string(debug, i2400m_debug_params, sizeof(i2400m_debug_params), - 0644); -MODULE_PARM_DESC(debug, - "String of space-separated NAME:VALUE pairs, where NAMEs " - "are the different debug submodules and VALUE are the " - "initial debug value to set."); - -static char i2400m_barkers_params[128]; -module_param_string(barkers, i2400m_barkers_params, - sizeof(i2400m_barkers_params), 0644); -MODULE_PARM_DESC(barkers, - "String of comma-separated 32-bit values; each is " - "recognized as the value the device sends as a reboot " - "signal; values are appended to a list--setting one value " - "as zero cleans the existing list and starts a new one."); - -static -struct i2400m_work *__i2400m_work_setup( - struct i2400m *i2400m, void (*fn)(struct work_struct *), - gfp_t gfp_flags, const void *pl, size_t pl_size) +/** + * i2400m_queue_work - schedule work on a i2400m's queue + * + * @i2400m: device descriptor + * + * @fn: function to run to execute work. It gets passed a 'struct + * work_struct' that is wrapped in a 'struct i2400m_work'. Once + * done, you have to (1) i2400m_put(i2400m_work->i2400m) and then + * (2) kfree(i2400m_work). + * + * @gfp_flags: GFP flags for memory allocation. + * + * @pl: pointer to a payload buffer that you want to pass to the _work + * function. Use this to pack (for example) a struct with extra + * arguments. + * + * @pl_size: size of the payload buffer. + * + * We do this quite often, so this just saves typing; allocate a + * wrapper for a i2400m, get a ref to it, pack arguments and launch + * the work. + * + * A usual workflow is: + * + * struct my_work_args { + * void *something; + * int whatever; + * }; + * ... + * + * struct my_work_args my_args = { + * .something = FOO, + * .whaetever = BLAH + * }; + * i2400m_queue_work(i2400m, 1, my_work_function, GFP_KERNEL, + * &args, sizeof(args)) + * + * And now the work function can unpack the arguments and call the + * real function (or do the job itself): + * + * static + * void my_work_fn((struct work_struct *ws) + * { + * struct i2400m_work *iw = + * container_of(ws, struct i2400m_work, ws); + * struct my_work_args *my_args = (void *) iw->pl; + * + * my_work(iw->i2400m, my_args->something, my_args->whatevert); + * } + */ +int i2400m_queue_work(struct i2400m *i2400m, + void (*fn)(struct work_struct *), gfp_t gfp_flags, + const void *pl, size_t pl_size) { + int result; struct i2400m_work *iw; + BUG_ON(i2400m->work_queue == NULL); + result = -ENOMEM; iw = kzalloc(sizeof(*iw) + pl_size, gfp_flags); if (iw == NULL) - return NULL; + goto error_kzalloc; iw->i2400m = i2400m_get(i2400m); - iw->pl_size = pl_size; memcpy(iw->pl, pl, pl_size); INIT_WORK(&iw->ws, fn); - return iw; + result = queue_work(i2400m->work_queue, &iw->ws); +error_kzalloc: + return result; } +EXPORT_SYMBOL_GPL(i2400m_queue_work); /* @@ -141,19 +175,21 @@ struct i2400m_work *__i2400m_work_setup( * it should not happen. */ int i2400m_schedule_work(struct i2400m *i2400m, - void (*fn)(struct work_struct *), gfp_t gfp_flags, - const void *pl, size_t pl_size) + void (*fn)(struct work_struct *), gfp_t gfp_flags) { int result; struct i2400m_work *iw; result = -ENOMEM; - iw = __i2400m_work_setup(i2400m, fn, gfp_flags, pl, pl_size); - if (iw != NULL) { - result = schedule_work(&iw->ws); - if (WARN_ON(result == 0)) - result = -ENXIO; - } + iw = kzalloc(sizeof(*iw), gfp_flags); + if (iw == NULL) + goto error_kzalloc; + iw->i2400m = i2400m_get(i2400m); + INIT_WORK(&iw->ws, fn); + result = schedule_work(&iw->ws); + if (result == 0) + result = -ENXIO; +error_kzalloc: return result; } @@ -255,7 +291,7 @@ int i2400m_op_reset(struct wimax_dev *wimax_dev) mutex_lock(&i2400m->init_mutex); i2400m->reset_ctx = &ctx; mutex_unlock(&i2400m->init_mutex); - result = i2400m_reset(i2400m, I2400M_RT_WARM); + result = i2400m->bus_reset(i2400m, I2400M_RT_WARM); if (result < 0) goto out; result = wait_for_completion_timeout(&ctx.completion, 4*HZ); @@ -384,15 +420,9 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags) dev_err(dev, "cannot create workqueue\n"); goto error_create_workqueue; } - if (i2400m->bus_dev_start) { - result = i2400m->bus_dev_start(i2400m); - if (result < 0) - goto error_bus_dev_start; - } - i2400m->ready = 1; - wmb(); /* see i2400m->ready's documentation */ - /* process pending reports from the device */ - queue_work(i2400m->work_queue, &i2400m->rx_report_ws); + result = i2400m->bus_dev_start(i2400m); + if (result < 0) + goto error_bus_dev_start; result = i2400m_firmware_check(i2400m); /* fw versions ok? */ if (result < 0) goto error_fw_check; @@ -400,6 +430,8 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags) result = i2400m_check_mac_addr(i2400m); if (result < 0) goto error_check_mac_addr; + i2400m->ready = 1; + wimax_state_change(wimax_dev, WIMAX_ST_UNINITIALIZED); result = i2400m_dev_initialize(i2400m); if (result < 0) goto error_dev_initialize; @@ -411,12 +443,8 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags) error_dev_initialize: error_check_mac_addr: - i2400m->ready = 0; - wmb(); /* see i2400m->ready's documentation */ - flush_workqueue(i2400m->work_queue); error_fw_check: - if (i2400m->bus_dev_stop) - i2400m->bus_dev_stop(i2400m); + i2400m->bus_dev_stop(i2400m); error_bus_dev_start: destroy_workqueue(i2400m->work_queue); error_create_workqueue: @@ -438,15 +466,11 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags) static int i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri bm_flags) { - int result = 0; + int result; mutex_lock(&i2400m->init_mutex); /* Well, start the device */ - if (i2400m->updown == 0) { - result = __i2400m_dev_start(i2400m, bm_flags); - if (result >= 0) { - i2400m->updown = 1; - wmb(); /* see i2400m->updown's documentation */ - } - } + result = __i2400m_dev_start(i2400m, bm_flags); + if (result >= 0) + i2400m->updown = 1; mutex_unlock(&i2400m->init_mutex); return result; } @@ -471,20 +495,9 @@ void __i2400m_dev_stop(struct i2400m *i2400m) d_fnstart(3, dev, "(i2400m %p)\n", i2400m); wimax_state_change(wimax_dev, __WIMAX_ST_QUIESCING); - i2400m_msg_to_dev_cancel_wait(i2400m, -EL3RST); - complete(&i2400m->msg_completion); - i2400m_net_wake_stop(i2400m); i2400m_dev_shutdown(i2400m); - /* - * Make sure no report hooks are running *before* we stop the - * communication infrastructure with the device. - */ - i2400m->ready = 0; /* nobody can queue work anymore */ - wmb(); /* see i2400m->ready's documentation */ - flush_workqueue(i2400m->work_queue); - - if (i2400m->bus_dev_stop) - i2400m->bus_dev_stop(i2400m); + i2400m->ready = 0; + i2400m->bus_dev_stop(i2400m); destroy_workqueue(i2400m->work_queue); i2400m_rx_release(i2400m); i2400m_tx_release(i2400m); @@ -505,138 +518,11 @@ void i2400m_dev_stop(struct i2400m *i2400m) if (i2400m->updown) { __i2400m_dev_stop(i2400m); i2400m->updown = 0; - wmb(); /* see i2400m->updown's documentation */ } mutex_unlock(&i2400m->init_mutex); } -/* - * Listen to PM events to cache the firmware before suspend/hibernation - * - * When the device comes out of suspend, it might go into reset and - * firmware has to be uploaded again. At resume, most of the times, we - * can't load firmware images from disk, so we need to cache it. - * - * i2400m_fw_cache() will allocate a kobject and attach the firmware - * to it; that way we don't have to worry too much about the fw loader - * hitting a race condition. - * - * Note: modus operandi stolen from the Orinoco driver; thx. - */ -static -int i2400m_pm_notifier(struct notifier_block *notifier, - unsigned long pm_event, - void *unused) -{ - struct i2400m *i2400m = - container_of(notifier, struct i2400m, pm_notifier); - struct device *dev = i2400m_dev(i2400m); - - d_fnstart(3, dev, "(i2400m %p pm_event %lx)\n", i2400m, pm_event); - switch (pm_event) { - case PM_HIBERNATION_PREPARE: - case PM_SUSPEND_PREPARE: - i2400m_fw_cache(i2400m); - break; - case PM_POST_RESTORE: - /* Restore from hibernation failed. We need to clean - * up in exactly the same way, so fall through. */ - case PM_POST_HIBERNATION: - case PM_POST_SUSPEND: - i2400m_fw_uncache(i2400m); - break; - - case PM_RESTORE_PREPARE: - default: - break; - } - d_fnend(3, dev, "(i2400m %p pm_event %lx) = void\n", i2400m, pm_event); - return NOTIFY_DONE; -} - - -/* - * pre-reset is called before a device is going on reset - * - * This has to be followed by a call to i2400m_post_reset(), otherwise - * bad things might happen. - */ -int i2400m_pre_reset(struct i2400m *i2400m) -{ - int result; - struct device *dev = i2400m_dev(i2400m); - - d_fnstart(3, dev, "(i2400m %p)\n", i2400m); - d_printf(1, dev, "pre-reset shut down\n"); - - result = 0; - mutex_lock(&i2400m->init_mutex); - if (i2400m->updown) { - netif_tx_disable(i2400m->wimax_dev.net_dev); - __i2400m_dev_stop(i2400m); - result = 0; - /* down't set updown to zero -- this way - * post_reset can restore properly */ - } - mutex_unlock(&i2400m->init_mutex); - if (i2400m->bus_release) - i2400m->bus_release(i2400m); - d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); - return result; -} -EXPORT_SYMBOL_GPL(i2400m_pre_reset); - - -/* - * Restore device state after a reset - * - * Do the work needed after a device reset to bring it up to the same - * state as it was before the reset. - * - * NOTE: this requires i2400m->init_mutex taken - */ -int i2400m_post_reset(struct i2400m *i2400m) -{ - int result = 0; - struct device *dev = i2400m_dev(i2400m); - - d_fnstart(3, dev, "(i2400m %p)\n", i2400m); - d_printf(1, dev, "post-reset start\n"); - if (i2400m->bus_setup) { - result = i2400m->bus_setup(i2400m); - if (result < 0) { - dev_err(dev, "bus-specific setup failed: %d\n", - result); - goto error_bus_setup; - } - } - mutex_lock(&i2400m->init_mutex); - if (i2400m->updown) { - result = __i2400m_dev_start( - i2400m, I2400M_BRI_SOFT | I2400M_BRI_MAC_REINIT); - if (result < 0) - goto error_dev_start; - } - mutex_unlock(&i2400m->init_mutex); - d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); - return result; - -error_dev_start: - if (i2400m->bus_release) - i2400m->bus_release(i2400m); -error_bus_setup: - /* even if the device was up, it could not be recovered, so we - * mark it as down. */ - i2400m->updown = 0; - wmb(); /* see i2400m->updown's documentation */ - mutex_unlock(&i2400m->init_mutex); - d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); - return result; -} -EXPORT_SYMBOL_GPL(i2400m_post_reset); - - /* * The device has rebooted; fix up the device and the driver * @@ -656,69 +542,56 @@ EXPORT_SYMBOL_GPL(i2400m_post_reset); * _stop()], don't do anything, let it fail and handle it. * * This function is ran always in a thread context - * - * This function gets passed, as payload to i2400m_work() a 'const - * char *' ptr with a "reason" why the reset happened (for messages). */ static void __i2400m_dev_reset_handle(struct work_struct *ws) { int result; struct i2400m_work *iw = container_of(ws, struct i2400m_work, ws); - const char *reason; struct i2400m *i2400m = iw->i2400m; struct device *dev = i2400m_dev(i2400m); + enum wimax_st wimax_state; struct i2400m_reset_ctx *ctx = i2400m->reset_ctx; - if (WARN_ON(iw->pl_size != sizeof(reason))) - reason = "SW BUG: reason n/a"; - else - memcpy(&reason, iw->pl, sizeof(reason)); - - d_fnstart(3, dev, "(ws %p i2400m %p reason %s)\n", ws, i2400m, reason); - + d_fnstart(3, dev, "(ws %p i2400m %p)\n", ws, i2400m); result = 0; if (mutex_trylock(&i2400m->init_mutex) == 0) { /* We are still in i2400m_dev_start() [let it fail] or * i2400m_dev_stop() [we are shutting down anyway, so * ignore it] or we are resetting somewhere else. */ - dev_err(dev, "device rebooted somewhere else?\n"); + dev_err(dev, "device rebooted\n"); i2400m_msg_to_dev_cancel_wait(i2400m, -EL3RST); complete(&i2400m->msg_completion); goto out; } - if (i2400m->updown == 0) { - dev_info(dev, "%s: device is down, doing nothing\n", reason); - goto out_unlock; + wimax_state = wimax_state_get(&i2400m->wimax_dev); + if (wimax_state < WIMAX_ST_UNINITIALIZED) { + dev_info(dev, "device rebooted: it is down, ignoring\n"); + goto out_unlock; /* ifconfig up/down wasn't called */ } - dev_err(dev, "%s: reinitializing driver\n", reason); + dev_err(dev, "device rebooted: reinitializing driver\n"); __i2400m_dev_stop(i2400m); + i2400m->updown = 0; result = __i2400m_dev_start(i2400m, I2400M_BRI_SOFT | I2400M_BRI_MAC_REINIT); if (result < 0) { - i2400m->updown = 0; - wmb(); /* see i2400m->updown's documentation */ - dev_err(dev, "%s: cannot start the device: %d\n", - reason, result); - result = -EUCLEAN; - } + dev_err(dev, "device reboot: cannot start the device: %d\n", + result); + result = i2400m->bus_reset(i2400m, I2400M_RT_BUS); + if (result >= 0) + result = -ENODEV; + } else + i2400m->updown = 1; out_unlock: if (i2400m->reset_ctx) { ctx->result = result; complete(&ctx->completion); } mutex_unlock(&i2400m->init_mutex); - if (result == -EUCLEAN) { - /* ops, need to clean up [w/ init_mutex not held] */ - result = i2400m_reset(i2400m, I2400M_RT_BUS); - if (result >= 0) - result = -ENODEV; - } out: i2400m_put(i2400m); kfree(iw); - d_fnend(3, dev, "(ws %p i2400m %p reason %s) = void\n", - ws, i2400m, reason); + d_fnend(3, dev, "(ws %p i2400m %p) = void\n", ws, i2400m); return; } @@ -735,104 +608,16 @@ void __i2400m_dev_reset_handle(struct work_struct *ws) * reinitializing the driver to handle the reset, calling into the * bus-specific functions ops as needed. */ -int i2400m_dev_reset_handle(struct i2400m *i2400m, const char *reason) +int i2400m_dev_reset_handle(struct i2400m *i2400m) { i2400m->boot_mode = 1; wmb(); /* Make sure i2400m_msg_to_dev() sees boot_mode */ return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle, - GFP_ATOMIC, &reason, sizeof(reason)); + GFP_ATOMIC); } EXPORT_SYMBOL_GPL(i2400m_dev_reset_handle); -/* - * Alloc the command and ack buffers for boot mode - * - * Get the buffers needed to deal with boot mode messages. These - * buffers need to be allocated before the sdio recieve irq is setup. - */ -static -int i2400m_bm_buf_alloc(struct i2400m *i2400m) -{ - int result; - - result = -ENOMEM; - i2400m->bm_cmd_buf = kzalloc(I2400M_BM_CMD_BUF_SIZE, GFP_KERNEL); - if (i2400m->bm_cmd_buf == NULL) - goto error_bm_cmd_kzalloc; - i2400m->bm_ack_buf = kzalloc(I2400M_BM_ACK_BUF_SIZE, GFP_KERNEL); - if (i2400m->bm_ack_buf == NULL) - goto error_bm_ack_buf_kzalloc; - return 0; - -error_bm_ack_buf_kzalloc: - kfree(i2400m->bm_cmd_buf); -error_bm_cmd_kzalloc: - return result; -} - - -/* - * Free boot mode command and ack buffers. - */ -static -void i2400m_bm_buf_free(struct i2400m *i2400m) -{ - kfree(i2400m->bm_ack_buf); - kfree(i2400m->bm_cmd_buf); -} - - -/** - * i2400m_init - Initialize a 'struct i2400m' from all zeroes - * - * This is a bus-generic API call. - */ -void i2400m_init(struct i2400m *i2400m) -{ - wimax_dev_init(&i2400m->wimax_dev); - - i2400m->boot_mode = 1; - i2400m->rx_reorder = 1; - init_waitqueue_head(&i2400m->state_wq); - - spin_lock_init(&i2400m->tx_lock); - i2400m->tx_pl_min = UINT_MAX; - i2400m->tx_size_min = UINT_MAX; - - spin_lock_init(&i2400m->rx_lock); - i2400m->rx_pl_min = UINT_MAX; - i2400m->rx_size_min = UINT_MAX; - INIT_LIST_HEAD(&i2400m->rx_reports); - INIT_WORK(&i2400m->rx_report_ws, i2400m_report_hook_work); - - mutex_init(&i2400m->msg_mutex); - init_completion(&i2400m->msg_completion); - - mutex_init(&i2400m->init_mutex); - /* wake_tx_ws is initialized in i2400m_tx_setup() */ -} -EXPORT_SYMBOL_GPL(i2400m_init); - - -int i2400m_reset(struct i2400m *i2400m, enum i2400m_reset_type rt) -{ - struct net_device *net_dev = i2400m->wimax_dev.net_dev; - - /* - * Make sure we stop TXs and down the carrier before - * resetting; this is needed to avoid things like - * i2400m_wake_tx() scheduling stuff in parallel. - */ - if (net_dev->reg_state == NETREG_REGISTERED) { - netif_tx_disable(net_dev); - netif_carrier_off(net_dev); - } - return i2400m->bus_reset(i2400m, rt); -} -EXPORT_SYMBOL_GPL(i2400m_reset); - - /** * i2400m_setup - bus-generic setup function for the i2400m device * @@ -840,9 +625,13 @@ EXPORT_SYMBOL_GPL(i2400m_reset); * * Returns: 0 if ok, < 0 errno code on error. * - * Sets up basic device comunication infrastructure, boots the ROM to - * read the MAC address, registers with the WiMAX and network stacks - * and then brings up the device. + * Initializes the bus-generic parts of the i2400m driver; the + * bus-specific parts have been initialized, function pointers filled + * out by the bus-specific probe function. + * + * As well, this registers the WiMAX and net device nodes. Once this + * function returns, the device is operative and has to be ready to + * receive and send network traffic and WiMAX control operations. */ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags) { @@ -856,21 +645,16 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags) snprintf(wimax_dev->name, sizeof(wimax_dev->name), "i2400m-%s:%s", dev->bus->name, dev_name(dev)); - result = i2400m_bm_buf_alloc(i2400m); - if (result < 0) { - dev_err(dev, "cannot allocate bootmode scratch buffers\n"); - goto error_bm_buf_alloc; + i2400m->bm_cmd_buf = kzalloc(I2400M_BM_CMD_BUF_SIZE, GFP_KERNEL); + if (i2400m->bm_cmd_buf == NULL) { + dev_err(dev, "cannot allocate USB command buffer\n"); + goto error_bm_cmd_kzalloc; } - - if (i2400m->bus_setup) { - result = i2400m->bus_setup(i2400m); - if (result < 0) { - dev_err(dev, "bus-specific setup failed: %d\n", - result); - goto error_bus_setup; - } + i2400m->bm_ack_buf = kzalloc(I2400M_BM_ACK_BUF_SIZE, GFP_KERNEL); + if (i2400m->bm_ack_buf == NULL) { + dev_err(dev, "cannot allocate USB ack buffer\n"); + goto error_bm_ack_buf_kzalloc; } - result = i2400m_bootrom_init(i2400m, bm_flags); if (result < 0) { dev_err(dev, "read mac addr: bootrom init " @@ -882,9 +666,6 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags) goto error_read_mac_addr; random_ether_addr(i2400m->src_mac_addr); - i2400m->pm_notifier.notifier_call = i2400m_pm_notifier; - register_pm_notifier(&i2400m->pm_notifier); - result = register_netdev(net_dev); /* Okey dokey, bring it up */ if (result < 0) { dev_err(dev, "cannot register i2400m network device: %d\n", @@ -893,13 +674,18 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags) } netif_carrier_off(net_dev); + result = i2400m_dev_start(i2400m, bm_flags); + if (result < 0) + goto error_dev_start; + i2400m->wimax_dev.op_msg_from_user = i2400m_op_msg_from_user; i2400m->wimax_dev.op_rfkill_sw_toggle = i2400m_op_rfkill_sw_toggle; i2400m->wimax_dev.op_reset = i2400m_op_reset; - result = wimax_dev_add(&i2400m->wimax_dev, net_dev); if (result < 0) goto error_wimax_dev_add; + /* User space needs to do some init stuff */ + wimax_state_change(wimax_dev, WIMAX_ST_UNINITIALIZED); /* Now setup all that requires a registered net and wimax device. */ result = sysfs_create_group(&net_dev->dev.kobj, &i2400m_dev_attr_group); @@ -907,37 +693,30 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags) dev_err(dev, "cannot setup i2400m's sysfs: %d\n", result); goto error_sysfs_setup; } - result = i2400m_debugfs_add(i2400m); if (result < 0) { dev_err(dev, "cannot setup i2400m's debugfs: %d\n", result); goto error_debugfs_setup; } - - result = i2400m_dev_start(i2400m, bm_flags); - if (result < 0) - goto error_dev_start; d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); return result; -error_dev_start: - i2400m_debugfs_rm(i2400m); error_debugfs_setup: sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj, &i2400m_dev_attr_group); error_sysfs_setup: wimax_dev_rm(&i2400m->wimax_dev); error_wimax_dev_add: + i2400m_dev_stop(i2400m); +error_dev_start: unregister_netdev(net_dev); error_register_netdev: - unregister_pm_notifier(&i2400m->pm_notifier); error_read_mac_addr: error_bootrom_init: - if (i2400m->bus_release) - i2400m->bus_release(i2400m); -error_bus_setup: - i2400m_bm_buf_free(i2400m); -error_bm_buf_alloc: + kfree(i2400m->bm_ack_buf); +error_bm_ack_buf_kzalloc: + kfree(i2400m->bm_cmd_buf); +error_bm_cmd_kzalloc: d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); return result; } @@ -956,17 +735,14 @@ void i2400m_release(struct i2400m *i2400m) d_fnstart(3, dev, "(i2400m %p)\n", i2400m); netif_stop_queue(i2400m->wimax_dev.net_dev); - i2400m_dev_stop(i2400m); - i2400m_debugfs_rm(i2400m); sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj, &i2400m_dev_attr_group); wimax_dev_rm(&i2400m->wimax_dev); + i2400m_dev_stop(i2400m); unregister_netdev(i2400m->wimax_dev.net_dev); - unregister_pm_notifier(&i2400m->pm_notifier); - if (i2400m->bus_release) - i2400m->bus_release(i2400m); - i2400m_bm_buf_free(i2400m); + kfree(i2400m->bm_ack_buf); + kfree(i2400m->bm_cmd_buf); d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); } EXPORT_SYMBOL_GPL(i2400m_release); @@ -983,7 +759,6 @@ struct d_level D_LEVEL[] = { D_SUBMODULE_DEFINE(netdev), D_SUBMODULE_DEFINE(rfkill), D_SUBMODULE_DEFINE(rx), - D_SUBMODULE_DEFINE(sysfs), D_SUBMODULE_DEFINE(tx), }; size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL); @@ -992,9 +767,7 @@ size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL); static int __init i2400m_driver_init(void) { - d_parse_params(D_LEVEL, D_LEVEL_SIZE, i2400m_debug_params, - "i2400m.debug"); - return i2400m_barker_db_init(i2400m_barkers_params); + return 0; } module_init(i2400m_driver_init); @@ -1003,7 +776,6 @@ void __exit i2400m_driver_exit(void) { /* for scheds i2400m_dev_reset_handle() */ flush_scheduled_work(); - i2400m_barker_db_exit(); return; } module_exit(i2400m_driver_exit); diff --git a/trunk/drivers/net/wimax/i2400m/fw.c b/trunk/drivers/net/wimax/i2400m/fw.c index 64cdfeb299ca..e81750e54452 100644 --- a/trunk/drivers/net/wimax/i2400m/fw.c +++ b/trunk/drivers/net/wimax/i2400m/fw.c @@ -40,9 +40,11 @@ * * THE PROCEDURE * - * The 2400m and derived devices work in two modes: boot-mode or - * normal mode. In boot mode we can execute only a handful of commands - * targeted at uploading the firmware and launching it. + * (this is decribed for USB, but for SDIO is similar) + * + * The 2400m works in two modes: boot-mode or normal mode. In boot + * mode we can execute only a handful of commands targeted at + * uploading the firmware and launching it. * * The 2400m enters boot mode when it is first connected to the * system, when it crashes and when you ask it to reboot. There are @@ -50,26 +52,18 @@ * firmwares signed with a certain private key, non-signed takes any * firmware. Normal hardware takes only signed firmware. * - * On boot mode, in USB, we write to the device using the bulk out - * endpoint and read from it in the notification endpoint. In SDIO we - * talk to it via the write address and read from the read address. - * - * Upon entrance to boot mode, the device sends (preceeded with a few - * zero length packets (ZLPs) on the notification endpoint in USB) a - * reboot barker (4 le32 words with the same value). We ack it by - * sending the same barker to the device. The device acks with a - * reboot ack barker (4 le32 words with value I2400M_ACK_BARKER) and - * then is fully booted. At this point we can upload the firmware. - * - * Note that different iterations of the device and EEPROM - * configurations will send different [re]boot barkers; these are - * collected in i2400m_barker_db along with the firmware - * characteristics they require. + * Upon entrance to boot mode, the device sends a few zero length + * packets (ZLPs) on the notification endpoint, then a reboot barker + * (4 le32 words with value I2400M_{S,N}BOOT_BARKER). We ack it by + * sending the same barker on the bulk out endpoint. The device acks + * with a reboot ack barker (4 le32 words with value 0xfeedbabe) and + * then the device is fully rebooted. At this point we can upload the + * firmware. * * This process is accomplished by the i2400m_bootrom_init() * function. All the device interaction happens through the * i2400m_bm_cmd() [boot mode command]. Special return values will - * indicate if the device did reset during the process. + * indicate if the device resets. * * After this, we read the MAC address and then (if needed) * reinitialize the device. We need to read it ahead of time because @@ -78,11 +72,11 @@ * * We can then upload the firmware file. The file is composed of a BCF * header (basic data, keys and signatures) and a list of write - * commands and payloads. Optionally more BCF headers might follow the - * main payload. We first upload the header [i2400m_dnload_init()] and - * then pass the commands and payloads verbatim to the i2400m_bm_cmd() - * function [i2400m_dnload_bcf()]. Then we tell the device to jump to - * the new firmware [i2400m_dnload_finalize()]. + * commands and payloads. We first upload the header + * [i2400m_dnload_init()] and then pass the commands and payloads + * verbatim to the i2400m_bm_cmd() function + * [i2400m_dnload_bcf()]. Then we tell the device to jump to the new + * firmware [i2400m_dnload_finalize()]. * * Once firmware is uploaded, we are good to go :) * @@ -105,32 +99,18 @@ * read an acknolwedgement from it (or an asynchronous notification) * from it. * - * FIRMWARE LOADING - * - * Note that in some cases, we can't just load a firmware file (for - * example, when resuming). For that, we might cache the firmware - * file. Thus, when doing the bootstrap, if there is a cache firmware - * file, it is used; if not, loading from disk is attempted. - * * ROADMAP * - * i2400m_barker_db_init Called by i2400m_driver_init() - * i2400m_barker_db_add - * - * i2400m_barker_db_exit Called by i2400m_driver_exit() - * * i2400m_dev_bootstrap Called by __i2400m_dev_start() * request_firmware - * i2400m_fw_bootstrap - * i2400m_fw_check - * i2400m_fw_hdr_check - * i2400m_fw_dnload + * i2400m_fw_check + * i2400m_fw_dnload * release_firmware * * i2400m_fw_dnload * i2400m_bootrom_init * i2400m_bm_cmd - * i2400m_reset + * i2400m->bus_reset * i2400m_dnload_init * i2400m_dnload_init_signed * i2400m_dnload_init_nonsigned @@ -145,14 +125,9 @@ * i2400m->bus_bm_cmd_send() * i2400m->bus_bm_wait_for_ack * __i2400m_bm_ack_verify - * i2400m_is_boot_barker * * i2400m_bm_cmd_prepare Used by bus-drivers to prep * commands before sending - * - * i2400m_pm_notifier Called on Power Management events - * i2400m_fw_cache - * i2400m_fw_uncache */ #include #include @@ -199,240 +174,6 @@ void i2400m_bm_cmd_prepare(struct i2400m_bootrom_header *cmd) EXPORT_SYMBOL_GPL(i2400m_bm_cmd_prepare); -/* - * Database of known barkers. - * - * A barker is what the device sends indicating he is ready to be - * bootloaded. Different versions of the device will send different - * barkers. Depending on the barker, it might mean the device wants - * some kind of firmware or the other. - */ -static struct i2400m_barker_db { - __le32 data[4]; -} *i2400m_barker_db; -static size_t i2400m_barker_db_used, i2400m_barker_db_size; - - -static -int i2400m_zrealloc_2x(void **ptr, size_t *_count, size_t el_size, - gfp_t gfp_flags) -{ - size_t old_count = *_count, - new_count = old_count ? 2 * old_count : 2, - old_size = el_size * old_count, - new_size = el_size * new_count; - void *nptr = krealloc(*ptr, new_size, gfp_flags); - if (nptr) { - /* zero the other half or the whole thing if old_count - * was zero */ - if (old_size == 0) - memset(nptr, 0, new_size); - else - memset(nptr + old_size, 0, old_size); - *_count = new_count; - *ptr = nptr; - return 0; - } else - return -ENOMEM; -} - - -/* - * Add a barker to the database - * - * This cannot used outside of this module and only at at module_init - * time. This is to avoid the need to do locking. - */ -static -int i2400m_barker_db_add(u32 barker_id) -{ - int result; - - struct i2400m_barker_db *barker; - if (i2400m_barker_db_used >= i2400m_barker_db_size) { - result = i2400m_zrealloc_2x( - (void **) &i2400m_barker_db, &i2400m_barker_db_size, - sizeof(i2400m_barker_db[0]), GFP_KERNEL); - if (result < 0) - return result; - } - barker = i2400m_barker_db + i2400m_barker_db_used++; - barker->data[0] = le32_to_cpu(barker_id); - barker->data[1] = le32_to_cpu(barker_id); - barker->data[2] = le32_to_cpu(barker_id); - barker->data[3] = le32_to_cpu(barker_id); - return 0; -} - - -void i2400m_barker_db_exit(void) -{ - kfree(i2400m_barker_db); - i2400m_barker_db = NULL; - i2400m_barker_db_size = 0; - i2400m_barker_db_used = 0; -} - - -/* - * Helper function to add all the known stable barkers to the barker - * database. - */ -static -int i2400m_barker_db_known_barkers(void) -{ - int result; - - result = i2400m_barker_db_add(I2400M_NBOOT_BARKER); - if (result < 0) - goto error_add; - result = i2400m_barker_db_add(I2400M_SBOOT_BARKER); - if (result < 0) - goto error_add; - result = i2400m_barker_db_add(I2400M_SBOOT_BARKER_6050); - if (result < 0) - goto error_add; -error_add: - return result; -} - - -/* - * Initialize the barker database - * - * This can only be used from the module_init function for this - * module; this is to avoid the need to do locking. - * - * @options: command line argument with extra barkers to - * recognize. This is a comma-separated list of 32-bit hex - * numbers. They are appended to the existing list. Setting 0 - * cleans the existing list and starts a new one. - */ -int i2400m_barker_db_init(const char *_options) -{ - int result; - char *options = NULL, *options_orig, *token; - - i2400m_barker_db = NULL; - i2400m_barker_db_size = 0; - i2400m_barker_db_used = 0; - - result = i2400m_barker_db_known_barkers(); - if (result < 0) - goto error_add; - /* parse command line options from i2400m.barkers */ - if (_options != NULL) { - unsigned barker; - - options_orig = kstrdup(_options, GFP_KERNEL); - if (options_orig == NULL) - goto error_parse; - options = options_orig; - - while ((token = strsep(&options, ",")) != NULL) { - if (*token == '\0') /* eat joint commas */ - continue; - if (sscanf(token, "%x", &barker) != 1 - || barker > 0xffffffff) { - printk(KERN_ERR "%s: can't recognize " - "i2400m.barkers value '%s' as " - "a 32-bit number\n", - __func__, token); - result = -EINVAL; - goto error_parse; - } - if (barker == 0) { - /* clean list and start new */ - i2400m_barker_db_exit(); - continue; - } - result = i2400m_barker_db_add(barker); - if (result < 0) - goto error_add; - } - kfree(options_orig); - } - return 0; - -error_parse: -error_add: - kfree(i2400m_barker_db); - return result; -} - - -/* - * Recognize a boot barker - * - * @buf: buffer where the boot barker. - * @buf_size: size of the buffer (has to be 16 bytes). It is passed - * here so the function can check it for the caller. - * - * Note that as a side effect, upon identifying the obtained boot - * barker, this function will set i2400m->barker to point to the right - * barker database entry. Subsequent calls to the function will result - * in verifying that the same type of boot barker is returned when the - * device [re]boots (as long as the same device instance is used). - * - * Return: 0 if @buf matches a known boot barker. -ENOENT if the - * buffer in @buf doesn't match any boot barker in the database or - * -EILSEQ if the buffer doesn't have the right size. - */ -int i2400m_is_boot_barker(struct i2400m *i2400m, - const void *buf, size_t buf_size) -{ - int result; - struct device *dev = i2400m_dev(i2400m); - struct i2400m_barker_db *barker; - int i; - - result = -ENOENT; - if (buf_size != sizeof(i2400m_barker_db[i].data)) - return result; - - /* Short circuit if we have already discovered the barker - * associated with the device. */ - if (i2400m->barker - && !memcmp(buf, i2400m->barker, sizeof(i2400m->barker->data))) { - unsigned index = (i2400m->barker - i2400m_barker_db) - / sizeof(*i2400m->barker); - d_printf(2, dev, "boot barker cache-confirmed #%u/%08x\n", - index, le32_to_cpu(i2400m->barker->data[0])); - return 0; - } - - for (i = 0; i < i2400m_barker_db_used; i++) { - barker = &i2400m_barker_db[i]; - BUILD_BUG_ON(sizeof(barker->data) != 16); - if (memcmp(buf, barker->data, sizeof(barker->data))) - continue; - - if (i2400m->barker == NULL) { - i2400m->barker = barker; - d_printf(1, dev, "boot barker set to #%u/%08x\n", - i, le32_to_cpu(barker->data[0])); - if (barker->data[0] == le32_to_cpu(I2400M_NBOOT_BARKER)) - i2400m->sboot = 0; - else - i2400m->sboot = 1; - } else if (i2400m->barker != barker) { - dev_err(dev, "HW inconsistency: device " - "reports a different boot barker " - "than set (from %08x to %08x)\n", - le32_to_cpu(i2400m->barker->data[0]), - le32_to_cpu(barker->data[0])); - result = -EIO; - } else - d_printf(2, dev, "boot barker confirmed #%u/%08x\n", - i, le32_to_cpu(barker->data[0])); - result = 0; - break; - } - return result; -} -EXPORT_SYMBOL_GPL(i2400m_is_boot_barker); - - /* * Verify the ack data received * @@ -463,10 +204,20 @@ ssize_t __i2400m_bm_ack_verify(struct i2400m *i2400m, int opcode, opcode, ack_size, sizeof(*ack)); goto error_ack_short; } - result = i2400m_is_boot_barker(i2400m, ack, ack_size); - if (result >= 0) { + if (ack_size == sizeof(i2400m_NBOOT_BARKER) + && memcmp(ack, i2400m_NBOOT_BARKER, sizeof(*ack)) == 0) { result = -ERESTARTSYS; - d_printf(6, dev, "boot-mode cmd %d: HW boot barker\n", opcode); + i2400m->sboot = 0; + d_printf(6, dev, "boot-mode cmd %d: " + "HW non-signed boot barker\n", opcode); + goto error_reboot; + } + if (ack_size == sizeof(i2400m_SBOOT_BARKER) + && memcmp(ack, i2400m_SBOOT_BARKER, sizeof(*ack)) == 0) { + result = -ERESTARTSYS; + i2400m->sboot = 1; + d_printf(6, dev, "boot-mode cmd %d: HW signed reboot barker\n", + opcode); goto error_reboot; } if (ack_size == sizeof(i2400m_ACK_BARKER) @@ -592,6 +343,7 @@ ssize_t i2400m_bm_cmd(struct i2400m *i2400m, BUG_ON(i2400m->boot_mode == 0); if (cmd != NULL) { /* send the command */ + memcpy(i2400m->bm_cmd_buf, cmd, cmd_size); result = i2400m->bus_bm_cmd_send(i2400m, cmd, cmd_size, flags); if (result < 0) goto error_cmd_send; @@ -680,8 +432,8 @@ static int i2400m_download_chunk(struct i2400m *i2400m, const void *chunk, * Download a BCF file's sections to the device * * @i2400m: device descriptor - * @bcf: pointer to firmware data (first header followed by the - * payloads). Assumed verified and consistent. + * @bcf: pointer to firmware data (followed by the payloads). Assumed + * verified and consistent. * @bcf_len: length (in bytes) of the @bcf buffer. * * Returns: < 0 errno code on error or the offset to the jump instruction. @@ -720,17 +472,14 @@ ssize_t i2400m_dnload_bcf(struct i2400m *i2400m, "downloading section #%zu (@%zu %zu B) to 0x%08x\n", section, offset, sizeof(*bh) + data_size, le32_to_cpu(bh->target_addr)); - /* - * We look for JUMP cmd from the bootmode header, - * either I2400M_BRH_SIGNED_JUMP for secure boot - * or I2400M_BRH_JUMP for unsecure boot, the last chunk - * should be the bootmode header with JUMP cmd. - */ - if (i2400m_brh_get_opcode(bh) == I2400M_BRH_SIGNED_JUMP || - i2400m_brh_get_opcode(bh) == I2400M_BRH_JUMP) { - d_printf(5, dev, "jump found @%zu\n", offset); + if (i2400m_brh_get_opcode(bh) == I2400M_BRH_SIGNED_JUMP) { + /* Secure boot needs to stop here */ + d_printf(5, dev, "signed jump found @%zu\n", offset); break; } + if (offset + section_size == bcf_len) + /* Non-secure boot stops here */ + break; if (offset + section_size > bcf_len) { dev_err(dev, "fw %s: bad section #%zu, " "end (@%zu) beyond EOF (@%zu)\n", @@ -760,31 +509,14 @@ ssize_t i2400m_dnload_bcf(struct i2400m *i2400m, } -/* - * Indicate if the device emitted a reboot barker that indicates - * "signed boot" - */ -static -unsigned i2400m_boot_is_signed(struct i2400m *i2400m) -{ - return likely(i2400m->sboot); -} - - /* * Do the final steps of uploading firmware * - * @bcf_hdr: BCF header we are actually using - * @bcf: pointer to the firmware image (which matches the first header - * that is followed by the actual payloads). - * @offset: [byte] offset into @bcf for the command we need to send. - * * Depending on the boot mode (signed vs non-signed), different * actions need to be taken. */ static int i2400m_dnload_finalize(struct i2400m *i2400m, - const struct i2400m_bcf_hdr *bcf_hdr, const struct i2400m_bcf_hdr *bcf, size_t offset) { int ret = 0; @@ -798,14 +530,10 @@ int i2400m_dnload_finalize(struct i2400m *i2400m, d_fnstart(3, dev, "offset %zu\n", offset); cmd = (void *) bcf + offset; - if (i2400m_boot_is_signed(i2400m) == 0) { + if (i2400m->sboot == 0) { struct i2400m_bootrom_header jump_ack; d_printf(1, dev, "unsecure boot, jumping to 0x%08x\n", le32_to_cpu(cmd->target_addr)); - cmd_buf = i2400m->bm_cmd_buf; - memcpy(&cmd_buf->cmd, cmd, sizeof(*cmd)); - cmd = &cmd_buf->cmd; - /* now cmd points to the actual bootrom_header in cmd_buf */ i2400m_brh_set_opcode(cmd, I2400M_BRH_JUMP); cmd->data_size = 0; ret = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd), @@ -816,13 +544,12 @@ int i2400m_dnload_finalize(struct i2400m *i2400m, cmd_buf = i2400m->bm_cmd_buf; memcpy(&cmd_buf->cmd, cmd, sizeof(*cmd)); signature_block_offset = - sizeof(*bcf_hdr) - + le32_to_cpu(bcf_hdr->key_size) * sizeof(u32) - + le32_to_cpu(bcf_hdr->exponent_size) * sizeof(u32); + sizeof(*bcf) + + le32_to_cpu(bcf->key_size) * sizeof(u32) + + le32_to_cpu(bcf->exponent_size) * sizeof(u32); signature_block_size = - le32_to_cpu(bcf_hdr->modulus_size) * sizeof(u32); - memcpy(cmd_buf->cmd_pl, - (void *) bcf_hdr + signature_block_offset, + le32_to_cpu(bcf->modulus_size) * sizeof(u32); + memcpy(cmd_buf->cmd_pl, (void *) bcf + signature_block_offset, signature_block_size); ret = i2400m_bm_cmd(i2400m, &cmd_buf->cmd, sizeof(cmd_buf->cmd) + signature_block_size, @@ -838,7 +565,7 @@ int i2400m_dnload_finalize(struct i2400m *i2400m, * * @i2400m: device descriptor * @flags: - * I2400M_BRI_SOFT: a reboot barker has been seen + * I2400M_BRI_SOFT: a reboot notification has been seen * already, so don't wait for it. * * I2400M_BRI_NO_REBOOT: Don't send a reboot command, but wait @@ -849,15 +576,17 @@ int i2400m_dnload_finalize(struct i2400m *i2400m, * * < 0 errno code on error, 0 if ok. * + * i2400m->sboot set to 0 for unsecure boot process, 1 for secure + * boot process. + * * Description: * * Tries hard enough to put the device in boot-mode. There are two * main phases to this: * * a. (1) send a reboot command and (2) get a reboot barker - * - * b. (1) echo/ack the reboot sending the reboot barker back and (2) - * getting an ack barker in return + * b. (1) ack the reboot sending a reboot barker and (2) getting an + * ack barker in return * * We want to skip (a) in some cases [soft]. The state machine is * horrible, but it is basically: on each phase, send what has to be @@ -865,16 +594,6 @@ int i2400m_dnload_finalize(struct i2400m *i2400m, * have to backtrack and retry, so we keep a max tries counter for * that. * - * It sucks because we don't know ahead of time which is going to be - * the reboot barker (the device might send different ones depending - * on its EEPROM config) and once the device reboots and waits for the - * echo/ack reboot barker being sent back, it doesn't understand - * anything else. So we can be left at the point where we don't know - * what to send to it -- cold reset and bus reset seem to have little - * effect. So the function iterates (in this case) through all the - * known barkers and tries them all until an ACK is - * received. Otherwise, it gives up. - * * If we get a timeout after sending a warm reset, we do it again. */ int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags) @@ -883,11 +602,10 @@ int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags) struct device *dev = i2400m_dev(i2400m); struct i2400m_bootrom_header *cmd; struct i2400m_bootrom_header ack; - int count = i2400m->bus_bm_retries; + int count = I2400M_BOOT_RETRIES; int ack_timeout_cnt = 1; - unsigned i; - BUILD_BUG_ON(sizeof(*cmd) != sizeof(i2400m_barker_db[0].data)); + BUILD_BUG_ON(sizeof(*cmd) != sizeof(i2400m_NBOOT_BARKER)); BUILD_BUG_ON(sizeof(ack) != sizeof(i2400m_ACK_BARKER)); d_fnstart(4, dev, "(i2400m %p flags 0x%08x)\n", i2400m, flags); @@ -896,59 +614,27 @@ int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags) if (flags & I2400M_BRI_SOFT) goto do_reboot_ack; do_reboot: - ack_timeout_cnt = 1; if (--count < 0) goto error_timeout; d_printf(4, dev, "device reboot: reboot command [%d # left]\n", count); if ((flags & I2400M_BRI_NO_REBOOT) == 0) - i2400m_reset(i2400m, I2400M_RT_WARM); + i2400m->bus_reset(i2400m, I2400M_RT_WARM); result = i2400m_bm_cmd(i2400m, NULL, 0, &ack, sizeof(ack), I2400M_BM_CMD_RAW); flags &= ~I2400M_BRI_NO_REBOOT; switch (result) { case -ERESTARTSYS: - /* - * at this point, i2400m_bm_cmd(), through - * __i2400m_bm_ack_process(), has updated - * i2400m->barker and we are good to go. - */ d_printf(4, dev, "device reboot: got reboot barker\n"); break; case -EISCONN: /* we don't know how it got here...but we follow it */ d_printf(4, dev, "device reboot: got ack barker - whatever\n"); goto do_reboot; - case -ETIMEDOUT: - /* - * Device has timed out, we might be in boot mode - * already and expecting an ack; if we don't know what - * the barker is, we just send them all. Cold reset - * and bus reset don't work. Beats me. - */ - if (i2400m->barker != NULL) { - dev_err(dev, "device boot: reboot barker timed out, " - "trying (set) %08x echo/ack\n", - le32_to_cpu(i2400m->barker->data[0])); - goto do_reboot_ack; - } - for (i = 0; i < i2400m_barker_db_used; i++) { - struct i2400m_barker_db *barker = &i2400m_barker_db[i]; - memcpy(cmd, barker->data, sizeof(barker->data)); - result = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd), - &ack, sizeof(ack), - I2400M_BM_CMD_RAW); - if (result == -EISCONN) { - dev_warn(dev, "device boot: got ack barker " - "after sending echo/ack barker " - "#%d/%08x; rebooting j.i.c.\n", - i, le32_to_cpu(barker->data[0])); - flags &= ~I2400M_BRI_NO_REBOOT; - goto do_reboot; - } - } - dev_err(dev, "device boot: tried all the echo/acks, could " - "not get device to respond; giving up"); - result = -ESHUTDOWN; + case -ETIMEDOUT: /* device has timed out, we might be in boot + * mode already and expecting an ack, let's try + * that */ + dev_info(dev, "warm reset timed out, trying an ack\n"); + goto do_reboot_ack; case -EPROTO: case -ESHUTDOWN: /* dev is gone */ case -EINTR: /* user cancelled */ @@ -956,7 +642,6 @@ int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags) default: dev_err(dev, "device reboot: error %d while waiting " "for reboot barker - rebooting\n", result); - d_dump(1, dev, &ack, result); goto do_reboot; } /* At this point we ack back with 4 REBOOT barkers and expect @@ -965,7 +650,12 @@ int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags) * notification and report it as -EISCONN. */ do_reboot_ack: d_printf(4, dev, "device reboot ack: sending ack [%d # left]\n", count); - memcpy(cmd, i2400m->barker->data, sizeof(i2400m->barker->data)); + if (i2400m->sboot == 0) + memcpy(cmd, i2400m_NBOOT_BARKER, + sizeof(i2400m_NBOOT_BARKER)); + else + memcpy(cmd, i2400m_SBOOT_BARKER, + sizeof(i2400m_SBOOT_BARKER)); result = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd), &ack, sizeof(ack), I2400M_BM_CMD_RAW); switch (result) { @@ -978,8 +668,10 @@ int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags) d_printf(4, dev, "reboot ack: got ack barker - good\n"); break; case -ETIMEDOUT: /* no response, maybe it is the other type? */ - if (ack_timeout_cnt-- < 0) { - d_printf(4, dev, "reboot ack timedout: retrying\n"); + if (ack_timeout_cnt-- >= 0) { + d_printf(4, dev, "reboot ack timedout: " + "trying the other type?\n"); + i2400m->sboot = !i2400m->sboot; goto do_reboot_ack; } else { dev_err(dev, "reboot ack timedout too long: " @@ -1147,29 +839,32 @@ int i2400m_dnload_init_signed(struct i2400m *i2400m, * (signed or non-signed). */ static -int i2400m_dnload_init(struct i2400m *i2400m, - const struct i2400m_bcf_hdr *bcf_hdr) +int i2400m_dnload_init(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf) { int result; struct device *dev = i2400m_dev(i2400m); + u32 module_id = le32_to_cpu(bcf->module_id); - if (i2400m_boot_is_signed(i2400m)) { - d_printf(1, dev, "signed boot\n"); - result = i2400m_dnload_init_signed(i2400m, bcf_hdr); + if (i2400m->sboot == 0 + && (module_id & I2400M_BCF_MOD_ID_POKES) == 0) { + /* non-signed boot process without pokes */ + result = i2400m_dnload_init_nonsigned(i2400m); if (result == -ERESTARTSYS) return result; if (result < 0) - dev_err(dev, "firmware %s: signed boot download " + dev_err(dev, "fw %s: non-signed download " "initialization failed: %d\n", i2400m->fw_name, result); - } else { - /* non-signed boot process without pokes */ - d_printf(1, dev, "non-signed boot\n"); - result = i2400m_dnload_init_nonsigned(i2400m); + } else if (i2400m->sboot == 0 + && (module_id & I2400M_BCF_MOD_ID_POKES)) { + /* non-signed boot process with pokes, nothing to do */ + result = 0; + } else { /* signed boot process */ + result = i2400m_dnload_init_signed(i2400m, bcf); if (result == -ERESTARTSYS) return result; if (result < 0) - dev_err(dev, "firmware %s: non-signed download " + dev_err(dev, "fw %s: signed boot download " "initialization failed: %d\n", i2400m->fw_name, result); } @@ -1178,200 +873,73 @@ int i2400m_dnload_init(struct i2400m *i2400m, /* - * Run consistency tests on the firmware file and load up headers + * Run quick consistency tests on the firmware file * * Check for the firmware being made for the i2400m device, * etc...These checks are mostly informative, as the device will make * them too; but the driver's response is more informative on what * went wrong. - * - * This will also look at all the headers present on the firmware - * file, and update i2400m->fw_bcf_hdr to point to them. */ static -int i2400m_fw_hdr_check(struct i2400m *i2400m, - const struct i2400m_bcf_hdr *bcf_hdr, - size_t index, size_t offset) +int i2400m_fw_check(struct i2400m *i2400m, + const struct i2400m_bcf_hdr *bcf, + size_t bcf_size) { + int result; struct device *dev = i2400m_dev(i2400m); - unsigned module_type, header_len, major_version, minor_version, module_id, module_vendor, date, size; - module_type = bcf_hdr->module_type; - header_len = sizeof(u32) * le32_to_cpu(bcf_hdr->header_len); - major_version = (le32_to_cpu(bcf_hdr->header_version) & 0xffff0000) - >> 16; - minor_version = le32_to_cpu(bcf_hdr->header_version) & 0x0000ffff; - module_id = le32_to_cpu(bcf_hdr->module_id); - module_vendor = le32_to_cpu(bcf_hdr->module_vendor); - date = le32_to_cpu(bcf_hdr->date); - size = sizeof(u32) * le32_to_cpu(bcf_hdr->size); - - d_printf(1, dev, "firmware %s #%zd@%08zx: BCF header " - "type:vendor:id 0x%x:%x:%x v%u.%u (%u/%u B) built %08x\n", - i2400m->fw_name, index, offset, - module_type, module_vendor, module_id, - major_version, minor_version, header_len, size, date); - - /* Hard errors */ - if (major_version != 1) { - dev_err(dev, "firmware %s #%zd@%08zx: major header version " - "v%u.%u not supported\n", - i2400m->fw_name, index, offset, - major_version, minor_version); - return -EBADF; + /* Check hard errors */ + result = -EINVAL; + if (bcf_size < sizeof(*bcf)) { /* big enough header? */ + dev_err(dev, "firmware %s too short: " + "%zu B vs %zu (at least) expected\n", + i2400m->fw_name, bcf_size, sizeof(*bcf)); + goto error; } - if (module_type != 6) { /* built for the right hardware? */ - dev_err(dev, "firmware %s #%zd@%08zx: unexpected module " - "type 0x%x; aborting\n", - i2400m->fw_name, index, offset, - module_type); - return -EBADF; + module_type = bcf->module_type; + header_len = sizeof(u32) * le32_to_cpu(bcf->header_len); + major_version = le32_to_cpu(bcf->header_version) & 0xffff0000 >> 16; + minor_version = le32_to_cpu(bcf->header_version) & 0x0000ffff; + module_id = le32_to_cpu(bcf->module_id); + module_vendor = le32_to_cpu(bcf->module_vendor); + date = le32_to_cpu(bcf->date); + size = sizeof(u32) * le32_to_cpu(bcf->size); + + if (bcf_size != size) { /* annoyingly paranoid */ + dev_err(dev, "firmware %s: bad size, got " + "%zu B vs %u expected\n", + i2400m->fw_name, bcf_size, size); + goto error; } - if (module_vendor != 0x8086) { - dev_err(dev, "firmware %s #%zd@%08zx: unexpected module " - "vendor 0x%x; aborting\n", - i2400m->fw_name, index, offset, module_vendor); - return -EBADF; + d_printf(2, dev, "type 0x%x id 0x%x vendor 0x%x; header v%u.%u (%zu B) " + "date %08x (%zu B)\n", + module_type, module_id, module_vendor, + major_version, minor_version, (size_t) header_len, + date, (size_t) size); + + if (module_type != 6) { /* built for the right hardware? */ + dev_err(dev, "bad fw %s: unexpected module type 0x%x; " + "aborting\n", i2400m->fw_name, module_type); + goto error; } + /* Check soft-er errors */ + result = 0; + if (module_vendor != 0x8086) + dev_err(dev, "bad fw %s? unexpected vendor 0x%04x\n", + i2400m->fw_name, module_vendor); if (date < 0x20080300) - dev_warn(dev, "firmware %s #%zd@%08zx: build date %08x " - "too old; unsupported\n", - i2400m->fw_name, index, offset, date); - return 0; -} - - -/* - * Run consistency tests on the firmware file and load up headers - * - * Check for the firmware being made for the i2400m device, - * etc...These checks are mostly informative, as the device will make - * them too; but the driver's response is more informative on what - * went wrong. - * - * This will also look at all the headers present on the firmware - * file, and update i2400m->fw_hdrs to point to them. - */ -static -int i2400m_fw_check(struct i2400m *i2400m, const void *bcf, size_t bcf_size) -{ - int result; - struct device *dev = i2400m_dev(i2400m); - size_t headers = 0; - const struct i2400m_bcf_hdr *bcf_hdr; - const void *itr, *next, *top; - size_t slots = 0, used_slots = 0; - - for (itr = bcf, top = itr + bcf_size; - itr < top; - headers++, itr = next) { - size_t leftover, offset, header_len, size; - - leftover = top - itr; - offset = itr - (const void *) bcf; - if (leftover <= sizeof(*bcf_hdr)) { - dev_err(dev, "firmware %s: %zu B left at @%zx, " - "not enough for BCF header\n", - i2400m->fw_name, leftover, offset); - break; - } - bcf_hdr = itr; - /* Only the first header is supposed to be followed by - * payload */ - header_len = sizeof(u32) * le32_to_cpu(bcf_hdr->header_len); - size = sizeof(u32) * le32_to_cpu(bcf_hdr->size); - if (headers == 0) - next = itr + size; - else - next = itr + header_len; - - result = i2400m_fw_hdr_check(i2400m, bcf_hdr, headers, offset); - if (result < 0) - continue; - if (used_slots + 1 >= slots) { - /* +1 -> we need to account for the one we'll - * occupy and at least an extra one for - * always being NULL */ - result = i2400m_zrealloc_2x( - (void **) &i2400m->fw_hdrs, &slots, - sizeof(i2400m->fw_hdrs[0]), - GFP_KERNEL); - if (result < 0) - goto error_zrealloc; - } - i2400m->fw_hdrs[used_slots] = bcf_hdr; - used_slots++; - } - if (headers == 0) { - dev_err(dev, "firmware %s: no usable headers found\n", - i2400m->fw_name); - result = -EBADF; - } else - result = 0; -error_zrealloc: + dev_err(dev, "bad fw %s? build date too old %08x\n", + i2400m->fw_name, date); +error: return result; } -/* - * Match a barker to a BCF header module ID - * - * The device sends a barker which tells the firmware loader which - * header in the BCF file has to be used. This does the matching. - */ -static -unsigned i2400m_bcf_hdr_match(struct i2400m *i2400m, - const struct i2400m_bcf_hdr *bcf_hdr) -{ - u32 barker = le32_to_cpu(i2400m->barker->data[0]) - & 0x7fffffff; - u32 module_id = le32_to_cpu(bcf_hdr->module_id) - & 0x7fffffff; /* high bit used for something else */ - - /* special case for 5x50 */ - if (barker == I2400M_SBOOT_BARKER && module_id == 0) - return 1; - if (module_id == barker) - return 1; - return 0; -} - -static -const struct i2400m_bcf_hdr *i2400m_bcf_hdr_find(struct i2400m *i2400m) -{ - struct device *dev = i2400m_dev(i2400m); - const struct i2400m_bcf_hdr **bcf_itr, *bcf_hdr; - unsigned i = 0; - u32 barker = le32_to_cpu(i2400m->barker->data[0]); - - d_printf(2, dev, "finding BCF header for barker %08x\n", barker); - if (barker == I2400M_NBOOT_BARKER) { - bcf_hdr = i2400m->fw_hdrs[0]; - d_printf(1, dev, "using BCF header #%u/%08x for non-signed " - "barker\n", 0, le32_to_cpu(bcf_hdr->module_id)); - return bcf_hdr; - } - for (bcf_itr = i2400m->fw_hdrs; *bcf_itr != NULL; bcf_itr++, i++) { - bcf_hdr = *bcf_itr; - if (i2400m_bcf_hdr_match(i2400m, bcf_hdr)) { - d_printf(1, dev, "hit on BCF hdr #%u/%08x\n", - i, le32_to_cpu(bcf_hdr->module_id)); - return bcf_hdr; - } else - d_printf(1, dev, "miss on BCF hdr #%u/%08x\n", - i, le32_to_cpu(bcf_hdr->module_id)); - } - dev_err(dev, "cannot find a matching BCF header for barker %08x\n", - barker); - return NULL; -} - - /* * Download the firmware to the device * @@ -1388,16 +956,14 @@ const struct i2400m_bcf_hdr *i2400m_bcf_hdr_find(struct i2400m *i2400m) */ static int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf, - size_t fw_size, enum i2400m_bri flags) + size_t bcf_size, enum i2400m_bri flags) { int ret = 0; struct device *dev = i2400m_dev(i2400m); int count = i2400m->bus_bm_retries; - const struct i2400m_bcf_hdr *bcf_hdr; - size_t bcf_size; - d_fnstart(5, dev, "(i2400m %p bcf %p fw size %zu)\n", - i2400m, bcf, fw_size); + d_fnstart(5, dev, "(i2400m %p bcf %p size %zu)\n", + i2400m, bcf, bcf_size); i2400m->boot_mode = 1; wmb(); /* Make sure other readers see it */ hw_reboot: @@ -1419,28 +985,13 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf, * Initialize the download, push the bytes to the device and * then jump to the new firmware. Note @ret is passed with the * offset of the jump instruction to _dnload_finalize() - * - * Note we need to use the BCF header in the firmware image - * that matches the barker that the device sent when it - * rebooted, so it has to be passed along. */ - ret = -EBADF; - bcf_hdr = i2400m_bcf_hdr_find(i2400m); - if (bcf_hdr == NULL) - goto error_bcf_hdr_find; - - ret = i2400m_dnload_init(i2400m, bcf_hdr); + ret = i2400m_dnload_init(i2400m, bcf); /* Init device's dnload */ if (ret == -ERESTARTSYS) goto error_dev_rebooted; if (ret < 0) goto error_dnload_init; - /* - * bcf_size refers to one header size plus the fw sections size - * indicated by the header,ie. if there are other extended headers - * at the tail, they are not counted - */ - bcf_size = sizeof(u32) * le32_to_cpu(bcf_hdr->size); ret = i2400m_dnload_bcf(i2400m, bcf, bcf_size); if (ret == -ERESTARTSYS) goto error_dev_rebooted; @@ -1450,7 +1001,7 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf, goto error_dnload_bcf; } - ret = i2400m_dnload_finalize(i2400m, bcf_hdr, bcf, ret); + ret = i2400m_dnload_finalize(i2400m, bcf, ret); if (ret == -ERESTARTSYS) goto error_dev_rebooted; if (ret < 0) { @@ -1467,11 +1018,10 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf, error_dnload_finalize: error_dnload_bcf: error_dnload_init: -error_bcf_hdr_find: error_bootrom_init: error_too_many_reboots: d_fnend(5, dev, "(i2400m %p bcf %p size %zu) = %d\n", - i2400m, bcf, fw_size, ret); + i2400m, bcf, bcf_size, ret); return ret; error_dev_rebooted: @@ -1481,61 +1031,6 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf, goto hw_reboot; } -static -int i2400m_fw_bootstrap(struct i2400m *i2400m, const struct firmware *fw, - enum i2400m_bri flags) -{ - int ret; - struct device *dev = i2400m_dev(i2400m); - const struct i2400m_bcf_hdr *bcf; /* Firmware data */ - - d_fnstart(5, dev, "(i2400m %p)\n", i2400m); - bcf = (void *) fw->data; - ret = i2400m_fw_check(i2400m, bcf, fw->size); - if (ret >= 0) - ret = i2400m_fw_dnload(i2400m, bcf, fw->size, flags); - if (ret < 0) - dev_err(dev, "%s: cannot use: %d, skipping\n", - i2400m->fw_name, ret); - kfree(i2400m->fw_hdrs); - i2400m->fw_hdrs = NULL; - d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret); - return ret; -} - - -/* Refcounted container for firmware data */ -struct i2400m_fw { - struct kref kref; - const struct firmware *fw; -}; - - -static -void i2400m_fw_destroy(struct kref *kref) -{ - struct i2400m_fw *i2400m_fw = - container_of(kref, struct i2400m_fw, kref); - release_firmware(i2400m_fw->fw); - kfree(i2400m_fw); -} - - -static -struct i2400m_fw *i2400m_fw_get(struct i2400m_fw *i2400m_fw) -{ - if (i2400m_fw != NULL && i2400m_fw != (void *) ~0) - kref_get(&i2400m_fw->kref); - return i2400m_fw; -} - - -static -void i2400m_fw_put(struct i2400m_fw *i2400m_fw) -{ - kref_put(&i2400m_fw->kref, i2400m_fw_destroy); -} - /** * i2400m_dev_bootstrap - Bring the device to a known state and upload firmware @@ -1554,109 +1049,42 @@ void i2400m_fw_put(struct i2400m_fw *i2400m_fw) */ int i2400m_dev_bootstrap(struct i2400m *i2400m, enum i2400m_bri flags) { - int ret, itr; + int ret = 0, itr = 0; struct device *dev = i2400m_dev(i2400m); - struct i2400m_fw *i2400m_fw; - const struct i2400m_bcf_hdr *bcf; /* Firmware data */ const struct firmware *fw; + const struct i2400m_bcf_hdr *bcf; /* Firmware data */ const char *fw_name; d_fnstart(5, dev, "(i2400m %p)\n", i2400m); - ret = -ENODEV; - spin_lock(&i2400m->rx_lock); - i2400m_fw = i2400m_fw_get(i2400m->fw_cached); - spin_unlock(&i2400m->rx_lock); - if (i2400m_fw == (void *) ~0) { - dev_err(dev, "can't load firmware now!"); - goto out; - } else if (i2400m_fw != NULL) { - dev_info(dev, "firmware %s: loading from cache\n", - i2400m->fw_name); - ret = i2400m_fw_bootstrap(i2400m, i2400m_fw->fw, flags); - i2400m_fw_put(i2400m_fw); - goto out; - } - /* Load firmware files to memory. */ - for (itr = 0, bcf = NULL, ret = -ENOENT; ; itr++) { + itr = 0; + while(1) { fw_name = i2400m->bus_fw_names[itr]; if (fw_name == NULL) { dev_err(dev, "Could not find a usable firmware image\n"); - break; + ret = -ENOENT; + goto error_no_fw; } - d_printf(1, dev, "trying firmware %s (%d)\n", fw_name, itr); ret = request_firmware(&fw, fw_name, dev); - if (ret < 0) { + if (ret == 0) + break; /* got it */ + if (ret < 0) dev_err(dev, "fw %s: cannot load file: %d\n", fw_name, ret); - continue; - } - i2400m->fw_name = fw_name; - ret = i2400m_fw_bootstrap(i2400m, fw, flags); - release_firmware(fw); - if (ret >= 0) /* firmware loaded succesfully */ - break; - i2400m->fw_name = NULL; + itr++; } -out: + + bcf = (void *) fw->data; + i2400m->fw_name = fw_name; + ret = i2400m_fw_check(i2400m, bcf, fw->size); + if (ret < 0) + goto error_fw_bad; + ret = i2400m_fw_dnload(i2400m, bcf, fw->size, flags); +error_fw_bad: + release_firmware(fw); +error_no_fw: d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret); return ret; } EXPORT_SYMBOL_GPL(i2400m_dev_bootstrap); - - -void i2400m_fw_cache(struct i2400m *i2400m) -{ - int result; - struct i2400m_fw *i2400m_fw; - struct device *dev = i2400m_dev(i2400m); - - /* if there is anything there, free it -- now, this'd be weird */ - spin_lock(&i2400m->rx_lock); - i2400m_fw = i2400m->fw_cached; - spin_unlock(&i2400m->rx_lock); - if (i2400m_fw != NULL && i2400m_fw != (void *) ~0) { - i2400m_fw_put(i2400m_fw); - WARN(1, "%s:%u: still cached fw still present?\n", - __func__, __LINE__); - } - - if (i2400m->fw_name == NULL) { - dev_err(dev, "firmware n/a: can't cache\n"); - i2400m_fw = (void *) ~0; - goto out; - } - - i2400m_fw = kzalloc(sizeof(*i2400m_fw), GFP_ATOMIC); - if (i2400m_fw == NULL) - goto out; - kref_init(&i2400m_fw->kref); - result = request_firmware(&i2400m_fw->fw, i2400m->fw_name, dev); - if (result < 0) { - dev_err(dev, "firmware %s: failed to cache: %d\n", - i2400m->fw_name, result); - kfree(i2400m_fw); - i2400m_fw = (void *) ~0; - } else - dev_info(dev, "firmware %s: cached\n", i2400m->fw_name); -out: - spin_lock(&i2400m->rx_lock); - i2400m->fw_cached = i2400m_fw; - spin_unlock(&i2400m->rx_lock); -} - - -void i2400m_fw_uncache(struct i2400m *i2400m) -{ - struct i2400m_fw *i2400m_fw; - - spin_lock(&i2400m->rx_lock); - i2400m_fw = i2400m->fw_cached; - i2400m->fw_cached = NULL; - spin_unlock(&i2400m->rx_lock); - - if (i2400m_fw != NULL && i2400m_fw != (void *) ~0) - i2400m_fw_put(i2400m_fw); -} - diff --git a/trunk/drivers/net/wimax/i2400m/i2400m-sdio.h b/trunk/drivers/net/wimax/i2400m/i2400m-sdio.h index b9c4bed3b457..9c4e3189f7b5 100644 --- a/trunk/drivers/net/wimax/i2400m/i2400m-sdio.h +++ b/trunk/drivers/net/wimax/i2400m/i2400m-sdio.h @@ -67,7 +67,6 @@ /* Host-Device interface for SDIO */ enum { - I2400M_SDIO_BOOT_RETRIES = 3, I2400MS_BLK_SIZE = 256, I2400MS_PL_SIZE_MAX = 0x3E00, @@ -78,11 +77,9 @@ enum { I2400MS_INTR_GET_SIZE_ADDR = 0x2C, /* The number of ticks to wait for the device to signal that * it is ready */ - I2400MS_INIT_SLEEP_INTERVAL = 100, + I2400MS_INIT_SLEEP_INTERVAL = 10, /* How long to wait for the device to settle after reset */ I2400MS_SETTLE_TIME = 40, - /* The number of msec to wait for IOR after sending IOE */ - IWMC3200_IOR_TIMEOUT = 10, }; @@ -100,14 +97,6 @@ enum { * @tx_workqueue: workqeueue used for data TX; we don't use the * system's workqueue as that might cause deadlocks with code in * the bus-generic driver. - * - * @debugfs_dentry: dentry for the SDIO specific debugfs files - * - * Note this value is set to NULL upon destruction; this is - * because some routinges use it to determine if we are inside the - * probe() path or some other path. When debugfs is disabled, - * creation sets the dentry to '(void*) -ENODEV', which is valid - * for the test. */ struct i2400ms { struct i2400m i2400m; /* FIRST! See doc */ @@ -122,9 +111,6 @@ struct i2400ms { wait_queue_head_t bm_wfa_wq; int bm_wait_result; size_t bm_ack_size; - - /* Device is any of the iwmc3200 SKUs */ - unsigned iwmc3200:1; }; diff --git a/trunk/drivers/net/wimax/i2400m/i2400m-usb.h b/trunk/drivers/net/wimax/i2400m/i2400m-usb.h index 5cc0f279417e..6f76558b170f 100644 --- a/trunk/drivers/net/wimax/i2400m/i2400m-usb.h +++ b/trunk/drivers/net/wimax/i2400m/i2400m-usb.h @@ -88,13 +88,6 @@ struct edc { u16 errorcount; }; -struct i2400m_endpoint_cfg { - unsigned char bulk_out; - unsigned char notification; - unsigned char reset_cold; - unsigned char bulk_in; -}; - static inline void edc_init(struct edc *edc) { edc->timestart = jiffies; @@ -144,13 +137,15 @@ static inline int edc_inc(struct edc *edc, u16 max_err, u16 timeframe) /* Host-Device interface for USB */ enum { - I2400M_USB_BOOT_RETRIES = 3, I2400MU_MAX_NOTIFICATION_LEN = 256, I2400MU_BLK_SIZE = 16, I2400MU_PL_SIZE_MAX = 0x3EFF, - /* Device IDs */ - USB_DEVICE_ID_I6050 = 0x0186, + /* Endpoints */ + I2400MU_EP_BULK_OUT = 0, + I2400MU_EP_NOTIFICATION, + I2400MU_EP_RESET_COLD, + I2400MU_EP_BULK_IN, }; @@ -220,7 +215,6 @@ struct i2400mu { struct usb_device *usb_dev; struct usb_interface *usb_iface; struct edc urb_edc; /* Error density counter */ - struct i2400m_endpoint_cfg endpoint_cfg; struct urb *notif_urb; struct task_struct *tx_kthread; diff --git a/trunk/drivers/net/wimax/i2400m/i2400m.h b/trunk/drivers/net/wimax/i2400m/i2400m.h index 04df9bbe340f..60330f313f27 100644 --- a/trunk/drivers/net/wimax/i2400m/i2400m.h +++ b/trunk/drivers/net/wimax/i2400m/i2400m.h @@ -117,31 +117,17 @@ * well as i2400m->wimax_dev.net_dev and call i2400m_setup(). The * i2400m driver will only register with the WiMAX and network stacks; * the only access done to the device is to read the MAC address so we - * can register a network device. - * - * The high-level call flow is: - * - * bus_probe() - * i2400m_setup() - * i2400m->bus_setup() - * boot rom initialization / read mac addr - * network / WiMAX stacks registration - * i2400m_dev_start() - * i2400m->bus_dev_start() - * i2400m_dev_initialize() - * - * The reverse applies for a disconnect() call: - * - * bus_disconnect() - * i2400m_release() - * i2400m_dev_stop() - * i2400m_dev_shutdown() - * i2400m->bus_dev_stop() - * network / WiMAX stack unregistration - * i2400m->bus_release() + * can register a network device. This calls i2400m_dev_start() to + * load firmware, setup communication with the device and configure it + * for operation. * * At this point, control and data communications are possible. * + * On disconnect/driver unload, the bus-specific disconnect function + * calls i2400m_release() to undo i2400m_setup(). i2400m_dev_stop() + * shuts the firmware down and releases resources uses to communicate + * with the device. + * * While the device is up, it might reset. The bus-specific driver has * to catch that situation and call i2400m_dev_reset_handle() to deal * with it (reset the internal driver structures and go back to square @@ -162,6 +148,9 @@ /* Misc constants */ enum { + /* Firmware uploading */ + I2400M_BOOT_RETRIES = 3, + I3200_BOOT_RETRIES = 3, /* Size of the Boot Mode Command buffer */ I2400M_BM_CMD_BUF_SIZE = 16 * 1024, I2400M_BM_ACK_BUF_SIZE = 256, @@ -208,7 +197,6 @@ enum i2400m_reset_type { struct i2400m_reset_ctx; struct i2400m_roq; -struct i2400m_barker_db; /** * struct i2400m - descriptor for an Intel 2400m @@ -216,50 +204,27 @@ struct i2400m_barker_db; * Members marked with [fill] must be filled out/initialized before * calling i2400m_setup(). * - * Note the @bus_setup/@bus_release, @bus_dev_start/@bus_dev_release - * call pairs are very much doing almost the same, and depending on - * the underlying bus, some stuff has to be put in one or the - * other. The idea of setup/release is that they setup the minimal - * amount needed for loading firmware, where us dev_start/stop setup - * the rest needed to do full data/control traffic. - * * @bus_tx_block_size: [fill] SDIO imposes a 256 block size, USB 16, * so we have a tx_blk_size variable that the bus layer sets to * tell the engine how much of that we need. * * @bus_pl_size_max: [fill] Maximum payload size. * - * @bus_setup: [optional fill] Function called by the bus-generic code - * [i2400m_setup()] to setup the basic bus-specific communications - * to the the device needed to load firmware. See LIFE CYCLE above. + * @bus_dev_start: [fill] Function called by the bus-generic code + * [i2400m_dev_start()] to setup the bus-specific communications + * to the the device. See LIFE CYCLE above. * * NOTE: Doesn't need to upload the firmware, as that is taken * care of by the bus-generic code. * - * @bus_release: [optional fill] Function called by the bus-generic - * code [i2400m_release()] to shutdown the basic bus-specific - * communications to the the device needed to load firmware. See - * LIFE CYCLE above. + * @bus_dev_stop: [fill] Function called by the bus-generic code + * [i2400m_dev_stop()] to shutdown the bus-specific communications + * to the the device. See LIFE CYCLE above. * * This function does not need to reset the device, just tear down * all the host resources created to handle communication with * the device. * - * @bus_dev_start: [optional fill] Function called by the bus-generic - * code [i2400m_dev_start()] to do things needed to start the - * device. See LIFE CYCLE above. - * - * NOTE: Doesn't need to upload the firmware, as that is taken - * care of by the bus-generic code. - * - * @bus_dev_stop: [optional fill] Function called by the bus-generic - * code [i2400m_dev_stop()] to do things needed for stopping the - * device. See LIFE CYCLE above. - * - * This function does not need to reset the device, just tear down - * all the host resources created to handle communication with - * the device. - * * @bus_tx_kick: [fill] Function called by the bus-generic code to let * the bus-specific code know that there is data available in the * TX FIFO for transmission to the device. @@ -281,9 +246,6 @@ struct i2400m_barker_db; * process, so it cannot rely on common infrastructure being laid * out. * - * IMPORTANT: don't call reset on RT_BUS with i2400m->init_mutex - * held, as the .pre/.post reset handlers will deadlock. - * * @bus_bm_retries: [fill] How many times shall a firmware upload / * device initialization be retried? Different models of the same * device might need different values, hence it is set by the @@ -335,27 +297,6 @@ struct i2400m_barker_db; * force this to be the first field so that we can get from * netdev_priv() the right pointer. * - * @updown: the device is up and ready for transmitting control and - * data packets. This implies @ready (communication infrastructure - * with the device is ready) and the device's firmware has been - * loaded and the device initialized. - * - * Write to it only inside a i2400m->init_mutex protected area - * followed with a wmb(); rmb() before accesing (unless locked - * inside i2400m->init_mutex). Read access can be loose like that - * [just using rmb()] because the paths that use this also do - * other error checks later on. - * - * @ready: Communication infrastructure with the device is ready, data - * frames can start to be passed around (this is lighter than - * using the WiMAX state for certain hot paths). - * - * Write to it only inside a i2400m->init_mutex protected area - * followed with a wmb(); rmb() before accesing (unless locked - * inside i2400m->init_mutex). Read access can be loose like that - * [just using rmb()] because the paths that use this also do - * other error checks later on. - * * @rx_reorder: 1 if RX reordering is enabled; this can only be * set at probe time. * @@ -421,13 +362,6 @@ struct i2400m_barker_db; * delivered. Then the driver can release them to the host. See * drivers/net/i2400m/rx.c for details. * - * @rx_reports: reports received from the device that couldn't be - * processed because the driver wasn't still ready; when ready, - * they are pulled from here and chewed. - * - * @rx_reports_ws: Work struct used to kick a scan of the RX reports - * list and to process each. - * * @src_mac_addr: MAC address used to make ethernet packets be coming * from. This is generated at i2400m_setup() time and used during * the life cycle of the instance. See i2400m_fake_eth_header(). @@ -488,25 +422,6 @@ struct i2400m_barker_db; * * @fw_version: version of the firmware interface, Major.minor, * encoded in the high word and low word (major << 16 | minor). - * - * @fw_hdrs: NULL terminated array of pointers to the firmware - * headers. This is only available during firmware load time. - * - * @fw_cached: Used to cache firmware when the system goes to - * suspend/standby/hibernation (as on resume we can't read it). If - * NULL, no firmware was cached, read it. If ~0, you can't read - * any firmware files (the system still didn't come out of suspend - * and failed to cache one), so abort; otherwise, a valid cached - * firmware to be used. Access to this variable is protected by - * the spinlock i2400m->rx_lock. - * - * @barker: barker type that the device uses; this is initialized by - * i2400m_is_boot_barker() the first time it is called. Then it - * won't change during the life cycle of the device and everytime - * a boot barker is received, it is just verified for it being the - * same. - * - * @pm_notifier: used to register for PM events */ struct i2400m { struct wimax_dev wimax_dev; /* FIRST! See doc */ @@ -514,7 +429,7 @@ struct i2400m { unsigned updown:1; /* Network device is up or down */ unsigned boot_mode:1; /* is the device in boot mode? */ unsigned sboot:1; /* signed or unsigned fw boot */ - unsigned ready:1; /* Device comm infrastructure ready */ + unsigned ready:1; /* all probing steps done */ unsigned rx_reorder:1; /* RX reorder is enabled */ u8 trace_msg_from_user; /* echo rx msgs to 'trace' pipe */ /* typed u8 so /sys/kernel/debug/u8 can tweak */ @@ -525,10 +440,8 @@ struct i2400m { size_t bus_pl_size_max; unsigned bus_bm_retries; - int (*bus_setup)(struct i2400m *); int (*bus_dev_start)(struct i2400m *); void (*bus_dev_stop)(struct i2400m *); - void (*bus_release)(struct i2400m *); void (*bus_tx_kick)(struct i2400m *); int (*bus_reset)(struct i2400m *, enum i2400m_reset_type); ssize_t (*bus_bm_cmd_send)(struct i2400m *, @@ -555,8 +468,6 @@ struct i2400m { rx_num, rx_size_acc, rx_size_min, rx_size_max; struct i2400m_roq *rx_roq; /* not under rx_lock! */ u8 src_mac_addr[ETH_HLEN]; - struct list_head rx_reports; /* under rx_lock! */ - struct work_struct rx_report_ws; struct mutex msg_mutex; /* serialize command execution */ struct completion msg_completion; @@ -576,14 +487,39 @@ struct i2400m { struct dentry *debugfs_dentry; const char *fw_name; /* name of the current firmware image */ unsigned long fw_version; /* version of the firmware interface */ - const struct i2400m_bcf_hdr **fw_hdrs; - struct i2400m_fw *fw_cached; /* protected by rx_lock */ - struct i2400m_barker_db *barker; - - struct notifier_block pm_notifier; }; +/* + * Initialize a 'struct i2400m' from all zeroes + * + * This is a bus-generic API call. + */ +static inline +void i2400m_init(struct i2400m *i2400m) +{ + wimax_dev_init(&i2400m->wimax_dev); + + i2400m->boot_mode = 1; + i2400m->rx_reorder = 1; + init_waitqueue_head(&i2400m->state_wq); + + spin_lock_init(&i2400m->tx_lock); + i2400m->tx_pl_min = UINT_MAX; + i2400m->tx_size_min = UINT_MAX; + + spin_lock_init(&i2400m->rx_lock); + i2400m->rx_pl_min = UINT_MAX; + i2400m->rx_size_min = UINT_MAX; + + mutex_init(&i2400m->msg_mutex); + init_completion(&i2400m->msg_completion); + + mutex_init(&i2400m->init_mutex); + /* wake_tx_ws is initialized in i2400m_tx_setup() */ +} + + /* * Bus-generic internal APIs * ------------------------- @@ -641,14 +577,6 @@ extern void i2400m_bm_cmd_prepare(struct i2400m_bootrom_header *); extern int i2400m_dev_bootstrap(struct i2400m *, enum i2400m_bri); extern int i2400m_read_mac_addr(struct i2400m *); extern int i2400m_bootrom_init(struct i2400m *, enum i2400m_bri); -extern int i2400m_is_boot_barker(struct i2400m *, const void *, size_t); -static inline -int i2400m_is_d2h_barker(const void *buf) -{ - const __le32 *barker = buf; - return le32_to_cpu(*barker) == I2400M_D2H_MSG_BARKER; -} -extern void i2400m_unknown_barker(struct i2400m *, const void *, size_t); /* Make/grok boot-rom header commands */ @@ -716,8 +644,6 @@ unsigned i2400m_brh_get_signature(const struct i2400m_bootrom_header *hdr) /* * Driver / device setup and internal functions */ -extern void i2400m_init(struct i2400m *); -extern int i2400m_reset(struct i2400m *, enum i2400m_reset_type); extern void i2400m_netdev_setup(struct net_device *net_dev); extern int i2400m_sysfs_setup(struct device_driver *); extern void i2400m_sysfs_release(struct device_driver *); @@ -728,14 +654,10 @@ extern void i2400m_tx_release(struct i2400m *); extern int i2400m_rx_setup(struct i2400m *); extern void i2400m_rx_release(struct i2400m *); -extern void i2400m_fw_cache(struct i2400m *); -extern void i2400m_fw_uncache(struct i2400m *); - extern void i2400m_net_rx(struct i2400m *, struct sk_buff *, unsigned, const void *, int); extern void i2400m_net_erx(struct i2400m *, struct sk_buff *, enum i2400m_cs); -extern void i2400m_net_wake_stop(struct i2400m *); enum i2400m_pt; extern int i2400m_tx(struct i2400m *, const void *, size_t, enum i2400m_pt); @@ -750,12 +672,14 @@ static inline int i2400m_debugfs_add(struct i2400m *i2400m) static inline void i2400m_debugfs_rm(struct i2400m *i2400m) {} #endif -/* Initialize/shutdown the device */ +/* Called by _dev_start()/_dev_stop() to initialize the device itself */ extern int i2400m_dev_initialize(struct i2400m *); extern void i2400m_dev_shutdown(struct i2400m *); extern struct attribute_group i2400m_dev_attr_group; +extern int i2400m_schedule_work(struct i2400m *, + void (*)(struct work_struct *), gfp_t); /* HDI message's payload description handling */ @@ -800,9 +724,7 @@ void i2400m_put(struct i2400m *i2400m) dev_put(i2400m->wimax_dev.net_dev); } -extern int i2400m_dev_reset_handle(struct i2400m *, const char *); -extern int i2400m_pre_reset(struct i2400m *); -extern int i2400m_post_reset(struct i2400m *); +extern int i2400m_dev_reset_handle(struct i2400m *); /* * _setup()/_release() are called by the probe/disconnect functions of @@ -815,6 +737,20 @@ extern int i2400m_rx(struct i2400m *, struct sk_buff *); extern struct i2400m_msg_hdr *i2400m_tx_msg_get(struct i2400m *, size_t *); extern void i2400m_tx_msg_sent(struct i2400m *); +static const __le32 i2400m_NBOOT_BARKER[4] = { + cpu_to_le32(I2400M_NBOOT_BARKER), + cpu_to_le32(I2400M_NBOOT_BARKER), + cpu_to_le32(I2400M_NBOOT_BARKER), + cpu_to_le32(I2400M_NBOOT_BARKER) +}; + +static const __le32 i2400m_SBOOT_BARKER[4] = { + cpu_to_le32(I2400M_SBOOT_BARKER), + cpu_to_le32(I2400M_SBOOT_BARKER), + cpu_to_le32(I2400M_SBOOT_BARKER), + cpu_to_le32(I2400M_SBOOT_BARKER) +}; + extern int i2400m_power_save_disabled; /* @@ -837,12 +773,10 @@ struct device *i2400m_dev(struct i2400m *i2400m) struct i2400m_work { struct work_struct ws; struct i2400m *i2400m; - size_t pl_size; u8 pl[0]; }; - -extern int i2400m_schedule_work(struct i2400m *, - void (*)(struct work_struct *), gfp_t, +extern int i2400m_queue_work(struct i2400m *, + void (*)(struct work_struct *), gfp_t, const void *, size_t); extern int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *, @@ -855,7 +789,6 @@ extern void i2400m_msg_ack_hook(struct i2400m *, const struct i2400m_l3l4_hdr *, size_t); extern void i2400m_report_hook(struct i2400m *, const struct i2400m_l3l4_hdr *, size_t); -extern void i2400m_report_hook_work(struct work_struct *); extern int i2400m_cmd_enter_powersave(struct i2400m *); extern int i2400m_cmd_get_state(struct i2400m *); extern int i2400m_cmd_exit_idle(struct i2400m *); @@ -916,12 +849,6 @@ void __i2400m_msleep(unsigned ms) #endif } - -/* module initialization helpers */ -extern int i2400m_barker_db_init(const char *); -extern void i2400m_barker_db_exit(void); - - /* Module parameters */ extern int i2400m_idle_mode_disabled; diff --git a/trunk/drivers/net/wimax/i2400m/netdev.c b/trunk/drivers/net/wimax/i2400m/netdev.c index 599aa4eb9baa..796396cb4c82 100644 --- a/trunk/drivers/net/wimax/i2400m/netdev.c +++ b/trunk/drivers/net/wimax/i2400m/netdev.c @@ -74,7 +74,6 @@ */ #include #include -#include #include "i2400m.h" @@ -89,10 +88,7 @@ enum { * The MTU is 1400 or less */ I2400M_MAX_MTU = 1400, - /* 20 secs? yep, this is the maximum timeout that the device - * might take to get out of IDLE / negotiate it with the base - * station. We add 1sec for good measure. */ - I2400M_TX_TIMEOUT = 21 * HZ, + I2400M_TX_TIMEOUT = HZ, I2400M_TX_QLEN = 5, }; @@ -105,19 +101,22 @@ int i2400m_open(struct net_device *net_dev) struct device *dev = i2400m_dev(i2400m); d_fnstart(3, dev, "(net_dev %p [i2400m %p])\n", net_dev, i2400m); - /* Make sure we wait until init is complete... */ - mutex_lock(&i2400m->init_mutex); - if (i2400m->updown) - result = 0; - else + if (i2400m->ready == 0) { + dev_err(dev, "Device is still initializing\n"); result = -EBUSY; - mutex_unlock(&i2400m->init_mutex); + } else + result = 0; d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n", net_dev, i2400m, result); return result; } +/* + * + * On kernel versions where cancel_work_sync() didn't return anything, + * we rely on wake_tx_skb() being non-NULL. + */ static int i2400m_stop(struct net_device *net_dev) { @@ -125,7 +124,21 @@ int i2400m_stop(struct net_device *net_dev) struct device *dev = i2400m_dev(i2400m); d_fnstart(3, dev, "(net_dev %p [i2400m %p])\n", net_dev, i2400m); - i2400m_net_wake_stop(i2400m); + /* See i2400m_hard_start_xmit(), references are taken there + * and here we release them if the work was still + * pending. Note we can't differentiate work not pending vs + * never scheduled, so the NULL check does that. */ + if (cancel_work_sync(&i2400m->wake_tx_ws) == 0 + && i2400m->wake_tx_skb != NULL) { + unsigned long flags; + struct sk_buff *wake_tx_skb; + spin_lock_irqsave(&i2400m->tx_lock, flags); + wake_tx_skb = i2400m->wake_tx_skb; /* compat help */ + i2400m->wake_tx_skb = NULL; /* compat help */ + spin_unlock_irqrestore(&i2400m->tx_lock, flags); + i2400m_put(i2400m); + kfree_skb(wake_tx_skb); + } d_fnend(3, dev, "(net_dev %p [i2400m %p]) = 0\n", net_dev, i2400m); return 0; } @@ -154,7 +167,6 @@ void i2400m_wake_tx_work(struct work_struct *ws) { int result; struct i2400m *i2400m = container_of(ws, struct i2400m, wake_tx_ws); - struct net_device *net_dev = i2400m->wimax_dev.net_dev; struct device *dev = i2400m_dev(i2400m); struct sk_buff *skb = i2400m->wake_tx_skb; unsigned long flags; @@ -170,36 +182,27 @@ void i2400m_wake_tx_work(struct work_struct *ws) dev_err(dev, "WAKE&TX: skb dissapeared!\n"); goto out_put; } - /* If we have, somehow, lost the connection after this was - * queued, don't do anything; this might be the device got - * reset or just disconnected. */ - if (unlikely(!netif_carrier_ok(net_dev))) - goto out_kfree; result = i2400m_cmd_exit_idle(i2400m); if (result == -EILSEQ) result = 0; if (result < 0) { dev_err(dev, "WAKE&TX: device didn't get out of idle: " - "%d - resetting\n", result); - i2400m_reset(i2400m, I2400M_RT_BUS); - goto error; + "%d\n", result); + goto error; } result = wait_event_timeout(i2400m->state_wq, - i2400m->state != I2400M_SS_IDLE, - net_dev->watchdog_timeo - HZ/2); + i2400m->state != I2400M_SS_IDLE, 5 * HZ); if (result == 0) result = -ETIMEDOUT; if (result < 0) { dev_err(dev, "WAKE&TX: error waiting for device to exit IDLE: " - "%d - resetting\n", result); - i2400m_reset(i2400m, I2400M_RT_BUS); + "%d\n", result); goto error; } msleep(20); /* device still needs some time or it drops it */ result = i2400m_tx(i2400m, skb->data, skb->len, I2400M_PT_DATA); + netif_wake_queue(i2400m->wimax_dev.net_dev); error: - netif_wake_queue(net_dev); -out_kfree: kfree_skb(skb); /* refcount transferred by _hard_start_xmit() */ out_put: i2400m_put(i2400m); @@ -226,38 +229,6 @@ void i2400m_tx_prep_header(struct sk_buff *skb) } - -/* - * Cleanup resources acquired during i2400m_net_wake_tx() - * - * This is called by __i2400m_dev_stop and means we have to make sure - * the workqueue is flushed from any pending work. - */ -void i2400m_net_wake_stop(struct i2400m *i2400m) -{ - struct device *dev = i2400m_dev(i2400m); - - d_fnstart(3, dev, "(i2400m %p)\n", i2400m); - /* See i2400m_hard_start_xmit(), references are taken there - * and here we release them if the work was still - * pending. Note we can't differentiate work not pending vs - * never scheduled, so the NULL check does that. */ - if (cancel_work_sync(&i2400m->wake_tx_ws) == 0 - && i2400m->wake_tx_skb != NULL) { - unsigned long flags; - struct sk_buff *wake_tx_skb; - spin_lock_irqsave(&i2400m->tx_lock, flags); - wake_tx_skb = i2400m->wake_tx_skb; /* compat help */ - i2400m->wake_tx_skb = NULL; /* compat help */ - spin_unlock_irqrestore(&i2400m->tx_lock, flags); - i2400m_put(i2400m); - kfree_skb(wake_tx_skb); - } - d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); - return; -} - - /* * TX an skb to an idle device * @@ -371,20 +342,6 @@ netdev_tx_t i2400m_hard_start_xmit(struct sk_buff *skb, int result; d_fnstart(3, dev, "(skb %p net_dev %p)\n", skb, net_dev); - if (skb_header_cloned(skb)) { - /* - * Make tcpdump/wireshark happy -- if they are - * running, the skb is cloned and we will overwrite - * the mac fields in i2400m_tx_prep_header. Expand - * seems to fix this... - */ - result = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); - if (result) { - result = NETDEV_TX_BUSY; - goto error_expand; - } - } - if (i2400m->state == I2400M_SS_IDLE) result = i2400m_net_wake_tx(i2400m, net_dev, skb); else @@ -395,11 +352,10 @@ netdev_tx_t i2400m_hard_start_xmit(struct sk_buff *skb, net_dev->stats.tx_packets++; net_dev->stats.tx_bytes += skb->len; } - result = NETDEV_TX_OK; -error_expand: kfree_skb(skb); - d_fnend(3, dev, "(skb %p net_dev %p) = %d\n", skb, net_dev, result); - return result; + + d_fnend(3, dev, "(skb %p net_dev %p)\n", skb, net_dev); + return NETDEV_TX_OK; } @@ -603,22 +559,6 @@ static const struct net_device_ops i2400m_netdev_ops = { .ndo_change_mtu = i2400m_change_mtu, }; -static void i2400m_get_drvinfo(struct net_device *net_dev, - struct ethtool_drvinfo *info) -{ - struct i2400m *i2400m = net_dev_to_i2400m(net_dev); - - strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver) - 1); - strncpy(info->fw_version, i2400m->fw_name, sizeof(info->fw_version) - 1); - if (net_dev->dev.parent) - strncpy(info->bus_info, dev_name(net_dev->dev.parent), - sizeof(info->bus_info) - 1); -} - -static const struct ethtool_ops i2400m_ethtool_ops = { - .get_drvinfo = i2400m_get_drvinfo, - .get_link = ethtool_op_get_link, -}; /** * i2400m_netdev_setup - Setup setup @net_dev's i2400m private data @@ -640,7 +580,6 @@ void i2400m_netdev_setup(struct net_device *net_dev) & ~IFF_MULTICAST); net_dev->watchdog_timeo = I2400M_TX_TIMEOUT; net_dev->netdev_ops = &i2400m_netdev_ops; - net_dev->ethtool_ops = &i2400m_ethtool_ops; d_fnend(3, NULL, "(net_dev %p) = void\n", net_dev); } EXPORT_SYMBOL_GPL(i2400m_netdev_setup); diff --git a/trunk/drivers/net/wimax/i2400m/rx.c b/trunk/drivers/net/wimax/i2400m/rx.c index e3d2a9de023c..07c32e68909f 100644 --- a/trunk/drivers/net/wimax/i2400m/rx.c +++ b/trunk/drivers/net/wimax/i2400m/rx.c @@ -158,104 +158,30 @@ struct i2400m_report_hook_args { struct sk_buff *skb_rx; const struct i2400m_l3l4_hdr *l3l4_hdr; size_t size; - struct list_head list_node; }; /* * Execute i2400m_report_hook in a workqueue * - * Goes over the list of queued reports in i2400m->rx_reports and - * processes them. + * Unpacks arguments from the deferred call, executes it and then + * drops the references. * - * NOTE: refcounts on i2400m are not needed because we flush the - * workqueue this runs on (i2400m->work_queue) before destroying - * i2400m. - */ -void i2400m_report_hook_work(struct work_struct *ws) -{ - struct i2400m *i2400m = container_of(ws, struct i2400m, rx_report_ws); - struct device *dev = i2400m_dev(i2400m); - struct i2400m_report_hook_args *args, *args_next; - LIST_HEAD(list); - unsigned long flags; - - while (1) { - spin_lock_irqsave(&i2400m->rx_lock, flags); - list_splice_init(&i2400m->rx_reports, &list); - spin_unlock_irqrestore(&i2400m->rx_lock, flags); - if (list_empty(&list)) - break; - else - d_printf(1, dev, "processing queued reports\n"); - list_for_each_entry_safe(args, args_next, &list, list_node) { - d_printf(2, dev, "processing queued report %p\n", args); - i2400m_report_hook(i2400m, args->l3l4_hdr, args->size); - kfree_skb(args->skb_rx); - list_del(&args->list_node); - kfree(args); - } - } -} - - -/* - * Flush the list of queued reports - */ -static -void i2400m_report_hook_flush(struct i2400m *i2400m) -{ - struct device *dev = i2400m_dev(i2400m); - struct i2400m_report_hook_args *args, *args_next; - LIST_HEAD(list); - unsigned long flags; - - d_printf(1, dev, "flushing queued reports\n"); - spin_lock_irqsave(&i2400m->rx_lock, flags); - list_splice_init(&i2400m->rx_reports, &list); - spin_unlock_irqrestore(&i2400m->rx_lock, flags); - list_for_each_entry_safe(args, args_next, &list, list_node) { - d_printf(2, dev, "flushing queued report %p\n", args); - kfree_skb(args->skb_rx); - list_del(&args->list_node); - kfree(args); - } -} - - -/* - * Queue a report for later processing - * - * @i2400m: device descriptor - * @skb_rx: skb that contains the payload (for reference counting) - * @l3l4_hdr: pointer to the control - * @size: size of the message + * Obvious NOTE: References are needed because we are a separate + * thread; otherwise the buffer changes under us because it is + * released by the original caller. */ static -void i2400m_report_hook_queue(struct i2400m *i2400m, struct sk_buff *skb_rx, - const void *l3l4_hdr, size_t size) +void i2400m_report_hook_work(struct work_struct *ws) { - struct device *dev = i2400m_dev(i2400m); - unsigned long flags; - struct i2400m_report_hook_args *args; - - args = kzalloc(sizeof(*args), GFP_NOIO); - if (args) { - args->skb_rx = skb_get(skb_rx); - args->l3l4_hdr = l3l4_hdr; - args->size = size; - spin_lock_irqsave(&i2400m->rx_lock, flags); - list_add_tail(&args->list_node, &i2400m->rx_reports); - spin_unlock_irqrestore(&i2400m->rx_lock, flags); - d_printf(2, dev, "queued report %p\n", args); - rmb(); /* see i2400m->ready's documentation */ - if (likely(i2400m->ready)) /* only send if up */ - queue_work(i2400m->work_queue, &i2400m->rx_report_ws); - } else { - if (printk_ratelimit()) - dev_err(dev, "%s:%u: Can't allocate %zu B\n", - __func__, __LINE__, sizeof(*args)); - } + struct i2400m_work *iw = + container_of(ws, struct i2400m_work, ws); + struct i2400m_report_hook_args *args = (void *) iw->pl; + if (iw->i2400m->ready) + i2400m_report_hook(iw->i2400m, args->l3l4_hdr, args->size); + kfree_skb(args->skb_rx); + i2400m_put(iw->i2400m); + kfree(iw); } @@ -369,29 +295,21 @@ void i2400m_rx_ctl(struct i2400m *i2400m, struct sk_buff *skb_rx, msg_type, size); d_dump(2, dev, l3l4_hdr, size); if (msg_type & I2400M_MT_REPORT_MASK) { - /* - * Process each report - * - * - has to be ran serialized as well - * - * - the handling might force the execution of - * commands. That might cause reentrancy issues with - * bus-specific subdrivers and workqueues, so the we - * run it in a separate workqueue. - * - * - when the driver is not yet ready to handle them, - * they are queued and at some point the queue is - * restarted [NOTE: we can't queue SKBs directly, as - * this might be a piece of a SKB, not the whole - * thing, and this is cheaper than cloning the - * SKB]. - * - * Note we don't do refcounting for the device - * structure; this is because before destroying - * 'i2400m', we make sure to flush the - * i2400m->work_queue, so there are no issues. - */ - i2400m_report_hook_queue(i2400m, skb_rx, l3l4_hdr, size); + /* These hooks have to be ran serialized; as well, the + * handling might force the execution of commands, and + * that might cause reentrancy issues with + * bus-specific subdrivers and workqueues. So we run + * it in a separate workqueue. */ + struct i2400m_report_hook_args args = { + .skb_rx = skb_rx, + .l3l4_hdr = l3l4_hdr, + .size = size + }; + if (unlikely(i2400m->ready == 0)) /* only send if up */ + return; + skb_get(skb_rx); + i2400m_queue_work(i2400m, i2400m_report_hook_work, + GFP_KERNEL, &args, sizeof(args)); if (unlikely(i2400m->trace_msg_from_user)) wimax_msg(&i2400m->wimax_dev, "echo", l3l4_hdr, size, GFP_KERNEL); @@ -445,6 +363,8 @@ void i2400m_rx_trace(struct i2400m *i2400m, msg_type & I2400M_MT_REPORT_MASK ? "REPORT" : "CMD/SET/GET", msg_type, size); d_dump(2, dev, l3l4_hdr, size); + if (unlikely(i2400m->ready == 0)) /* only send if up */ + return; result = wimax_msg(wimax_dev, "trace", l3l4_hdr, size, GFP_KERNEL); if (result < 0) dev_err(dev, "error sending trace to userspace: %d\n", @@ -828,7 +748,7 @@ void i2400m_roq_queue(struct i2400m *i2400m, struct i2400m_roq *roq, dev_err(dev, "SW BUG? queue nsn %d (lbn %u ws %u)\n", nsn, lbn, roq->ws); i2400m_roq_log_dump(i2400m, roq); - i2400m_reset(i2400m, I2400M_RT_WARM); + i2400m->bus_reset(i2400m, I2400M_RT_WARM); } else { __i2400m_roq_queue(i2400m, roq, skb, lbn, nsn); i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_PACKET, @@ -894,7 +814,7 @@ void i2400m_roq_queue_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq, dev_err(dev, "SW BUG? queue_update_ws nsn %u (sn %u ws %u)\n", nsn, sn, roq->ws); i2400m_roq_log_dump(i2400m, roq); - i2400m_reset(i2400m, I2400M_RT_WARM); + i2400m->bus_reset(i2400m, I2400M_RT_WARM); } else { /* if the queue is empty, don't bother as we'd queue * it and inmediately unqueue it -- just deliver it */ @@ -1274,28 +1194,6 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) EXPORT_SYMBOL_GPL(i2400m_rx); -void i2400m_unknown_barker(struct i2400m *i2400m, - const void *buf, size_t size) -{ - struct device *dev = i2400m_dev(i2400m); - char prefix[64]; - const __le32 *barker = buf; - dev_err(dev, "RX: HW BUG? unknown barker %08x, " - "dropping %zu bytes\n", le32_to_cpu(*barker), size); - snprintf(prefix, sizeof(prefix), "%s %s: ", - dev_driver_string(dev), dev_name(dev)); - if (size > 64) { - print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, - 8, 4, buf, 64, 0); - printk(KERN_ERR "%s... (only first 64 bytes " - "dumped)\n", prefix); - } else - print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, - 8, 4, buf, size, 0); -} -EXPORT_SYMBOL(i2400m_unknown_barker); - - /* * Initialize the RX queue and infrastructure * @@ -1363,6 +1261,4 @@ void i2400m_rx_release(struct i2400m *i2400m) kfree(i2400m->rx_roq[0].log); kfree(i2400m->rx_roq); } - /* at this point, nothing can be received... */ - i2400m_report_hook_flush(i2400m); } diff --git a/trunk/drivers/net/wimax/i2400m/sdio-fw.c b/trunk/drivers/net/wimax/i2400m/sdio-fw.c index 8e025418f5be..7d6ec0f475f8 100644 --- a/trunk/drivers/net/wimax/i2400m/sdio-fw.c +++ b/trunk/drivers/net/wimax/i2400m/sdio-fw.c @@ -118,8 +118,7 @@ ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *i2400m, if (cmd_size > I2400M_BM_CMD_BUF_SIZE) goto error_too_big; - if (_cmd != i2400m->bm_cmd_buf) - memmove(i2400m->bm_cmd_buf, _cmd, cmd_size); + memcpy(i2400m->bm_cmd_buf, _cmd, cmd_size); /* Prep command */ cmd = i2400m->bm_cmd_buf; if (cmd_size_a > cmd_size) /* Zero pad space */ memset(i2400m->bm_cmd_buf + cmd_size, 0, cmd_size_a - cmd_size); @@ -178,6 +177,10 @@ ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *i2400m, d_fnstart(5, dev, "(i2400m %p ack %p size %zu)\n", i2400m, ack, ack_size); + spin_lock(&i2400m->rx_lock); + i2400ms->bm_ack_size = -EINPROGRESS; + spin_unlock(&i2400m->rx_lock); + result = wait_event_timeout(i2400ms->bm_wfa_wq, i2400ms->bm_ack_size != -EINPROGRESS, 2 * HZ); @@ -196,10 +199,6 @@ ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *i2400m, size = min(ack_size, i2400ms->bm_ack_size); memcpy(ack, i2400m->bm_ack_buf, size); } - /* - * Remember always to clear the bm_ack_size to -EINPROGRESS - * after the RX data is processed - */ i2400ms->bm_ack_size = -EINPROGRESS; spin_unlock(&i2400m->rx_lock); diff --git a/trunk/drivers/net/wimax/i2400m/sdio-rx.c b/trunk/drivers/net/wimax/i2400m/sdio-rx.c index 8adf6c9b6f8f..321beadf6e47 100644 --- a/trunk/drivers/net/wimax/i2400m/sdio-rx.c +++ b/trunk/drivers/net/wimax/i2400m/sdio-rx.c @@ -53,7 +53,6 @@ * i2400ms_irq() * i2400ms_rx() * __i2400ms_rx_get_size() - * i2400m_is_boot_barker() * i2400m_rx() * * i2400ms_rx_setup() @@ -139,11 +138,6 @@ void i2400ms_rx(struct i2400ms *i2400ms) ret = rx_size; goto error_get_size; } - /* - * Hardware quirk: make sure to clear the INTR status register - * AFTER getting the data transfer size. - */ - sdio_writeb(func, 1, I2400MS_INTR_CLEAR_ADDR, &ret); ret = -ENOMEM; skb = alloc_skb(rx_size, GFP_ATOMIC); @@ -159,34 +153,25 @@ void i2400ms_rx(struct i2400ms *i2400ms) } rmb(); /* make sure we get boot_mode from dev_reset_handle */ - if (unlikely(i2400m->boot_mode == 1)) { + if (i2400m->boot_mode == 1) { spin_lock(&i2400m->rx_lock); i2400ms->bm_ack_size = rx_size; spin_unlock(&i2400m->rx_lock); memcpy(i2400m->bm_ack_buf, skb->data, rx_size); wake_up(&i2400ms->bm_wfa_wq); - d_printf(5, dev, "RX: SDIO boot mode message\n"); + dev_err(dev, "RX: SDIO boot mode message\n"); kfree_skb(skb); - goto out; - } - ret = -EIO; - if (unlikely(rx_size < sizeof(__le32))) { - dev_err(dev, "HW BUG? only %zu bytes received\n", rx_size); - goto error_bad_size; - } - if (likely(i2400m_is_d2h_barker(skb->data))) { - skb_put(skb, rx_size); - i2400m_rx(i2400m, skb); - } else if (unlikely(i2400m_is_boot_barker(i2400m, - skb->data, rx_size))) { - ret = i2400m_dev_reset_handle(i2400m, "device rebooted"); + } else if (unlikely(!memcmp(skb->data, i2400m_NBOOT_BARKER, + sizeof(i2400m_NBOOT_BARKER)) + || !memcmp(skb->data, i2400m_SBOOT_BARKER, + sizeof(i2400m_SBOOT_BARKER)))) { + ret = i2400m_dev_reset_handle(i2400m); dev_err(dev, "RX: SDIO reboot barker\n"); kfree_skb(skb); } else { - i2400m_unknown_barker(i2400m, skb->data, rx_size); - kfree_skb(skb); + skb_put(skb, rx_size); + i2400m_rx(i2400m, skb); } -out: d_fnend(7, dev, "(i2400ms %p) = void\n", i2400ms); return; @@ -194,7 +179,6 @@ void i2400ms_rx(struct i2400ms *i2400ms) kfree_skb(skb); error_alloc_skb: error_get_size: -error_bad_size: d_fnend(7, dev, "(i2400ms %p) = %d\n", i2400ms, ret); return; } @@ -225,6 +209,7 @@ void i2400ms_irq(struct sdio_func *func) dev_err(dev, "RX: BUG? got IRQ but no interrupt ready?\n"); goto error_no_irq; } + sdio_writeb(func, 1, I2400MS_INTR_CLEAR_ADDR, &ret); i2400ms_rx(i2400ms); error_no_irq: d_fnend(6, dev, "(i2400ms %p) = void\n", i2400ms); @@ -249,13 +234,6 @@ int i2400ms_rx_setup(struct i2400ms *i2400ms) init_waitqueue_head(&i2400ms->bm_wfa_wq); spin_lock(&i2400m->rx_lock); i2400ms->bm_wait_result = -EINPROGRESS; - /* - * Before we are about to enable the RX interrupt, make sure - * bm_ack_size is cleared to -EINPROGRESS which indicates - * no RX interrupt happened yet or the previous interrupt - * has been handled, we are ready to take the new interrupt - */ - i2400ms->bm_ack_size = -EINPROGRESS; spin_unlock(&i2400m->rx_lock); sdio_claim_host(func); diff --git a/trunk/drivers/net/wimax/i2400m/sdio-tx.c b/trunk/drivers/net/wimax/i2400m/sdio-tx.c index de66d068c9cb..5105a5ebc44f 100644 --- a/trunk/drivers/net/wimax/i2400m/sdio-tx.c +++ b/trunk/drivers/net/wimax/i2400m/sdio-tx.c @@ -149,8 +149,5 @@ int i2400ms_tx_setup(struct i2400ms *i2400ms) void i2400ms_tx_release(struct i2400ms *i2400ms) { - if (i2400ms->tx_workqueue) { - destroy_workqueue(i2400ms->tx_workqueue); - i2400ms->tx_workqueue = NULL; - } + destroy_workqueue(i2400ms->tx_workqueue); } diff --git a/trunk/drivers/net/wimax/i2400m/sdio.c b/trunk/drivers/net/wimax/i2400m/sdio.c index 76a50ac02ebb..2981e211e04f 100644 --- a/trunk/drivers/net/wimax/i2400m/sdio.c +++ b/trunk/drivers/net/wimax/i2400m/sdio.c @@ -43,9 +43,18 @@ * i2400m_release() * free_netdev(net_dev) * - * i2400ms_bus_reset() Called by i2400m_reset + * i2400ms_bus_reset() Called by i2400m->bus_reset * __i2400ms_reset() * __i2400ms_send_barker() + * + * i2400ms_bus_dev_start() Called by i2400m_dev_start() [who is + * i2400ms_tx_setup() called by i2400m_setup()] + * i2400ms_rx_setup() + * + * i2400ms_bus_dev_stop() Called by i2400m_dev_stop() [who is + * i2400ms_rx_release() is called by i2400m_release()] + * i2400ms_tx_release() + * */ #include @@ -62,14 +71,6 @@ static int ioe_timeout = 2; module_param(ioe_timeout, int, 0); -static char i2400ms_debug_params[128]; -module_param_string(debug, i2400ms_debug_params, sizeof(i2400ms_debug_params), - 0644); -MODULE_PARM_DESC(debug, - "String of space-separated NAME:VALUE pairs, where NAMEs " - "are the different debug submodules and VALUE are the " - "initial debug value to set."); - /* Our firmware file name list */ static const char *i2400ms_bus_fw_names[] = { #define I2400MS_FW_FILE_NAME "i2400m-fw-sdio-1.3.sbcf" @@ -94,24 +95,17 @@ static const struct i2400m_poke_table i2400ms_pokes[] = { * when we ask it to explicitly doing). Tries until a timeout is * reached. * - * The @maxtries argument indicates how many times (at most) it should - * be tried to enable the function. 0 means forever. This acts along - * with the timeout (ie: it'll stop trying as soon as the maximum - * number of tries is reached _or_ as soon as the timeout is reached). - * * The reverse of this is...sdio_disable_function() * * Returns: 0 if the SDIO function was enabled, < 0 errno code on * error (-ENODEV when it was unable to enable the function). */ static -int i2400ms_enable_function(struct i2400ms *i2400ms, unsigned maxtries) +int i2400ms_enable_function(struct sdio_func *func) { - struct sdio_func *func = i2400ms->func; u64 timeout; int err; struct device *dev = &func->dev; - unsigned tries = 0; d_fnstart(3, dev, "(func %p)\n", func); /* Setup timeout (FIXME: This needs to read the CIS table to @@ -121,14 +115,6 @@ int i2400ms_enable_function(struct i2400ms *i2400ms, unsigned maxtries) err = -ENODEV; while (err != 0 && time_before64(get_jiffies_64(), timeout)) { sdio_claim_host(func); - /* - * There is a sillicon bug on the IWMC3200, where the - * IOE timeout will cause problems on Moorestown - * platforms (system hang). We explicitly overwrite - * func->enable_timeout here to work around the issue. - */ - if (i2400ms->iwmc3200) - func->enable_timeout = IWMC3200_IOR_TIMEOUT; err = sdio_enable_func(func); if (0 == err) { sdio_release_host(func); @@ -136,11 +122,8 @@ int i2400ms_enable_function(struct i2400ms *i2400ms, unsigned maxtries) goto function_enabled; } d_printf(2, dev, "SDIO function failed to enable: %d\n", err); + sdio_disable_func(func); sdio_release_host(func); - if (maxtries > 0 && ++tries >= maxtries) { - err = -ETIME; - break; - } msleep(I2400MS_INIT_SLEEP_INTERVAL); } /* If timed out, device is not there yet -- get -ENODEV so @@ -157,99 +140,46 @@ int i2400ms_enable_function(struct i2400ms *i2400ms, unsigned maxtries) /* - * Setup minimal device communication infrastructure needed to at - * least be able to update the firmware. + * Setup driver resources needed to communicate with the device * - * Note the ugly trick: if we are in the probe path - * (i2400ms->debugfs_dentry == NULL), we only retry function - * enablement one, to avoid racing with the iwmc3200 top controller. + * The fw needs some time to settle, and it was just uploaded, + * so give it a break first. I'd prefer to just wait for the device to + * send something, but seems the poking we do to enable SDIO stuff + * interferes with it, so just give it a break before starting... */ static -int i2400ms_bus_setup(struct i2400m *i2400m) +int i2400ms_bus_dev_start(struct i2400m *i2400m) { int result; - struct i2400ms *i2400ms = - container_of(i2400m, struct i2400ms, i2400m); - struct device *dev = i2400m_dev(i2400m); + struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m); struct sdio_func *func = i2400ms->func; - int retries; - - sdio_claim_host(func); - result = sdio_set_block_size(func, I2400MS_BLK_SIZE); - sdio_release_host(func); - if (result < 0) { - dev_err(dev, "Failed to set block size: %d\n", result); - goto error_set_blk_size; - } - - if (i2400ms->iwmc3200 && i2400ms->debugfs_dentry == NULL) - retries = 1; - else - retries = 0; - result = i2400ms_enable_function(i2400ms, retries); - if (result < 0) { - dev_err(dev, "Cannot enable SDIO function: %d\n", result); - goto error_func_enable; - } + struct device *dev = &func->dev; + d_fnstart(3, dev, "(i2400m %p)\n", i2400m); + msleep(200); result = i2400ms_tx_setup(i2400ms); if (result < 0) goto error_tx_setup; - result = i2400ms_rx_setup(i2400ms); - if (result < 0) - goto error_rx_setup; - return 0; - -error_rx_setup: - i2400ms_tx_release(i2400ms); -error_tx_setup: - sdio_claim_host(func); - sdio_disable_func(func); - sdio_release_host(func); -error_func_enable: -error_set_blk_size: + d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); return result; -} - - -/* - * Tear down minimal device communication infrastructure needed to at - * least be able to update the firmware. - */ -static -void i2400ms_bus_release(struct i2400m *i2400m) -{ - struct i2400ms *i2400ms = - container_of(i2400m, struct i2400ms, i2400m); - struct sdio_func *func = i2400ms->func; - i2400ms_rx_release(i2400ms); +error_tx_setup: i2400ms_tx_release(i2400ms); - sdio_claim_host(func); - sdio_disable_func(func); - sdio_release_host(func); + d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); + return result; } -/* - * Setup driver resources needed to communicate with the device - * - * The fw needs some time to settle, and it was just uploaded, - * so give it a break first. I'd prefer to just wait for the device to - * send something, but seems the poking we do to enable SDIO stuff - * interferes with it, so just give it a break before starting... - */ static -int i2400ms_bus_dev_start(struct i2400m *i2400m) +void i2400ms_bus_dev_stop(struct i2400m *i2400m) { struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m); struct sdio_func *func = i2400ms->func; struct device *dev = &func->dev; d_fnstart(3, dev, "(i2400m %p)\n", i2400m); - msleep(200); - d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, 0); - return 0; + i2400ms_tx_release(i2400ms); + d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); } @@ -303,17 +233,18 @@ int __i2400ms_send_barker(struct i2400ms *i2400ms, * Warm reset: * * The device will be fully reset internally, but won't be - * disconnected from the bus (so no reenumeration will + * disconnected from the USB bus (so no reenumeration will * happen). Firmware upload will be neccessary. * - * The device will send a reboot barker that will trigger the driver - * to reinitialize the state via __i2400m_dev_reset_handle. + * The device will send a reboot barker in the notification endpoint + * that will trigger the driver to reinitialize the state + * automatically from notif.c:i2400m_notification_grok() into + * i2400m_dev_bootstrap_delayed(). * - * - * Cold and bus reset: + * Cold and bus (USB) reset: * * The device will be fully reset internally, disconnected from the - * bus an a reenumeration will happen. Firmware upload will be + * USB bus an a reenumeration will happen. Firmware upload will be * neccessary. Thus, we don't do any locking or struct * reinitialization, as we are going to be fully disconnected and * reenumerated. @@ -352,13 +283,25 @@ int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt) sizeof(i2400m_COLD_BOOT_BARKER)); else if (rt == I2400M_RT_BUS) { do_bus_reset: + /* call netif_tx_disable() before sending IOE disable, + * so that all the tx from network layer are stopped + * while IOE is being reset. Make sure it is called + * only after register_netdev() was issued. + */ + if (i2400m->wimax_dev.net_dev->reg_state == NETREG_REGISTERED) + netif_tx_disable(i2400m->wimax_dev.net_dev); - i2400ms_bus_release(i2400m); + i2400ms_rx_release(i2400ms); + sdio_claim_host(i2400ms->func); + sdio_disable_func(i2400ms->func); + sdio_release_host(i2400ms->func); /* Wait for the device to settle */ msleep(40); - result = i2400ms_bus_setup(i2400m); + result = i2400ms_enable_function(i2400ms->func); + if (result >= 0) + i2400ms_rx_setup(i2400ms); } else BUG(); if (result < 0 && rt != I2400M_RT_BUS) { @@ -407,7 +350,7 @@ int i2400ms_debugfs_add(struct i2400ms *i2400ms) int result; struct dentry *dentry = i2400ms->i2400m.wimax_dev.debugfs_dentry; - dentry = debugfs_create_dir("i2400m-sdio", dentry); + dentry = debugfs_create_dir("i2400m-usb", dentry); result = PTR_ERR(dentry); if (IS_ERR(dentry)) { if (result == -ENODEV) @@ -424,7 +367,6 @@ int i2400ms_debugfs_add(struct i2400ms *i2400ms) error: debugfs_remove_recursive(i2400ms->debugfs_dentry); - i2400ms->debugfs_dentry = NULL; return result; } @@ -483,30 +425,37 @@ int i2400ms_probe(struct sdio_func *func, i2400m->bus_tx_block_size = I2400MS_BLK_SIZE; i2400m->bus_pl_size_max = I2400MS_PL_SIZE_MAX; - i2400m->bus_setup = i2400ms_bus_setup; i2400m->bus_dev_start = i2400ms_bus_dev_start; - i2400m->bus_dev_stop = NULL; - i2400m->bus_release = i2400ms_bus_release; + i2400m->bus_dev_stop = i2400ms_bus_dev_stop; i2400m->bus_tx_kick = i2400ms_bus_tx_kick; i2400m->bus_reset = i2400ms_bus_reset; /* The iwmc3200-wimax sometimes requires the driver to try * hard when we paint it into a corner. */ - i2400m->bus_bm_retries = I2400M_SDIO_BOOT_RETRIES; + i2400m->bus_bm_retries = I3200_BOOT_RETRIES; i2400m->bus_bm_cmd_send = i2400ms_bus_bm_cmd_send; i2400m->bus_bm_wait_for_ack = i2400ms_bus_bm_wait_for_ack; i2400m->bus_fw_names = i2400ms_bus_fw_names; i2400m->bus_bm_mac_addr_impaired = 1; i2400m->bus_bm_pokes_table = &i2400ms_pokes[0]; - switch (func->device) { - case SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX: - case SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX_2G5: - i2400ms->iwmc3200 = 1; - break; - default: - i2400ms->iwmc3200 = 0; + sdio_claim_host(func); + result = sdio_set_block_size(func, I2400MS_BLK_SIZE); + sdio_release_host(func); + if (result < 0) { + dev_err(dev, "Failed to set block size: %d\n", result); + goto error_set_blk_size; + } + + result = i2400ms_enable_function(i2400ms->func); + if (result < 0) { + dev_err(dev, "Cannot enable SDIO function: %d\n", result); + goto error_func_enable; } + result = i2400ms_rx_setup(i2400ms); + if (result < 0) + goto error_rx_setup; + result = i2400m_setup(i2400m, I2400M_BRI_NO_REBOOT); if (result < 0) { dev_err(dev, "cannot setup device: %d\n", result); @@ -524,6 +473,13 @@ int i2400ms_probe(struct sdio_func *func, error_debugfs_add: i2400m_release(i2400m); error_setup: + i2400ms_rx_release(i2400ms); +error_rx_setup: + sdio_claim_host(func); + sdio_disable_func(func); + sdio_release_host(func); +error_func_enable: +error_set_blk_size: sdio_set_drvdata(func, NULL); free_netdev(net_dev); error_alloc_netdev: @@ -541,9 +497,12 @@ void i2400ms_remove(struct sdio_func *func) d_fnstart(3, dev, "SDIO func %p\n", func); debugfs_remove_recursive(i2400ms->debugfs_dentry); - i2400ms->debugfs_dentry = NULL; + i2400ms_rx_release(i2400ms); i2400m_release(i2400m); sdio_set_drvdata(func, NULL); + sdio_claim_host(func); + sdio_disable_func(func); + sdio_release_host(func); free_netdev(net_dev); d_fnend(3, dev, "SDIO func %p\n", func); } @@ -553,8 +512,6 @@ const struct sdio_device_id i2400ms_sdio_ids[] = { /* Intel: i2400m WiMAX (iwmc3200) over SDIO */ { SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, - SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX_2G5) }, { /* end: all zeroes */ }, }; MODULE_DEVICE_TABLE(sdio, i2400ms_sdio_ids); @@ -572,8 +529,6 @@ struct sdio_driver i2400m_sdio_driver = { static int __init i2400ms_driver_init(void) { - d_parse_params(D_LEVEL, D_LEVEL_SIZE, i2400ms_debug_params, - "i2400m_sdio.debug"); return sdio_register_driver(&i2400m_sdio_driver); } module_init(i2400ms_driver_init); diff --git a/trunk/drivers/net/wimax/i2400m/tx.c b/trunk/drivers/net/wimax/i2400m/tx.c index 54480e8947f1..fa16ccf8e26a 100644 --- a/trunk/drivers/net/wimax/i2400m/tx.c +++ b/trunk/drivers/net/wimax/i2400m/tx.c @@ -310,7 +310,7 @@ size_t __i2400m_tx_tail_room(struct i2400m *i2400m) size_t tail_room; size_t tx_in; - if (unlikely(i2400m->tx_in == 0)) + if (unlikely(i2400m->tx_in) == 0) return I2400M_TX_BUF_SIZE; tx_in = i2400m->tx_in % I2400M_TX_BUF_SIZE; tail_room = I2400M_TX_BUF_SIZE - tx_in; @@ -642,9 +642,6 @@ int i2400m_tx(struct i2400m *i2400m, const void *buf, size_t buf_len, * current one is out of payload slots or we have a singleton, * close it and start a new one */ spin_lock_irqsave(&i2400m->tx_lock, flags); - result = -ESHUTDOWN; - if (i2400m->tx_buf == NULL) - goto error_tx_new; try_new: if (unlikely(i2400m->tx_msg == NULL)) i2400m_tx_new(i2400m); @@ -700,10 +697,7 @@ int i2400m_tx(struct i2400m *i2400m, const void *buf, size_t buf_len, } error_tx_new: spin_unlock_irqrestore(&i2400m->tx_lock, flags); - /* kick in most cases, except when the TX subsys is down, as - * it might free space */ - if (likely(result != -ESHUTDOWN)) - i2400m->bus_tx_kick(i2400m); + i2400m->bus_tx_kick(i2400m); /* always kick, might free up space */ d_fnend(3, dev, "(i2400m %p skb %p [%zu bytes] pt %u) = %d\n", i2400m, buf, buf_len, pl_type, result); return result; @@ -746,9 +740,6 @@ struct i2400m_msg_hdr *i2400m_tx_msg_get(struct i2400m *i2400m, d_fnstart(3, dev, "(i2400m %p bus_size %p)\n", i2400m, bus_size); spin_lock_irqsave(&i2400m->tx_lock, flags); - tx_msg_moved = NULL; - if (i2400m->tx_buf == NULL) - goto out_unlock; skip: tx_msg_moved = NULL; if (i2400m->tx_in == i2400m->tx_out) { /* Empty FIFO? */ @@ -838,8 +829,6 @@ void i2400m_tx_msg_sent(struct i2400m *i2400m) d_fnstart(3, dev, "(i2400m %p)\n", i2400m); spin_lock_irqsave(&i2400m->tx_lock, flags); - if (i2400m->tx_buf == NULL) - goto out_unlock; i2400m->tx_out += i2400m->tx_msg_size; d_printf(2, dev, "TX: sent %zu b\n", (size_t) i2400m->tx_msg_size); i2400m->tx_msg_size = 0; @@ -848,7 +837,6 @@ void i2400m_tx_msg_sent(struct i2400m *i2400m) n = i2400m->tx_out / I2400M_TX_BUF_SIZE; i2400m->tx_out %= I2400M_TX_BUF_SIZE; i2400m->tx_in -= n * I2400M_TX_BUF_SIZE; -out_unlock: spin_unlock_irqrestore(&i2400m->tx_lock, flags); d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); } @@ -888,9 +876,5 @@ int i2400m_tx_setup(struct i2400m *i2400m) */ void i2400m_tx_release(struct i2400m *i2400m) { - unsigned long flags; - spin_lock_irqsave(&i2400m->tx_lock, flags); kfree(i2400m->tx_buf); - i2400m->tx_buf = NULL; - spin_unlock_irqrestore(&i2400m->tx_lock, flags); } diff --git a/trunk/drivers/net/wimax/i2400m/usb-fw.c b/trunk/drivers/net/wimax/i2400m/usb-fw.c index ce6b9938fde0..5ad287c228b8 100644 --- a/trunk/drivers/net/wimax/i2400m/usb-fw.c +++ b/trunk/drivers/net/wimax/i2400m/usb-fw.c @@ -99,10 +99,10 @@ ssize_t i2400mu_tx_bulk_out(struct i2400mu *i2400mu, void *buf, size_t buf_size) dev_err(dev, "BM-CMD: can't get autopm: %d\n", result); do_autopm = 0; } - epd = usb_get_epd(i2400mu->usb_iface, i2400mu->endpoint_cfg.bulk_out); + epd = usb_get_epd(i2400mu->usb_iface, I2400MU_EP_BULK_OUT); pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress); retry: - result = usb_bulk_msg(i2400mu->usb_dev, pipe, buf, buf_size, &len, 200); + result = usb_bulk_msg(i2400mu->usb_dev, pipe, buf, buf_size, &len, HZ); switch (result) { case 0: if (len != buf_size) { @@ -113,28 +113,6 @@ ssize_t i2400mu_tx_bulk_out(struct i2400mu *i2400mu, void *buf, size_t buf_size) } result = len; break; - case -EPIPE: - /* - * Stall -- maybe the device is choking with our - * requests. Clear it and give it some time. If they - * happen to often, it might be another symptom, so we - * reset. - * - * No error handling for usb_clear_halt(0; if it - * works, the retry works; if it fails, this switch - * does the error handling for us. - */ - if (edc_inc(&i2400mu->urb_edc, - 10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { - dev_err(dev, "BM-CMD: too many stalls in " - "URB; resetting device\n"); - usb_queue_reset_device(i2400mu->usb_iface); - /* fallthrough */ - } else { - usb_clear_halt(i2400mu->usb_dev, pipe); - msleep(10); /* give the device some time */ - goto retry; - } case -EINVAL: /* while removing driver */ case -ENODEV: /* dev disconnect ... */ case -ENOENT: /* just ignore it */ @@ -157,6 +135,7 @@ ssize_t i2400mu_tx_bulk_out(struct i2400mu *i2400mu, void *buf, size_t buf_size) result); goto retry; } + result = len; if (do_autopm) usb_autopm_put_interface(i2400mu->usb_iface); return result; @@ -193,8 +172,7 @@ ssize_t i2400mu_bus_bm_cmd_send(struct i2400m *i2400m, result = -E2BIG; if (cmd_size > I2400M_BM_CMD_BUF_SIZE) goto error_too_big; - if (_cmd != i2400m->bm_cmd_buf) - memmove(i2400m->bm_cmd_buf, _cmd, cmd_size); + memcpy(i2400m->bm_cmd_buf, _cmd, cmd_size); cmd = i2400m->bm_cmd_buf; if (cmd_size_a > cmd_size) /* Zero pad space */ memset(i2400m->bm_cmd_buf + cmd_size, 0, cmd_size_a - cmd_size); @@ -248,8 +226,7 @@ int i2400mu_notif_submit(struct i2400mu *i2400mu, struct urb *urb, struct usb_endpoint_descriptor *epd; int pipe; - epd = usb_get_epd(i2400mu->usb_iface, - i2400mu->endpoint_cfg.notification); + epd = usb_get_epd(i2400mu->usb_iface, I2400MU_EP_NOTIFICATION); pipe = usb_rcvintpipe(i2400mu->usb_dev, epd->bEndpointAddress); usb_fill_int_urb(urb, i2400mu->usb_dev, pipe, i2400m->bm_ack_buf, I2400M_BM_ACK_BUF_SIZE, @@ -351,8 +328,8 @@ ssize_t i2400mu_bus_bm_wait_for_ack(struct i2400m *i2400m, out: if (do_autopm) usb_autopm_put_interface(i2400mu->usb_iface); - d_fnend(8, dev, "(i2400m %p ack %p size %zu) = %ld\n", - i2400m, ack, ack_size, (long) result); + d_fnend(8, dev, "(i2400m %p ack %p size %zu) = %zd\n", + i2400m, ack, ack_size, result); return result; error_exceeded: diff --git a/trunk/drivers/net/wimax/i2400m/usb-notif.c b/trunk/drivers/net/wimax/i2400m/usb-notif.c index f88d1c6e35cb..6add27c3f35c 100644 --- a/trunk/drivers/net/wimax/i2400m/usb-notif.c +++ b/trunk/drivers/net/wimax/i2400m/usb-notif.c @@ -51,7 +51,6 @@ * * i2400mu_usb_notification_cb() Called when a URB is ready * i2400mu_notif_grok() - * i2400m_is_boot_barker() * i2400m_dev_reset_handle() * i2400mu_rx_kick() */ @@ -88,21 +87,32 @@ int i2400mu_notification_grok(struct i2400mu *i2400mu, const void *buf, d_fnstart(4, dev, "(i2400m %p buf %p buf_len %zu)\n", i2400mu, buf, buf_len); ret = -EIO; - if (buf_len < sizeof(i2400m_ZERO_BARKER)) + if (buf_len < sizeof(i2400m_NBOOT_BARKER)) /* Not a bug, just ignore */ goto error_bad_size; - ret = 0; - if (!memcmp(i2400m_ZERO_BARKER, buf, sizeof(i2400m_ZERO_BARKER))) { + if (!memcmp(i2400m_NBOOT_BARKER, buf, sizeof(i2400m_NBOOT_BARKER)) + || !memcmp(i2400m_SBOOT_BARKER, buf, sizeof(i2400m_SBOOT_BARKER))) + ret = i2400m_dev_reset_handle(i2400m); + else if (!memcmp(i2400m_ZERO_BARKER, buf, sizeof(i2400m_ZERO_BARKER))) { i2400mu_rx_kick(i2400mu); - goto out; + ret = 0; + } else { /* Unknown or unexpected data in the notif message */ + char prefix[64]; + ret = -EIO; + dev_err(dev, "HW BUG? Unknown/unexpected data in notification " + "message (%zu bytes)\n", buf_len); + snprintf(prefix, sizeof(prefix), "%s %s: ", + dev_driver_string(dev), dev_name(dev)); + if (buf_len > 64) { + print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, + 8, 4, buf, 64, 0); + printk(KERN_ERR "%s... (only first 64 bytes " + "dumped)\n", prefix); + } else + print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, + 8, 4, buf, buf_len, 0); } - ret = i2400m_is_boot_barker(i2400m, buf, buf_len); - if (unlikely(ret >= 0)) - ret = i2400m_dev_reset_handle(i2400m, "device rebooted"); - else /* Unknown or unexpected data in the notif message */ - i2400m_unknown_barker(i2400m, buf, buf_len); error_bad_size: -out: d_fnend(4, dev, "(i2400m %p buf %p buf_len %zu) = %d\n", i2400mu, buf, buf_len, ret); return ret; @@ -210,8 +220,7 @@ int i2400mu_notification_setup(struct i2400mu *i2400mu) dev_err(dev, "notification: cannot allocate URB\n"); goto error_alloc_urb; } - epd = usb_get_epd(i2400mu->usb_iface, - i2400mu->endpoint_cfg.notification); + epd = usb_get_epd(i2400mu->usb_iface, I2400MU_EP_NOTIFICATION); usb_pipe = usb_rcvintpipe(i2400mu->usb_dev, epd->bEndpointAddress); usb_fill_int_urb(i2400mu->notif_urb, i2400mu->usb_dev, usb_pipe, buf, I2400MU_MAX_NOTIFICATION_LEN, diff --git a/trunk/drivers/net/wimax/i2400m/usb-rx.c b/trunk/drivers/net/wimax/i2400m/usb-rx.c index ba1b02362dfc..a314799967cf 100644 --- a/trunk/drivers/net/wimax/i2400m/usb-rx.c +++ b/trunk/drivers/net/wimax/i2400m/usb-rx.c @@ -204,7 +204,7 @@ struct sk_buff *i2400mu_rx(struct i2400mu *i2400mu, struct sk_buff *rx_skb) dev_err(dev, "RX: can't get autopm: %d\n", result); do_autopm = 0; } - epd = usb_get_epd(i2400mu->usb_iface, i2400mu->endpoint_cfg.bulk_in); + epd = usb_get_epd(i2400mu->usb_iface, I2400MU_EP_BULK_IN); usb_pipe = usb_rcvbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress); retry: rx_size = skb_end_pointer(rx_skb) - rx_skb->data - rx_skb->len; @@ -214,7 +214,7 @@ struct sk_buff *i2400mu_rx(struct i2400mu *i2400mu, struct sk_buff *rx_skb) } result = usb_bulk_msg( i2400mu->usb_dev, usb_pipe, rx_skb->data + rx_skb->len, - rx_size, &read_size, 200); + rx_size, &read_size, HZ); usb_mark_last_busy(i2400mu->usb_dev); switch (result) { case 0: @@ -222,26 +222,6 @@ struct sk_buff *i2400mu_rx(struct i2400mu *i2400mu, struct sk_buff *rx_skb) goto retry; /* ZLP, just resubmit */ skb_put(rx_skb, read_size); break; - case -EPIPE: - /* - * Stall -- maybe the device is choking with our - * requests. Clear it and give it some time. If they - * happen to often, it might be another symptom, so we - * reset. - * - * No error handling for usb_clear_halt(0; if it - * works, the retry works; if it fails, this switch - * does the error handling for us. - */ - if (edc_inc(&i2400mu->urb_edc, - 10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { - dev_err(dev, "BM-CMD: too many stalls in " - "URB; resetting device\n"); - goto do_reset; - } - usb_clear_halt(i2400mu->usb_dev, usb_pipe); - msleep(10); /* give the device some time */ - goto retry; case -EINVAL: /* while removing driver */ case -ENODEV: /* dev disconnect ... */ case -ENOENT: /* just ignore it */ @@ -303,7 +283,6 @@ struct sk_buff *i2400mu_rx(struct i2400mu *i2400mu, struct sk_buff *rx_skb) error_reset: dev_err(dev, "RX: maximum errors in URB exceeded; " "resetting device\n"); -do_reset: usb_queue_reset_device(i2400mu->usb_iface); rx_skb = ERR_PTR(result); goto out; @@ -337,15 +316,10 @@ int i2400mu_rxd(void *_i2400mu) size_t pending; int rx_size; struct sk_buff *rx_skb; - unsigned long flags; d_fnstart(4, dev, "(i2400mu %p)\n", i2400mu); - spin_lock_irqsave(&i2400m->rx_lock, flags); - BUG_ON(i2400mu->rx_kthread != NULL); - i2400mu->rx_kthread = current; - spin_unlock_irqrestore(&i2400m->rx_lock, flags); while (1) { - d_printf(2, dev, "RX: waiting for messages\n"); + d_printf(2, dev, "TX: waiting for messages\n"); pending = 0; wait_event_interruptible( i2400mu->rx_wq, @@ -393,9 +367,6 @@ int i2400mu_rxd(void *_i2400mu) } result = 0; out: - spin_lock_irqsave(&i2400m->rx_lock, flags); - i2400mu->rx_kthread = NULL; - spin_unlock_irqrestore(&i2400m->rx_lock, flags); d_fnend(4, dev, "(i2400mu %p) = %d\n", i2400mu, result); return result; @@ -432,33 +403,18 @@ int i2400mu_rx_setup(struct i2400mu *i2400mu) struct i2400m *i2400m = &i2400mu->i2400m; struct device *dev = &i2400mu->usb_iface->dev; struct wimax_dev *wimax_dev = &i2400m->wimax_dev; - struct task_struct *kthread; - kthread = kthread_run(i2400mu_rxd, i2400mu, "%s-rx", - wimax_dev->name); - /* the kthread function sets i2400mu->rx_thread */ - if (IS_ERR(kthread)) { - result = PTR_ERR(kthread); + i2400mu->rx_kthread = kthread_run(i2400mu_rxd, i2400mu, "%s-rx", + wimax_dev->name); + if (IS_ERR(i2400mu->rx_kthread)) { + result = PTR_ERR(i2400mu->rx_kthread); dev_err(dev, "RX: cannot start thread: %d\n", result); } return result; } - void i2400mu_rx_release(struct i2400mu *i2400mu) { - unsigned long flags; - struct i2400m *i2400m = &i2400mu->i2400m; - struct device *dev = i2400m_dev(i2400m); - struct task_struct *kthread; - - spin_lock_irqsave(&i2400m->rx_lock, flags); - kthread = i2400mu->rx_kthread; - i2400mu->rx_kthread = NULL; - spin_unlock_irqrestore(&i2400m->rx_lock, flags); - if (kthread) - kthread_stop(kthread); - else - d_printf(1, dev, "RX: kthread had already exited\n"); + kthread_stop(i2400mu->rx_kthread); } diff --git a/trunk/drivers/net/wimax/i2400m/usb-tx.c b/trunk/drivers/net/wimax/i2400m/usb-tx.c index c65b9979f87e..dfd893356f49 100644 --- a/trunk/drivers/net/wimax/i2400m/usb-tx.c +++ b/trunk/drivers/net/wimax/i2400m/usb-tx.c @@ -101,11 +101,11 @@ int i2400mu_tx(struct i2400mu *i2400mu, struct i2400m_msg_hdr *tx_msg, dev_err(dev, "TX: can't get autopm: %d\n", result); do_autopm = 0; } - epd = usb_get_epd(i2400mu->usb_iface, i2400mu->endpoint_cfg.bulk_out); + epd = usb_get_epd(i2400mu->usb_iface, I2400MU_EP_BULK_OUT); usb_pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress); retry: result = usb_bulk_msg(i2400mu->usb_dev, usb_pipe, - tx_msg, tx_msg_size, &sent_size, 200); + tx_msg, tx_msg_size, &sent_size, HZ); usb_mark_last_busy(i2400mu->usb_dev); switch (result) { case 0: @@ -115,28 +115,6 @@ int i2400mu_tx(struct i2400mu *i2400mu, struct i2400m_msg_hdr *tx_msg, result = -EIO; } break; - case -EPIPE: - /* - * Stall -- maybe the device is choking with our - * requests. Clear it and give it some time. If they - * happen to often, it might be another symptom, so we - * reset. - * - * No error handling for usb_clear_halt(0; if it - * works, the retry works; if it fails, this switch - * does the error handling for us. - */ - if (edc_inc(&i2400mu->urb_edc, - 10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { - dev_err(dev, "BM-CMD: too many stalls in " - "URB; resetting device\n"); - usb_queue_reset_device(i2400mu->usb_iface); - /* fallthrough */ - } else { - usb_clear_halt(i2400mu->usb_dev, usb_pipe); - msleep(10); /* give the device some time */ - goto retry; - } case -EINVAL: /* while removing driver */ case -ENODEV: /* dev disconnect ... */ case -ENOENT: /* just ignore it */ @@ -183,15 +161,9 @@ int i2400mu_txd(void *_i2400mu) struct device *dev = &i2400mu->usb_iface->dev; struct i2400m_msg_hdr *tx_msg; size_t tx_msg_size; - unsigned long flags; d_fnstart(4, dev, "(i2400mu %p)\n", i2400mu); - spin_lock_irqsave(&i2400m->tx_lock, flags); - BUG_ON(i2400mu->tx_kthread != NULL); - i2400mu->tx_kthread = current; - spin_unlock_irqrestore(&i2400m->tx_lock, flags); - while (1) { d_printf(2, dev, "TX: waiting for messages\n"); tx_msg = NULL; @@ -211,11 +183,6 @@ int i2400mu_txd(void *_i2400mu) if (result < 0) break; } - - spin_lock_irqsave(&i2400m->tx_lock, flags); - i2400mu->tx_kthread = NULL; - spin_unlock_irqrestore(&i2400m->tx_lock, flags); - d_fnend(4, dev, "(i2400mu %p) = %d\n", i2400mu, result); return result; } @@ -246,13 +213,11 @@ int i2400mu_tx_setup(struct i2400mu *i2400mu) struct i2400m *i2400m = &i2400mu->i2400m; struct device *dev = &i2400mu->usb_iface->dev; struct wimax_dev *wimax_dev = &i2400m->wimax_dev; - struct task_struct *kthread; - kthread = kthread_run(i2400mu_txd, i2400mu, "%s-tx", - wimax_dev->name); - /* the kthread function sets i2400mu->tx_thread */ - if (IS_ERR(kthread)) { - result = PTR_ERR(kthread); + i2400mu->tx_kthread = kthread_run(i2400mu_txd, i2400mu, "%s-tx", + wimax_dev->name); + if (IS_ERR(i2400mu->tx_kthread)) { + result = PTR_ERR(i2400mu->tx_kthread); dev_err(dev, "TX: cannot start thread: %d\n", result); } return result; @@ -260,17 +225,5 @@ int i2400mu_tx_setup(struct i2400mu *i2400mu) void i2400mu_tx_release(struct i2400mu *i2400mu) { - unsigned long flags; - struct i2400m *i2400m = &i2400mu->i2400m; - struct device *dev = i2400m_dev(i2400m); - struct task_struct *kthread; - - spin_lock_irqsave(&i2400m->tx_lock, flags); - kthread = i2400mu->tx_kthread; - i2400mu->tx_kthread = NULL; - spin_unlock_irqrestore(&i2400m->tx_lock, flags); - if (kthread) - kthread_stop(kthread); - else - d_printf(1, dev, "TX: kthread had already exited\n"); + kthread_stop(i2400mu->tx_kthread); } diff --git a/trunk/drivers/net/wimax/i2400m/usb.c b/trunk/drivers/net/wimax/i2400m/usb.c index 47e84ef355c5..7eadd11c815b 100644 --- a/trunk/drivers/net/wimax/i2400m/usb.c +++ b/trunk/drivers/net/wimax/i2400m/usb.c @@ -58,7 +58,7 @@ * i2400mu_rx_release() * i2400mu_tx_release() * - * i2400mu_bus_reset() Called by i2400m_reset + * i2400mu_bus_reset() Called by i2400m->bus_reset * __i2400mu_reset() * __i2400mu_send_barker() * usb_reset_device() @@ -71,25 +71,13 @@ #define D_SUBMODULE usb #include "usb-debug-levels.h" -static char i2400mu_debug_params[128]; -module_param_string(debug, i2400mu_debug_params, sizeof(i2400mu_debug_params), - 0644); -MODULE_PARM_DESC(debug, - "String of space-separated NAME:VALUE pairs, where NAMEs " - "are the different debug submodules and VALUE are the " - "initial debug value to set."); /* Our firmware file name */ -static const char *i2400mu_bus_fw_names_5x50[] = { +static const char *i2400mu_bus_fw_names[] = { #define I2400MU_FW_FILE_NAME_v1_4 "i2400m-fw-usb-1.4.sbcf" I2400MU_FW_FILE_NAME_v1_4, - NULL, -}; - - -static const char *i2400mu_bus_fw_names_6050[] = { -#define I6050U_FW_FILE_NAME_v1_5 "i6050-fw-usb-1.5.sbcf" - I6050U_FW_FILE_NAME_v1_5, +#define I2400MU_FW_FILE_NAME_v1_3 "i2400m-fw-usb-1.3.sbcf" + I2400MU_FW_FILE_NAME_v1_3, NULL, }; @@ -172,59 +160,14 @@ int __i2400mu_send_barker(struct i2400mu *i2400mu, epd = usb_get_epd(i2400mu->usb_iface, endpoint); pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress); memcpy(buffer, barker, barker_size); -retry: ret = usb_bulk_msg(i2400mu->usb_dev, pipe, buffer, barker_size, - &actual_len, 200); - switch (ret) { - case 0: - if (actual_len != barker_size) { /* Too short? drop it */ - dev_err(dev, "E: %s: short write (%d B vs %zu " - "expected)\n", - __func__, actual_len, barker_size); - ret = -EIO; - } - break; - case -EPIPE: - /* - * Stall -- maybe the device is choking with our - * requests. Clear it and give it some time. If they - * happen to often, it might be another symptom, so we - * reset. - * - * No error handling for usb_clear_halt(0; if it - * works, the retry works; if it fails, this switch - * does the error handling for us. - */ - if (edc_inc(&i2400mu->urb_edc, - 10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { - dev_err(dev, "E: %s: too many stalls in " - "URB; resetting device\n", __func__); - usb_queue_reset_device(i2400mu->usb_iface); - /* fallthrough */ - } else { - usb_clear_halt(i2400mu->usb_dev, pipe); - msleep(10); /* give the device some time */ - goto retry; - } - case -EINVAL: /* while removing driver */ - case -ENODEV: /* dev disconnect ... */ - case -ENOENT: /* just ignore it */ - case -ESHUTDOWN: /* and exit */ - case -ECONNRESET: - ret = -ESHUTDOWN; - break; - default: /* Some error? */ - if (edc_inc(&i2400mu->urb_edc, - EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { - dev_err(dev, "E: %s: maximum errors in URB " - "exceeded; resetting device\n", - __func__); - usb_queue_reset_device(i2400mu->usb_iface); - } else { - dev_warn(dev, "W: %s: cannot send URB: %d\n", - __func__, ret); - goto retry; - } + &actual_len, HZ); + if (ret < 0) { + if (ret != -EINVAL) + dev_err(dev, "E: barker error: %d\n", ret); + } else if (actual_len != barker_size) { + dev_err(dev, "E: only %d bytes transmitted\n", actual_len); + ret = -EIO; } kfree(buffer); error_kzalloc: @@ -289,16 +232,15 @@ int i2400mu_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt) d_fnstart(3, dev, "(i2400m %p rt %u)\n", i2400m, rt); if (rt == I2400M_RT_WARM) - result = __i2400mu_send_barker( - i2400mu, i2400m_WARM_BOOT_BARKER, - sizeof(i2400m_WARM_BOOT_BARKER), - i2400mu->endpoint_cfg.bulk_out); + result = __i2400mu_send_barker(i2400mu, i2400m_WARM_BOOT_BARKER, + sizeof(i2400m_WARM_BOOT_BARKER), + I2400MU_EP_BULK_OUT); else if (rt == I2400M_RT_COLD) - result = __i2400mu_send_barker( - i2400mu, i2400m_COLD_BOOT_BARKER, - sizeof(i2400m_COLD_BOOT_BARKER), - i2400mu->endpoint_cfg.reset_cold); + result = __i2400mu_send_barker(i2400mu, i2400m_COLD_BOOT_BARKER, + sizeof(i2400m_COLD_BOOT_BARKER), + I2400MU_EP_RESET_COLD); else if (rt == I2400M_RT_BUS) { +do_bus_reset: result = usb_reset_device(i2400mu->usb_dev); switch (result) { case 0: @@ -306,7 +248,7 @@ int i2400mu_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt) case -ENODEV: case -ENOENT: case -ESHUTDOWN: - result = 0; + result = rt == I2400M_RT_WARM ? -ENODEV : 0; break; /* We assume the device is disconnected */ default: dev_err(dev, "USB reset failed (%d), giving up!\n", @@ -319,17 +261,10 @@ int i2400mu_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt) if (result < 0 && result != -EINVAL /* device is gone */ && rt != I2400M_RT_BUS) { - /* - * Things failed -- resort to lower level reset, that - * we queue in another context; the reason for this is - * that the pre and post reset functionality requires - * the i2400m->init_mutex; RT_WARM and RT_COLD can - * come from areas where i2400m->init_mutex is taken. - */ dev_err(dev, "%s reset failed (%d); trying USB reset\n", rt == I2400M_RT_WARM ? "warm" : "cold", result); - usb_queue_reset_device(i2400mu->usb_iface); - result = -ENODEV; + rt = I2400M_RT_BUS; + goto do_bus_reset; } d_fnend(3, dev, "(i2400m %p rt %u) = %d\n", i2400m, rt, result); return result; @@ -467,33 +402,20 @@ int i2400mu_probe(struct usb_interface *iface, i2400m->bus_tx_block_size = I2400MU_BLK_SIZE; i2400m->bus_pl_size_max = I2400MU_PL_SIZE_MAX; - i2400m->bus_setup = NULL; i2400m->bus_dev_start = i2400mu_bus_dev_start; i2400m->bus_dev_stop = i2400mu_bus_dev_stop; - i2400m->bus_release = NULL; i2400m->bus_tx_kick = i2400mu_bus_tx_kick; i2400m->bus_reset = i2400mu_bus_reset; - i2400m->bus_bm_retries = I2400M_USB_BOOT_RETRIES; + i2400m->bus_bm_retries = I2400M_BOOT_RETRIES; i2400m->bus_bm_cmd_send = i2400mu_bus_bm_cmd_send; i2400m->bus_bm_wait_for_ack = i2400mu_bus_bm_wait_for_ack; + i2400m->bus_fw_names = i2400mu_bus_fw_names; i2400m->bus_bm_mac_addr_impaired = 0; - if (id->idProduct == USB_DEVICE_ID_I6050) { - i2400m->bus_fw_names = i2400mu_bus_fw_names_6050; - i2400mu->endpoint_cfg.bulk_out = 0; - i2400mu->endpoint_cfg.notification = 3; - i2400mu->endpoint_cfg.reset_cold = 2; - i2400mu->endpoint_cfg.bulk_in = 1; - } else { - i2400m->bus_fw_names = i2400mu_bus_fw_names_5x50; - i2400mu->endpoint_cfg.bulk_out = 0; - i2400mu->endpoint_cfg.notification = 1; - i2400mu->endpoint_cfg.reset_cold = 2; - i2400mu->endpoint_cfg.bulk_in = 3; - } #ifdef CONFIG_PM iface->needs_remote_wakeup = 1; /* autosuspend (15s delay) */ device_init_wakeup(dev, 1); + usb_autopm_enable(i2400mu->usb_iface); usb_dev->autosuspend_delay = 15 * HZ; usb_dev->autosuspend_disabled = 0; #endif @@ -561,10 +483,7 @@ void i2400mu_disconnect(struct usb_interface *iface) * So at the end, the three cases require common handling. * * If at the time of this call the device's firmware is not loaded, - * nothing has to be done. Note we can be "loose" about not reading - * i2400m->updown under i2400m->init_mutex. If it happens to change - * inmediately, other parts of the call flow will fail and effectively - * catch it. + * nothing has to be done. * * If the firmware is loaded, we need to: * @@ -603,7 +522,6 @@ int i2400mu_suspend(struct usb_interface *iface, pm_message_t pm_msg) #endif d_fnstart(3, dev, "(iface %p pm_msg %u)\n", iface, pm_msg.event); - rmb(); /* see i2400m->updown's documentation */ if (i2400m->updown == 0) goto no_firmware; if (i2400m->state == I2400M_SS_DATA_PATH_CONNECTED && is_autosuspend) { @@ -657,7 +575,6 @@ int i2400mu_resume(struct usb_interface *iface) struct i2400m *i2400m = &i2400mu->i2400m; d_fnstart(3, dev, "(iface %p)\n", iface); - rmb(); /* see i2400m->updown's documentation */ if (i2400m->updown == 0) { d_printf(1, dev, "fw was down, no resume neeed\n"); goto out; @@ -673,55 +590,8 @@ int i2400mu_resume(struct usb_interface *iface) } -static -int i2400mu_reset_resume(struct usb_interface *iface) -{ - int result; - struct device *dev = &iface->dev; - struct i2400mu *i2400mu = usb_get_intfdata(iface); - struct i2400m *i2400m = &i2400mu->i2400m; - - d_fnstart(3, dev, "(iface %p)\n", iface); - result = i2400m_dev_reset_handle(i2400m, "device reset on resume"); - d_fnend(3, dev, "(iface %p) = %d\n", iface, result); - return result < 0 ? result : 0; -} - - -/* - * Another driver or user space is triggering a reset on the device - * which contains the interface passed as an argument. Cease IO and - * save any device state you need to restore. - * - * If you need to allocate memory here, use GFP_NOIO or GFP_ATOMIC, if - * you are in atomic context. - */ -static -int i2400mu_pre_reset(struct usb_interface *iface) -{ - struct i2400mu *i2400mu = usb_get_intfdata(iface); - return i2400m_pre_reset(&i2400mu->i2400m); -} - - -/* - * The reset has completed. Restore any saved device state and begin - * using the device again. - * - * If you need to allocate memory here, use GFP_NOIO or GFP_ATOMIC, if - * you are in atomic context. - */ -static -int i2400mu_post_reset(struct usb_interface *iface) -{ - struct i2400mu *i2400mu = usb_get_intfdata(iface); - return i2400m_post_reset(&i2400mu->i2400m); -} - - static struct usb_device_id i2400mu_id_table[] = { - { USB_DEVICE(0x8086, USB_DEVICE_ID_I6050) }, { USB_DEVICE(0x8086, 0x0181) }, { USB_DEVICE(0x8086, 0x1403) }, { USB_DEVICE(0x8086, 0x1405) }, @@ -739,11 +609,8 @@ struct usb_driver i2400mu_driver = { .name = KBUILD_MODNAME, .suspend = i2400mu_suspend, .resume = i2400mu_resume, - .reset_resume = i2400mu_reset_resume, .probe = i2400mu_probe, .disconnect = i2400mu_disconnect, - .pre_reset = i2400mu_pre_reset, - .post_reset = i2400mu_post_reset, .id_table = i2400mu_id_table, .supports_autosuspend = 1, }; @@ -751,8 +618,6 @@ struct usb_driver i2400mu_driver = { static int __init i2400mu_driver_init(void) { - d_parse_params(D_LEVEL, D_LEVEL_SIZE, i2400mu_debug_params, - "i2400m_usb.debug"); return usb_register(&i2400mu_driver); } module_init(i2400mu_driver_init); @@ -767,7 +632,7 @@ void __exit i2400mu_driver_exit(void) module_exit(i2400mu_driver_exit); MODULE_AUTHOR("Intel Corporation "); -MODULE_DESCRIPTION("Driver for USB based Intel Wireless WiMAX Connection 2400M " - "(5x50 & 6050)"); +MODULE_DESCRIPTION("Intel 2400M WiMAX networking for USB"); MODULE_LICENSE("GPL"); MODULE_FIRMWARE(I2400MU_FW_FILE_NAME_v1_4); +MODULE_FIRMWARE(I2400MU_FW_FILE_NAME_v1_3); diff --git a/trunk/drivers/net/wireless/ath/ath9k/rc.c b/trunk/drivers/net/wireless/ath/ath9k/rc.c index bb72b46567f9..063936423d86 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/rc.c +++ b/trunk/drivers/net/wireless/ath/ath9k/rc.c @@ -679,7 +679,7 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc, return rate; if (rate_table->info[rate].valid_single_stream && - !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) + !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)); return rate; /* This should not happen */ diff --git a/trunk/drivers/net/wireless/b43/dma.c b/trunk/drivers/net/wireless/b43/dma.c index de4e804bedf0..8701034569fa 100644 --- a/trunk/drivers/net/wireless/b43/dma.c +++ b/trunk/drivers/net/wireless/b43/dma.c @@ -1157,9 +1157,8 @@ struct b43_dmaring *parse_cookie(struct b43_wldev *dev, u16 cookie, int *slot) } static int dma_tx_fragment(struct b43_dmaring *ring, - struct sk_buff **in_skb) + struct sk_buff *skb) { - struct sk_buff *skb = *in_skb; const struct b43_dma_ops *ops = ring->ops; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); u8 *header; @@ -1225,14 +1224,8 @@ static int dma_tx_fragment(struct b43_dmaring *ring, } memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len); - memcpy(bounce_skb->cb, skb->cb, sizeof(skb->cb)); - bounce_skb->dev = skb->dev; - skb_set_queue_mapping(bounce_skb, skb_get_queue_mapping(skb)); - info = IEEE80211_SKB_CB(bounce_skb); - dev_kfree_skb_any(skb); skb = bounce_skb; - *in_skb = bounce_skb; meta->skb = skb; meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { @@ -1362,11 +1355,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb) * static, so we don't need to store it per frame. */ ring->queue_prio = skb_get_queue_mapping(skb); - /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing - * into the skb data or cb now. */ - hdr = NULL; - info = NULL; - err = dma_tx_fragment(ring, &skb); + err = dma_tx_fragment(ring, skb); if (unlikely(err == -ENOKEY)) { /* Drop this packet, as we don't have the encryption key * anymore and must not transmit it unencrypted. */ diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c index a741d37fd96f..240cff1e6979 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c @@ -6325,10 +6325,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, fail: if (dev) { - if (registered) { - unregister_ieee80211(priv->ieee); + if (registered) unregister_netdev(dev); - } ipw2100_hw_stop_adapter(priv); @@ -6385,7 +6383,6 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) /* Unregister the device first - this results in close() * being called if the device is open. If we free storage * first, then close() will crash. */ - unregister_ieee80211(priv->ieee); unregister_netdev(dev); /* ipw2100_down will ensure that there is no more pending work diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c index 4539e63e978e..61ef8904af97 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c @@ -11822,7 +11822,6 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, if (err) { IPW_ERROR("Failed to register promiscuous network " "device (error %d).\n", err); - unregister_ieee80211(priv->ieee); unregister_netdev(priv->net_dev); goto out_remove_sysfs; } @@ -11873,7 +11872,6 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev) mutex_unlock(&priv->mutex); - unregister_ieee80211(priv->ieee); unregister_netdev(priv->net_dev); if (priv->rxq) { diff --git a/trunk/drivers/net/wireless/ipw2x00/libipw.h b/trunk/drivers/net/wireless/ipw2x00/libipw.h index f42ade6c2d3e..bf45391172f3 100644 --- a/trunk/drivers/net/wireless/ipw2x00/libipw.h +++ b/trunk/drivers/net/wireless/ipw2x00/libipw.h @@ -1020,7 +1020,6 @@ static inline int libipw_is_cck_rate(u8 rate) /* ieee80211.c */ extern void free_ieee80211(struct net_device *dev, int monitor); extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor); -extern void unregister_ieee80211(struct libipw_device *ieee); extern int libipw_change_mtu(struct net_device *dev, int new_mtu); extern void libipw_networks_age(struct libipw_device *ieee, diff --git a/trunk/drivers/net/wireless/ipw2x00/libipw_module.c b/trunk/drivers/net/wireless/ipw2x00/libipw_module.c index be5b809ec97a..a0e9f6aed7da 100644 --- a/trunk/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/trunk/drivers/net/wireless/ipw2x00/libipw_module.c @@ -235,19 +235,16 @@ void free_ieee80211(struct net_device *dev, int monitor) libipw_networks_free(ieee); /* free cfg80211 resources */ - if (!monitor) + if (!monitor) { + wiphy_unregister(ieee->wdev.wiphy); + kfree(ieee->a_band.channels); + kfree(ieee->bg_band.channels); wiphy_free(ieee->wdev.wiphy); + } free_netdev(dev); } -void unregister_ieee80211(struct libipw_device *ieee) -{ - wiphy_unregister(ieee->wdev.wiphy); - kfree(ieee->a_band.channels); - kfree(ieee->bg_band.channels); -} - #ifdef CONFIG_LIBIPW_DEBUG static int debug = 0; @@ -333,4 +330,3 @@ module_init(libipw_init); EXPORT_SYMBOL(alloc_ieee80211); EXPORT_SYMBOL(free_ieee80211); -EXPORT_SYMBOL(unregister_ieee80211); diff --git a/trunk/drivers/net/wireless/libertas/if_usb.c b/trunk/drivers/net/wireless/libertas/if_usb.c index f12d667ba100..a8262dea9b1f 100644 --- a/trunk/drivers/net/wireless/libertas/if_usb.c +++ b/trunk/drivers/net/wireless/libertas/if_usb.c @@ -511,7 +511,7 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp, /* Fill the receive configuration URB and initialise the Rx call back */ usb_fill_bulk_urb(cardp->rx_urb, cardp->udev, usb_rcvbulkpipe(cardp->udev, cardp->ep_in), - skb->data + IPFIELD_ALIGN_OFFSET, + (void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET), MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn, cardp); diff --git a/trunk/drivers/net/wireless/rt2x00/rt73usb.c b/trunk/drivers/net/wireless/rt2x00/rt73usb.c index 14e7bb210075..b8f5ee33445e 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt73usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt73usb.c @@ -2389,13 +2389,10 @@ static struct usb_device_id rt73usb_device_table[] = { { USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x13b1, 0x0028), USB_DEVICE_DATA(&rt73usb_ops) }, /* MSI */ - { USB_DEVICE(0x0db0, 0x4600), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0xa861), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0xa874), USB_DEVICE_DATA(&rt73usb_ops) }, - /* Ovislink */ - { USB_DEVICE(0x1b75, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) }, /* Ralink */ { USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) }, @@ -2423,8 +2420,6 @@ static struct usb_device_id rt73usb_device_table[] = { /* Planex */ { USB_DEVICE(0x2019, 0xab01), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x2019, 0xab50), USB_DEVICE_DATA(&rt73usb_ops) }, - /* WideTell */ - { USB_DEVICE(0x7167, 0x3840), USB_DEVICE_DATA(&rt73usb_ops) }, /* Zcom */ { USB_DEVICE(0x0cde, 0x001c), USB_DEVICE_DATA(&rt73usb_ops) }, /* ZyXEL */ diff --git a/trunk/drivers/serial/serial_cs.c b/trunk/drivers/serial/serial_cs.c index 7c7914f5fa02..ff4617e21426 100644 --- a/trunk/drivers/serial/serial_cs.c +++ b/trunk/drivers/serial/serial_cs.c @@ -879,10 +879,10 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "cis/DP83903.cis"), PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"), PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"), - PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */ - PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ - PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ - PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ + PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */ + PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ + PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ + PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "cis/COMpad2.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"), diff --git a/trunk/firmware/Makefile b/trunk/firmware/Makefile index 6d5c3abd06be..45c04660a44d 100644 --- a/trunk/firmware/Makefile +++ b/trunk/firmware/Makefile @@ -69,13 +69,11 @@ fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \ fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis \ cis/DP83903.cis cis/NE2K.cis \ - cis/tamarack.cis cis/PE-200.cis + cis/tamarack.cis fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis \ - cis/COMpad2.cis cis/COMpad4.cis \ - cis/SW_555_SER.cis cis/SW_7xx_SER.cis \ - cis/SW_8xx_SER.cis + cis/COMpad2.cis cis/COMpad4.cis fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \ advansys/3550.bin advansys/38C0800.bin diff --git a/trunk/firmware/WHENCE b/trunk/firmware/WHENCE index 34b5d0a036db..a07aede9fcc3 100644 --- a/trunk/firmware/WHENCE +++ b/trunk/firmware/WHENCE @@ -600,7 +600,6 @@ File: cis/LA-PCM.cis cis/DP83903.cis cis/NE2K.cis cis/tamarack.cis - cis/PE-200.cis Licence: GPL @@ -634,9 +633,6 @@ File: cis/MT5634ZLX.cis cis/RS-COM-2P.cis cis/COMpad2.cis cis/COMpad4.cis - cis/SW_555_SER.cis - cis/SW_7xx_SER.cis - cis/SW_8xx_SER.cis Licence: GPL diff --git a/trunk/firmware/cis/PE-200.cis.ihex b/trunk/firmware/cis/PE-200.cis.ihex deleted file mode 100644 index e6dbdab6eb79..000000000000 --- a/trunk/firmware/cis/PE-200.cis.ihex +++ /dev/null @@ -1,9 +0,0 @@ -:1000000001030000FF151E0401504D582020200060 -:1000100050452D3230300045544845524E4554002D -:1000200052303100FF210206031A050101000101CF -:100030001B0EC181190155E051000F100F30FFFF59 -:040040001400FF00A9 -:00000001FF -# -# Replacement CIS for PE-200 ethernet card -# diff --git a/trunk/firmware/cis/SW_555_SER.cis.ihex b/trunk/firmware/cis/SW_555_SER.cis.ihex deleted file mode 100644 index 9b9348acee7b..000000000000 --- a/trunk/firmware/cis/SW_555_SER.cis.ihex +++ /dev/null @@ -1,12 +0,0 @@ -:100000000101FF17034100FF20043F0110072102F7 -:100010000200152A070053696572726120576972E0 -:10002000656C657373004169724361726420353594 -:1000300035004135353500526576203100FF1A050F -:1000400001030007731B0BE00118A360F8030730DE -:10005000BC3F1B08A10108A360F802071B08A2010E -:1000600008A360E803071B08A30108A360E80207D0 -:0A0070001B04A40108231400FF0084 -:00000001FF -# -# Replacement CIS for AC555 provided by Sierra Wireless -# diff --git a/trunk/firmware/cis/SW_7xx_SER.cis.ihex b/trunk/firmware/cis/SW_7xx_SER.cis.ihex deleted file mode 100644 index 11e44ad86437..000000000000 --- a/trunk/firmware/cis/SW_7xx_SER.cis.ihex +++ /dev/null @@ -1,13 +0,0 @@ -:100000000101FF17034100FF2004920110072102A4 -:1000100002001537070053696572726120576972D3 -:10002000656C6573730041433731302F4143373579 -:10003000300047505253204E6574776F726B2041E9 -:1000400064617074657200523100FF1A050103008B -:1000500007731B10E00119784D555D25A360F80367 -:100060000730BC861B08A10108A360F802071B0823 -:10007000A20108A360E803071B08A30108A360E826 -:0C00800002071B04A40108231400FF0069 -:00000001FF -# -# Replacement CIS for AC7xx provided by Sierra Wireless -# diff --git a/trunk/firmware/cis/SW_8xx_SER.cis.ihex b/trunk/firmware/cis/SW_8xx_SER.cis.ihex deleted file mode 100644 index bbcfe6348328..000000000000 --- a/trunk/firmware/cis/SW_8xx_SER.cis.ihex +++ /dev/null @@ -1,13 +0,0 @@ -:100000000101FF17034100FF2004920110072102A4 -:100010000200152F070053696572726120576972DB -:10002000656C657373004143383530003347204EAB -:100030006574776F726B20416461707465720052F1 -:100040003100FF1A0501030007731B10E001197846 -:100050004D555D25A360F8480730BC861B08A101FB -:1000600008A360F847071B08A20108A360E8480737 -:100070001B08A30108A360E847071B04A401082389 -:040080001400FF0069 -:00000001FF -# -# Replacement CIS for AC8xx provided by Sierra Wireless -# diff --git a/trunk/include/linux/can/core.h b/trunk/include/linux/can/core.h index 6c507bea275f..25085cbadcfc 100644 --- a/trunk/include/linux/can/core.h +++ b/trunk/include/linux/can/core.h @@ -32,12 +32,14 @@ * struct can_proto - CAN protocol structure * @type: type argument in socket() syscall, e.g. SOCK_DGRAM. * @protocol: protocol number in socket() syscall. + * @capability: capability needed to open the socket, or -1 for no restriction. * @ops: pointer to struct proto_ops for sock->ops. * @prot: pointer to struct proto structure. */ struct can_proto { int type; int protocol; + int capability; struct proto_ops *ops; struct proto *prot; }; diff --git a/trunk/include/linux/mmc/sdio_ids.h b/trunk/include/linux/mmc/sdio_ids.h index 33b2ea09a4ad..2dbfb5a05994 100644 --- a/trunk/include/linux/mmc/sdio_ids.h +++ b/trunk/include/linux/mmc/sdio_ids.h @@ -28,7 +28,6 @@ #define SDIO_DEVICE_ID_INTEL_IWMC3200TOP 0x1404 #define SDIO_DEVICE_ID_INTEL_IWMC3200GPS 0x1405 #define SDIO_DEVICE_ID_INTEL_IWMC3200BT 0x1406 -#define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX_2G5 0x1407 #define SDIO_VENDOR_ID_MARVELL 0x02df #define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103 diff --git a/trunk/include/linux/net.h b/trunk/include/linux/net.h index 70ee3c310f15..4da9d571b053 100644 --- a/trunk/include/linux/net.h +++ b/trunk/include/linux/net.h @@ -204,8 +204,7 @@ struct proto_ops { struct net_proto_family { int family; - int (*create)(struct net *net, struct socket *sock, - int protocol, int kern); + int (*create)(struct net *net, struct socket *sock, int protocol); struct module *owner; }; diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index 63f47426977a..d0448c5d1ffc 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -354,8 +354,8 @@ struct sk_buff { ipvs_property:1, peeked:1, nf_trace:1; - __be16 protocol:16; kmemcheck_bitfield_end(flags1); + __be16 protocol; void (*destructor)(struct sk_buff *skb); #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) @@ -367,6 +367,7 @@ struct sk_buff { #endif int iif; + __u16 queue_mapping; #ifdef CONFIG_NET_SCHED __u16 tc_index; /* traffic control index */ #ifdef CONFIG_NET_CLS_ACT @@ -375,7 +376,6 @@ struct sk_buff { #endif kmemcheck_bitfield_begin(flags2); - __u16 queue_mapping:16; #ifdef CONFIG_IPV6_NDISC_NODETYPE __u8 ndisc_nodetype:2; #endif @@ -1768,8 +1768,6 @@ extern int skb_copy_datagram_const_iovec(const struct sk_buff *from, int to_offset, int size); extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb); -extern void skb_free_datagram_locked(struct sock *sk, - struct sk_buff *skb); extern int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags); extern __wsum skb_checksum(const struct sk_buff *skb, int offset, diff --git a/trunk/include/linux/wimax/debug.h b/trunk/include/linux/wimax/debug.h index db8096e88533..c703e0340423 100644 --- a/trunk/include/linux/wimax/debug.h +++ b/trunk/include/linux/wimax/debug.h @@ -450,76 +450,4 @@ do { \ }) -static inline -void d_submodule_set(struct d_level *d_level, size_t d_level_size, - const char *submodule, u8 level, const char *tag) -{ - struct d_level *itr, *top; - int index = -1; - - for (itr = d_level, top = itr + d_level_size; itr < top; itr++) { - index++; - if (itr->name == NULL) { - printk(KERN_ERR "%s: itr->name NULL?? (%p, #%d)\n", - tag, itr, index); - continue; - } - if (!strcmp(itr->name, submodule)) { - itr->level = level; - return; - } - } - printk(KERN_ERR "%s: unknown submodule %s\n", tag, submodule); -} - - -/** - * d_parse_params - Parse a string with debug parameters from the - * command line - * - * @d_level: level structure (D_LEVEL) - * @d_level_size: number of items in the level structure - * (D_LEVEL_SIZE). - * @_params: string with the parameters; this is a space (not tab!) - * separated list of NAME:VALUE, where value is the debug level - * and NAME is the name of the submodule. - * @tag: string for error messages (example: MODULE.ARGNAME). - */ -static inline -void d_parse_params(struct d_level *d_level, size_t d_level_size, - const char *_params, const char *tag) -{ - char submodule[130], *params, *params_orig, *token, *colon; - unsigned level, tokens; - - if (_params == NULL) - return; - params_orig = kstrdup(_params, GFP_KERNEL); - params = params_orig; - while (1) { - token = strsep(¶ms, " "); - if (token == NULL) - break; - if (*token == '\0') /* eat joint spaces */ - continue; - /* kernel's sscanf %s eats until whitespace, so we - * replace : by \n so it doesn't get eaten later by - * strsep */ - colon = strchr(token, ':'); - if (colon != NULL) - *colon = '\n'; - tokens = sscanf(token, "%s\n%u", submodule, &level); - if (colon != NULL) - *colon = ':'; /* set back, for error messages */ - if (tokens == 2) - d_submodule_set(d_level, d_level_size, - submodule, level, tag); - else - printk(KERN_ERR "%s: can't parse '%s' as a " - "SUBMODULE:LEVEL (%d tokens)\n", - tag, token, tokens); - } - kfree(params_orig); -} - #endif /* #ifndef __debug__h__ */ diff --git a/trunk/include/linux/wimax/i2400m.h b/trunk/include/linux/wimax/i2400m.h index 62d356153565..433693ef2bb0 100644 --- a/trunk/include/linux/wimax/i2400m.h +++ b/trunk/include/linux/wimax/i2400m.h @@ -138,7 +138,7 @@ struct i2400m_bcf_hdr { __le32 module_id; __le32 module_vendor; __le32 date; /* BCD YYYMMDD */ - __le32 size; /* in dwords */ + __le32 size; __le32 key_size; /* in dwords */ __le32 modulus_size; /* in dwords */ __le32 exponent_size; /* in dwords */ @@ -168,6 +168,16 @@ enum i2400m_brh { }; +/* Constants for bcf->module_id */ +enum i2400m_bcf_mod_id { + /* Firmware file carries its own pokes -- pokes are a set of + * magical values that have to be written in certain memory + * addresses to get the device up and ready for firmware + * download when it is in non-signed boot mode. */ + I2400M_BCF_MOD_ID_POKES = 0x000000001, +}; + + /** * i2400m_bootrom_header - Header for a boot-mode command * @@ -266,7 +276,6 @@ enum { I2400M_WARM_RESET_BARKER = 0x50f750f7, I2400M_NBOOT_BARKER = 0xdeadbeef, I2400M_SBOOT_BARKER = 0x0ff1c1a1, - I2400M_SBOOT_BARKER_6050 = 0x80000001, I2400M_ACK_BARKER = 0xfeedbabe, I2400M_D2H_MSG_BARKER = 0xbeefbabe, }; diff --git a/trunk/include/net/ip_fib.h b/trunk/include/net/ip_fib.h index c93f94edc610..68fd5ebd0949 100644 --- a/trunk/include/net/ip_fib.h +++ b/trunk/include/net/ip_fib.h @@ -213,8 +213,7 @@ extern struct fib_table *fib_get_table(struct net *net, u32 id); extern const struct nla_policy rtm_ipv4_policy[]; extern void ip_fib_init(void); extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, - struct net_device *dev, __be32 *spec_dst, - u32 *itag, u32 mark); + struct net_device *dev, __be32 *spec_dst, u32 *itag); extern void fib_select_default(struct net *net, const struct flowi *flp, struct fib_result *res); diff --git a/trunk/include/net/netfilter/nf_conntrack.h b/trunk/include/net/netfilter/nf_conntrack.h index 5cf7270e3ffc..cbdd6284996d 100644 --- a/trunk/include/net/netfilter/nf_conntrack.h +++ b/trunk/include/net/netfilter/nf_conntrack.h @@ -255,9 +255,11 @@ static inline bool nf_ct_kill(struct nf_conn *ct) } /* These are for NAT. Icky. */ -extern s16 (*nf_ct_nat_offset)(const struct nf_conn *ct, - enum ip_conntrack_dir dir, - u32 seq); +/* Update TCP window tracking data when NAT mangles the packet */ +extern void nf_conntrack_tcp_update(const struct sk_buff *skb, + unsigned int dataoff, + struct nf_conn *ct, int dir, + s16 offset); /* Fake conntrack entry for untracked connections */ extern struct nf_conn nf_conntrack_untracked; diff --git a/trunk/include/net/netfilter/nf_nat_helper.h b/trunk/include/net/netfilter/nf_nat_helper.h index 4222220920a5..237a961f40e1 100644 --- a/trunk/include/net/netfilter/nf_nat_helper.h +++ b/trunk/include/net/netfilter/nf_nat_helper.h @@ -32,8 +32,4 @@ extern int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, * to port ct->master->saved_proto. */ extern void nf_nat_follow_master(struct nf_conn *ct, struct nf_conntrack_expect *this); - -extern s16 nf_nat_get_offset(const struct nf_conn *ct, - enum ip_conntrack_dir dir, - u32 seq); #endif diff --git a/trunk/include/net/protocol.h b/trunk/include/net/protocol.h index f1effdd3c265..89932d45da59 100644 --- a/trunk/include/net/protocol.h +++ b/trunk/include/net/protocol.h @@ -82,6 +82,10 @@ struct inet_protosw { struct proto *prot; const struct proto_ops *ops; + int capability; /* Which (if any) capability do + * we need to use this socket + * interface? + */ char no_check; /* checksum on rcv/xmit/none? */ unsigned char flags; /* See INET_PROTOSW_* below. */ }; diff --git a/trunk/include/net/wimax.h b/trunk/include/net/wimax.h index d69c4a7a1267..2af7bf839f23 100644 --- a/trunk/include/net/wimax.h +++ b/trunk/include/net/wimax.h @@ -195,12 +195,6 @@ * defining the `struct nla_policy` for each message, it has to have * an array size of WIMAX_GNL_ATTR_MAX+1. * - * The op_*() function pointers will not be called if the wimax_dev is - * in a state <= %WIMAX_ST_UNINITIALIZED. The exception is: - * - * - op_reset: can be called at any time after wimax_dev_add() has - * been called. - * * THE PIPE INTERFACE: * * This interface is kept intentionally simple. The driver can send diff --git a/trunk/include/net/wpan-phy.h b/trunk/include/net/wpan-phy.h index 547b1e271ac9..5e803a0e4e72 100644 --- a/trunk/include/net/wpan-phy.h +++ b/trunk/include/net/wpan-phy.h @@ -56,6 +56,12 @@ static inline void *wpan_phy_priv(struct wpan_phy *phy) } struct wpan_phy *wpan_phy_find(const char *str); + +static inline void wpan_phy_put(struct wpan_phy *phy) +{ + put_device(&phy->dev); +} + static inline const char *wpan_phy_name(struct wpan_phy *phy) { return dev_name(&phy->dev); diff --git a/trunk/net/appletalk/ddp.c b/trunk/net/appletalk/ddp.c index 4b0ce2e2b46e..abe38014b7fd 100644 --- a/trunk/net/appletalk/ddp.c +++ b/trunk/net/appletalk/ddp.c @@ -1021,8 +1021,7 @@ static struct proto ddp_proto = { * Create a socket. Initialise the socket, blank the addresses * set the state. */ -static int atalk_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int atalk_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; int rc = -ESOCKTNOSUPPORT; diff --git a/trunk/net/atm/pvc.c b/trunk/net/atm/pvc.c index 8d74e62b0d79..a6e1fdbae87f 100644 --- a/trunk/net/atm/pvc.c +++ b/trunk/net/atm/pvc.c @@ -127,8 +127,7 @@ static const struct proto_ops pvc_proto_ops = { }; -static int pvc_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int pvc_create(struct net *net, struct socket *sock,int protocol) { if (net != &init_net) return -EAFNOSUPPORT; diff --git a/trunk/net/atm/svc.c b/trunk/net/atm/svc.c index c7395070ee78..819354233318 100644 --- a/trunk/net/atm/svc.c +++ b/trunk/net/atm/svc.c @@ -25,7 +25,7 @@ #include "signaling.h" #include "addr.h" -static int svc_create(struct net *net, struct socket *sock, int protocol, int kern); +static int svc_create(struct net *net, struct socket *sock,int protocol); /* * Note: since all this is still nicely synchronized with the signaling demon, @@ -330,7 +330,7 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags) lock_sock(sk); - error = svc_create(sock_net(sk), newsock, 0, 0); + error = svc_create(sock_net(sk), newsock,0); if (error) goto out; @@ -650,8 +650,7 @@ static const struct proto_ops svc_proto_ops = { }; -static int svc_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int svc_create(struct net *net, struct socket *sock,int protocol) { int error; diff --git a/trunk/net/ax25/af_ax25.c b/trunk/net/ax25/af_ax25.c index d6ddfa4c4471..f1e998b2796e 100644 --- a/trunk/net/ax25/af_ax25.c +++ b/trunk/net/ax25/af_ax25.c @@ -799,8 +799,7 @@ static struct proto ax25_proto = { .obj_size = sizeof(struct sock), }; -static int ax25_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int ax25_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; ax25_cb *ax25; diff --git a/trunk/net/bluetooth/af_bluetooth.c b/trunk/net/bluetooth/af_bluetooth.c index 087cc51f5927..399e59c9c6cb 100644 --- a/trunk/net/bluetooth/af_bluetooth.c +++ b/trunk/net/bluetooth/af_bluetooth.c @@ -126,8 +126,7 @@ int bt_sock_unregister(int proto) } EXPORT_SYMBOL(bt_sock_unregister); -static int bt_sock_create(struct net *net, struct socket *sock, int proto, - int kern) +static int bt_sock_create(struct net *net, struct socket *sock, int proto) { int err; @@ -145,7 +144,7 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto, read_lock(&bt_proto_lock); if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) { - err = bt_proto[proto]->create(net, sock, proto, kern); + err = bt_proto[proto]->create(net, sock, proto); bt_sock_reclassify_lock(sock, proto); module_put(bt_proto[proto]->owner); } diff --git a/trunk/net/bluetooth/bnep/sock.c b/trunk/net/bluetooth/bnep/sock.c index 2ff6ac7b2ed4..0a2c5460bb48 100644 --- a/trunk/net/bluetooth/bnep/sock.c +++ b/trunk/net/bluetooth/bnep/sock.c @@ -195,8 +195,7 @@ static struct proto bnep_proto = { .obj_size = sizeof(struct bt_sock) }; -static int bnep_sock_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int bnep_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; diff --git a/trunk/net/bluetooth/cmtp/sock.c b/trunk/net/bluetooth/cmtp/sock.c index 978cc3a718ad..de7c8040bc56 100644 --- a/trunk/net/bluetooth/cmtp/sock.c +++ b/trunk/net/bluetooth/cmtp/sock.c @@ -190,8 +190,7 @@ static struct proto cmtp_proto = { .obj_size = sizeof(struct bt_sock) }; -static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; diff --git a/trunk/net/bluetooth/hci_sock.c b/trunk/net/bluetooth/hci_sock.c index 1ca5c7ca9bd4..e7395f231989 100644 --- a/trunk/net/bluetooth/hci_sock.c +++ b/trunk/net/bluetooth/hci_sock.c @@ -621,8 +621,7 @@ static struct proto hci_sk_proto = { .obj_size = sizeof(struct hci_pinfo) }; -static int hci_sock_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int hci_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; diff --git a/trunk/net/bluetooth/hidp/sock.c b/trunk/net/bluetooth/hidp/sock.c index 9cfef68b9fec..4beb6a7a2953 100644 --- a/trunk/net/bluetooth/hidp/sock.c +++ b/trunk/net/bluetooth/hidp/sock.c @@ -241,8 +241,7 @@ static struct proto hidp_proto = { .obj_size = sizeof(struct bt_sock) }; -static int hidp_sock_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int hidp_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; diff --git a/trunk/net/bluetooth/l2cap.c b/trunk/net/bluetooth/l2cap.c index ff0233df6246..d65101d92ee5 100644 --- a/trunk/net/bluetooth/l2cap.c +++ b/trunk/net/bluetooth/l2cap.c @@ -819,8 +819,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p return sk; } -static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; @@ -832,7 +831,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, sock->type != SOCK_DGRAM && sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; - if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW)) + if (sock->type == SOCK_RAW && !capable(CAP_NET_RAW)) return -EPERM; sock->ops = &l2cap_sock_ops; diff --git a/trunk/net/bluetooth/rfcomm/sock.c b/trunk/net/bluetooth/rfcomm/sock.c index 4b5968dda673..d3bfc1b0afb1 100644 --- a/trunk/net/bluetooth/rfcomm/sock.c +++ b/trunk/net/bluetooth/rfcomm/sock.c @@ -323,8 +323,7 @@ static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int return sk; } -static int rfcomm_sock_create(struct net *net, struct socket *sock, - int protocol, int kern) +static int rfcomm_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; diff --git a/trunk/net/bluetooth/sco.c b/trunk/net/bluetooth/sco.c index dd8f6ec57dce..694a65541b73 100644 --- a/trunk/net/bluetooth/sco.c +++ b/trunk/net/bluetooth/sco.c @@ -430,8 +430,7 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int pro return sk; } -static int sco_sock_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int sco_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; diff --git a/trunk/net/bridge/br_if.c b/trunk/net/bridge/br_if.c index a6f74b2b9571..2117e5ba24c8 100644 --- a/trunk/net/bridge/br_if.c +++ b/trunk/net/bridge/br_if.c @@ -377,16 +377,12 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) struct net_bridge_port *p; int err = 0; - /* Don't allow bridging non-ethernet like devices */ - if ((dev->flags & IFF_LOOPBACK) || - dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN) + if (dev->flags & IFF_LOOPBACK || dev->type != ARPHRD_ETHER) return -EINVAL; - /* No bridging of bridges */ if (dev->netdev_ops->ndo_start_xmit == br_dev_xmit) return -ELOOP; - /* Device is already being bridged */ if (dev->br_port != NULL) return -EBUSY; diff --git a/trunk/net/bridge/br_ioctl.c b/trunk/net/bridge/br_ioctl.c index 2af6e4a90262..6a6433daaf27 100644 --- a/trunk/net/bridge/br_ioctl.c +++ b/trunk/net/bridge/br_ioctl.c @@ -81,7 +81,6 @@ static int get_fdb_entries(struct net_bridge *br, void __user *userbuf, return num; } -/* called with RTNL */ static int add_del_if(struct net_bridge *br, int ifindex, int isadd) { struct net_device *dev; @@ -90,7 +89,7 @@ static int add_del_if(struct net_bridge *br, int ifindex, int isadd) if (!capable(CAP_NET_ADMIN)) return -EPERM; - dev = __dev_get_by_index(dev_net(br->dev), ifindex); + dev = dev_get_by_index(dev_net(br->dev), ifindex); if (dev == NULL) return -EINVAL; @@ -99,6 +98,7 @@ static int add_del_if(struct net_bridge *br, int ifindex, int isadd) else ret = br_del_if(br, dev); + dev_put(dev); return ret; } diff --git a/trunk/net/can/af_can.c b/trunk/net/can/af_can.c index 833bd838edc6..3f2eb27e1ffb 100644 --- a/trunk/net/can/af_can.c +++ b/trunk/net/can/af_can.c @@ -114,8 +114,7 @@ static void can_sock_destruct(struct sock *sk) skb_queue_purge(&sk->sk_receive_queue); } -static int can_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int can_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct can_proto *cp; @@ -161,6 +160,11 @@ static int can_create(struct net *net, struct socket *sock, int protocol, goto errout; } + if (cp->capability >= 0 && !capable(cp->capability)) { + err = -EPERM; + goto errout; + } + sock->ops = cp->ops; sk = sk_alloc(net, PF_CAN, GFP_KERNEL, cp->prot); diff --git a/trunk/net/can/bcm.c b/trunk/net/can/bcm.c index 67b5433db13b..2f47039c79dd 100644 --- a/trunk/net/can/bcm.c +++ b/trunk/net/can/bcm.c @@ -1576,6 +1576,7 @@ static struct proto bcm_proto __read_mostly = { static struct can_proto bcm_can_proto __read_mostly = { .type = SOCK_DGRAM, .protocol = CAN_BCM, + .capability = -1, .ops = &bcm_ops, .prot = &bcm_proto, }; diff --git a/trunk/net/can/raw.c b/trunk/net/can/raw.c index abca920440b5..6e77db58b9e6 100644 --- a/trunk/net/can/raw.c +++ b/trunk/net/can/raw.c @@ -742,6 +742,7 @@ static struct proto raw_proto __read_mostly = { static struct can_proto raw_can_proto __read_mostly = { .type = SOCK_RAW, .protocol = CAN_RAW, + .capability = -1, .ops = &raw_ops, .prot = &raw_proto, }; diff --git a/trunk/net/core/datagram.c b/trunk/net/core/datagram.c index 95c2e0840d0d..4d57f5e12b05 100644 --- a/trunk/net/core/datagram.c +++ b/trunk/net/core/datagram.c @@ -224,15 +224,6 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb) consume_skb(skb); sk_mem_reclaim_partial(sk); } -EXPORT_SYMBOL(skb_free_datagram); - -void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb) -{ - lock_sock(sk); - skb_free_datagram(sk, skb); - release_sock(sk); -} -EXPORT_SYMBOL(skb_free_datagram_locked); /** * skb_kill_datagram - Free a datagram skbuff forcibly @@ -762,4 +753,5 @@ unsigned int datagram_poll(struct file *file, struct socket *sock, EXPORT_SYMBOL(datagram_poll); EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec); EXPORT_SYMBOL(skb_copy_datagram_iovec); +EXPORT_SYMBOL(skb_free_datagram); EXPORT_SYMBOL(skb_recv_datagram); diff --git a/trunk/net/core/pktgen.c b/trunk/net/core/pktgen.c index d38470a32792..5ce017bf4afa 100644 --- a/trunk/net/core/pktgen.c +++ b/trunk/net/core/pktgen.c @@ -340,7 +340,6 @@ struct pktgen_dev { __u16 cur_udp_src; __u16 cur_queue_map; __u32 cur_pkt_size; - __u32 last_pkt_size; __u8 hh[14]; /* = { @@ -3435,7 +3434,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) pkt_dev->clone_count--; /* back out increment, OOM */ return; } - pkt_dev->last_pkt_size = pkt_dev->skb->len; + pkt_dev->allocated_skbs++; pkt_dev->clone_count = 0; /* reset counter */ } @@ -3462,7 +3461,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) pkt_dev->last_ok = 1; pkt_dev->sofar++; pkt_dev->seq_num++; - pkt_dev->tx_bytes += pkt_dev->last_pkt_size; + pkt_dev->tx_bytes += pkt_dev->cur_pkt_size; break; default: /* Drivers are not supposed to return other values! */ if (net_ratelimit()) diff --git a/trunk/net/core/sock.c b/trunk/net/core/sock.c index 76ff58d43e26..5a51512f638a 100644 --- a/trunk/net/core/sock.c +++ b/trunk/net/core/sock.c @@ -417,18 +417,17 @@ static int sock_bindtodevice(struct sock *sk, char __user *optval, int optlen) if (copy_from_user(devname, optval, optlen)) goto out; - index = 0; - if (devname[0] != '\0') { - struct net_device *dev; - - rcu_read_lock(); - dev = dev_get_by_name_rcu(net, devname); - if (dev) - index = dev->ifindex; - rcu_read_unlock(); + if (devname[0] == '\0') { + index = 0; + } else { + struct net_device *dev = dev_get_by_name(net, devname); + ret = -ENODEV; if (!dev) goto out; + + index = dev->ifindex; + dev_put(dev); } lock_sock(sk); diff --git a/trunk/net/dccp/ipv4.c b/trunk/net/dccp/ipv4.c index 2423a0866733..00028d4b09d9 100644 --- a/trunk/net/dccp/ipv4.c +++ b/trunk/net/dccp/ipv4.c @@ -991,6 +991,7 @@ static struct inet_protosw dccp_v4_protosw = { .protocol = IPPROTO_DCCP, .prot = &dccp_v4_prot, .ops = &inet_dccp_ops, + .capability = -1, .no_check = 0, .flags = INET_PROTOSW_ICSK, }; diff --git a/trunk/net/dccp/ipv6.c b/trunk/net/dccp/ipv6.c index 50ea91a77705..6d89f9f7d5d8 100644 --- a/trunk/net/dccp/ipv6.c +++ b/trunk/net/dccp/ipv6.c @@ -1185,6 +1185,7 @@ static struct inet_protosw dccp_v6_protosw = { .protocol = IPPROTO_DCCP, .prot = &dccp_v6_prot, .ops = &inet6_dccp_ops, + .capability = -1, .flags = INET_PROTOSW_ICSK, }; diff --git a/trunk/net/decnet/af_decnet.c b/trunk/net/decnet/af_decnet.c index 9ade3a6de954..2e355841ca99 100644 --- a/trunk/net/decnet/af_decnet.c +++ b/trunk/net/decnet/af_decnet.c @@ -675,8 +675,7 @@ char *dn_addr2asc(__u16 addr, char *buf) -static int dn_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int dn_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; diff --git a/trunk/net/decnet/sysctl_net_decnet.c b/trunk/net/decnet/sysctl_net_decnet.c index 2036568beea9..26b0ab1e9f56 100644 --- a/trunk/net/decnet/sysctl_net_decnet.c +++ b/trunk/net/decnet/sysctl_net_decnet.c @@ -263,10 +263,11 @@ static int dn_def_dev_strategy(ctl_table *table, return -ENODEV; rv = -ENODEV; - if (dev->dn_ptr != NULL) + if (dev->dn_ptr != NULL) { rv = dn_dev_set_default(dev, 1); - if (rv) - dev_put(dev); + if (rv) + dev_put(dev); + } } return rv; diff --git a/trunk/net/econet/af_econet.c b/trunk/net/econet/af_econet.c index 596679803de5..5e9426a11c3e 100644 --- a/trunk/net/econet/af_econet.c +++ b/trunk/net/econet/af_econet.c @@ -605,8 +605,7 @@ static struct proto econet_proto = { * Create an Econet socket */ -static int econet_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int econet_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct econet_sock *eo; diff --git a/trunk/net/ieee802154/af_ieee802154.c b/trunk/net/ieee802154/af_ieee802154.c index de6e34d2a7f8..309348fba72b 100644 --- a/trunk/net/ieee802154/af_ieee802154.c +++ b/trunk/net/ieee802154/af_ieee802154.c @@ -234,7 +234,7 @@ static const struct proto_ops ieee802154_dgram_ops = { * set the state. */ static int ieee802154_create(struct net *net, struct socket *sock, - int protocol, int kern) + int protocol) { struct sock *sk; int rc; diff --git a/trunk/net/ipv4/af_inet.c b/trunk/net/ipv4/af_inet.c index 7d12c6a9b19b..538e84d0bcba 100644 --- a/trunk/net/ipv4/af_inet.c +++ b/trunk/net/ipv4/af_inet.c @@ -262,8 +262,7 @@ static inline int inet_netns_ok(struct net *net, int protocol) * Create an inet socket. */ -static int inet_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int inet_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct inet_protosw *answer; @@ -326,7 +325,7 @@ static int inet_create(struct net *net, struct socket *sock, int protocol, } err = -EPERM; - if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW)) + if (answer->capability > 0 && !capable(answer->capability)) goto out_rcu_unlock; err = -EAFNOSUPPORT; @@ -948,6 +947,7 @@ static struct inet_protosw inetsw_array[] = .protocol = IPPROTO_TCP, .prot = &tcp_prot, .ops = &inet_stream_ops, + .capability = -1, .no_check = 0, .flags = INET_PROTOSW_PERMANENT | INET_PROTOSW_ICSK, @@ -958,6 +958,7 @@ static struct inet_protosw inetsw_array[] = .protocol = IPPROTO_UDP, .prot = &udp_prot, .ops = &inet_dgram_ops, + .capability = -1, .no_check = UDP_CSUM_DEFAULT, .flags = INET_PROTOSW_PERMANENT, }, @@ -968,6 +969,7 @@ static struct inet_protosw inetsw_array[] = .protocol = IPPROTO_IP, /* wild card */ .prot = &raw_prot, .ops = &inet_sockraw_ops, + .capability = CAP_NET_RAW, .no_check = UDP_CSUM_DEFAULT, .flags = INET_PROTOSW_REUSE, } diff --git a/trunk/net/ipv4/fib_frontend.c b/trunk/net/ipv4/fib_frontend.c index 816e2180bd60..f73dbed0f0d7 100644 --- a/trunk/net/ipv4/fib_frontend.c +++ b/trunk/net/ipv4/fib_frontend.c @@ -229,17 +229,14 @@ unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev, */ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, - struct net_device *dev, __be32 *spec_dst, - u32 *itag, u32 mark) + struct net_device *dev, __be32 *spec_dst, u32 *itag) { struct in_device *in_dev; struct flowi fl = { .nl_u = { .ip4_u = { .daddr = src, .saddr = dst, .tos = tos } }, - .mark = mark, .iif = oif }; - struct fib_result res; int no_addr, rpf; int ret; diff --git a/trunk/net/ipv4/ip_fragment.c b/trunk/net/ipv4/ip_fragment.c index b007f8af6e1f..575f9bd51ccd 100644 --- a/trunk/net/ipv4/ip_fragment.c +++ b/trunk/net/ipv4/ip_fragment.c @@ -206,11 +206,10 @@ static void ip_expire(unsigned long arg) struct sk_buff *head = qp->q.fragments; /* Send an ICMP "Fragment Reassembly Timeout" message. */ - rcu_read_lock(); - head->dev = dev_get_by_index_rcu(net, qp->iif); - if (head->dev) + if ((head->dev = dev_get_by_index(net, qp->iif)) != NULL) { icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0); - rcu_read_unlock(); + dev_put(head->dev); + } } out: spin_unlock(&qp->q.lock); diff --git a/trunk/net/ipv4/ip_gre.c b/trunk/net/ipv4/ip_gre.c index 71a3242fb7d0..a77807d449e3 100644 --- a/trunk/net/ipv4/ip_gre.c +++ b/trunk/net/ipv4/ip_gre.c @@ -1476,7 +1476,7 @@ static void ipgre_tap_setup(struct net_device *dev) ether_setup(dev); - dev->netdev_ops = &ipgre_tap_netdev_ops; + dev->netdev_ops = &ipgre_netdev_ops; dev->destructor = free_netdev; dev->iflink = 0; @@ -1537,29 +1537,25 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[], if (t->dev != dev) return -EEXIST; } else { - t = nt; + unsigned nflags = 0; - if (dev->type != ARPHRD_ETHER) { - unsigned nflags = 0; + t = nt; - if (ipv4_is_multicast(p.iph.daddr)) - nflags = IFF_BROADCAST; - else if (p.iph.daddr) - nflags = IFF_POINTOPOINT; + if (ipv4_is_multicast(p.iph.daddr)) + nflags = IFF_BROADCAST; + else if (p.iph.daddr) + nflags = IFF_POINTOPOINT; - if ((dev->flags ^ nflags) & - (IFF_POINTOPOINT | IFF_BROADCAST)) - return -EINVAL; - } + if ((dev->flags ^ nflags) & + (IFF_POINTOPOINT | IFF_BROADCAST)) + return -EINVAL; ipgre_tunnel_unlink(ign, t); t->parms.iph.saddr = p.iph.saddr; t->parms.iph.daddr = p.iph.daddr; t->parms.i_key = p.i_key; - if (dev->type != ARPHRD_ETHER) { - memcpy(dev->dev_addr, &p.iph.saddr, 4); - memcpy(dev->broadcast, &p.iph.daddr, 4); - } + memcpy(dev->dev_addr, &p.iph.saddr, 4); + memcpy(dev->broadcast, &p.iph.daddr, 4); ipgre_tunnel_link(ign, t); netdev_state_change(dev); } diff --git a/trunk/net/ipv4/netfilter/nf_nat_core.c b/trunk/net/ipv4/netfilter/nf_nat_core.c index fe1a64479dd0..68afc6ecd343 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_core.c +++ b/trunk/net/ipv4/netfilter/nf_nat_core.c @@ -750,8 +750,6 @@ static int __init nf_nat_init(void) BUG_ON(nfnetlink_parse_nat_setup_hook != NULL); rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, nfnetlink_parse_nat_setup); - BUG_ON(nf_ct_nat_offset != NULL); - rcu_assign_pointer(nf_ct_nat_offset, nf_nat_get_offset); return 0; cleanup_extend: @@ -766,7 +764,6 @@ static void __exit nf_nat_cleanup(void) nf_ct_extend_unregister(&nat_extend); rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL); rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL); - rcu_assign_pointer(nf_ct_nat_offset, NULL); synchronize_net(); } diff --git a/trunk/net/ipv4/netfilter/nf_nat_helper.c b/trunk/net/ipv4/netfilter/nf_nat_helper.c index f9520fa3aba9..09172a65d9b6 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_helper.c +++ b/trunk/net/ipv4/netfilter/nf_nat_helper.c @@ -73,28 +73,6 @@ adjust_tcp_sequence(u32 seq, DUMP_OFFSET(this_way); } -/* Get the offset value, for conntrack */ -s16 nf_nat_get_offset(const struct nf_conn *ct, - enum ip_conntrack_dir dir, - u32 seq) -{ - struct nf_conn_nat *nat = nfct_nat(ct); - struct nf_nat_seq *this_way; - s16 offset; - - if (!nat) - return 0; - - this_way = &nat->seq[dir]; - spin_lock_bh(&nf_nat_seqofs_lock); - offset = after(seq, this_way->correction_pos) - ? this_way->offset_after : this_way->offset_before; - spin_unlock_bh(&nf_nat_seqofs_lock); - - return offset; -} -EXPORT_SYMBOL_GPL(nf_nat_get_offset); - /* Frobs data inside this packet, which is linear. */ static void mangle_contents(struct sk_buff *skb, unsigned int dataoff, @@ -211,6 +189,11 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb, adjust_tcp_sequence(ntohl(tcph->seq), (int)rep_len - (int)match_len, ct, ctinfo); + /* Tell TCP window tracking about seq change */ + nf_conntrack_tcp_update(skb, ip_hdrlen(skb), + ct, CTINFO2DIR(ctinfo), + (int)rep_len - (int)match_len); + nf_conntrack_event_cache(IPCT_NATSEQADJ, ct); } return 1; @@ -432,7 +415,12 @@ nf_nat_seq_adjust(struct sk_buff *skb, tcph->seq = newseq; tcph->ack_seq = newack; - return nf_nat_sack_adjust(skb, tcph, ct, ctinfo); + if (!nf_nat_sack_adjust(skb, tcph, ct, ctinfo)) + return 0; + + nf_conntrack_tcp_update(skb, ip_hdrlen(skb), ct, dir, seqoff); + + return 1; } /* Setup NAT on this expected conntrack so it follows master. */ diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index ff258b57680b..68fb22702051 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -1851,7 +1851,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, goto e_inval; spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); } else if (fib_validate_source(saddr, 0, tos, 0, - dev, &spec_dst, &itag, 0) < 0) + dev, &spec_dst, &itag) < 0) goto e_inval; rth = dst_alloc(&ipv4_dst_ops); @@ -1964,7 +1964,7 @@ static int __mkroute_input(struct sk_buff *skb, err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(*res), - in_dev->dev, &spec_dst, &itag, skb->mark); + in_dev->dev, &spec_dst, &itag); if (err < 0) { ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr, saddr); @@ -2138,7 +2138,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, int result; result = fib_validate_source(saddr, daddr, tos, net->loopback_dev->ifindex, - dev, &spec_dst, &itag, skb->mark); + dev, &spec_dst, &itag); if (result < 0) goto martian_source; if (result) @@ -2167,7 +2167,7 @@ out: return err; spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); else { err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, - &itag, skb->mark); + &itag); if (err < 0) goto martian_source; if (err) diff --git a/trunk/net/ipv4/udp.c b/trunk/net/ipv4/udp.c index d5e75e976513..4274c1cc78fd 100644 --- a/trunk/net/ipv4/udp.c +++ b/trunk/net/ipv4/udp.c @@ -1005,7 +1005,9 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, err = ulen; out_free: - skb_free_datagram_locked(sk, skb); + lock_sock(sk); + skb_free_datagram(sk, skb); + release_sock(sk); out: return err; diff --git a/trunk/net/ipv4/udplite.c b/trunk/net/ipv4/udplite.c index 66f79513f4a5..470c504b9554 100644 --- a/trunk/net/ipv4/udplite.c +++ b/trunk/net/ipv4/udplite.c @@ -64,6 +64,7 @@ static struct inet_protosw udplite4_protosw = { .protocol = IPPROTO_UDPLITE, .prot = &udplite_prot, .ops = &inet_dgram_ops, + .capability = -1, .no_check = 0, /* must checksum (RFC 3828) */ .flags = INET_PROTOSW_PERMANENT, }; diff --git a/trunk/net/ipv6/af_inet6.c b/trunk/net/ipv6/af_inet6.c index 12e69d364dd5..9105b25defe5 100644 --- a/trunk/net/ipv6/af_inet6.c +++ b/trunk/net/ipv6/af_inet6.c @@ -95,8 +95,7 @@ static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) return (struct ipv6_pinfo *)(((u8 *)sk) + offset); } -static int inet6_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int inet6_create(struct net *net, struct socket *sock, int protocol) { struct inet_sock *inet; struct ipv6_pinfo *np; @@ -159,7 +158,7 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol, } err = -EPERM; - if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW)) + if (answer->capability > 0 && !capable(answer->capability)) goto out_rcu_unlock; sock->ops = answer->ops; diff --git a/trunk/net/ipv6/raw.c b/trunk/net/ipv6/raw.c index 818ef21ba76d..cb834ab7f071 100644 --- a/trunk/net/ipv6/raw.c +++ b/trunk/net/ipv6/raw.c @@ -1336,6 +1336,7 @@ static struct inet_protosw rawv6_protosw = { .protocol = IPPROTO_IP, /* wild card */ .prot = &rawv6_prot, .ops = &inet6_sockraw_ops, + .capability = CAP_NET_RAW, .no_check = UDP_CSUM_DEFAULT, .flags = INET_PROTOSW_REUSE, }; diff --git a/trunk/net/ipv6/reassembly.c b/trunk/net/ipv6/reassembly.c index dce699fb2672..da5bd0ed83df 100644 --- a/trunk/net/ipv6/reassembly.c +++ b/trunk/net/ipv6/reassembly.c @@ -208,17 +208,18 @@ static void ip6_frag_expire(unsigned long data) fq_kill(fq); net = container_of(fq->q.net, struct net, ipv6.frags); - rcu_read_lock(); - dev = dev_get_by_index_rcu(net, fq->iif); + dev = dev_get_by_index(net, fq->iif); if (!dev) - goto out_rcu_unlock; + goto out; + rcu_read_lock(); IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT); IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); + rcu_read_unlock(); /* Don't send error if the first segment did not arrive. */ if (!(fq->q.last_in & INET_FRAG_FIRST_IN) || !fq->q.fragments) - goto out_rcu_unlock; + goto out; /* But use as source device on which LAST ARRIVED @@ -227,9 +228,9 @@ static void ip6_frag_expire(unsigned long data) */ fq->q.fragments->dev = dev; icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev); -out_rcu_unlock: - rcu_read_unlock(); out: + if (dev) + dev_put(dev); spin_unlock(&fq->q.lock); fq_put(fq); } diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index 696a22f034e8..34925f089e07 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -2112,6 +2112,7 @@ static struct inet_protosw tcpv6_protosw = { .protocol = IPPROTO_TCP, .prot = &tcpv6_prot, .ops = &inet6_stream_ops, + .capability = -1, .no_check = 0, .flags = INET_PROTOSW_PERMANENT | INET_PROTOSW_ICSK, diff --git a/trunk/net/ipv6/udp.c b/trunk/net/ipv6/udp.c index 5bc7cdbf030a..d3b59d73f507 100644 --- a/trunk/net/ipv6/udp.c +++ b/trunk/net/ipv6/udp.c @@ -288,7 +288,9 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, err = ulen; out_free: - skb_free_datagram_locked(sk, skb); + lock_sock(sk); + skb_free_datagram(sk, skb); + release_sock(sk); out: return err; @@ -1284,6 +1286,7 @@ static struct inet_protosw udpv6_protosw = { .protocol = IPPROTO_UDP, .prot = &udpv6_prot, .ops = &inet6_dgram_ops, + .capability =-1, .no_check = UDP_CSUM_DEFAULT, .flags = INET_PROTOSW_PERMANENT, }; diff --git a/trunk/net/ipv6/udplite.c b/trunk/net/ipv6/udplite.c index 6ea6938919e6..d737a27ee010 100644 --- a/trunk/net/ipv6/udplite.c +++ b/trunk/net/ipv6/udplite.c @@ -62,6 +62,7 @@ static struct inet_protosw udplite6_protosw = { .protocol = IPPROTO_UDPLITE, .prot = &udplitev6_prot, .ops = &inet6_dgram_ops, + .capability = -1, .no_check = 0, .flags = INET_PROTOSW_PERMANENT, }; diff --git a/trunk/net/ipx/af_ipx.c b/trunk/net/ipx/af_ipx.c index 96d193a24415..6481ee4bdf72 100644 --- a/trunk/net/ipx/af_ipx.c +++ b/trunk/net/ipx/af_ipx.c @@ -1352,8 +1352,7 @@ static struct proto ipx_proto = { .obj_size = sizeof(struct ipx_sock), }; -static int ipx_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int ipx_create(struct net *net, struct socket *sock, int protocol) { int rc = -ESOCKTNOSUPPORT; struct sock *sk; diff --git a/trunk/net/irda/af_irda.c b/trunk/net/irda/af_irda.c index e73a0016c0aa..9429e4002bca 100644 --- a/trunk/net/irda/af_irda.c +++ b/trunk/net/irda/af_irda.c @@ -61,7 +61,7 @@ #include -static int irda_create(struct net *net, struct socket *sock, int protocol, int kern); +static int irda_create(struct net *net, struct socket *sock, int protocol); static const struct proto_ops irda_stream_ops; static const struct proto_ops irda_seqpacket_ops; @@ -839,7 +839,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) IRDA_DEBUG(2, "%s()\n", __func__); - err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0); + err = irda_create(sock_net(sk), newsock, sk->sk_protocol); if (err) return err; @@ -1062,8 +1062,7 @@ static struct proto irda_proto = { * Create IrDA socket * */ -static int irda_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int irda_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct irda_sock *self; diff --git a/trunk/net/iucv/af_iucv.c b/trunk/net/iucv/af_iucv.c index 1e428863574f..3aebabb158a8 100644 --- a/trunk/net/iucv/af_iucv.c +++ b/trunk/net/iucv/af_iucv.c @@ -481,8 +481,7 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio) } /* Create an IUCV socket */ -static int iucv_sock_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int iucv_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; diff --git a/trunk/net/key/af_key.c b/trunk/net/key/af_key.c index 86b2c22d0918..472f6594184a 100644 --- a/trunk/net/key/af_key.c +++ b/trunk/net/key/af_key.c @@ -177,8 +177,7 @@ static struct proto key_proto = { .obj_size = sizeof(struct pfkey_sock), }; -static int pfkey_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int pfkey_create(struct net *net, struct socket *sock, int protocol) { struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id); struct sock *sk; diff --git a/trunk/net/llc/af_llc.c b/trunk/net/llc/af_llc.c index 5266c286b260..4866b4fb0c27 100644 --- a/trunk/net/llc/af_llc.c +++ b/trunk/net/llc/af_llc.c @@ -140,17 +140,14 @@ static struct proto llc_proto = { /** * llc_ui_create - alloc and init a new llc_ui socket - * @net: network namespace (must be default network) * @sock: Socket to initialize and attach allocated sk to. * @protocol: Unused. - * @kern: on behalf of kernel or userspace * * Allocate and initialize a new llc_ui socket, validate the user wants a * socket type we have available. * Returns 0 upon success, negative upon failure. */ -static int llc_ui_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int llc_ui_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; int rc = -ESOCKTNOSUPPORT; diff --git a/trunk/net/mac80211/agg-tx.c b/trunk/net/mac80211/agg-tx.c index b09948ceec4a..bd765f30dba2 100644 --- a/trunk/net/mac80211/agg-tx.c +++ b/trunk/net/mac80211/agg-tx.c @@ -666,25 +666,26 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, state = &sta->ampdu_mlme.tid_state_tx[tid]; - del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); - spin_lock_bh(&sta->lock); - if (!(*state & HT_ADDBA_REQUESTED_MSK)) - goto timer_still_needed; + if (!(*state & HT_ADDBA_REQUESTED_MSK)) { + spin_unlock_bh(&sta->lock); + return; + } if (mgmt->u.action.u.addba_resp.dialog_token != sta->ampdu_mlme.tid_tx[tid]->dialog_token) { + spin_unlock_bh(&sta->lock); #ifdef CONFIG_MAC80211_HT_DEBUG printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); #endif /* CONFIG_MAC80211_HT_DEBUG */ - goto timer_still_needed; + return; } + del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); #ifdef CONFIG_MAC80211_HT_DEBUG printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); #endif /* CONFIG_MAC80211_HT_DEBUG */ - if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) == WLAN_STATUS_SUCCESS) { u8 curstate = *state; @@ -698,11 +699,5 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, } else { ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); } - - goto out; - - timer_still_needed: - add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); - out: spin_unlock_bh(&sta->lock); } diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index 7b5131bd6fa1..5608f6c68413 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -72,9 +72,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy, struct ieee80211_sub_if_data *sdata; int ret; - if (netif_running(dev)) - return -EBUSY; - if (!nl80211_type_check(type)) return -EINVAL; @@ -84,6 +81,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy, if (ret) return ret; + if (netif_running(sdata->dev)) + return -EBUSY; + if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) ieee80211_sdata_set_mesh_id(sdata, params->mesh_id_len, diff --git a/trunk/net/mac80211/ht.c b/trunk/net/mac80211/ht.c index 48ef1a282b91..0891bfb06996 100644 --- a/trunk/net/mac80211/ht.c +++ b/trunk/net/mac80211/ht.c @@ -153,7 +153,7 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, if (net_ratelimit()) printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n", mgmt->sa, initiator ? "initiator" : "recipient", tid, - le16_to_cpu(mgmt->u.action.u.delba.reason_code)); + mgmt->u.action.u.delba.reason_code); #endif /* CONFIG_MAC80211_HT_DEBUG */ if (initiator == WLAN_BACK_INITIATOR) diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index f1362f32c17d..ca8ecce31d34 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -73,7 +73,6 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt; u8 *pos; struct ieee80211_supported_band *sband; - struct cfg80211_bss *bss; u32 bss_change; u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; @@ -178,9 +177,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, mod_timer(&ifibss->timer, round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); - bss = cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel, - mgmt, skb->len, 0, GFP_KERNEL); - cfg80211_put_bss(bss); + cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel, + mgmt, skb->len, 0, GFP_KERNEL); cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); } diff --git a/trunk/net/netfilter/nf_conntrack_core.c b/trunk/net/netfilter/nf_conntrack_core.c index 0cdfb388a191..7c9ec3dee96e 100644 --- a/trunk/net/netfilter/nf_conntrack_core.c +++ b/trunk/net/netfilter/nf_conntrack_core.c @@ -1350,11 +1350,6 @@ static int nf_conntrack_init_net(struct net *net) return ret; } -s16 (*nf_ct_nat_offset)(const struct nf_conn *ct, - enum ip_conntrack_dir dir, - u32 seq); -EXPORT_SYMBOL_GPL(nf_ct_nat_offset); - int nf_conntrack_init(struct net *net) { int ret; @@ -1372,9 +1367,6 @@ int nf_conntrack_init(struct net *net) /* For use by REJECT target */ rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach); rcu_assign_pointer(nf_ct_destroy, destroy_conntrack); - - /* Howto get NAT offsets */ - rcu_assign_pointer(nf_ct_nat_offset, NULL); } return 0; diff --git a/trunk/net/netfilter/nf_conntrack_proto_tcp.c b/trunk/net/netfilter/nf_conntrack_proto_tcp.c index ba2b76937283..97a82ba75376 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_tcp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_tcp.c @@ -492,21 +492,6 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff, } } -#ifdef CONFIG_NF_NAT_NEEDED -static inline s16 nat_offset(const struct nf_conn *ct, - enum ip_conntrack_dir dir, - u32 seq) -{ - typeof(nf_ct_nat_offset) get_offset = rcu_dereference(nf_ct_nat_offset); - - return get_offset != NULL ? get_offset(ct, dir, seq) : 0; -} -#define NAT_OFFSET(pf, ct, dir, seq) \ - (pf == NFPROTO_IPV4 ? nat_offset(ct, dir, seq) : 0) -#else -#define NAT_OFFSET(pf, ct, dir, seq) 0 -#endif - static bool tcp_in_window(const struct nf_conn *ct, struct ip_ct_tcp *state, enum ip_conntrack_dir dir, @@ -521,7 +506,6 @@ static bool tcp_in_window(const struct nf_conn *ct, struct ip_ct_tcp_state *receiver = &state->seen[!dir]; const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; __u32 seq, ack, sack, end, win, swin; - s16 receiver_offset; bool res; /* @@ -535,16 +519,11 @@ static bool tcp_in_window(const struct nf_conn *ct, if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM) tcp_sack(skb, dataoff, tcph, &sack); - /* Take into account NAT sequence number mangling */ - receiver_offset = NAT_OFFSET(pf, ct, !dir, ack - 1); - ack -= receiver_offset; - sack -= receiver_offset; - pr_debug("tcp_in_window: START\n"); pr_debug("tcp_in_window: "); nf_ct_dump_tuple(tuple); - pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n", - seq, ack, receiver_offset, sack, receiver_offset, win, end); + pr_debug("seq=%u ack=%u sack=%u win=%u end=%u\n", + seq, ack, sack, win, end); pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " "receiver end=%u maxend=%u maxwin=%u scale=%i\n", sender->td_end, sender->td_maxend, sender->td_maxwin, @@ -634,8 +613,8 @@ static bool tcp_in_window(const struct nf_conn *ct, pr_debug("tcp_in_window: "); nf_ct_dump_tuple(tuple); - pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n", - seq, ack, receiver_offset, sack, receiver_offset, win, end); + pr_debug("seq=%u ack=%u sack =%u win=%u end=%u\n", + seq, ack, sack, win, end); pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " "receiver end=%u maxend=%u maxwin=%u scale=%i\n", sender->td_end, sender->td_maxend, sender->td_maxwin, @@ -721,7 +700,7 @@ static bool tcp_in_window(const struct nf_conn *ct, before(seq, sender->td_maxend + 1) ? after(end, sender->td_end - receiver->td_maxwin - 1) ? before(sack, receiver->td_end + 1) ? - after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1) ? "BUG" + after(ack, receiver->td_end - MAXACKWINDOW(sender)) ? "BUG" : "ACK is under the lower bound (possible overly delayed ACK)" : "ACK is over the upper bound (ACKed data not seen yet)" : "SEQ is under the lower bound (already ACKed data retransmitted)" @@ -736,6 +715,39 @@ static bool tcp_in_window(const struct nf_conn *ct, return res; } +#ifdef CONFIG_NF_NAT_NEEDED +/* Update sender->td_end after NAT successfully mangled the packet */ +/* Caller must linearize skb at tcp header. */ +void nf_conntrack_tcp_update(const struct sk_buff *skb, + unsigned int dataoff, + struct nf_conn *ct, int dir, + s16 offset) +{ + const struct tcphdr *tcph = (const void *)skb->data + dataoff; + const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[dir]; + const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[!dir]; + __u32 end; + + end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph); + + spin_lock_bh(&ct->lock); + /* + * We have to worry for the ack in the reply packet only... + */ + if (ct->proto.tcp.seen[dir].td_end + offset == end) + ct->proto.tcp.seen[dir].td_end = end; + ct->proto.tcp.last_end = end; + spin_unlock_bh(&ct->lock); + pr_debug("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i " + "receiver end=%u maxend=%u maxwin=%u scale=%i\n", + sender->td_end, sender->td_maxend, sender->td_maxwin, + sender->td_scale, + receiver->td_end, receiver->td_maxend, receiver->td_maxwin, + receiver->td_scale); +} +EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update); +#endif + #define TH_FIN 0x01 #define TH_SYN 0x02 #define TH_RST 0x04 diff --git a/trunk/net/netlabel/netlabel_unlabeled.c b/trunk/net/netlabel/netlabel_unlabeled.c index 3dfe2bac8623..fb357f010189 100644 --- a/trunk/net/netlabel/netlabel_unlabeled.c +++ b/trunk/net/netlabel/netlabel_unlabeled.c @@ -472,12 +472,13 @@ int netlbl_unlhsh_add(struct net *net, rcu_read_lock(); if (dev_name != NULL) { - dev = dev_get_by_name_rcu(net, dev_name); + dev = dev_get_by_name(net, dev_name); if (dev == NULL) { ret_val = -ENODEV; goto unlhsh_add_return; } ifindex = dev->ifindex; + dev_put(dev); iface = netlbl_unlhsh_search_iface(ifindex); } else { ifindex = 0; @@ -736,12 +737,13 @@ int netlbl_unlhsh_remove(struct net *net, rcu_read_lock(); if (dev_name != NULL) { - dev = dev_get_by_name_rcu(net, dev_name); + dev = dev_get_by_name(net, dev_name); if (dev == NULL) { ret_val = -ENODEV; goto unlhsh_remove_return; } iface = netlbl_unlhsh_search_iface(dev->ifindex); + dev_put(dev); } else iface = rcu_dereference(netlbl_unlhsh_def); if (iface == NULL) { diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c index aea805c98da3..0cd2d8829313 100644 --- a/trunk/net/netlink/af_netlink.c +++ b/trunk/net/netlink/af_netlink.c @@ -428,8 +428,7 @@ static int __netlink_create(struct net *net, struct socket *sock, return 0; } -static int netlink_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int netlink_create(struct net *net, struct socket *sock, int protocol) { struct module *module = NULL; struct mutex *cb_mutex; diff --git a/trunk/net/netrom/af_netrom.c b/trunk/net/netrom/af_netrom.c index 4bdd5697f63b..281fa597cae5 100644 --- a/trunk/net/netrom/af_netrom.c +++ b/trunk/net/netrom/af_netrom.c @@ -425,8 +425,7 @@ static struct proto nr_proto = { .obj_size = sizeof(struct nr_sock), }; -static int nr_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int nr_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct nr_sock *nr; diff --git a/trunk/net/packet/af_packet.c b/trunk/net/packet/af_packet.c index 3304caa65347..91d246d34780 100644 --- a/trunk/net/packet/af_packet.c +++ b/trunk/net/packet/af_packet.c @@ -1344,8 +1344,7 @@ static struct proto packet_proto = { * Create a packet of type SOCK_PACKET. */ -static int packet_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int packet_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct packet_sock *po; diff --git a/trunk/net/phonet/af_phonet.c b/trunk/net/phonet/af_phonet.c index 3bd1be6b26f0..66737aa995ea 100644 --- a/trunk/net/phonet/af_phonet.c +++ b/trunk/net/phonet/af_phonet.c @@ -60,8 +60,7 @@ static inline void phonet_proto_put(struct phonet_protocol *pp) /* protocol family functions */ -static int pn_socket_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int pn_socket_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct pn_sock *pn; diff --git a/trunk/net/rds/af_rds.c b/trunk/net/rds/af_rds.c index e25d8d5ce8df..2b978dc6e75d 100644 --- a/trunk/net/rds/af_rds.c +++ b/trunk/net/rds/af_rds.c @@ -410,8 +410,7 @@ static int __rds_create(struct socket *sock, struct sock *sk, int protocol) return 0; } -static int rds_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int rds_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; diff --git a/trunk/net/rose/af_rose.c b/trunk/net/rose/af_rose.c index 4de4287fec37..c17734c2ce89 100644 --- a/trunk/net/rose/af_rose.c +++ b/trunk/net/rose/af_rose.c @@ -512,8 +512,7 @@ static struct proto rose_proto = { .obj_size = sizeof(struct rose_sock), }; -static int rose_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int rose_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct rose_sock *rose; diff --git a/trunk/net/rose/rose_route.c b/trunk/net/rose/rose_route.c index ea2e72337e2f..d936226916f2 100644 --- a/trunk/net/rose/rose_route.c +++ b/trunk/net/rose/rose_route.c @@ -578,18 +578,18 @@ static int rose_clear_routes(void) /* * Check that the device given is a valid AX.25 interface that is "up". - * called whith RTNL */ -static struct net_device *rose_ax25_dev_find(char *devname) +static struct net_device *rose_ax25_dev_get(char *devname) { struct net_device *dev; - if ((dev = __dev_get_by_name(&init_net, devname)) == NULL) + if ((dev = dev_get_by_name(&init_net, devname)) == NULL) return NULL; if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25) return dev; + dev_put(dev); return NULL; } @@ -720,23 +720,27 @@ int rose_rt_ioctl(unsigned int cmd, void __user *arg) case SIOCADDRT: if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct))) return -EFAULT; - if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL) + if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL) return -EINVAL; - if (rose_dev_exists(&rose_route.address)) /* Can't add routes to ourself */ + if (rose_dev_exists(&rose_route.address)) { /* Can't add routes to ourself */ + dev_put(dev); return -EINVAL; + } if (rose_route.mask > 10) /* Mask can't be more than 10 digits */ return -EINVAL; if (rose_route.ndigis > AX25_MAX_DIGIS) return -EINVAL; err = rose_add_node(&rose_route, dev); + dev_put(dev); return err; case SIOCDELRT: if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct))) return -EFAULT; - if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL) + if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL) return -EINVAL; err = rose_del_node(&rose_route, dev); + dev_put(dev); return err; case SIOCRSCLRRT: diff --git a/trunk/net/rxrpc/af_rxrpc.c b/trunk/net/rxrpc/af_rxrpc.c index f978d02a248a..6817c9781ef3 100644 --- a/trunk/net/rxrpc/af_rxrpc.c +++ b/trunk/net/rxrpc/af_rxrpc.c @@ -608,8 +608,7 @@ static unsigned int rxrpc_poll(struct file *file, struct socket *sock, /* * create an RxRPC socket */ -static int rxrpc_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int rxrpc_create(struct net *net, struct socket *sock, int protocol) { struct rxrpc_sock *rx; struct sock *sk; diff --git a/trunk/net/sched/cls_api.c b/trunk/net/sched/cls_api.c index c024da77824f..7cf6c0fbc7a6 100644 --- a/trunk/net/sched/cls_api.c +++ b/trunk/net/sched/cls_api.c @@ -404,7 +404,6 @@ static int tcf_node_dump(struct tcf_proto *tp, unsigned long n, a->cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTFILTER); } -/* called with RTNL */ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) { struct net *net = sock_net(skb->sk); @@ -423,7 +422,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) return skb->len; - if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) + if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) return skb->len; if (!tcm->tcm_parent) @@ -485,6 +484,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) if (cl) cops->put(q, cl); out: + dev_put(dev); return skb->len; } diff --git a/trunk/net/sctp/ipv6.c b/trunk/net/sctp/ipv6.c index cc50fbe99291..bb280e60e00a 100644 --- a/trunk/net/sctp/ipv6.c +++ b/trunk/net/sctp/ipv6.c @@ -837,16 +837,15 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr) if (type & IPV6_ADDR_LINKLOCAL) { if (!addr->v6.sin6_scope_id) return 0; - rcu_read_lock(); - dev = dev_get_by_index_rcu(&init_net, - addr->v6.sin6_scope_id); - if (!dev || - !ipv6_chk_addr(&init_net, &addr->v6.sin6_addr, + dev = dev_get_by_index(&init_net, addr->v6.sin6_scope_id); + if (!dev) + return 0; + if (!ipv6_chk_addr(&init_net, &addr->v6.sin6_addr, dev, 0)) { - rcu_read_unlock(); + dev_put(dev); return 0; } - rcu_read_unlock(); + dev_put(dev); } else if (type == IPV6_ADDR_MAPPED) { if (!opt->v4mapped) return 0; @@ -874,12 +873,10 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr) if (type & IPV6_ADDR_LINKLOCAL) { if (!addr->v6.sin6_scope_id) return 0; - rcu_read_lock(); - dev = dev_get_by_index_rcu(&init_net, - addr->v6.sin6_scope_id); - rcu_read_unlock(); + dev = dev_get_by_index(&init_net, addr->v6.sin6_scope_id); if (!dev) return 0; + dev_put(dev); } af = opt->pf->af; } @@ -933,6 +930,7 @@ static struct inet_protosw sctpv6_seqpacket_protosw = { .protocol = IPPROTO_SCTP, .prot = &sctpv6_prot, .ops = &inet6_seqpacket_ops, + .capability = -1, .no_check = 0, .flags = SCTP_PROTOSW_FLAG }; @@ -941,6 +939,7 @@ static struct inet_protosw sctpv6_stream_protosw = { .protocol = IPPROTO_SCTP, .prot = &sctpv6_prot, .ops = &inet6_seqpacket_ops, + .capability = -1, .no_check = 0, .flags = SCTP_PROTOSW_FLAG, }; diff --git a/trunk/net/sctp/protocol.c b/trunk/net/sctp/protocol.c index 08ef203d36ac..fe44c57101de 100644 --- a/trunk/net/sctp/protocol.c +++ b/trunk/net/sctp/protocol.c @@ -909,6 +909,7 @@ static struct inet_protosw sctp_seqpacket_protosw = { .protocol = IPPROTO_SCTP, .prot = &sctp_prot, .ops = &inet_seqpacket_ops, + .capability = -1, .no_check = 0, .flags = SCTP_PROTOSW_FLAG }; @@ -917,6 +918,7 @@ static struct inet_protosw sctp_stream_protosw = { .protocol = IPPROTO_SCTP, .prot = &sctp_prot, .ops = &inet_seqpacket_ops, + .capability = -1, .no_check = 0, .flags = SCTP_PROTOSW_FLAG }; diff --git a/trunk/net/socket.c b/trunk/net/socket.c index 4f3e0f0c156b..9dff31c9b799 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -1252,7 +1252,7 @@ static int __sock_create(struct net *net, int family, int type, int protocol, /* Now protected by module ref count */ rcu_read_unlock(); - err = pf->create(net, sock, protocol, kern); + err = pf->create(net, sock, protocol); if (err < 0) goto out_module_put; diff --git a/trunk/net/sunrpc/svcsock.c b/trunk/net/sunrpc/svcsock.c index 870929e08e5d..c2a17876defd 100644 --- a/trunk/net/sunrpc/svcsock.c +++ b/trunk/net/sunrpc/svcsock.c @@ -111,7 +111,7 @@ static void svc_release_skb(struct svc_rqst *rqstp) rqstp->rq_xprt_ctxt = NULL; dprintk("svc: service %p, releasing skb %p\n", rqstp, skb); - skb_free_datagram_locked(svsk->sk_sk, skb); + skb_free_datagram(svsk->sk_sk, skb); } } @@ -578,7 +578,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) "svc: received unknown control message %d/%d; " "dropping RPC reply datagram\n", cmh->cmsg_level, cmh->cmsg_type); - skb_free_datagram_locked(svsk->sk_sk, skb); + skb_free_datagram(svsk->sk_sk, skb); return 0; } @@ -588,18 +588,18 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) if (csum_partial_copy_to_xdr(&rqstp->rq_arg, skb)) { local_bh_enable(); /* checksum error */ - skb_free_datagram_locked(svsk->sk_sk, skb); + skb_free_datagram(svsk->sk_sk, skb); return 0; } local_bh_enable(); - skb_free_datagram_locked(svsk->sk_sk, skb); + skb_free_datagram(svsk->sk_sk, skb); } else { /* we can use it in-place */ rqstp->rq_arg.head[0].iov_base = skb->data + sizeof(struct udphdr); rqstp->rq_arg.head[0].iov_len = len; if (skb_checksum_complete(skb)) { - skb_free_datagram_locked(svsk->sk_sk, skb); + skb_free_datagram(svsk->sk_sk, skb); return 0; } rqstp->rq_xprt_ctxt = skb; diff --git a/trunk/net/tipc/socket.c b/trunk/net/tipc/socket.c index d00c2119faf3..e6d9abf7440e 100644 --- a/trunk/net/tipc/socket.c +++ b/trunk/net/tipc/socket.c @@ -177,7 +177,6 @@ static void reject_rx_queue(struct sock *sk) * @net: network namespace (must be default network) * @sock: pre-allocated socket structure * @protocol: protocol indicator (must be 0) - * @kern: caused by kernel or by userspace? * * This routine creates additional data structures used by the TIPC socket, * initializes them, and links them together. @@ -185,8 +184,7 @@ static void reject_rx_queue(struct sock *sk) * Returns 0 on success, errno otherwise */ -static int tipc_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int tipc_create(struct net *net, struct socket *sock, int protocol) { const struct proto_ops *ops; socket_state state; @@ -1530,7 +1528,7 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) buf = skb_peek(&sk->sk_receive_queue); - res = tipc_create(sock_net(sock->sk), new_sock, 0, 0); + res = tipc_create(sock_net(sock->sk), new_sock, 0); if (!res) { struct sock *new_sk = new_sock->sk; struct tipc_sock *new_tsock = tipc_sk(new_sk); diff --git a/trunk/net/unix/af_unix.c b/trunk/net/unix/af_unix.c index 178d3af2a605..3291902f0b88 100644 --- a/trunk/net/unix/af_unix.c +++ b/trunk/net/unix/af_unix.c @@ -621,8 +621,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock) return sk; } -static int unix_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int unix_create(struct net *net, struct socket *sock, int protocol) { if (protocol && protocol != PF_UNIX) return -EPROTONOSUPPORT; diff --git a/trunk/net/wimax/op-msg.c b/trunk/net/wimax/op-msg.c index d3bfb6ef13ae..d631a17186bc 100644 --- a/trunk/net/wimax/op-msg.c +++ b/trunk/net/wimax/op-msg.c @@ -388,8 +388,6 @@ int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info) } mutex_lock(&wimax_dev->mutex); result = wimax_dev_is_ready(wimax_dev); - if (result == -ENOMEDIUM) - result = 0; if (result < 0) goto error_not_ready; result = -ENOSYS; diff --git a/trunk/net/wimax/op-rfkill.c b/trunk/net/wimax/op-rfkill.c index 94d339c345d2..70ef4df863b9 100644 --- a/trunk/net/wimax/op-rfkill.c +++ b/trunk/net/wimax/op-rfkill.c @@ -305,15 +305,8 @@ int wimax_rfkill(struct wimax_dev *wimax_dev, enum wimax_rf_state state) d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); mutex_lock(&wimax_dev->mutex); result = wimax_dev_is_ready(wimax_dev); - if (result < 0) { - /* While initializing, < 1.4.3 wimax-tools versions use - * this call to check if the device is a valid WiMAX - * device; so we allow it to proceed always, - * considering the radios are all off. */ - if (result == -ENOMEDIUM && state == WIMAX_RF_QUERY) - result = WIMAX_RF_OFF << 1 | WIMAX_RF_OFF; + if (result < 0) goto error_not_ready; - } switch (state) { case WIMAX_RF_ON: case WIMAX_RF_OFF: @@ -362,7 +355,6 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev) wimax_dev->rfkill = rfkill; - rfkill_init_sw_state(rfkill, 1); result = rfkill_register(wimax_dev->rfkill); if (result < 0) goto error_rfkill_register; diff --git a/trunk/net/wimax/stack.c b/trunk/net/wimax/stack.c index c8866412f830..79fb7d7c640f 100644 --- a/trunk/net/wimax/stack.c +++ b/trunk/net/wimax/stack.c @@ -60,14 +60,6 @@ #define D_SUBMODULE stack #include "debug-levels.h" -static char wimax_debug_params[128]; -module_param_string(debug, wimax_debug_params, sizeof(wimax_debug_params), - 0644); -MODULE_PARM_DESC(debug, - "String of space-separated NAME:VALUE pairs, where NAMEs " - "are the different debug submodules and VALUE are the " - "initial debug value to set."); - /* * Authoritative source for the RE_STATE_CHANGE attribute policy * @@ -570,9 +562,6 @@ int __init wimax_subsys_init(void) int result, cnt; d_fnstart(4, NULL, "()\n"); - d_parse_params(D_LEVEL, D_LEVEL_SIZE, wimax_debug_params, - "wimax.debug"); - snprintf(wimax_gnl_family.name, sizeof(wimax_gnl_family.name), "WiMAX"); result = genl_register_family(&wimax_gnl_family); diff --git a/trunk/net/wireless/sme.c b/trunk/net/wireless/sme.c index 0115d07d2c1a..98a3b7efac4c 100644 --- a/trunk/net/wireless/sme.c +++ b/trunk/net/wireless/sme.c @@ -165,7 +165,7 @@ void cfg80211_conn_work(struct work_struct *work) struct cfg80211_registered_device *rdev = container_of(work, struct cfg80211_registered_device, conn_work); struct wireless_dev *wdev; - u8 bssid_buf[ETH_ALEN], *bssid = NULL; + u8 bssid[ETH_ALEN]; rtnl_lock(); cfg80211_lock_rdev(rdev); @@ -181,10 +181,7 @@ void cfg80211_conn_work(struct work_struct *work) wdev_unlock(wdev); continue; } - if (wdev->conn->params.bssid) { - memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN); - bssid = bssid_buf; - } + memcpy(bssid, wdev->conn->params.bssid, ETH_ALEN); if (cfg80211_conn_do_work(wdev)) __cfg80211_connect_result( wdev->netdev, bssid, diff --git a/trunk/net/x25/af_x25.c b/trunk/net/x25/af_x25.c index 38e235f61e27..e19d811788a5 100644 --- a/trunk/net/x25/af_x25.c +++ b/trunk/net/x25/af_x25.c @@ -501,8 +501,7 @@ static struct sock *x25_alloc_socket(struct net *net) return sk; } -static int x25_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int x25_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct x25_sock *x25;