Path: blob/main/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c
39566 views
/*-1* SPDX-License-Identifier: BSD-2-Clause OR GPL-2.02*3* Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.4* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.5* Copyright (c) 2005 Mellanox Technologies. All rights reserved.6* Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.7*8* This software is available to you under a choice of one of two9* licenses. You may choose to be licensed under the terms of the GNU10* General Public License (GPL) Version 2, available from the file11* COPYING in the main directory of this source tree, or the12* OpenIB.org BSD license below:13*14* Redistribution and use in source and binary forms, with or15* without modification, are permitted provided that the following16* conditions are met:17*18* - Redistributions of source code must retain the above19* copyright notice, this list of conditions and the following20* disclaimer.21*22* - Redistributions in binary form must reproduce the above23* copyright notice, this list of conditions and the following24* disclaimer in the documentation and/or other materials25* provided with the distribution.26*27* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,28* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF29* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND30* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS31* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN32* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN33* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE34* SOFTWARE.35*/3637#include <sys/cdefs.h>38#include "ipoib.h"3940#include <rdma/ib_cache.h>4142#include <security/mac/mac_framework.h>4344#include <linux/delay.h>45#include <linux/dma-mapping.h>4647#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG_DATA48static int data_debug_level;4950module_param(data_debug_level, int, 0644);51MODULE_PARM_DESC(data_debug_level,52"Enable data path debug tracing if > 0");53#endif5455static DEFINE_MUTEX(pkey_mutex);5657struct ipoib_ah *ipoib_create_ah(struct ipoib_dev_priv *priv,58struct ib_pd *pd, struct ib_ah_attr *attr)59{60struct ipoib_ah *ah;6162ah = kmalloc(sizeof *ah, GFP_KERNEL);63if (!ah)64return NULL;6566ah->priv = priv;67ah->last_send = 0;68kref_init(&ah->ref);6970ah->ah = ib_create_ah(pd, attr, RDMA_CREATE_AH_SLEEPABLE);71if (IS_ERR(ah->ah)) {72kfree(ah);73ah = NULL;74} else75ipoib_dbg(priv, "Created ah %p\n", ah->ah);7677return ah;78}7980void ipoib_free_ah(struct kref *kref)81{82struct ipoib_ah *ah = container_of(kref, struct ipoib_ah, ref);83struct ipoib_dev_priv *priv = ah->priv;8485unsigned long flags;8687spin_lock_irqsave(&priv->lock, flags);88list_add_tail(&ah->list, &priv->dead_ahs);89spin_unlock_irqrestore(&priv->lock, flags);90}9192void93ipoib_dma_unmap_rx(struct ipoib_dev_priv *priv, struct ipoib_rx_buf *rx_req)94{95struct mbuf *m;96int i;9798for (i = 0, m = rx_req->mb; m != NULL; m = m->m_next, i++)99ib_dma_unmap_single(priv->ca, rx_req->mapping[i], m->m_len,100DMA_FROM_DEVICE);101}102103void104ipoib_dma_mb(struct ipoib_dev_priv *priv, struct mbuf *mb, unsigned int length)105{106107m_adj(mb, -(mb->m_pkthdr.len - length));108}109110struct mbuf *111ipoib_alloc_map_mb(struct ipoib_dev_priv *priv, struct ipoib_rx_buf *rx_req,112int align, int size, int max_frags)113{114struct mbuf *mb, *m;115int i, j;116117rx_req->mb = NULL;118mb = m_getm2(NULL, align + size, M_NOWAIT, MT_DATA, M_PKTHDR);119if (mb == NULL)120return (NULL);121for (i = 0, m = mb; m != NULL; m = m->m_next, i++) {122MPASS(i < max_frags);123124m->m_len = M_SIZE(m) - align;125m->m_data += align;126align = 0;127mb->m_pkthdr.len += m->m_len;128rx_req->mapping[i] = ib_dma_map_single(priv->ca,129mtod(m, void *), m->m_len, DMA_FROM_DEVICE);130if (unlikely(ib_dma_mapping_error(priv->ca,131rx_req->mapping[i])))132goto error;133134}135rx_req->mb = mb;136return (mb);137error:138for (j = 0, m = mb; j < i; m = m->m_next, j++)139ib_dma_unmap_single(priv->ca, rx_req->mapping[j], m->m_len,140DMA_FROM_DEVICE);141m_freem(mb);142return (NULL);143144}145146static int ipoib_ib_post_receive(struct ipoib_dev_priv *priv, int id)147{148struct ipoib_rx_buf *rx_req;149const struct ib_recv_wr *bad_wr;150struct mbuf *m;151int ret;152int i;153154rx_req = &priv->rx_ring[id];155for (m = rx_req->mb, i = 0; m != NULL; m = m->m_next, i++) {156priv->rx_sge[i].addr = rx_req->mapping[i];157priv->rx_sge[i].length = m->m_len;158}159priv->rx_wr.num_sge = i;160priv->rx_wr.wr_id = id | IPOIB_OP_RECV;161162ret = ib_post_recv(priv->qp, &priv->rx_wr, &bad_wr);163if (unlikely(ret)) {164ipoib_warn(priv, "receive failed for buf %d (%d)\n", id, ret);165ipoib_dma_unmap_rx(priv, &priv->rx_ring[id]);166m_freem(priv->rx_ring[id].mb);167priv->rx_ring[id].mb = NULL;168}169170return ret;171}172173static struct mbuf *174ipoib_alloc_rx_mb(struct ipoib_dev_priv *priv, int id)175{176return ipoib_alloc_map_mb(priv, &priv->rx_ring[id],1770, priv->max_ib_mtu + IB_GRH_BYTES, IPOIB_UD_RX_SG);178}179180static int ipoib_ib_post_receives(struct ipoib_dev_priv *priv)181{182int i;183184for (i = 0; i < ipoib_recvq_size; ++i) {185if (!ipoib_alloc_rx_mb(priv, i)) {186ipoib_warn(priv, "failed to allocate receive buffer %d\n", i);187return -ENOMEM;188}189if (ipoib_ib_post_receive(priv, i)) {190ipoib_warn(priv, "ipoib_ib_post_receive failed for buf %d\n", i);191return -EIO;192}193}194195return 0;196}197198static void199ipoib_ib_handle_rx_wc(struct ipoib_dev_priv *priv, struct ib_wc *wc)200{201struct ipoib_rx_buf saverx;202unsigned int wr_id = wc->wr_id & ~IPOIB_OP_RECV;203if_t dev = priv->dev;204struct ipoib_header *eh;205struct mbuf *mb;206207ipoib_dbg_data(priv, "recv completion: id %d, status: %d\n",208wr_id, wc->status);209210if (unlikely(wr_id >= ipoib_recvq_size)) {211ipoib_warn(priv, "recv completion event with wrid %d (> %d)\n",212wr_id, ipoib_recvq_size);213return;214}215216mb = priv->rx_ring[wr_id].mb;217218if (unlikely(wc->status != IB_WC_SUCCESS)) {219if (wc->status != IB_WC_WR_FLUSH_ERR) {220ipoib_warn(priv, "failed recv event "221"(status=%d, wrid=%d vend_err %x)\n",222wc->status, wr_id, wc->vendor_err);223goto repost;224}225if (mb) {226ipoib_dma_unmap_rx(priv, &priv->rx_ring[wr_id]);227m_freem(mb);228priv->rx_ring[wr_id].mb = NULL;229}230return;231}232233/*234* Drop packets that this interface sent, ie multicast packets235* that the HCA has replicated.236*/237if (wc->slid == priv->local_lid && wc->src_qp == priv->qp->qp_num)238goto repost;239240memcpy(&saverx, &priv->rx_ring[wr_id], sizeof(saverx));241/*242* If we can't allocate a new RX buffer, dump243* this packet and reuse the old buffer.244*/245if (unlikely(!ipoib_alloc_rx_mb(priv, wr_id))) {246memcpy(&priv->rx_ring[wr_id], &saverx, sizeof(saverx));247if_inc_counter(dev, IFCOUNTER_IQDROPS, 1);248goto repost;249}250251ipoib_dbg_data(priv, "received %d bytes, SLID 0x%04x\n",252wc->byte_len, wc->slid);253254ipoib_dma_unmap_rx(priv, &saverx);255ipoib_dma_mb(priv, mb, wc->byte_len);256257if_inc_counter(dev, IFCOUNTER_IPACKETS, 1);258if_inc_counter(dev, IFCOUNTER_IBYTES, mb->m_pkthdr.len);259mb->m_pkthdr.rcvif = dev;260m_adj(mb, sizeof(struct ib_grh) - INFINIBAND_ALEN);261eh = mtod(mb, struct ipoib_header *);262bzero(eh->hwaddr, 4); /* Zero the queue pair, only dgid is in grh */263264if (test_bit(IPOIB_FLAG_CSUM, &priv->flags) && likely(wc->wc_flags & IB_WC_IP_CSUM_OK))265mb->m_pkthdr.csum_flags = CSUM_IP_CHECKED | CSUM_IP_VALID;266267if_input(dev, mb);268269repost:270if (unlikely(ipoib_ib_post_receive(priv, wr_id)))271ipoib_warn(priv, "ipoib_ib_post_receive failed "272"for buf %d\n", wr_id);273}274275int ipoib_dma_map_tx(struct ib_device *ca, struct ipoib_tx_buf *tx_req, int max)276{277struct mbuf *mb = tx_req->mb;278u64 *mapping = tx_req->mapping;279struct mbuf *m, *p;280int error;281int i;282283for (m = mb, p = NULL, i = 0; m != NULL; p = m, m = m->m_next, i++) {284if (m->m_len != 0)285continue;286if (p == NULL)287panic("ipoib_dma_map_tx: First mbuf empty\n");288p->m_next = m_free(m);289m = p;290i--;291}292i--;293if (i >= max) {294tx_req->mb = mb = m_defrag(mb, M_NOWAIT);295if (mb == NULL)296return -EIO;297for (m = mb, i = 0; m != NULL; m = m->m_next, i++);298if (i >= max)299return -EIO;300}301error = 0;302for (m = mb, i = 0; m != NULL; m = m->m_next, i++) {303mapping[i] = ib_dma_map_single(ca, mtod(m, void *),304m->m_len, DMA_TO_DEVICE);305if (unlikely(ib_dma_mapping_error(ca, mapping[i]))) {306error = -EIO;307break;308}309}310if (error) {311int end;312313end = i;314for (m = mb, i = 0; i < end; m = m->m_next, i++)315ib_dma_unmap_single(ca, mapping[i], m->m_len,316DMA_TO_DEVICE);317}318return error;319}320321void ipoib_dma_unmap_tx(struct ib_device *ca, struct ipoib_tx_buf *tx_req)322{323struct mbuf *mb = tx_req->mb;324u64 *mapping = tx_req->mapping;325struct mbuf *m;326int i;327328for (m = mb, i = 0; m != NULL; m = m->m_next, i++)329ib_dma_unmap_single(ca, mapping[i], m->m_len, DMA_TO_DEVICE);330}331332static void ipoib_ib_handle_tx_wc(struct ipoib_dev_priv *priv, struct ib_wc *wc)333{334if_t dev = priv->dev;335unsigned int wr_id = wc->wr_id;336struct ipoib_tx_buf *tx_req;337338ipoib_dbg_data(priv, "send completion: id %d, status: %d\n",339wr_id, wc->status);340341if (unlikely(wr_id >= ipoib_sendq_size)) {342ipoib_warn(priv, "send completion event with wrid %d (> %d)\n",343wr_id, ipoib_sendq_size);344return;345}346347tx_req = &priv->tx_ring[wr_id];348349ipoib_dma_unmap_tx(priv->ca, tx_req);350351if_inc_counter(dev, IFCOUNTER_OPACKETS, 1);352353m_freem(tx_req->mb);354355++priv->tx_tail;356if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) &&357(if_getdrvflags(dev) & IFF_DRV_OACTIVE) &&358test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))359if_setdrvflagbits(dev, 0, IFF_DRV_OACTIVE);360361if (wc->status != IB_WC_SUCCESS &&362wc->status != IB_WC_WR_FLUSH_ERR)363ipoib_warn(priv, "failed send event "364"(status=%d, wrid=%d vend_err %x)\n",365wc->status, wr_id, wc->vendor_err);366}367368int369ipoib_poll_tx(struct ipoib_dev_priv *priv, bool do_start)370{371int n, i;372373n = ib_poll_cq(priv->send_cq, MAX_SEND_CQE, priv->send_wc);374for (i = 0; i < n; ++i) {375struct ib_wc *wc = priv->send_wc + i;376if (wc->wr_id & IPOIB_OP_CM)377ipoib_cm_handle_tx_wc(priv, wc);378else379ipoib_ib_handle_tx_wc(priv, wc);380}381382if (do_start && n != 0)383ipoib_start_locked(priv->dev, priv);384385return n == MAX_SEND_CQE;386}387388static void389ipoib_poll(struct ipoib_dev_priv *priv)390{391int n, i;392393poll_more:394spin_lock(&priv->drain_lock);395for (;;) {396n = ib_poll_cq(priv->recv_cq, IPOIB_NUM_WC, priv->ibwc);397for (i = 0; i < n; i++) {398struct ib_wc *wc = priv->ibwc + i;399400if ((wc->wr_id & IPOIB_OP_RECV) == 0)401panic("ipoib_poll: Bad wr_id 0x%jX\n",402(intmax_t)wc->wr_id);403if (wc->wr_id & IPOIB_OP_CM)404ipoib_cm_handle_rx_wc(priv, wc);405else406ipoib_ib_handle_rx_wc(priv, wc);407}408409if (n != IPOIB_NUM_WC)410break;411}412spin_unlock(&priv->drain_lock);413414if (ib_req_notify_cq(priv->recv_cq,415IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS) > 0)416goto poll_more;417}418419void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)420{421struct ipoib_dev_priv *priv = dev_ptr;422423ipoib_poll(priv);424}425426static void drain_tx_cq(struct ipoib_dev_priv *priv)427{428if_t dev = priv->dev;429430spin_lock(&priv->lock);431while (ipoib_poll_tx(priv, true))432; /* nothing */433434if (if_getdrvflags(dev) & IFF_DRV_OACTIVE)435mod_timer(&priv->poll_timer, jiffies + 1);436437spin_unlock(&priv->lock);438}439440void ipoib_send_comp_handler(struct ib_cq *cq, void *dev_ptr)441{442struct ipoib_dev_priv *priv = dev_ptr;443444mod_timer(&priv->poll_timer, jiffies);445}446447static inline int448post_send(struct ipoib_dev_priv *priv, unsigned int wr_id,449struct ib_ah *address, u32 qpn, struct ipoib_tx_buf *tx_req, void *head,450int hlen)451{452const struct ib_send_wr *bad_wr;453struct mbuf *mb = tx_req->mb;454u64 *mapping = tx_req->mapping;455struct mbuf *m;456int i;457458for (m = mb, i = 0; m != NULL; m = m->m_next, i++) {459priv->tx_sge[i].addr = mapping[i];460priv->tx_sge[i].length = m->m_len;461}462priv->tx_wr.wr.num_sge = i;463priv->tx_wr.wr.wr_id = wr_id;464priv->tx_wr.remote_qpn = qpn;465priv->tx_wr.ah = address;466467if (head) {468priv->tx_wr.mss = 0; /* XXX mb_shinfo(mb)->gso_size; */469priv->tx_wr.header = head;470priv->tx_wr.hlen = hlen;471priv->tx_wr.wr.opcode = IB_WR_LSO;472} else473priv->tx_wr.wr.opcode = IB_WR_SEND;474475return ib_post_send(priv->qp, &priv->tx_wr.wr, &bad_wr);476}477478void479ipoib_send(struct ipoib_dev_priv *priv, struct mbuf *mb,480struct ipoib_ah *address, u32 qpn)481{482if_t dev = priv->dev;483struct ipoib_tx_buf *tx_req;484int hlen;485void *phead;486487if (unlikely(priv->tx_outstanding > MAX_SEND_CQE))488while (ipoib_poll_tx(priv, false))489; /* nothing */490491m_adj(mb, sizeof (struct ipoib_pseudoheader));492if (0 /* XXX segment offload mb_is_gso(mb) */) {493/* XXX hlen = mb_transport_offset(mb) + tcp_hdrlen(mb); */494phead = mtod(mb, void *);495if (mb->m_len < hlen) {496ipoib_warn(priv, "linear data too small\n");497if_inc_counter(dev, IFCOUNTER_OERRORS, 1);498m_freem(mb);499return;500}501m_adj(mb, hlen);502} else {503if (unlikely(mb->m_pkthdr.len - IPOIB_ENCAP_LEN > priv->mcast_mtu)) {504ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",505mb->m_pkthdr.len, priv->mcast_mtu);506if_inc_counter(dev, IFCOUNTER_OERRORS, 1);507ipoib_cm_mb_too_long(priv, mb, priv->mcast_mtu);508return;509}510phead = NULL;511hlen = 0;512}513514ipoib_dbg_data(priv, "sending packet, length=%d address=%p qpn=0x%06x\n",515mb->m_pkthdr.len, address, qpn);516517/*518* We put the mb into the tx_ring _before_ we call post_send()519* because it's entirely possible that the completion handler will520* run before we execute anything after the post_send(). That521* means we have to make sure everything is properly recorded and522* our state is consistent before we call post_send().523*/524tx_req = &priv->tx_ring[priv->tx_head & (ipoib_sendq_size - 1)];525tx_req->mb = mb;526if (unlikely(ipoib_dma_map_tx(priv->ca, tx_req, IPOIB_UD_TX_SG))) {527if_inc_counter(dev, IFCOUNTER_OERRORS, 1);528if (tx_req->mb)529m_freem(tx_req->mb);530return;531}532533if (mb->m_pkthdr.csum_flags & (CSUM_IP|CSUM_TCP|CSUM_UDP))534priv->tx_wr.wr.send_flags |= IB_SEND_IP_CSUM;535else536priv->tx_wr.wr.send_flags &= ~IB_SEND_IP_CSUM;537538if (++priv->tx_outstanding == ipoib_sendq_size) {539ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n");540if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP))541ipoib_warn(priv, "request notify on send CQ failed\n");542if_setdrvflagbits(dev, IFF_DRV_OACTIVE, 0);543}544545if (unlikely(post_send(priv,546priv->tx_head & (ipoib_sendq_size - 1), address->ah, qpn,547tx_req, phead, hlen))) {548ipoib_warn(priv, "post_send failed\n");549if_inc_counter(dev, IFCOUNTER_OERRORS, 1);550--priv->tx_outstanding;551ipoib_dma_unmap_tx(priv->ca, tx_req);552m_freem(mb);553if (if_getdrvflags(dev) & IFF_DRV_OACTIVE)554if_setdrvflagbits(dev, 0, IFF_DRV_OACTIVE);555} else {556address->last_send = priv->tx_head;557++priv->tx_head;558}559}560561static void __ipoib_reap_ah(struct ipoib_dev_priv *priv)562{563struct ipoib_ah *ah, *tah;564LIST_HEAD(remove_list);565unsigned long flags;566567spin_lock_irqsave(&priv->lock, flags);568569list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list)570if ((int) priv->tx_tail - (int) ah->last_send >= 0) {571list_del(&ah->list);572ib_destroy_ah(ah->ah, 0);573kfree(ah);574}575576spin_unlock_irqrestore(&priv->lock, flags);577}578579void ipoib_reap_ah(struct work_struct *work)580{581struct ipoib_dev_priv *priv =582container_of(work, struct ipoib_dev_priv, ah_reap_task.work);583584__ipoib_reap_ah(priv);585586if (!test_bit(IPOIB_STOP_REAPER, &priv->flags))587queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task,588HZ);589}590591static void ipoib_ah_dev_cleanup(struct ipoib_dev_priv *priv)592{593unsigned long begin;594595begin = jiffies;596597while (!list_empty(&priv->dead_ahs)) {598__ipoib_reap_ah(priv);599600if (time_after(jiffies, begin + HZ)) {601ipoib_warn(priv, "timing out; will leak address handles\n");602break;603}604605msleep(1);606}607}608609static void ipoib_ib_tx_timer_func(unsigned long ctx)610{611drain_tx_cq((struct ipoib_dev_priv *)ctx);612}613614int ipoib_ib_dev_open(struct ipoib_dev_priv *priv)615{616int ret;617618if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &priv->pkey_index)) {619ipoib_warn(priv, "P_Key 0x%04x not found\n", priv->pkey);620clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);621return -1;622}623set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);624625ret = ipoib_init_qp(priv);626if (ret) {627ipoib_warn(priv, "ipoib_init_qp returned %d\n", ret);628return -1;629}630631ret = ipoib_ib_post_receives(priv);632if (ret) {633ipoib_warn(priv, "ipoib_ib_post_receives returned %d\n", ret);634ipoib_ib_dev_stop(priv, 1);635return -1;636}637638ret = ipoib_cm_dev_open(priv);639if (ret) {640ipoib_warn(priv, "ipoib_cm_dev_open returned %d\n", ret);641ipoib_ib_dev_stop(priv, 1);642return -1;643}644645clear_bit(IPOIB_STOP_REAPER, &priv->flags);646queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, HZ);647648set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);649650return 0;651}652653static void ipoib_pkey_dev_check_presence(struct ipoib_dev_priv *priv)654{655u16 pkey_index = 0;656657if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &pkey_index))658clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);659else660set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);661}662663int ipoib_ib_dev_up(struct ipoib_dev_priv *priv)664{665666ipoib_pkey_dev_check_presence(priv);667668if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) {669ipoib_dbg(priv, "PKEY is not assigned.\n");670return 0;671}672673set_bit(IPOIB_FLAG_OPER_UP, &priv->flags);674675return ipoib_mcast_start_thread(priv);676}677678int ipoib_ib_dev_down(struct ipoib_dev_priv *priv, int flush)679{680681ipoib_dbg(priv, "downing ib_dev\n");682683clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags);684if_link_state_change(priv->dev, LINK_STATE_DOWN);685686/* Shutdown the P_Key thread if still active */687if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) {688mutex_lock(&pkey_mutex);689set_bit(IPOIB_PKEY_STOP, &priv->flags);690cancel_delayed_work(&priv->pkey_poll_task);691mutex_unlock(&pkey_mutex);692if (flush)693flush_workqueue(ipoib_workqueue);694}695696ipoib_mcast_stop_thread(priv, flush);697ipoib_mcast_dev_flush(priv);698699ipoib_flush_paths(priv);700701return 0;702}703704static int recvs_pending(struct ipoib_dev_priv *priv)705{706int pending = 0;707int i;708709for (i = 0; i < ipoib_recvq_size; ++i)710if (priv->rx_ring[i].mb)711++pending;712713return pending;714}715716static void check_qp_movement_and_print(struct ipoib_dev_priv *priv,717struct ib_qp *qp,718enum ib_qp_state new_state)719{720struct ib_qp_attr qp_attr;721struct ib_qp_init_attr query_init_attr;722int ret;723724ret = ib_query_qp(qp, &qp_attr, IB_QP_STATE, &query_init_attr);725if (ret) {726ipoib_warn(priv, "%s: Failed to query QP (%d)\n", __func__, ret);727return;728}729730/* print according to the new-state and the previous state */731if (new_state == IB_QPS_ERR && qp_attr.qp_state == IB_QPS_RESET) {732ipoib_dbg(priv, "Failed to modify QP %d->%d, acceptable\n",733qp_attr.qp_state, new_state);734} else {735ipoib_warn(priv, "Failed to modify QP %d->%d\n",736qp_attr.qp_state, new_state);737}738}739740void ipoib_drain_cq(struct ipoib_dev_priv *priv)741{742int i, n;743744spin_lock(&priv->drain_lock);745do {746n = ib_poll_cq(priv->recv_cq, IPOIB_NUM_WC, priv->ibwc);747for (i = 0; i < n; ++i) {748/*749* Convert any successful completions to flush750* errors to avoid passing packets up the751* stack after bringing the device down.752*/753if (priv->ibwc[i].status == IB_WC_SUCCESS)754priv->ibwc[i].status = IB_WC_WR_FLUSH_ERR;755756if ((priv->ibwc[i].wr_id & IPOIB_OP_RECV) == 0)757panic("ipoib_drain_cq: Bad wrid 0x%jX\n",758(intmax_t)priv->ibwc[i].wr_id);759if (priv->ibwc[i].wr_id & IPOIB_OP_CM)760ipoib_cm_handle_rx_wc(priv, priv->ibwc + i);761else762ipoib_ib_handle_rx_wc(priv, priv->ibwc + i);763}764} while (n == IPOIB_NUM_WC);765spin_unlock(&priv->drain_lock);766767spin_lock(&priv->lock);768while (ipoib_poll_tx(priv, true))769; /* nothing */770771spin_unlock(&priv->lock);772}773774int ipoib_ib_dev_stop(struct ipoib_dev_priv *priv, int flush)775{776struct ib_qp_attr qp_attr;777unsigned long begin;778struct ipoib_tx_buf *tx_req;779int i;780781clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);782783ipoib_cm_dev_stop(priv);784785/*786* Move our QP to the error state and then reinitialize in787* when all work requests have completed or have been flushed.788*/789qp_attr.qp_state = IB_QPS_ERR;790if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))791check_qp_movement_and_print(priv, priv->qp, IB_QPS_ERR);792793/* Wait for all sends and receives to complete */794begin = jiffies;795796while (priv->tx_head != priv->tx_tail || recvs_pending(priv)) {797if (time_after(jiffies, begin + 5 * HZ)) {798ipoib_warn(priv, "timing out; %d sends %d receives not completed\n",799priv->tx_head - priv->tx_tail, recvs_pending(priv));800801/*802* assume the HW is wedged and just free up803* all our pending work requests.804*/805while ((int) priv->tx_tail - (int) priv->tx_head < 0) {806tx_req = &priv->tx_ring[priv->tx_tail &807(ipoib_sendq_size - 1)];808ipoib_dma_unmap_tx(priv->ca, tx_req);809m_freem(tx_req->mb);810++priv->tx_tail;811--priv->tx_outstanding;812}813814for (i = 0; i < ipoib_recvq_size; ++i) {815struct ipoib_rx_buf *rx_req;816817rx_req = &priv->rx_ring[i];818if (!rx_req->mb)819continue;820ipoib_dma_unmap_rx(priv, &priv->rx_ring[i]);821m_freem(rx_req->mb);822rx_req->mb = NULL;823}824825goto timeout;826}827828ipoib_drain_cq(priv);829830msleep(1);831}832833ipoib_dbg(priv, "All sends and receives done.\n");834835timeout:836del_timer_sync(&priv->poll_timer);837qp_attr.qp_state = IB_QPS_RESET;838if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))839ipoib_warn(priv, "Failed to modify QP to RESET state\n");840841/* Wait for all AHs to be reaped */842set_bit(IPOIB_STOP_REAPER, &priv->flags);843cancel_delayed_work(&priv->ah_reap_task);844if (flush)845flush_workqueue(ipoib_workqueue);846847ipoib_ah_dev_cleanup(priv);848849ib_req_notify_cq(priv->recv_cq, IB_CQ_NEXT_COMP);850851return 0;852}853854int ipoib_ib_dev_init(struct ipoib_dev_priv *priv, struct ib_device *ca, int port)855{856if_t dev = priv->dev;857858priv->ca = ca;859priv->port = port;860priv->qp = NULL;861862if (ipoib_transport_dev_init(priv, ca)) {863printk(KERN_WARNING "%s: ipoib_transport_dev_init failed\n", ca->name);864return -ENODEV;865}866867setup_timer(&priv->poll_timer, ipoib_ib_tx_timer_func,868(unsigned long) priv);869870if (if_getflags(dev) & IFF_UP) {871if (ipoib_ib_dev_open(priv)) {872ipoib_transport_dev_cleanup(priv);873return -ENODEV;874}875}876877return 0;878}879880static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv,881enum ipoib_flush_level level)882{883struct ipoib_dev_priv *cpriv;884u16 new_index;885886mutex_lock(&priv->vlan_mutex);887888/*889* Flush any child interfaces too -- they might be up even if890* the parent is down.891*/892list_for_each_entry(cpriv, &priv->child_intfs, list)893__ipoib_ib_dev_flush(cpriv, level);894895mutex_unlock(&priv->vlan_mutex);896897if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) {898ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n");899return;900}901902if (!test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) {903ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_ADMIN_UP not set.\n");904return;905}906907if (level == IPOIB_FLUSH_HEAVY) {908if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &new_index)) {909clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);910ipoib_ib_dev_down(priv, 0);911ipoib_ib_dev_stop(priv, 0);912if (ipoib_pkey_dev_delay_open(priv))913return;914}915916/* restart QP only if P_Key index is changed */917if (test_and_set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) &&918new_index == priv->pkey_index) {919ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n");920return;921}922priv->pkey_index = new_index;923}924925if (level == IPOIB_FLUSH_LIGHT) {926ipoib_mark_paths_invalid(priv);927ipoib_mcast_dev_flush(priv);928}929930if (level >= IPOIB_FLUSH_NORMAL)931ipoib_ib_dev_down(priv, 0);932933if (level == IPOIB_FLUSH_HEAVY) {934ipoib_ib_dev_stop(priv, 0);935ipoib_ib_dev_open(priv);936}937938/*939* The device could have been brought down between the start and when940* we get here, don't bring it back up if it's not configured up941*/942if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) {943if (level >= IPOIB_FLUSH_NORMAL)944ipoib_ib_dev_up(priv);945ipoib_mcast_restart_task(&priv->restart_task);946}947}948949void ipoib_ib_dev_flush_light(struct work_struct *work)950{951struct ipoib_dev_priv *priv =952container_of(work, struct ipoib_dev_priv, flush_light);953954__ipoib_ib_dev_flush(priv, IPOIB_FLUSH_LIGHT);955}956957void ipoib_ib_dev_flush_normal(struct work_struct *work)958{959struct ipoib_dev_priv *priv =960container_of(work, struct ipoib_dev_priv, flush_normal);961962__ipoib_ib_dev_flush(priv, IPOIB_FLUSH_NORMAL);963}964965void ipoib_ib_dev_flush_heavy(struct work_struct *work)966{967struct ipoib_dev_priv *priv =968container_of(work, struct ipoib_dev_priv, flush_heavy);969970__ipoib_ib_dev_flush(priv, IPOIB_FLUSH_HEAVY);971}972973void ipoib_ib_dev_cleanup(struct ipoib_dev_priv *priv)974{975976ipoib_dbg(priv, "cleaning up ib_dev\n");977978ipoib_mcast_stop_thread(priv, 1);979ipoib_mcast_dev_flush(priv);980981ipoib_ah_dev_cleanup(priv);982ipoib_transport_dev_cleanup(priv);983}984985/*986* Delayed P_Key Assigment Interim Support987*988* The following is initial implementation of delayed P_Key assigment989* mechanism. It is using the same approach implemented for the multicast990* group join. The single goal of this implementation is to quickly address991* Bug #2507. This implementation will probably be removed when the P_Key992* change async notification is available.993*/994995void ipoib_pkey_poll(struct work_struct *work)996{997struct ipoib_dev_priv *priv =998container_of(work, struct ipoib_dev_priv, pkey_poll_task.work);9991000ipoib_pkey_dev_check_presence(priv);10011002if (test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags))1003ipoib_open(priv);1004else {1005mutex_lock(&pkey_mutex);1006if (!test_bit(IPOIB_PKEY_STOP, &priv->flags))1007queue_delayed_work(ipoib_workqueue,1008&priv->pkey_poll_task,1009HZ);1010mutex_unlock(&pkey_mutex);1011}1012}10131014int ipoib_pkey_dev_delay_open(struct ipoib_dev_priv *priv)1015{10161017/* Look for the interface pkey value in the IB Port P_Key table and */1018/* set the interface pkey assigment flag */1019ipoib_pkey_dev_check_presence(priv);10201021/* P_Key value not assigned yet - start polling */1022if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) {1023mutex_lock(&pkey_mutex);1024clear_bit(IPOIB_PKEY_STOP, &priv->flags);1025queue_delayed_work(ipoib_workqueue,1026&priv->pkey_poll_task,1027HZ);1028mutex_unlock(&pkey_mutex);1029return 1;1030}10311032return 0;1033}103410351036