diff --git a/[refs] b/[refs] index f1c6dca5f7f1..7f459437f71f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: fc502ba0086f142639208f879e577e1b5a4eeb8e +refs/heads/master: d6916f87ca5e566786f1a935a7cabba54774bbda diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 857cdf154f32..c9c6324a7a9f 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -2643,8 +2643,9 @@ S: Maintained F: arch/x86/math-emu/ FRAME RELAY DLCI/FRAD (Sangoma drivers too) +M: Mike McLagan L: netdev@vger.kernel.org -S: Orphan +S: Maintained F: drivers/net/wan/dlci.c F: drivers/net/wan/sdla.c diff --git a/trunk/drivers/connector/cn_proc.c b/trunk/drivers/connector/cn_proc.c index e55814bc0d06..3ee1fdb31ea7 100644 --- a/trunk/drivers/connector/cn_proc.c +++ b/trunk/drivers/connector/cn_proc.c @@ -57,7 +57,6 @@ void proc_fork_connector(struct task_struct *task) struct proc_event *ev; __u8 buffer[CN_PROC_MSG_SIZE]; struct timespec ts; - struct task_struct *parent; if (atomic_read(&proc_event_num_listeners) < 1) return; @@ -68,11 +67,8 @@ void proc_fork_connector(struct task_struct *task) ktime_get_ts(&ts); /* get high res monotonic timestamp */ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); ev->what = PROC_EVENT_FORK; - rcu_read_lock(); - parent = rcu_dereference(task->real_parent); - ev->event_data.fork.parent_pid = parent->pid; - ev->event_data.fork.parent_tgid = parent->tgid; - rcu_read_unlock(); + ev->event_data.fork.parent_pid = task->real_parent->pid; + ev->event_data.fork.parent_tgid = task->real_parent->tgid; ev->event_data.fork.child_pid = task->pid; ev->event_data.fork.child_tgid = task->tgid; diff --git a/trunk/drivers/net/benet/be.h b/trunk/drivers/net/benet/be.h index af57b51b2787..c85768cd1b18 100644 --- a/trunk/drivers/net/benet/be.h +++ b/trunk/drivers/net/benet/be.h @@ -29,7 +29,6 @@ #include #include #include -#include #include "be_hw.h" @@ -168,15 +167,15 @@ struct be_mcc_obj { }; struct be_tx_stats { - u64 tx_bytes; - u64 tx_pkts; - u64 tx_reqs; - u64 tx_wrbs; - u64 tx_compl; - ulong tx_jiffies; - u32 tx_stops; - struct u64_stats_sync sync; - struct u64_stats_sync sync_compl; + u32 be_tx_reqs; /* number of TX requests initiated */ + u32 be_tx_stops; /* number of times TX Q was stopped */ + u32 be_tx_wrbs; /* number of tx WRBs used */ + u32 be_tx_compl; /* number of tx completion entries processed */ + ulong be_tx_jiffies; + u64 be_tx_bytes; + u64 be_tx_bytes_prev; + u64 be_tx_pkts; + u32 be_tx_rate; }; struct be_tx_obj { @@ -196,20 +195,22 @@ struct be_rx_page_info { }; struct be_rx_stats { + u32 rx_post_fail;/* number of ethrx buffer alloc failures */ + u32 rx_polls; /* number of times NAPI called poll function */ + u32 rx_events; /* number of ucast rx completion events */ + u32 rx_compl; /* number of rx completion entries processed */ + ulong rx_dropped; /* number of skb allocation errors */ + ulong rx_jiffies; u64 rx_bytes; + u64 rx_bytes_prev; u64 rx_pkts; - u64 rx_pkts_prev; - ulong rx_jiffies; - u32 rx_drops_no_skbs; /* skb allocation errors */ - u32 rx_drops_no_frags; /* HW has no fetched frags */ - u32 rx_post_fail; /* page post alloc failures */ - u32 rx_polls; /* NAPI calls */ - u32 rx_events; - u32 rx_compl; + u32 rx_rate; u32 rx_mcast_pkts; - u32 rx_compl_err; /* completions with err set */ - u32 rx_pps; /* pkts per second */ - struct u64_stats_sync sync; + u32 rxcp_err; /* Num rx completion entries w/ err set. */ + ulong rx_fps_jiffies; /* jiffies at last FPS calc */ + u32 rx_frags; + u32 prev_rx_frags; + u32 rx_fps; /* Rx frags per second */ }; struct be_rx_compl_info { @@ -246,40 +247,43 @@ struct be_rx_obj { struct be_drv_stats { u8 be_on_die_temperature; - u32 tx_events; - u32 eth_red_drops; - u32 rx_drops_no_pbuf; - u32 rx_drops_no_txpb; - u32 rx_drops_no_erx_descr; - u32 rx_drops_no_tpre_descr; - u32 rx_drops_too_many_frags; - u32 rx_drops_invalid_ring; - u32 forwarded_packets; - u32 rx_drops_mtu; - u32 rx_crc_errors; - u32 rx_alignment_symbol_errors; - u32 rx_pause_frames; - u32 rx_priority_pause_frames; - u32 rx_control_frames; - u32 rx_in_range_errors; - u32 rx_out_range_errors; - u32 rx_frame_too_long; - u32 rx_address_match_errors; - u32 rx_dropped_too_small; - u32 rx_dropped_too_short; - u32 rx_dropped_header_too_small; - u32 rx_dropped_tcp_length; - u32 rx_dropped_runt; - u32 rx_ip_checksum_errs; - u32 rx_tcp_checksum_errs; - u32 rx_udp_checksum_errs; - u32 tx_pauseframes; - u32 tx_priority_pauseframes; - u32 tx_controlframes; - u32 rxpp_fifo_overflow_drop; - u32 rx_input_fifo_overflow_drop; - u32 pmem_fifo_overflow_drop; - u32 jabber_events; + u64 be_tx_events; + u64 eth_red_drops; + u64 rx_drops_no_pbuf; + u64 rx_drops_no_txpb; + u64 rx_drops_no_erx_descr; + u64 rx_drops_no_tpre_descr; + u64 rx_drops_too_many_frags; + u64 rx_drops_invalid_ring; + u64 forwarded_packets; + u64 rx_drops_mtu; + u64 rx_crc_errors; + u64 rx_alignment_symbol_errors; + u64 rx_pause_frames; + u64 rx_priority_pause_frames; + u64 rx_control_frames; + u64 rx_in_range_errors; + u64 rx_out_range_errors; + u64 rx_frame_too_long; + u64 rx_address_match_errors; + u64 rx_dropped_too_small; + u64 rx_dropped_too_short; + u64 rx_dropped_header_too_small; + u64 rx_dropped_tcp_length; + u64 rx_dropped_runt; + u64 rx_ip_checksum_errs; + u64 rx_tcp_checksum_errs; + u64 rx_udp_checksum_errs; + u64 rx_switched_unicast_packets; + u64 rx_switched_multicast_packets; + u64 rx_switched_broadcast_packets; + u64 tx_pauseframes; + u64 tx_priority_pauseframes; + u64 tx_controlframes; + u64 rxpp_fifo_overflow_drop; + u64 rx_input_fifo_overflow_drop; + u64 pmem_fifo_overflow_drop; + u64 jabber_events; }; struct be_vf_cfg { @@ -522,6 +526,7 @@ static inline bool be_multi_rxq(const struct be_adapter *adapter) extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped); extern void be_link_status_update(struct be_adapter *adapter, bool link_up); +extern void netdev_stats_update(struct be_adapter *adapter); extern void be_parse_stats(struct be_adapter *adapter); extern int be_load_fw(struct be_adapter *adapter, u8 *func); #endif /* BE_H */ diff --git a/trunk/drivers/net/benet/be_cmds.c b/trunk/drivers/net/benet/be_cmds.c index 7dc47410443d..054fa67bc4e3 100644 --- a/trunk/drivers/net/benet/be_cmds.c +++ b/trunk/drivers/net/benet/be_cmds.c @@ -82,7 +82,28 @@ static int be_mcc_compl_process(struct be_adapter *adapter, if (((compl->tag0 == OPCODE_ETH_GET_STATISTICS) || (compl->tag0 == OPCODE_ETH_GET_PPORT_STATS)) && (compl->tag1 == CMD_SUBSYSTEM_ETH)) { + if (adapter->generation == BE_GEN3) { + if (lancer_chip(adapter)) { + struct lancer_cmd_resp_pport_stats + *resp = adapter->stats_cmd.va; + be_dws_le_to_cpu(&resp->pport_stats, + sizeof(resp->pport_stats)); + } else { + struct be_cmd_resp_get_stats_v1 *resp = + adapter->stats_cmd.va; + + be_dws_le_to_cpu(&resp->hw_stats, + sizeof(resp->hw_stats)); + } + } else { + struct be_cmd_resp_get_stats_v0 *resp = + adapter->stats_cmd.va; + + be_dws_le_to_cpu(&resp->hw_stats, + sizeof(resp->hw_stats)); + } be_parse_stats(adapter); + netdev_stats_update(adapter); adapter->stats_cmd_sent = false; } } else { diff --git a/trunk/drivers/net/benet/be_cmds.h b/trunk/drivers/net/benet/be_cmds.h index d3342c452c6b..8e4d48824fe9 100644 --- a/trunk/drivers/net/benet/be_cmds.h +++ b/trunk/drivers/net/benet/be_cmds.h @@ -693,7 +693,8 @@ struct be_cmd_resp_get_stats_v0 { struct be_hw_stats_v0 hw_stats; }; -struct lancer_pport_stats { +#define make_64bit_val(hi_32, lo_32) (((u64)hi_32<<32) | lo_32) +struct lancer_cmd_pport_stats { u32 tx_packets_lo; u32 tx_packets_hi; u32 tx_unicast_packets_lo; @@ -870,16 +871,16 @@ struct lancer_cmd_req_pport_stats { struct be_cmd_req_hdr hdr; union { struct pport_stats_params params; - u8 rsvd[sizeof(struct lancer_pport_stats)]; + u8 rsvd[sizeof(struct lancer_cmd_pport_stats)]; } cmd_params; }; struct lancer_cmd_resp_pport_stats { struct be_cmd_resp_hdr hdr; - struct lancer_pport_stats pport_stats; + struct lancer_cmd_pport_stats pport_stats; }; -static inline struct lancer_pport_stats* +static inline struct lancer_cmd_pport_stats* pport_stats_from_cmd(struct be_adapter *adapter) { struct lancer_cmd_resp_pport_stats *cmd = adapter->stats_cmd.va; @@ -1382,7 +1383,8 @@ struct be_cmd_resp_get_stats_v1 { struct be_hw_stats_v1 hw_stats; }; -static inline void *hw_stats_from_cmd(struct be_adapter *adapter) +static inline void * +hw_stats_from_cmd(struct be_adapter *adapter) { if (adapter->generation == BE_GEN3) { struct be_cmd_resp_get_stats_v1 *cmd = adapter->stats_cmd.va; @@ -1395,6 +1397,34 @@ static inline void *hw_stats_from_cmd(struct be_adapter *adapter) } } +static inline void *be_port_rxf_stats_from_cmd(struct be_adapter *adapter) +{ + if (adapter->generation == BE_GEN3) { + struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); + struct be_rxf_stats_v1 *rxf_stats = &hw_stats->rxf; + + return &rxf_stats->port[adapter->port_num]; + } else { + struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); + struct be_rxf_stats_v0 *rxf_stats = &hw_stats->rxf; + + return &rxf_stats->port[adapter->port_num]; + } +} + +static inline void *be_rxf_stats_from_cmd(struct be_adapter *adapter) +{ + if (adapter->generation == BE_GEN3) { + struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); + + return &hw_stats->rxf; + } else { + struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); + + return &hw_stats->rxf; + } +} + static inline void *be_erx_stats_from_cmd(struct be_adapter *adapter) { if (adapter->generation == BE_GEN3) { @@ -1408,6 +1438,19 @@ static inline void *be_erx_stats_from_cmd(struct be_adapter *adapter) } } +static inline void *be_pmem_stats_from_cmd(struct be_adapter *adapter) +{ + if (adapter->generation == BE_GEN3) { + struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); + + return &hw_stats->pmem; + } else { + struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); + + return &hw_stats->pmem; + } +} + extern int be_pci_fnum_get(struct be_adapter *adapter); extern int be_cmd_POST(struct be_adapter *adapter); extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, diff --git a/trunk/drivers/net/benet/be_ethtool.c b/trunk/drivers/net/benet/be_ethtool.c index e92a8d8813a0..7fd8130d86ea 100644 --- a/trunk/drivers/net/benet/be_ethtool.c +++ b/trunk/drivers/net/benet/be_ethtool.c @@ -26,18 +26,33 @@ struct be_ethtool_stat { int offset; }; -enum {DRVSTAT_TX, DRVSTAT_RX, DRVSTAT}; +enum {NETSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT, + DRVSTAT}; #define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \ offsetof(_struct, field) +#define NETSTAT_INFO(field) #field, NETSTAT,\ + FIELDINFO(struct net_device_stats,\ + field) #define DRVSTAT_TX_INFO(field) #field, DRVSTAT_TX,\ FIELDINFO(struct be_tx_stats, field) #define DRVSTAT_RX_INFO(field) #field, DRVSTAT_RX,\ FIELDINFO(struct be_rx_stats, field) +#define ERXSTAT_INFO(field) #field, ERXSTAT,\ + FIELDINFO(struct be_erx_stats_v1, field) #define DRVSTAT_INFO(field) #field, DRVSTAT,\ - FIELDINFO(struct be_drv_stats, field) + FIELDINFO(struct be_drv_stats, \ + field) static const struct be_ethtool_stat et_stats[] = { - {DRVSTAT_INFO(tx_events)}, + {NETSTAT_INFO(rx_packets)}, + {NETSTAT_INFO(tx_packets)}, + {NETSTAT_INFO(rx_bytes)}, + {NETSTAT_INFO(tx_bytes)}, + {NETSTAT_INFO(rx_errors)}, + {NETSTAT_INFO(tx_errors)}, + {NETSTAT_INFO(rx_dropped)}, + {NETSTAT_INFO(tx_dropped)}, + {DRVSTAT_INFO(be_tx_events)}, {DRVSTAT_INFO(rx_crc_errors)}, {DRVSTAT_INFO(rx_alignment_symbol_errors)}, {DRVSTAT_INFO(rx_pause_frames)}, @@ -56,6 +71,9 @@ static const struct be_ethtool_stat et_stats[] = { {DRVSTAT_INFO(rx_ip_checksum_errs)}, {DRVSTAT_INFO(rx_tcp_checksum_errs)}, {DRVSTAT_INFO(rx_udp_checksum_errs)}, + {DRVSTAT_INFO(rx_switched_unicast_packets)}, + {DRVSTAT_INFO(rx_switched_multicast_packets)}, + {DRVSTAT_INFO(rx_switched_broadcast_packets)}, {DRVSTAT_INFO(tx_pauseframes)}, {DRVSTAT_INFO(tx_controlframes)}, {DRVSTAT_INFO(rx_priority_pause_frames)}, @@ -74,33 +92,28 @@ static const struct be_ethtool_stat et_stats[] = { }; #define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats) -/* Stats related to multi RX queues: get_stats routine assumes bytes, pkts - * are first and second members respectively. - */ +/* Stats related to multi RX queues */ static const struct be_ethtool_stat et_rx_stats[] = { - {DRVSTAT_RX_INFO(rx_bytes)},/* If moving this member see above note */ - {DRVSTAT_RX_INFO(rx_pkts)}, /* If moving this member see above note */ + {DRVSTAT_RX_INFO(rx_bytes)}, + {DRVSTAT_RX_INFO(rx_pkts)}, + {DRVSTAT_RX_INFO(rx_rate)}, {DRVSTAT_RX_INFO(rx_polls)}, {DRVSTAT_RX_INFO(rx_events)}, {DRVSTAT_RX_INFO(rx_compl)}, {DRVSTAT_RX_INFO(rx_mcast_pkts)}, {DRVSTAT_RX_INFO(rx_post_fail)}, - {DRVSTAT_RX_INFO(rx_drops_no_skbs)}, - {DRVSTAT_RX_INFO(rx_drops_no_frags)} + {DRVSTAT_RX_INFO(rx_dropped)}, + {ERXSTAT_INFO(rx_drops_no_fragments)} }; #define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats)) -/* Stats related to multi TX queues: get_stats routine assumes compl is the - * first member - */ +/* Stats related to multi TX queues */ static const struct be_ethtool_stat et_tx_stats[] = { - {DRVSTAT_TX_INFO(tx_compl)}, /* If moving this member see above note */ - {DRVSTAT_TX_INFO(tx_bytes)}, - {DRVSTAT_TX_INFO(tx_pkts)}, - {DRVSTAT_TX_INFO(tx_reqs)}, - {DRVSTAT_TX_INFO(tx_wrbs)}, - {DRVSTAT_TX_INFO(tx_compl)}, - {DRVSTAT_TX_INFO(tx_stops)} + {DRVSTAT_TX_INFO(be_tx_rate)}, + {DRVSTAT_TX_INFO(be_tx_reqs)}, + {DRVSTAT_TX_INFO(be_tx_wrbs)}, + {DRVSTAT_TX_INFO(be_tx_stops)}, + {DRVSTAT_TX_INFO(be_tx_compl)} }; #define ETHTOOL_TXSTATS_NUM (ARRAY_SIZE(et_tx_stats)) @@ -247,49 +260,50 @@ be_get_ethtool_stats(struct net_device *netdev, struct be_adapter *adapter = netdev_priv(netdev); struct be_rx_obj *rxo; struct be_tx_obj *txo; - void *p; - unsigned int i, j, base = 0, start; + void *p = NULL; + int i, j, base; for (i = 0; i < ETHTOOL_STATS_NUM; i++) { - p = (u8 *)&adapter->drv_stats + et_stats[i].offset; - data[i] = *(u32 *)p; + switch (et_stats[i].type) { + case NETSTAT: + p = &netdev->stats; + break; + case DRVSTAT: + p = &adapter->drv_stats; + break; + } + + p = (u8 *)p + et_stats[i].offset; + data[i] = (et_stats[i].size == sizeof(u64)) ? + *(u64 *)p: *(u32 *)p; } - base += ETHTOOL_STATS_NUM; + base = ETHTOOL_STATS_NUM; for_all_rx_queues(adapter, rxo, j) { - struct be_rx_stats *stats = rx_stats(rxo); - - do { - start = u64_stats_fetch_begin_bh(&stats->sync); - data[base] = stats->rx_bytes; - data[base + 1] = stats->rx_pkts; - } while (u64_stats_fetch_retry_bh(&stats->sync, start)); - - for (i = 2; i < ETHTOOL_RXSTATS_NUM; i++) { - p = (u8 *)stats + et_rx_stats[i].offset; - data[base + i] = *(u32 *)p; + for (i = 0; i < ETHTOOL_RXSTATS_NUM; i++) { + switch (et_rx_stats[i].type) { + case DRVSTAT_RX: + p = (u8 *)&rxo->stats + et_rx_stats[i].offset; + break; + case ERXSTAT: + p = (u32 *)be_erx_stats_from_cmd(adapter) + + rxo->q.id; + break; + } + data[base + j * ETHTOOL_RXSTATS_NUM + i] = + (et_rx_stats[i].size == sizeof(u64)) ? + *(u64 *)p: *(u32 *)p; } - base += ETHTOOL_RXSTATS_NUM; } + base = ETHTOOL_STATS_NUM + adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM; for_all_tx_queues(adapter, txo, j) { - struct be_tx_stats *stats = tx_stats(txo); - - do { - start = u64_stats_fetch_begin_bh(&stats->sync_compl); - data[base] = stats->tx_compl; - } while (u64_stats_fetch_retry_bh(&stats->sync_compl, start)); - - do { - start = u64_stats_fetch_begin_bh(&stats->sync); - for (i = 1; i < ETHTOOL_TXSTATS_NUM; i++) { - p = (u8 *)stats + et_tx_stats[i].offset; - data[base + i] = - (et_tx_stats[i].size == sizeof(u64)) ? - *(u64 *)p : *(u32 *)p; - } - } while (u64_stats_fetch_retry_bh(&stats->sync, start)); - base += ETHTOOL_TXSTATS_NUM; + for (i = 0; i < ETHTOOL_TXSTATS_NUM; i++) { + p = (u8 *)&txo->stats + et_tx_stats[i].offset; + data[base + j * ETHTOOL_TXSTATS_NUM + i] = + (et_tx_stats[i].size == sizeof(u64)) ? + *(u64 *)p: *(u32 *)p; + } } } diff --git a/trunk/drivers/net/benet/be_main.c b/trunk/drivers/net/benet/be_main.c index 9f2f66c66be6..c411bb1845fd 100644 --- a/trunk/drivers/net/benet/be_main.c +++ b/trunk/drivers/net/benet/be_main.c @@ -245,14 +245,14 @@ static int be_mac_addr_set(struct net_device *netdev, void *p) static void populate_be2_stats(struct be_adapter *adapter) { - struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); - struct be_pmem_stats *pmem_sts = &hw_stats->pmem; - struct be_rxf_stats_v0 *rxf_stats = &hw_stats->rxf; - struct be_port_rxf_stats_v0 *port_stats = - &rxf_stats->port[adapter->port_num]; + struct be_drv_stats *drvs = &adapter->drv_stats; + struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter); + struct be_port_rxf_stats_v0 *port_stats = + be_port_rxf_stats_from_cmd(adapter); + struct be_rxf_stats_v0 *rxf_stats = + be_rxf_stats_from_cmd(adapter); - be_dws_le_to_cpu(hw_stats, sizeof(*hw_stats)); drvs->rx_pause_frames = port_stats->rx_pause_frames; drvs->rx_crc_errors = port_stats->rx_crc_errors; drvs->rx_control_frames = port_stats->rx_control_frames; @@ -267,10 +267,12 @@ static void populate_be2_stats(struct be_adapter *adapter) drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small; drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short; drvs->rx_out_range_errors = port_stats->rx_out_range_errors; - drvs->rx_input_fifo_overflow_drop = port_stats->rx_input_fifo_overflow; + drvs->rx_input_fifo_overflow_drop = + port_stats->rx_input_fifo_overflow; drvs->rx_dropped_header_too_small = port_stats->rx_dropped_header_too_small; - drvs->rx_address_match_errors = port_stats->rx_address_match_errors; + drvs->rx_address_match_errors = + port_stats->rx_address_match_errors; drvs->rx_alignment_symbol_errors = port_stats->rx_alignment_symbol_errors; @@ -278,30 +280,36 @@ static void populate_be2_stats(struct be_adapter *adapter) drvs->tx_controlframes = port_stats->tx_controlframes; if (adapter->port_num) - drvs->jabber_events = rxf_stats->port1_jabber_events; + drvs->jabber_events = + rxf_stats->port1_jabber_events; else - drvs->jabber_events = rxf_stats->port0_jabber_events; + drvs->jabber_events = + rxf_stats->port0_jabber_events; drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf; drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb; drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr; drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring; drvs->forwarded_packets = rxf_stats->forwarded_packets; drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu; - drvs->rx_drops_no_tpre_descr = rxf_stats->rx_drops_no_tpre_descr; - drvs->rx_drops_too_many_frags = rxf_stats->rx_drops_too_many_frags; + drvs->rx_drops_no_tpre_descr = + rxf_stats->rx_drops_no_tpre_descr; + drvs->rx_drops_too_many_frags = + rxf_stats->rx_drops_too_many_frags; adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops; } static void populate_be3_stats(struct be_adapter *adapter) { - struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); - struct be_pmem_stats *pmem_sts = &hw_stats->pmem; - struct be_rxf_stats_v1 *rxf_stats = &hw_stats->rxf; - struct be_port_rxf_stats_v1 *port_stats = - &rxf_stats->port[adapter->port_num]; struct be_drv_stats *drvs = &adapter->drv_stats; + struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter); - be_dws_le_to_cpu(hw_stats, sizeof(*hw_stats)); + struct be_rxf_stats_v1 *rxf_stats = + be_rxf_stats_from_cmd(adapter); + struct be_port_rxf_stats_v1 *port_stats = + be_port_rxf_stats_from_cmd(adapter); + + drvs->rx_priority_pause_frames = 0; + drvs->pmem_fifo_overflow_drop = 0; drvs->rx_pause_frames = port_stats->rx_pause_frames; drvs->rx_crc_errors = port_stats->rx_crc_errors; drvs->rx_control_frames = port_stats->rx_control_frames; @@ -319,10 +327,12 @@ static void populate_be3_stats(struct be_adapter *adapter) port_stats->rx_dropped_header_too_small; drvs->rx_input_fifo_overflow_drop = port_stats->rx_input_fifo_overflow_drop; - drvs->rx_address_match_errors = port_stats->rx_address_match_errors; + drvs->rx_address_match_errors = + port_stats->rx_address_match_errors; drvs->rx_alignment_symbol_errors = port_stats->rx_alignment_symbol_errors; - drvs->rxpp_fifo_overflow_drop = port_stats->rxpp_fifo_overflow_drop; + drvs->rxpp_fifo_overflow_drop = + port_stats->rxpp_fifo_overflow_drop; drvs->tx_pauseframes = port_stats->tx_pauseframes; drvs->tx_controlframes = port_stats->tx_controlframes; drvs->jabber_events = port_stats->jabber_events; @@ -332,8 +342,10 @@ static void populate_be3_stats(struct be_adapter *adapter) drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring; drvs->forwarded_packets = rxf_stats->forwarded_packets; drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu; - drvs->rx_drops_no_tpre_descr = rxf_stats->rx_drops_no_tpre_descr; - drvs->rx_drops_too_many_frags = rxf_stats->rx_drops_too_many_frags; + drvs->rx_drops_no_tpre_descr = + rxf_stats->rx_drops_no_tpre_descr; + drvs->rx_drops_too_many_frags = + rxf_stats->rx_drops_too_many_frags; adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops; } @@ -341,15 +353,22 @@ static void populate_lancer_stats(struct be_adapter *adapter) { struct be_drv_stats *drvs = &adapter->drv_stats; - struct lancer_pport_stats *pport_stats = - pport_stats_from_cmd(adapter); - - be_dws_le_to_cpu(pport_stats, sizeof(*pport_stats)); - drvs->rx_pause_frames = pport_stats->rx_pause_frames_lo; - drvs->rx_crc_errors = pport_stats->rx_crc_errors_lo; - drvs->rx_control_frames = pport_stats->rx_control_frames_lo; + struct lancer_cmd_pport_stats *pport_stats = pport_stats_from_cmd + (adapter); + drvs->rx_priority_pause_frames = 0; + drvs->pmem_fifo_overflow_drop = 0; + drvs->rx_pause_frames = + make_64bit_val(pport_stats->rx_pause_frames_hi, + pport_stats->rx_pause_frames_lo); + drvs->rx_crc_errors = make_64bit_val(pport_stats->rx_crc_errors_hi, + pport_stats->rx_crc_errors_lo); + drvs->rx_control_frames = + make_64bit_val(pport_stats->rx_control_frames_hi, + pport_stats->rx_control_frames_lo); drvs->rx_in_range_errors = pport_stats->rx_in_range_errors; - drvs->rx_frame_too_long = pport_stats->rx_frames_too_long_lo; + drvs->rx_frame_too_long = + make_64bit_val(pport_stats->rx_internal_mac_errors_hi, + pport_stats->rx_frames_too_long_lo); drvs->rx_dropped_runt = pport_stats->rx_dropped_runt; drvs->rx_ip_checksum_errs = pport_stats->rx_ip_checksum_errors; drvs->rx_tcp_checksum_errs = pport_stats->rx_tcp_checksum_errors; @@ -363,24 +382,32 @@ static void populate_lancer_stats(struct be_adapter *adapter) pport_stats->rx_dropped_header_too_small; drvs->rx_input_fifo_overflow_drop = pport_stats->rx_fifo_overflow; drvs->rx_address_match_errors = pport_stats->rx_address_match_errors; - drvs->rx_alignment_symbol_errors = pport_stats->rx_symbol_errors_lo; + drvs->rx_alignment_symbol_errors = + make_64bit_val(pport_stats->rx_symbol_errors_hi, + pport_stats->rx_symbol_errors_lo); drvs->rxpp_fifo_overflow_drop = pport_stats->rx_fifo_overflow; - drvs->tx_pauseframes = pport_stats->tx_pause_frames_lo; - drvs->tx_controlframes = pport_stats->tx_control_frames_lo; + drvs->tx_pauseframes = make_64bit_val(pport_stats->tx_pause_frames_hi, + pport_stats->tx_pause_frames_lo); + drvs->tx_controlframes = + make_64bit_val(pport_stats->tx_control_frames_hi, + pport_stats->tx_control_frames_lo); drvs->jabber_events = pport_stats->rx_jabbers; + drvs->rx_drops_no_pbuf = 0; + drvs->rx_drops_no_txpb = 0; + drvs->rx_drops_no_erx_descr = 0; drvs->rx_drops_invalid_ring = pport_stats->rx_drops_invalid_queue; - drvs->forwarded_packets = pport_stats->num_forwards_lo; - drvs->rx_drops_mtu = pport_stats->rx_drops_mtu_lo; + drvs->forwarded_packets = make_64bit_val(pport_stats->num_forwards_hi, + pport_stats->num_forwards_lo); + drvs->rx_drops_mtu = make_64bit_val(pport_stats->rx_drops_mtu_hi, + pport_stats->rx_drops_mtu_lo); + drvs->rx_drops_no_tpre_descr = 0; drvs->rx_drops_too_many_frags = - pport_stats->rx_drops_too_many_frags_lo; + make_64bit_val(pport_stats->rx_drops_too_many_frags_hi, + pport_stats->rx_drops_too_many_frags_lo); } void be_parse_stats(struct be_adapter *adapter) { - struct be_erx_stats_v1 *erx = be_erx_stats_from_cmd(adapter); - struct be_rx_obj *rxo; - int i; - if (adapter->generation == BE_GEN3) { if (lancer_chip(adapter)) populate_lancer_stats(adapter); @@ -389,51 +416,50 @@ void be_parse_stats(struct be_adapter *adapter) } else { populate_be2_stats(adapter); } - - /* as erx_v1 is longer than v0, ok to use v1 defn for v0 access */ - for_all_rx_queues(adapter, rxo, i) - rx_stats(rxo)->rx_drops_no_frags = - erx->rx_drops_no_fragments[rxo->q.id]; } -static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev, - struct rtnl_link_stats64 *stats) +void netdev_stats_update(struct be_adapter *adapter) { - struct be_adapter *adapter = netdev_priv(netdev); struct be_drv_stats *drvs = &adapter->drv_stats; + struct net_device_stats *dev_stats = &adapter->netdev->stats; struct be_rx_obj *rxo; struct be_tx_obj *txo; - u64 pkts, bytes; - unsigned int start; + unsigned long pkts = 0, bytes = 0, mcast = 0, drops = 0; int i; for_all_rx_queues(adapter, rxo, i) { - const struct be_rx_stats *rx_stats = rx_stats(rxo); - do { - start = u64_stats_fetch_begin_bh(&rx_stats->sync); - pkts = rx_stats(rxo)->rx_pkts; - bytes = rx_stats(rxo)->rx_bytes; - } while (u64_stats_fetch_retry_bh(&rx_stats->sync, start)); - stats->rx_packets += pkts; - stats->rx_bytes += bytes; - stats->multicast += rx_stats(rxo)->rx_mcast_pkts; - stats->rx_dropped += rx_stats(rxo)->rx_drops_no_skbs + - rx_stats(rxo)->rx_drops_no_frags; + pkts += rx_stats(rxo)->rx_pkts; + bytes += rx_stats(rxo)->rx_bytes; + mcast += rx_stats(rxo)->rx_mcast_pkts; + drops += rx_stats(rxo)->rx_dropped; + /* no space in linux buffers: best possible approximation */ + if (adapter->generation == BE_GEN3) { + if (!(lancer_chip(adapter))) { + struct be_erx_stats_v1 *erx = + be_erx_stats_from_cmd(adapter); + drops += erx->rx_drops_no_fragments[rxo->q.id]; + } + } else { + struct be_erx_stats_v0 *erx = + be_erx_stats_from_cmd(adapter); + drops += erx->rx_drops_no_fragments[rxo->q.id]; + } } + dev_stats->rx_packets = pkts; + dev_stats->rx_bytes = bytes; + dev_stats->multicast = mcast; + dev_stats->rx_dropped = drops; + pkts = bytes = 0; for_all_tx_queues(adapter, txo, i) { - const struct be_tx_stats *tx_stats = tx_stats(txo); - do { - start = u64_stats_fetch_begin_bh(&tx_stats->sync); - pkts = tx_stats(txo)->tx_pkts; - bytes = tx_stats(txo)->tx_bytes; - } while (u64_stats_fetch_retry_bh(&tx_stats->sync, start)); - stats->tx_packets += pkts; - stats->tx_bytes += bytes; + pkts += tx_stats(txo)->be_tx_pkts; + bytes += tx_stats(txo)->be_tx_bytes; } + dev_stats->tx_packets = pkts; + dev_stats->tx_bytes = bytes; /* bad pkts received */ - stats->rx_errors = drvs->rx_crc_errors + + dev_stats->rx_errors = drvs->rx_crc_errors + drvs->rx_alignment_symbol_errors + drvs->rx_in_range_errors + drvs->rx_out_range_errors + @@ -442,24 +468,26 @@ static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev, drvs->rx_dropped_too_short + drvs->rx_dropped_header_too_small + drvs->rx_dropped_tcp_length + - drvs->rx_dropped_runt; + drvs->rx_dropped_runt + + drvs->rx_tcp_checksum_errs + + drvs->rx_ip_checksum_errs + + drvs->rx_udp_checksum_errs; /* detailed rx errors */ - stats->rx_length_errors = drvs->rx_in_range_errors + + dev_stats->rx_length_errors = drvs->rx_in_range_errors + drvs->rx_out_range_errors + drvs->rx_frame_too_long; - stats->rx_crc_errors = drvs->rx_crc_errors; + dev_stats->rx_crc_errors = drvs->rx_crc_errors; /* frame alignment errors */ - stats->rx_frame_errors = drvs->rx_alignment_symbol_errors; + dev_stats->rx_frame_errors = drvs->rx_alignment_symbol_errors; /* receiver fifo overrun */ /* drops_no_pbuf is no per i/f, it's per BE card */ - stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop + + dev_stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop + drvs->rx_input_fifo_overflow_drop + drvs->rx_drops_no_pbuf; - return stats; } void be_link_status_update(struct be_adapter *adapter, bool link_up) @@ -480,19 +508,89 @@ void be_link_status_update(struct be_adapter *adapter, bool link_up) } } +/* Update the EQ delay n BE based on the RX frags consumed / sec */ +static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo) +{ + struct be_eq_obj *rx_eq = &rxo->rx_eq; + struct be_rx_stats *stats = &rxo->stats; + ulong now = jiffies; + u32 eqd; + + if (!rx_eq->enable_aic) + return; + + /* Wrapped around */ + if (time_before(now, stats->rx_fps_jiffies)) { + stats->rx_fps_jiffies = now; + return; + } + + /* Update once a second */ + if ((now - stats->rx_fps_jiffies) < HZ) + return; + + stats->rx_fps = (stats->rx_frags - stats->prev_rx_frags) / + ((now - stats->rx_fps_jiffies) / HZ); + + stats->rx_fps_jiffies = now; + stats->prev_rx_frags = stats->rx_frags; + eqd = stats->rx_fps / 110000; + eqd = eqd << 3; + if (eqd > rx_eq->max_eqd) + eqd = rx_eq->max_eqd; + if (eqd < rx_eq->min_eqd) + eqd = rx_eq->min_eqd; + if (eqd < 10) + eqd = 0; + if (eqd != rx_eq->cur_eqd) + be_cmd_modify_eqd(adapter, rx_eq->q.id, eqd); + + rx_eq->cur_eqd = eqd; +} + +static u32 be_calc_rate(u64 bytes, unsigned long ticks) +{ + u64 rate = bytes; + + do_div(rate, ticks / HZ); + rate <<= 3; /* bytes/sec -> bits/sec */ + do_div(rate, 1000000ul); /* MB/Sec */ + + return rate; +} + +static void be_tx_rate_update(struct be_tx_obj *txo) +{ + struct be_tx_stats *stats = tx_stats(txo); + ulong now = jiffies; + + /* Wrapped around? */ + if (time_before(now, stats->be_tx_jiffies)) { + stats->be_tx_jiffies = now; + return; + } + + /* Update tx rate once in two seconds */ + if ((now - stats->be_tx_jiffies) > 2 * HZ) { + stats->be_tx_rate = be_calc_rate(stats->be_tx_bytes + - stats->be_tx_bytes_prev, + now - stats->be_tx_jiffies); + stats->be_tx_jiffies = now; + stats->be_tx_bytes_prev = stats->be_tx_bytes; + } +} + static void be_tx_stats_update(struct be_tx_obj *txo, u32 wrb_cnt, u32 copied, u32 gso_segs, bool stopped) { struct be_tx_stats *stats = tx_stats(txo); - u64_stats_update_begin(&stats->sync); - stats->tx_reqs++; - stats->tx_wrbs += wrb_cnt; - stats->tx_bytes += copied; - stats->tx_pkts += (gso_segs ? gso_segs : 1); + stats->be_tx_reqs++; + stats->be_tx_wrbs += wrb_cnt; + stats->be_tx_bytes += copied; + stats->be_tx_pkts += (gso_segs ? gso_segs : 1); if (stopped) - stats->tx_stops++; - u64_stats_update_end(&stats->sync); + stats->be_tx_stops++; } /* Determine number of WRB entries needed to xmit data in an skb */ @@ -907,17 +1005,10 @@ static int be_set_vf_tx_rate(struct net_device *netdev, return status; } -static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo) +static void be_rx_rate_update(struct be_rx_obj *rxo) { - struct be_eq_obj *rx_eq = &rxo->rx_eq; - struct be_rx_stats *stats = rx_stats(rxo); + struct be_rx_stats *stats = &rxo->stats; ulong now = jiffies; - ulong delta = now - stats->rx_jiffies; - u64 pkts; - unsigned int start, eqd; - - if (!rx_eq->enable_aic) - return; /* Wrapped around */ if (time_before(now, stats->rx_jiffies)) { @@ -925,46 +1016,29 @@ static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo) return; } - /* Update once a second */ - if (delta < HZ) + /* Update the rate once in two seconds */ + if ((now - stats->rx_jiffies) < 2 * HZ) return; - do { - start = u64_stats_fetch_begin_bh(&stats->sync); - pkts = stats->rx_pkts; - } while (u64_stats_fetch_retry_bh(&stats->sync, start)); - - stats->rx_pps = (pkts - stats->rx_pkts_prev) / (delta / HZ); - stats->rx_pkts_prev = pkts; + stats->rx_rate = be_calc_rate(stats->rx_bytes - stats->rx_bytes_prev, + now - stats->rx_jiffies); stats->rx_jiffies = now; - eqd = stats->rx_pps / 110000; - eqd = eqd << 3; - if (eqd > rx_eq->max_eqd) - eqd = rx_eq->max_eqd; - if (eqd < rx_eq->min_eqd) - eqd = rx_eq->min_eqd; - if (eqd < 10) - eqd = 0; - if (eqd != rx_eq->cur_eqd) { - be_cmd_modify_eqd(adapter, rx_eq->q.id, eqd); - rx_eq->cur_eqd = eqd; - } + stats->rx_bytes_prev = stats->rx_bytes; } static void be_rx_stats_update(struct be_rx_obj *rxo, struct be_rx_compl_info *rxcp) { - struct be_rx_stats *stats = rx_stats(rxo); + struct be_rx_stats *stats = &rxo->stats; - u64_stats_update_begin(&stats->sync); stats->rx_compl++; + stats->rx_frags += rxcp->num_rcvd; stats->rx_bytes += rxcp->pkt_size; stats->rx_pkts++; if (rxcp->pkt_type == BE_MULTICAST_PACKET) stats->rx_mcast_pkts++; if (rxcp->err) - stats->rx_compl_err++; - u64_stats_update_end(&stats->sync); + stats->rxcp_err++; } static inline bool csum_passed(struct be_rx_compl_info *rxcp) @@ -1100,7 +1174,7 @@ static void be_rx_compl_process(struct be_adapter *adapter, skb = netdev_alloc_skb_ip_align(netdev, BE_HDR_LEN); if (unlikely(!skb)) { - rx_stats(rxo)->rx_drops_no_skbs++; + rxo->stats.rx_dropped++; be_rx_compl_discard(adapter, rxo, rxcp); return; } @@ -1315,7 +1389,7 @@ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp) if (!pagep) { pagep = be_alloc_pages(adapter->big_page_size, gfp); if (unlikely(!pagep)) { - rx_stats(rxo)->rx_post_fail++; + rxo->stats.rx_post_fail++; break; } page_dmaaddr = dma_map_page(&adapter->pdev->dev, pagep, @@ -1825,7 +1899,7 @@ static int be_poll_rx(struct napi_struct *napi, int budget) struct be_rx_compl_info *rxcp; u32 work_done; - rx_stats(rxo)->rx_polls++; + rxo->stats.rx_polls++; for (work_done = 0; work_done < budget; work_done++) { rxcp = be_rx_compl_get(rxo); if (!rxcp) @@ -1894,9 +1968,8 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) netif_wake_subqueue(adapter->netdev, i); } - u64_stats_update_begin(&tx_stats(txo)->sync_compl); - tx_stats(txo)->tx_compl += tx_compl; - u64_stats_update_end(&tx_stats(txo)->sync_compl); + adapter->drv_stats.be_tx_events++; + txo->stats.be_tx_compl += tx_compl; } } @@ -1910,7 +1983,6 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) napi_complete(napi); be_eq_notify(adapter, tx_eq->q.id, true, false, 0); - adapter->drv_stats.tx_events++; return 1; } @@ -1959,6 +2031,7 @@ static void be_worker(struct work_struct *work) struct be_adapter *adapter = container_of(work, struct be_adapter, work.work); struct be_rx_obj *rxo; + struct be_tx_obj *txo; int i; if (!adapter->ue_detected && !lancer_chip(adapter)) @@ -1987,7 +2060,11 @@ static void be_worker(struct work_struct *work) be_cmd_get_stats(adapter, &adapter->stats_cmd); } + for_all_tx_queues(adapter, txo, i) + be_tx_rate_update(txo); + for_all_rx_queues(adapter, rxo, i) { + be_rx_rate_update(rxo); be_rx_eqd_update(adapter, rxo); if (rxo->rx_post_starved) { @@ -2861,7 +2938,6 @@ static struct net_device_ops be_netdev_ops = { .ndo_set_rx_mode = be_set_multicast_list, .ndo_set_mac_address = be_mac_addr_set, .ndo_change_mtu = be_change_mtu, - .ndo_get_stats64 = be_get_stats64, .ndo_validate_addr = eth_validate_addr, .ndo_vlan_rx_add_vid = be_vlan_add_vid, .ndo_vlan_rx_kill_vid = be_vlan_rem_vid, diff --git a/trunk/drivers/net/bna/bfa_ioc_ct.c b/trunk/drivers/net/bna/bfa_ioc_ct.c index 29b5fd0ca740..87aecdf22cf9 100644 --- a/trunk/drivers/net/bna/bfa_ioc_ct.c +++ b/trunk/drivers/net/bna/bfa_ioc_ct.c @@ -50,32 +50,26 @@ static enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode); static struct bfa_ioc_hwif nw_hwif_ct; -static void -bfa_ioc_set_ctx_hwif(struct bfa_ioc *ioc, struct bfa_ioc_hwif *hwif) -{ - hwif->ioc_firmware_lock = bfa_ioc_ct_firmware_lock; - hwif->ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock; - hwif->ioc_notify_fail = bfa_ioc_ct_notify_fail; - hwif->ioc_ownership_reset = bfa_ioc_ct_ownership_reset; - hwif->ioc_sync_start = bfa_ioc_ct_sync_start; - hwif->ioc_sync_join = bfa_ioc_ct_sync_join; - hwif->ioc_sync_leave = bfa_ioc_ct_sync_leave; - hwif->ioc_sync_ack = bfa_ioc_ct_sync_ack; - hwif->ioc_sync_complete = bfa_ioc_ct_sync_complete; -} - /** * Called from bfa_ioc_attach() to map asic specific calls. */ void bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc) { - bfa_ioc_set_ctx_hwif(ioc, &nw_hwif_ct); - nw_hwif_ct.ioc_pll_init = bfa_ioc_ct_pll_init; + nw_hwif_ct.ioc_firmware_lock = bfa_ioc_ct_firmware_lock; + nw_hwif_ct.ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock; nw_hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init; nw_hwif_ct.ioc_map_port = bfa_ioc_ct_map_port; nw_hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set; + nw_hwif_ct.ioc_notify_fail = bfa_ioc_ct_notify_fail; + nw_hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset; + nw_hwif_ct.ioc_sync_start = bfa_ioc_ct_sync_start; + nw_hwif_ct.ioc_sync_join = bfa_ioc_ct_sync_join; + nw_hwif_ct.ioc_sync_leave = bfa_ioc_ct_sync_leave; + nw_hwif_ct.ioc_sync_ack = bfa_ioc_ct_sync_ack; + nw_hwif_ct.ioc_sync_complete = bfa_ioc_ct_sync_complete; + ioc->ioc_hwif = &nw_hwif_ct; } @@ -89,6 +83,12 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc) u32 usecnt; struct bfi_ioc_image_hdr fwhdr; + /** + * Firmware match check is relevant only for CNA. + */ + if (!ioc->cna) + return true; + /** * If bios boot (flash based) -- do not increment usage count */ @@ -139,6 +139,12 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc) { u32 usecnt; + /** + * Firmware lock is relevant only for CNA. + */ + if (!ioc->cna) + return; + /** * If bios boot (flash based) -- do not decrement usage count */ @@ -303,7 +309,7 @@ bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix) /** * If already in desired mode, do not change anything */ - if ((!msix && mode) || (msix && !mode)) + if (!msix && mode) return; if (msix) diff --git a/trunk/drivers/net/ipg.c b/trunk/drivers/net/ipg.c index b470281158e9..d4aa40adf1e9 100644 --- a/trunk/drivers/net/ipg.c +++ b/trunk/drivers/net/ipg.c @@ -20,9 +20,6 @@ * http://www.icplus.com.tw * jesse@icplus.com.tw */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -70,7 +67,7 @@ MODULE_LICENSE("GPL"); * Variable record -- index by leading revision/length * Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN */ -static const unsigned short DefaultPhyParam[] = { +static unsigned short DefaultPhyParam[] = { /* 11/12/03 IP1000A v1-3 rev=0x40 */ /*-------------------------------------------------------------------------- (0x4000|(15*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 22, 0x85bd, 24, 0xfff2, @@ -88,7 +85,7 @@ static const unsigned short DefaultPhyParam[] = { 0x0000 }; -static const char * const ipg_brand_name[] = { +static const char *ipg_brand_name[] = { "IC PLUS IP1000 1000/100/10 based NIC", "Sundance Technology ST2021 based NIC", "Tamarack Microelectronics TC9020/9021 based NIC", @@ -121,23 +118,23 @@ static void ipg_dump_rfdlist(struct net_device *dev) IPG_DEBUG_MSG("_dump_rfdlist\n"); - netdev_info(dev, "rx_current = %02x\n", sp->rx_current); - netdev_info(dev, "rx_dirty = %02x\n", sp->rx_dirty); - netdev_info(dev, "RFDList start address = %016lx\n", - (unsigned long)sp->rxd_map); - netdev_info(dev, "RFDListPtr register = %08x%08x\n", - ipg_r32(IPG_RFDLISTPTR1), ipg_r32(IPG_RFDLISTPTR0)); + printk(KERN_INFO "rx_current = %2.2x\n", sp->rx_current); + printk(KERN_INFO "rx_dirty = %2.2x\n", sp->rx_dirty); + printk(KERN_INFO "RFDList start address = %16.16lx\n", + (unsigned long) sp->rxd_map); + printk(KERN_INFO "RFDListPtr register = %8.8x%8.8x\n", + ipg_r32(IPG_RFDLISTPTR1), ipg_r32(IPG_RFDLISTPTR0)); for (i = 0; i < IPG_RFDLIST_LENGTH; i++) { offset = (u32) &sp->rxd[i].next_desc - (u32) sp->rxd; - netdev_info(dev, "%02x %04x RFDNextPtr = %016lx\n", - i, offset, (unsigned long)sp->rxd[i].next_desc); + printk(KERN_INFO "%2.2x %4.4x RFDNextPtr = %16.16lx\n", i, + offset, (unsigned long) sp->rxd[i].next_desc); offset = (u32) &sp->rxd[i].rfs - (u32) sp->rxd; - netdev_info(dev, "%02x %04x RFS = %016lx\n", - i, offset, (unsigned long)sp->rxd[i].rfs); + printk(KERN_INFO "%2.2x %4.4x RFS = %16.16lx\n", i, + offset, (unsigned long) sp->rxd[i].rfs); offset = (u32) &sp->rxd[i].frag_info - (u32) sp->rxd; - netdev_info(dev, "%02x %04x frag_info = %016lx\n", - i, offset, (unsigned long)sp->rxd[i].frag_info); + printk(KERN_INFO "%2.2x %4.4x frag_info = %16.16lx\n", i, + offset, (unsigned long) sp->rxd[i].frag_info); } } @@ -150,24 +147,24 @@ static void ipg_dump_tfdlist(struct net_device *dev) IPG_DEBUG_MSG("_dump_tfdlist\n"); - netdev_info(dev, "tx_current = %02x\n", sp->tx_current); - netdev_info(dev, "tx_dirty = %02x\n", sp->tx_dirty); - netdev_info(dev, "TFDList start address = %016lx\n", - (unsigned long) sp->txd_map); - netdev_info(dev, "TFDListPtr register = %08x%08x\n", - ipg_r32(IPG_TFDLISTPTR1), ipg_r32(IPG_TFDLISTPTR0)); + printk(KERN_INFO "tx_current = %2.2x\n", sp->tx_current); + printk(KERN_INFO "tx_dirty = %2.2x\n", sp->tx_dirty); + printk(KERN_INFO "TFDList start address = %16.16lx\n", + (unsigned long) sp->txd_map); + printk(KERN_INFO "TFDListPtr register = %8.8x%8.8x\n", + ipg_r32(IPG_TFDLISTPTR1), ipg_r32(IPG_TFDLISTPTR0)); for (i = 0; i < IPG_TFDLIST_LENGTH; i++) { offset = (u32) &sp->txd[i].next_desc - (u32) sp->txd; - netdev_info(dev, "%02x %04x TFDNextPtr = %016lx\n", - i, offset, (unsigned long)sp->txd[i].next_desc); + printk(KERN_INFO "%2.2x %4.4x TFDNextPtr = %16.16lx\n", i, + offset, (unsigned long) sp->txd[i].next_desc); offset = (u32) &sp->txd[i].tfc - (u32) sp->txd; - netdev_info(dev, "%02x %04x TFC = %016lx\n", - i, offset, (unsigned long) sp->txd[i].tfc); + printk(KERN_INFO "%2.2x %4.4x TFC = %16.16lx\n", i, + offset, (unsigned long) sp->txd[i].tfc); offset = (u32) &sp->txd[i].frag_info - (u32) sp->txd; - netdev_info(dev, "%02x %04x frag_info = %016lx\n", - i, offset, (unsigned long) sp->txd[i].frag_info); + printk(KERN_INFO "%2.2x %4.4x frag_info = %16.16lx\n", i, + offset, (unsigned long) sp->txd[i].frag_info); } } #endif @@ -483,10 +480,6 @@ static int ipg_config_autoneg(struct net_device *dev) u32 mac_ctrl_val; u32 asicctrl; u8 phyctrl; - const char *speed; - const char *duplex; - const char *tx_desc; - const char *rx_desc; IPG_DEBUG_MSG("_config_autoneg\n"); @@ -506,27 +499,27 @@ static int ipg_config_autoneg(struct net_device *dev) */ sp->tenmbpsmode = 0; + printk(KERN_INFO "%s: Link speed = ", dev->name); + /* Determine actual speed of operation. */ switch (phyctrl & IPG_PC_LINK_SPEED) { case IPG_PC_LINK_SPEED_10MBPS: - speed = "10Mbps"; + printk("10Mbps.\n"); + printk(KERN_INFO "%s: 10Mbps operational mode enabled.\n", + dev->name); sp->tenmbpsmode = 1; break; case IPG_PC_LINK_SPEED_100MBPS: - speed = "100Mbps"; + printk("100Mbps.\n"); break; case IPG_PC_LINK_SPEED_1000MBPS: - speed = "1000Mbps"; + printk("1000Mbps.\n"); break; default: - speed = "undefined!"; + printk("undefined!\n"); return 0; } - netdev_info(dev, "Link speed = %s\n", speed); - if (sp->tenmbpsmode == 1) - netdev_info(dev, "10Mbps operational mode enabled\n"); - if (phyctrl & IPG_PC_DUPLEX_STATUS) { fullduplex = 1; txflowcontrol = 1; @@ -535,41 +528,38 @@ static int ipg_config_autoneg(struct net_device *dev) /* Configure full duplex, and flow control. */ if (fullduplex == 1) { - /* Configure IPG for full duplex operation. */ - - duplex = "full"; + printk(KERN_INFO "%s: setting full duplex, ", dev->name); mac_ctrl_val |= IPG_MC_DUPLEX_SELECT_FD; if (txflowcontrol == 1) { - tx_desc = ""; + printk("TX flow control"); mac_ctrl_val |= IPG_MC_TX_FLOW_CONTROL_ENABLE; } else { - tx_desc = "no "; + printk("no TX flow control"); mac_ctrl_val &= ~IPG_MC_TX_FLOW_CONTROL_ENABLE; } if (rxflowcontrol == 1) { - rx_desc = ""; + printk(", RX flow control."); mac_ctrl_val |= IPG_MC_RX_FLOW_CONTROL_ENABLE; } else { - rx_desc = "no "; + printk(", no RX flow control."); mac_ctrl_val &= ~IPG_MC_RX_FLOW_CONTROL_ENABLE; } + + printk("\n"); } else { - duplex = "half"; - tx_desc = "no "; - rx_desc = "no "; - mac_ctrl_val &= (~IPG_MC_DUPLEX_SELECT_FD & - ~IPG_MC_TX_FLOW_CONTROL_ENABLE & - ~IPG_MC_RX_FLOW_CONTROL_ENABLE); - } + /* Configure IPG for half duplex operation. */ + printk(KERN_INFO "%s: setting half duplex, " + "no TX flow control, no RX flow control.\n", dev->name); - netdev_info(dev, "setting %s duplex, %sTX, %sRX flow control\n", - duplex, tx_desc, rx_desc); + mac_ctrl_val &= ~IPG_MC_DUPLEX_SELECT_FD & + ~IPG_MC_TX_FLOW_CONTROL_ENABLE & + ~IPG_MC_RX_FLOW_CONTROL_ENABLE; + } ipg_w32(mac_ctrl_val, MAC_CTRL); - return 0; } @@ -794,13 +784,14 @@ static int init_rfdlist(struct net_device *dev) * A receive buffer was not ready, break the * RFD list here. */ - IPG_DEBUG_MSG("Cannot allocate Rx buffer\n"); + IPG_DEBUG_MSG("Cannot allocate Rx buffer.\n"); /* Just in case we cannot allocate a single RFD. * Should not occur. */ if (i == 0) { - netdev_err(dev, "No memory available for RFD list\n"); + printk(KERN_ERR "%s: No memory available" + " for RFD list.\n", dev->name); return -ENOMEM; } } @@ -847,7 +838,7 @@ static void init_tfdlist(struct net_device *dev) sp->tx_dirty = 0; /* Write the location of the TFDList to the IPG. */ - IPG_DDEBUG_MSG("Starting TFDListPtr = %08x\n", + IPG_DDEBUG_MSG("Starting TFDListPtr = %8.8x\n", (u32) sp->txd_map); ipg_w32((u32) sp->txd_map, TFD_LIST_PTR_0); ipg_w32(0x00000000, TFD_LIST_PTR_1); @@ -873,7 +864,7 @@ static void ipg_nic_txfree(struct net_device *dev) struct sk_buff *skb = sp->tx_buff[dirty]; struct ipg_tx *txfd = sp->txd + dirty; - IPG_DEBUG_MSG("TFC = %016lx\n", (unsigned long) txfd->tfc); + IPG_DEBUG_MSG("TFC = %16.16lx\n", (unsigned long) txfd->tfc); /* Look at each TFD's TFC field beginning * at the last freed TFD up to the current TFD. @@ -915,8 +906,10 @@ static void ipg_tx_timeout(struct net_device *dev) spin_lock_irq(&sp->lock); /* Re-configure after DMA reset. */ - if (ipg_io_config(dev) < 0) - netdev_info(dev, "Error during re-configuration\n"); + if (ipg_io_config(dev) < 0) { + printk(KERN_INFO "%s: Error during re-configuration.\n", + dev->name); + } init_tfdlist(dev); @@ -945,7 +938,7 @@ static void ipg_nic_txcleanup(struct net_device *dev) */ u32 txstatusdword = ipg_r32(TX_STATUS); - IPG_DEBUG_MSG("TxStatus = %08x\n", txstatusdword); + IPG_DEBUG_MSG("TxStatus = %8.8x\n", txstatusdword); /* Check for Transmit errors. Error bits only valid if * TX_COMPLETE bit in the TXSTATUS register is a 1. @@ -960,20 +953,20 @@ static void ipg_nic_txcleanup(struct net_device *dev) /* Transmit error, increment stat counters. */ if (txstatusdword & IPG_TS_TX_ERROR) { - IPG_DEBUG_MSG("Transmit error\n"); + IPG_DEBUG_MSG("Transmit error.\n"); sp->stats.tx_errors++; } /* Late collision, re-enable transmitter. */ if (txstatusdword & IPG_TS_LATE_COLLISION) { - IPG_DEBUG_MSG("Late collision on transmit\n"); + IPG_DEBUG_MSG("Late collision on transmit.\n"); ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_TX_ENABLE) & IPG_MC_RSVD_MASK, MAC_CTRL); } /* Maximum collisions, re-enable transmitter. */ if (txstatusdword & IPG_TS_TX_MAX_COLL) { - IPG_DEBUG_MSG("Maximum collisions on transmit\n"); + IPG_DEBUG_MSG("Maximum collisions on transmit.\n"); ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_TX_ENABLE) & IPG_MC_RSVD_MASK, MAC_CTRL); } @@ -982,14 +975,16 @@ static void ipg_nic_txcleanup(struct net_device *dev) * transmitter. */ if (txstatusdword & IPG_TS_TX_UNDERRUN) { - IPG_DEBUG_MSG("Transmitter underrun\n"); + IPG_DEBUG_MSG("Transmitter underrun.\n"); sp->stats.tx_fifo_errors++; ipg_reset(dev, IPG_AC_TX_RESET | IPG_AC_DMA | IPG_AC_NETWORK | IPG_AC_FIFO); /* Re-configure after DMA reset. */ if (ipg_io_config(dev) < 0) { - netdev_info(dev, "Error during re-configuration\n"); + printk(KERN_INFO + "%s: Error during re-configuration.\n", + dev->name); } init_tfdlist(dev); @@ -1068,7 +1063,7 @@ static int ipg_nic_rxrestore(struct net_device *dev) * Linux system). */ if (ipg_get_rxbuff(dev, entry) < 0) { - IPG_DEBUG_MSG("Cannot allocate new Rx buffer\n"); + IPG_DEBUG_MSG("Cannot allocate new Rx buffer.\n"); break; } @@ -1139,7 +1134,7 @@ static int ipg_nic_rx_check_error(struct net_device *dev) (IPG_RFS_RXFIFOOVERRUN | IPG_RFS_RXRUNTFRAME | IPG_RFS_RXALIGNMENTERROR | IPG_RFS_RXFCSERROR | IPG_RFS_RXOVERSIZEDFRAME | IPG_RFS_RXLENGTHERROR))) { - IPG_DEBUG_MSG("Rx error, RFS = %016lx\n", + IPG_DEBUG_MSG("Rx error, RFS = %16.16lx\n", (unsigned long) rxfd->rfs); /* Increment general receive error statistic. */ @@ -1147,13 +1142,13 @@ static int ipg_nic_rx_check_error(struct net_device *dev) /* Increment detailed receive error statistics. */ if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFIFOOVERRUN) { - IPG_DEBUG_MSG("RX FIFO overrun occurred\n"); + IPG_DEBUG_MSG("RX FIFO overrun occurred.\n"); sp->stats.rx_fifo_errors++; } if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXRUNTFRAME) { - IPG_DEBUG_MSG("RX runt occurred\n"); + IPG_DEBUG_MSG("RX runt occurred.\n"); sp->stats.rx_length_errors++; } @@ -1162,7 +1157,7 @@ static int ipg_nic_rx_check_error(struct net_device *dev) */ if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXALIGNMENTERROR) { - IPG_DEBUG_MSG("RX alignment error occurred\n"); + IPG_DEBUG_MSG("RX alignment error occurred.\n"); sp->stats.rx_frame_errors++; } @@ -1409,7 +1404,7 @@ static int ipg_nic_rx(struct net_device *dev) */ if (framelen > sp->rxfrag_size) { IPG_DEBUG_MSG - ("RFS FrameLen > allocated fragment size\n"); + ("RFS FrameLen > allocated fragment size.\n"); framelen = sp->rxfrag_size; } @@ -1419,7 +1414,7 @@ static int ipg_nic_rx(struct net_device *dev) IPG_RFS_RXALIGNMENTERROR | IPG_RFS_RXFCSERROR | IPG_RFS_RXOVERSIZEDFRAME | IPG_RFS_RXLENGTHERROR)))) { - IPG_DEBUG_MSG("Rx error, RFS = %016lx\n", + IPG_DEBUG_MSG("Rx error, RFS = %16.16lx\n", (unsigned long int) rxfd->rfs); /* Increment general receive error statistic. */ @@ -1427,12 +1422,12 @@ static int ipg_nic_rx(struct net_device *dev) /* Increment detailed receive error statistics. */ if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFIFOOVERRUN) { - IPG_DEBUG_MSG("RX FIFO overrun occurred\n"); + IPG_DEBUG_MSG("RX FIFO overrun occurred.\n"); sp->stats.rx_fifo_errors++; } if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXRUNTFRAME) { - IPG_DEBUG_MSG("RX runt occurred\n"); + IPG_DEBUG_MSG("RX runt occurred.\n"); sp->stats.rx_length_errors++; } @@ -1442,7 +1437,7 @@ static int ipg_nic_rx(struct net_device *dev) */ if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXALIGNMENTERROR) { - IPG_DEBUG_MSG("RX alignment error occurred\n"); + IPG_DEBUG_MSG("RX alignment error occurred.\n"); sp->stats.rx_frame_errors++; } @@ -1513,7 +1508,7 @@ static int ipg_nic_rx(struct net_device *dev) rxfd = sp->rxd + entry; - IPG_DEBUG_MSG("Frame requires multiple RFDs\n"); + IPG_DEBUG_MSG("Frame requires multiple RFDs.\n"); /* An unexpected event, additional code needed to handle * properly. So for the time being, just disregard the @@ -1562,7 +1557,8 @@ static void ipg_reset_after_host_error(struct work_struct *work) init_tfdlist(dev); if (ipg_io_config(dev) < 0) { - netdev_info(dev, "Cannot recover from PCI error\n"); + printk(KERN_INFO "%s: Cannot recover from PCI error.\n", + dev->name); schedule_delayed_work(&sp->task, HZ); } } @@ -1590,7 +1586,7 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst) */ status = ipg_r16(INT_STATUS_ACK); - IPG_DEBUG_MSG("IntStatusAck = %04x\n", status); + IPG_DEBUG_MSG("IntStatusAck = %4.4x\n", status); /* Shared IRQ of remove event. */ if (!(status & IPG_IS_RSVD_MASK)) @@ -1603,7 +1599,7 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst) /* If RFDListEnd interrupt, restore all used RFDs. */ if (status & IPG_IS_RFD_LIST_END) { - IPG_DEBUG_MSG("RFDListEnd Interrupt\n"); + IPG_DEBUG_MSG("RFDListEnd Interrupt.\n"); /* The RFD list end indicates an RFD was encountered * with a 0 NextPtr, or with an RFDDone bit set to 1 @@ -1665,20 +1661,21 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst) /* If LinkEvent interrupt, resolve autonegotiation. */ if (status & IPG_IS_LINK_EVENT) { if (ipg_config_autoneg(dev) < 0) - netdev_info(dev, "Auto-negotiation error\n"); + printk(KERN_INFO "%s: Auto-negotiation error.\n", + dev->name); } /* If MACCtrlFrame interrupt, do nothing. */ if (status & IPG_IS_MAC_CTRL_FRAME) - IPG_DEBUG_MSG("MACCtrlFrame interrupt\n"); + IPG_DEBUG_MSG("MACCtrlFrame interrupt.\n"); /* If RxComplete interrupt, do nothing. */ if (status & IPG_IS_RX_COMPLETE) - IPG_DEBUG_MSG("RxComplete interrupt\n"); + IPG_DEBUG_MSG("RxComplete interrupt.\n"); /* If RxEarly interrupt, do nothing. */ if (status & IPG_IS_RX_EARLY) - IPG_DEBUG_MSG("RxEarly interrupt\n"); + IPG_DEBUG_MSG("RxEarly interrupt.\n"); out_enable: /* Re-enable IPG interrupts. */ @@ -1752,7 +1749,8 @@ static int ipg_nic_open(struct net_device *dev) rc = request_irq(pdev->irq, ipg_interrupt_handler, IRQF_SHARED, dev->name, dev); if (rc < 0) { - netdev_info(dev, "Error when requesting interrupt\n"); + printk(KERN_INFO "%s: Error when requesting interrupt.\n", + dev->name); goto out; } @@ -1772,7 +1770,8 @@ static int ipg_nic_open(struct net_device *dev) rc = init_rfdlist(dev); if (rc < 0) { - netdev_info(dev, "Error during configuration\n"); + printk(KERN_INFO "%s: Error during configuration.\n", + dev->name); goto err_free_tx_2; } @@ -1780,13 +1779,14 @@ static int ipg_nic_open(struct net_device *dev) rc = ipg_io_config(dev); if (rc < 0) { - netdev_info(dev, "Error during configuration\n"); + printk(KERN_INFO "%s: Error during configuration.\n", + dev->name); goto err_release_tfdlist_3; } /* Resolve autonegotiation. */ if (ipg_config_autoneg(dev) < 0) - netdev_info(dev, "Auto-negotiation error\n"); + printk(KERN_INFO "%s: Auto-negotiation error.\n", dev->name); /* initialize JUMBO Frame control variable */ sp->jumbo.found_start = 0; @@ -1961,7 +1961,7 @@ static void ipg_set_phy_default_param(unsigned char rev, { unsigned short length; unsigned char revision; - const unsigned short *phy_param; + unsigned short *phy_param; unsigned short address, value; phy_param = &DefaultPhyParam[0]; @@ -2222,7 +2222,7 @@ static int __devinit ipg_probe(struct pci_dev *pdev, if (rc < 0) goto out; - pr_info("%s: %s\n", pci_name(pdev), ipg_brand_name[i]); + printk(KERN_INFO "%s: %s\n", pci_name(pdev), ipg_brand_name[i]); pci_set_master(pdev); @@ -2230,7 +2230,8 @@ static int __devinit ipg_probe(struct pci_dev *pdev, if (rc < 0) { rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (rc < 0) { - pr_err("%s: DMA config failed\n", pci_name(pdev)); + printk(KERN_ERR "%s: DMA config failed.\n", + pci_name(pdev)); goto err_disable_0; } } @@ -2240,7 +2241,7 @@ static int __devinit ipg_probe(struct pci_dev *pdev, */ dev = alloc_etherdev(sizeof(struct ipg_nic_private)); if (!dev) { - pr_err("%s: alloc_etherdev failed\n", pci_name(pdev)); + printk(KERN_ERR "%s: alloc_etherdev failed\n", pci_name(pdev)); rc = -ENOMEM; goto err_disable_0; } @@ -2266,7 +2267,7 @@ static int __devinit ipg_probe(struct pci_dev *pdev, ioaddr = pci_iomap(pdev, 1, pci_resource_len(pdev, 1)); if (!ioaddr) { - pr_err("%s: cannot map MMIO\n", pci_name(pdev)); + printk(KERN_ERR "%s cannot map MMIO\n", pci_name(pdev)); rc = -EIO; goto err_release_regions_2; } @@ -2288,7 +2289,7 @@ static int __devinit ipg_probe(struct pci_dev *pdev, if (rc < 0) goto err_unmap_3; - netdev_info(dev, "Ethernet device registered\n"); + printk(KERN_INFO "Ethernet device registered as: %s\n", dev->name); out: return rc; diff --git a/trunk/drivers/net/qlcnic/qlcnic.h b/trunk/drivers/net/qlcnic/qlcnic.h index 53c6e5dcf26c..baf646d98fa0 100644 --- a/trunk/drivers/net/qlcnic/qlcnic.h +++ b/trunk/drivers/net/qlcnic/qlcnic.h @@ -36,8 +36,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 22 -#define QLCNIC_LINUX_VERSIONID "5.0.22" +#define _QLCNIC_LINUX_SUBVERSION 21 +#define QLCNIC_LINUX_VERSIONID "5.0.21" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) @@ -911,7 +911,6 @@ struct qlcnic_ipaddr { #define QLCNIC_PROMISC_DISABLED 0x800 #define QLCNIC_NEED_FLR 0x1000 #define QLCNIC_FW_RESET_OWNER 0x2000 -#define QLCNIC_FW_HANG 0x4000 #define QLCNIC_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) @@ -1345,7 +1344,6 @@ enum op_codes { #define QLCNIC_FORCE_FW_DUMP_KEY 0xdeadfeed #define QLCNIC_ENABLE_FW_DUMP 0xaddfeed #define QLCNIC_DISABLE_FW_DUMP 0xbadfeed -#define QLCNIC_FORCE_FW_RESET 0xdeaddead struct qlcnic_dump_operations { enum op_codes opcode; diff --git a/trunk/drivers/net/qlcnic/qlcnic_ethtool.c b/trunk/drivers/net/qlcnic/qlcnic_ethtool.c index 7c64f2ffc219..72a723d5c988 100644 --- a/trunk/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/trunk/drivers/net/qlcnic/qlcnic_ethtool.c @@ -1105,10 +1105,7 @@ qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump) struct qlcnic_adapter *adapter = netdev_priv(netdev); struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; - if (fw_dump->clr) - dump->len = fw_dump->tmpl_hdr->size + fw_dump->size; - else - dump->len = 0; + dump->len = fw_dump->tmpl_hdr->size + fw_dump->size; dump->flag = fw_dump->tmpl_hdr->drv_cap_mask; dump->version = adapter->fw_version; return 0; @@ -1155,8 +1152,7 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val) struct qlcnic_adapter *adapter = netdev_priv(netdev); struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; - switch (val->flag) { - case QLCNIC_FORCE_FW_DUMP_KEY: + if (val->flag == QLCNIC_FORCE_FW_DUMP_KEY) { if (!fw_dump->enable) { netdev_info(netdev, "FW dump not enabled\n"); return ret; @@ -1168,25 +1164,17 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val) } netdev_info(netdev, "Forcing a FW dump\n"); qlcnic_dev_request_reset(adapter); - break; - case QLCNIC_DISABLE_FW_DUMP: + } else if (val->flag == QLCNIC_DISABLE_FW_DUMP) { if (fw_dump->enable) { netdev_info(netdev, "Disabling FW dump\n"); fw_dump->enable = 0; } - break; - case QLCNIC_ENABLE_FW_DUMP: + } else if (val->flag == QLCNIC_ENABLE_FW_DUMP) { if (!fw_dump->enable && fw_dump->tmpl_hdr) { netdev_info(netdev, "Enabling FW dump\n"); fw_dump->enable = 1; } - break; - case QLCNIC_FORCE_FW_RESET: - netdev_info(netdev, "Forcing a FW reset\n"); - qlcnic_dev_request_reset(adapter); - adapter->flags &= ~QLCNIC_FW_RESET_OWNER; - break; - default: + } else { if (val->flag > QLCNIC_DUMP_MASK_MAX || val->flag < QLCNIC_DUMP_MASK_MIN) { netdev_info(netdev, diff --git a/trunk/drivers/net/qlcnic/qlcnic_hw.c b/trunk/drivers/net/qlcnic/qlcnic_hw.c index 74e9d7b94965..4055c218ef2a 100644 --- a/trunk/drivers/net/qlcnic/qlcnic_hw.c +++ b/trunk/drivers/net/qlcnic/qlcnic_hw.c @@ -1773,8 +1773,8 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter) goto error; } else { fw_dump->clr = 1; - snprintf(mesg, sizeof(mesg), "FW_DUMP=%s", - adapter->netdev->name); + snprintf(mesg, sizeof(mesg), "FW dump for device: %d\n", + adapter->pdev->devfn); dev_info(&adapter->pdev->dev, "Dump data, %d bytes captured\n", fw_dump->size); /* Send a udev event to notify availability of FW dump */ diff --git a/trunk/drivers/net/qlcnic/qlcnic_init.c b/trunk/drivers/net/qlcnic/qlcnic_init.c index 3b6741e4754d..ee8a3982395e 100644 --- a/trunk/drivers/net/qlcnic/qlcnic_init.c +++ b/trunk/drivers/net/qlcnic/qlcnic_init.c @@ -1056,8 +1056,7 @@ qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter) int qlcnic_need_fw_reset(struct qlcnic_adapter *adapter) { - if ((adapter->flags & QLCNIC_FW_HANG) || - qlcnic_check_fw_hearbeat(adapter)) { + if (qlcnic_check_fw_hearbeat(adapter)) { qlcnic_rom_lock_recovery(adapter); return 1; } diff --git a/trunk/drivers/net/qlcnic/qlcnic_main.c b/trunk/drivers/net/qlcnic/qlcnic_main.c index ec8ef72d38d3..5ca1b562443c 100644 --- a/trunk/drivers/net/qlcnic/qlcnic_main.c +++ b/trunk/drivers/net/qlcnic/qlcnic_main.c @@ -643,11 +643,8 @@ static void get_brd_name(struct qlcnic_adapter *adapter, char *name) static void qlcnic_check_options(struct qlcnic_adapter *adapter) { - u32 fw_major, fw_minor, fw_build, prev_fw_version; + u32 fw_major, fw_minor, fw_build; struct pci_dev *pdev = adapter->pdev; - struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; - - prev_fw_version = adapter->fw_version; fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR); fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR); @@ -655,17 +652,6 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build); - if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC) { - if (fw_dump->tmpl_hdr == NULL || - adapter->fw_version > prev_fw_version) { - if (fw_dump->tmpl_hdr) - vfree(fw_dump->tmpl_hdr); - if (!qlcnic_fw_cmd_get_minidump_temp(adapter)) - dev_info(&pdev->dev, - "Supports FW dump capability\n"); - } - } - dev_info(&pdev->dev, "firmware v%d.%d.%d\n", fw_major, fw_minor, fw_build); if (adapter->ahw->port_type == QLCNIC_XGBE) { @@ -1624,6 +1610,12 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_decr_ref; } + /* Get FW dump template and store it */ + if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC) + if (!qlcnic_fw_cmd_get_minidump_temp(adapter)) + dev_info(&pdev->dev, + "Supports FW dump capability\n"); + if (qlcnic_read_mac_addr(adapter)) dev_warn(&pdev->dev, "failed to read mac addr\n"); @@ -2690,7 +2682,6 @@ qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed) qlcnic_api_unlock(adapter); err: adapter->fw_fail_cnt = 0; - adapter->flags &= ~QLCNIC_FW_HANG; clear_bit(__QLCNIC_START_FW, &adapter->state); clear_bit(__QLCNIC_RESETTING, &adapter->state); } @@ -2868,7 +2859,6 @@ qlcnic_fwinit_work(struct work_struct *work) (adapter->flags & QLCNIC_FW_RESET_OWNER)) { QLCDB(adapter, DRV, "Take FW dump\n"); qlcnic_dump_fw(adapter); - adapter->flags |= QLCNIC_FW_HANG; } rtnl_unlock(); @@ -3056,7 +3046,6 @@ qlcnic_attach_work(struct work_struct *work) done: netif_device_attach(netdev); adapter->fw_fail_cnt = 0; - adapter->flags &= ~QLCNIC_FW_HANG; clear_bit(__QLCNIC_RESETTING, &adapter->state); if (!qlcnic_clr_drv_state(adapter)) @@ -3101,26 +3090,13 @@ qlcnic_check_health(struct qlcnic_adapter *adapter) if (++adapter->fw_fail_cnt < FW_FAIL_THRESH) return 0; - adapter->flags |= QLCNIC_FW_HANG; - qlcnic_dev_request_reset(adapter); if (auto_fw_reset) clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state); dev_info(&netdev->dev, "firmware hang detected\n"); - dev_info(&adapter->pdev->dev, "Dumping hw/fw registers\n" - "PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n" - "PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,\n" - "PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,\n" - "PEG_NET_4_PC: 0x%x\n", - QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS1), - QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS2), - QLCRD32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x3c), - QLCRD32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x3c), - QLCRD32(adapter, QLCNIC_CRB_PEG_NET_2 + 0x3c), - QLCRD32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x3c), - QLCRD32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x3c)); + detach: adapter->dev_state = (state == QLCNIC_DEV_NEED_QUISCENT) ? state : QLCNIC_DEV_NEED_RESET; diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index c77286edba4d..7d9c650f395e 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -239,7 +239,6 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, - { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4302), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_AT, 0xc107), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, { PCI_VENDOR_ID_LINKSYS, 0x1032, diff --git a/trunk/drivers/net/sis190.c b/trunk/drivers/net/sis190.c index 3c0f1312b391..8ad7bfbaa3af 100644 --- a/trunk/drivers/net/sis190.c +++ b/trunk/drivers/net/sis190.c @@ -1825,16 +1825,6 @@ static int sis190_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL); } -static int sis190_mac_addr(struct net_device *dev, void *p) -{ - int rc; - - rc = eth_mac_addr(dev, p); - if (!rc) - sis190_init_rxfilter(dev); - return rc; -} - static const struct net_device_ops sis190_netdev_ops = { .ndo_open = sis190_open, .ndo_stop = sis190_close, @@ -1843,7 +1833,7 @@ static const struct net_device_ops sis190_netdev_ops = { .ndo_tx_timeout = sis190_tx_timeout, .ndo_set_multicast_list = sis190_set_rx_mode, .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = sis190_mac_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = sis190_netpoll, diff --git a/trunk/net/dccp/dccp.h b/trunk/net/dccp/dccp.h index 5fdb07229017..583490aaf56f 100644 --- a/trunk/net/dccp/dccp.h +++ b/trunk/net/dccp/dccp.h @@ -474,6 +474,7 @@ static inline int dccp_ack_pending(const struct sock *sk) return dccp_ackvec_pending(sk) || inet_csk_ack_scheduled(sk); } +extern int dccp_feat_signal_nn_change(struct sock *sk, u8 feat, u64 nn_val); extern int dccp_feat_finalise_settings(struct dccp_sock *dp); extern int dccp_feat_server_ccid_dependencies(struct dccp_request_sock *dreq); extern int dccp_feat_insert_opts(struct dccp_sock*, struct dccp_request_sock*, diff --git a/trunk/net/dccp/feat.c b/trunk/net/dccp/feat.c index 568def952722..8bd28f244fef 100644 --- a/trunk/net/dccp/feat.c +++ b/trunk/net/dccp/feat.c @@ -12,6 +12,7 @@ * ----------- * o Feature negotiation is coordinated with connection setup (as in TCP), wild * changes of parameters of an established connection are not supported. + * o Changing non-negotiable (NN) values is supported in state OPEN/PARTOPEN. * o All currently known SP features have 1-byte quantities. If in the future * extensions of RFCs 4340..42 define features with item lengths larger than * one byte, a feature-specific extension of the code will be required. @@ -730,6 +731,70 @@ int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local, 0, list, len); } +/** + * dccp_feat_nn_get - Query current/pending value of NN feature + * @sk: DCCP socket of an established connection + * @feat: NN feature number from %dccp_feature_numbers + * For a known NN feature, returns value currently being negotiated, or + * current (confirmed) value if no negotiation is going on. + */ +u64 dccp_feat_nn_get(struct sock *sk, u8 feat) +{ + if (dccp_feat_type(feat) == FEAT_NN) { + struct dccp_sock *dp = dccp_sk(sk); + struct dccp_feat_entry *entry; + + entry = dccp_feat_list_lookup(&dp->dccps_featneg, feat, 1); + if (entry != NULL) + return entry->val.nn; + + switch (feat) { + case DCCPF_ACK_RATIO: + return dp->dccps_l_ack_ratio; + case DCCPF_SEQUENCE_WINDOW: + return dp->dccps_l_seq_win; + } + } + DCCP_BUG("attempt to look up unsupported feature %u", feat); + return 0; +} +EXPORT_SYMBOL_GPL(dccp_feat_nn_get); + +/** + * dccp_feat_signal_nn_change - Update NN values for an established connection + * @sk: DCCP socket of an established connection + * @feat: NN feature number from %dccp_feature_numbers + * @nn_val: the new value to use + * This function is used to communicate NN updates out-of-band. + */ +int dccp_feat_signal_nn_change(struct sock *sk, u8 feat, u64 nn_val) +{ + struct list_head *fn = &dccp_sk(sk)->dccps_featneg; + dccp_feat_val fval = { .nn = nn_val }; + struct dccp_feat_entry *entry; + + if (sk->sk_state != DCCP_OPEN && sk->sk_state != DCCP_PARTOPEN) + return 0; + + if (dccp_feat_type(feat) != FEAT_NN || + !dccp_feat_is_valid_nn_val(feat, nn_val)) + return -EINVAL; + + if (nn_val == dccp_feat_nn_get(sk, feat)) + return 0; /* already set or negotiation under way */ + + entry = dccp_feat_list_lookup(fn, feat, 1); + if (entry != NULL) { + dccp_pr_debug("Clobbering existing NN entry %llu -> %llu\n", + (unsigned long long)entry->val.nn, + (unsigned long long)nn_val); + dccp_feat_list_pop(entry); + } + + inet_csk_schedule_ack(sk); + return dccp_feat_push_change(fn, feat, 1, 0, &fval); +} +EXPORT_SYMBOL_GPL(dccp_feat_signal_nn_change); /* * Tracking features whose value depend on the choice of CCID diff --git a/trunk/net/dccp/feat.h b/trunk/net/dccp/feat.h index e56a4e5e634e..90b957d34d26 100644 --- a/trunk/net/dccp/feat.h +++ b/trunk/net/dccp/feat.h @@ -129,6 +129,7 @@ extern int dccp_feat_clone_list(struct list_head const *, struct list_head *); extern void dccp_encode_value_var(const u64 value, u8 *to, const u8 len); extern u64 dccp_decode_value_var(const u8 *bf, const u8 len); +extern u64 dccp_feat_nn_get(struct sock *sk, u8 feat); extern int dccp_insert_option_mandatory(struct sk_buff *skb); extern int dccp_insert_fn_opt(struct sk_buff *skb, u8 type, u8 feat, diff --git a/trunk/net/ipv6/exthdrs.c b/trunk/net/ipv6/exthdrs.c index 1318de4c3e8d..79a485e8a700 100644 --- a/trunk/net/ipv6/exthdrs.c +++ b/trunk/net/ipv6/exthdrs.c @@ -273,12 +273,12 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) __u16 dstbuf; #endif - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst; if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || !pskb_may_pull(skb, (skb_transport_offset(skb) + ((skb_transport_header(skb)[1] + 1) << 3)))) { - IP6_INC_STATS_BH(dev_net(dst->dev), ip6_dst_idev(dst), + IP6_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_INHDRERRORS); kfree_skb(skb); return -1; @@ -289,7 +289,9 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) dstbuf = opt->dst1; #endif + dst = dst_clone(skb_dst(skb)); if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) { + dst_release(dst); skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3; opt = IP6CB(skb); #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) @@ -302,6 +304,7 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) IP6_INC_STATS_BH(dev_net(dst->dev), ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); + dst_release(dst); return -1; } diff --git a/trunk/net/ipv6/icmp.c b/trunk/net/ipv6/icmp.c index 2b59154c65d3..11900417b1cc 100644 --- a/trunk/net/ipv6/icmp.c +++ b/trunk/net/ipv6/icmp.c @@ -490,8 +490,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) goto out_dst_release; } - rcu_read_lock(); - idev = __in6_dev_get(skb->dev); + idev = in6_dev_get(skb->dev); err = ip6_append_data(sk, icmpv6_getfrag, &msg, len + sizeof(struct icmp6hdr), @@ -501,16 +500,19 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) if (err) { ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); ip6_flush_pending_frames(sk); - } else { - err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, - len + sizeof(struct icmp6hdr)); + goto out_put; } - rcu_read_unlock(); + err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, len + sizeof(struct icmp6hdr)); + +out_put: + if (likely(idev != NULL)) + in6_dev_put(idev); out_dst_release: dst_release(dst); out: icmpv6_xmit_unlock(sk); } + EXPORT_SYMBOL(icmpv6_send); static void icmpv6_echo_reply(struct sk_buff *skb) @@ -567,7 +569,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) if (hlimit < 0) hlimit = ip6_dst_hoplimit(dst); - idev = __in6_dev_get(skb->dev); + idev = in6_dev_get(skb->dev); msg.skb = skb; msg.offset = 0; @@ -581,10 +583,13 @@ static void icmpv6_echo_reply(struct sk_buff *skb) if (err) { ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); ip6_flush_pending_frames(sk); - } else { - err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, - skb->len + sizeof(struct icmp6hdr)); + goto out_put; } + err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, skb->len + sizeof(struct icmp6hdr)); + +out_put: + if (likely(idev != NULL)) + in6_dev_put(idev); dst_release(dst); out: icmpv6_xmit_unlock(sk); diff --git a/trunk/net/ipv6/inet6_connection_sock.c b/trunk/net/ipv6/inet6_connection_sock.c index 2916200f90c1..8a58e8cf6646 100644 --- a/trunk/net/ipv6/inet6_connection_sock.c +++ b/trunk/net/ipv6/inet6_connection_sock.c @@ -211,7 +211,6 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) struct flowi6 fl6; struct dst_entry *dst; struct in6_addr *final_p, final; - int res; memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_proto = sk->sk_protocol; @@ -242,14 +241,12 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) __inet6_csk_dst_store(sk, dst, NULL, NULL); } - rcu_read_lock(); - skb_dst_set_noref(skb, dst); + skb_dst_set(skb, dst_clone(dst)); /* Restore final destination back after routing done */ ipv6_addr_copy(&fl6.daddr, &np->daddr); - res = ip6_xmit(sk, skb, &fl6, np->opt); - rcu_read_unlock(); - return res; + return ip6_xmit(sk, skb, &fl6, np->opt); } + EXPORT_SYMBOL_GPL(inet6_csk_xmit); diff --git a/trunk/net/ipv6/ip6_tunnel.c b/trunk/net/ipv6/ip6_tunnel.c index 6fb1fb3624bf..0bc98886c383 100644 --- a/trunk/net/ipv6/ip6_tunnel.c +++ b/trunk/net/ipv6/ip6_tunnel.c @@ -889,7 +889,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, struct net_device_stats *stats = &t->dev->stats; struct ipv6hdr *ipv6h = ipv6_hdr(skb); struct ipv6_tel_txoption opt; - struct dst_entry *dst, *ndst = NULL; + struct dst_entry *dst; struct net_device *tdev; int mtu; unsigned int max_headroom = sizeof(struct ipv6hdr); @@ -897,19 +897,19 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, int err = -1; int pkt_len; - dst = ip6_tnl_dst_check(t); - if (!dst) { - ndst = ip6_route_output(net, NULL, fl6); + if ((dst = ip6_tnl_dst_check(t)) != NULL) + dst_hold(dst); + else { + dst = ip6_route_output(net, NULL, fl6); - if (ndst->error) + if (dst->error) goto tx_err_link_failure; - ndst = xfrm_lookup(net, ndst, flowi6_to_flowi(fl6), NULL, 0); - if (IS_ERR(ndst)) { - err = PTR_ERR(ndst); - ndst = NULL; + dst = xfrm_lookup(net, dst, flowi6_to_flowi(fl6), NULL, 0); + if (IS_ERR(dst)) { + err = PTR_ERR(dst); + dst = NULL; goto tx_err_link_failure; } - dst = ndst; } tdev = dst->dev; @@ -955,7 +955,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, skb = new_skb; } skb_dst_drop(skb); - skb_dst_set_noref(skb, dst); + skb_dst_set(skb, dst_clone(dst)); skb->transport_header = skb->network_header; @@ -987,14 +987,13 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, stats->tx_errors++; stats->tx_aborted_errors++; } - if (ndst) - ip6_tnl_dst_store(t, ndst); + ip6_tnl_dst_store(t, dst); return 0; tx_err_link_failure: stats->tx_carrier_errors++; dst_link_failure(skb); tx_err_dst_release: - dst_release(ndst); + dst_release(dst); return err; } diff --git a/trunk/net/ipv6/ndisc.c b/trunk/net/ipv6/ndisc.c index 1f52dd257631..9da6e02eaaeb 100644 --- a/trunk/net/ipv6/ndisc.c +++ b/trunk/net/ipv6/ndisc.c @@ -533,8 +533,7 @@ void ndisc_send_skb(struct sk_buff *skb, skb_dst_set(skb, dst); - rcu_read_lock(); - idev = __in6_dev_get(dst->dev); + idev = in6_dev_get(dst->dev); IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, @@ -544,7 +543,8 @@ void ndisc_send_skb(struct sk_buff *skb, ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); } - rcu_read_unlock(); + if (likely(idev != NULL)) + in6_dev_put(idev); } EXPORT_SYMBOL(ndisc_send_skb); @@ -1039,7 +1039,7 @@ static void ndisc_recv_rs(struct sk_buff *skb) if (skb->len < sizeof(*rs_msg)) return; - idev = __in6_dev_get(skb->dev); + idev = in6_dev_get(skb->dev); if (!idev) { if (net_ratelimit()) ND_PRINTK1("ICMP6 RS: can't find in6 device\n"); @@ -1080,7 +1080,7 @@ static void ndisc_recv_rs(struct sk_buff *skb) neigh_release(neigh); } out: - return; + in6_dev_put(idev); } static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt) @@ -1179,7 +1179,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) * set the RA_RECV flag in the interface */ - in6_dev = __in6_dev_get(skb->dev); + in6_dev = in6_dev_get(skb->dev); if (in6_dev == NULL) { ND_PRINTK0(KERN_ERR "ICMPv6 RA: can't find inet6 device for %s.\n", @@ -1188,6 +1188,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) } if (!ndisc_parse_options(opt, optlen, &ndopts)) { + in6_dev_put(in6_dev); ND_PRINTK2(KERN_WARNING "ICMP6 RA: invalid ND options\n"); return; @@ -1254,6 +1255,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) ND_PRINTK0(KERN_ERR "ICMPv6 RA: %s() failed to add default route.\n", __func__); + in6_dev_put(in6_dev); return; } @@ -1263,6 +1265,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) "ICMPv6 RA: %s() got default router without neighbour.\n", __func__); dst_release(&rt->dst); + in6_dev_put(in6_dev); return; } neigh->flags |= NTF_ROUTER; @@ -1419,6 +1422,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) dst_release(&rt->dst); else if (neigh) neigh_release(neigh); + in6_dev_put(in6_dev); } static void ndisc_redirect_rcv(struct sk_buff *skb) @@ -1477,11 +1481,13 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) return; } - in6_dev = __in6_dev_get(skb->dev); + in6_dev = in6_dev_get(skb->dev); if (!in6_dev) return; - if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) + if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) { + in6_dev_put(in6_dev); return; + } /* RFC2461 8.1: * The IP source address of the Redirect MUST be the same as the current @@ -1491,6 +1497,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) { ND_PRINTK2(KERN_WARNING "ICMPv6 Redirect: invalid ND options\n"); + in6_dev_put(in6_dev); return; } if (ndopts.nd_opts_tgt_lladdr) { @@ -1499,6 +1506,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) if (!lladdr) { ND_PRINTK2(KERN_WARNING "ICMPv6 Redirect: invalid link-layer address length\n"); + in6_dev_put(in6_dev); return; } } @@ -1510,6 +1518,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) on_link); neigh_release(neigh); } + in6_dev_put(in6_dev); } void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, @@ -1642,8 +1651,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, csum_partial(icmph, len, 0)); skb_dst_set(buff, dst); - rcu_read_lock(); - idev = __in6_dev_get(dst->dev); + idev = in6_dev_get(dst->dev); IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev, dst_output); @@ -1652,7 +1660,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); } - rcu_read_unlock(); + if (likely(idev != NULL)) + in6_dev_put(idev); return; release: diff --git a/trunk/net/netfilter/ipvs/ip_vs_ctl.c b/trunk/net/netfilter/ipvs/ip_vs_ctl.c index 2b771dc708a3..be43fd805bd0 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_ctl.c +++ b/trunk/net/netfilter/ipvs/ip_vs_ctl.c @@ -3771,7 +3771,6 @@ int __init ip_vs_control_init(void) void ip_vs_control_cleanup(void) { EnterFunction(2); - unregister_netdevice_notifier(&ip_vs_dst_notifier); ip_vs_genl_unregister(); nf_unregister_sockopt(&ip_vs_sockopts); LeaveFunction(2); diff --git a/trunk/net/sunrpc/xprt.c b/trunk/net/sunrpc/xprt.c index f4385e45a5fc..9b6a4d1ea8f8 100644 --- a/trunk/net/sunrpc/xprt.c +++ b/trunk/net/sunrpc/xprt.c @@ -187,7 +187,6 @@ EXPORT_SYMBOL_GPL(xprt_load_transport); /** * xprt_reserve_xprt - serialize write access to transports * @task: task that is requesting access to the transport - * @xprt: pointer to the target transport * * This prevents mixing the payload of separate requests, and prevents * transport connects from colliding with writes. No congestion control diff --git a/trunk/net/xfrm/xfrm_algo.c b/trunk/net/xfrm/xfrm_algo.c index 791ab2e77f3f..58064d9e565d 100644 --- a/trunk/net/xfrm/xfrm_algo.c +++ b/trunk/net/xfrm/xfrm_algo.c @@ -462,8 +462,8 @@ static struct xfrm_algo_desc ealg_list[] = { .desc = { .sadb_alg_id = SADB_X_EALG_AESCTR, .sadb_alg_ivlen = 8, - .sadb_alg_minbits = 160, - .sadb_alg_maxbits = 288 + .sadb_alg_minbits = 128, + .sadb_alg_maxbits = 256 } }, };