From owner-svn-src-all@FreeBSD.ORG Wed Sep 8 17:11:49 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7542210656E0; Wed, 8 Sep 2010 17:11:49 +0000 (UTC) (envelope-from jchandra@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 5A5468FC14; Wed, 8 Sep 2010 17:11:49 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o88HBnla051655; Wed, 8 Sep 2010 17:11:49 GMT (envelope-from jchandra@svn.freebsd.org) Received: (from jchandra@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o88HBn8B051653; Wed, 8 Sep 2010 17:11:49 GMT (envelope-from jchandra@svn.freebsd.org) Message-Id: <201009081711.o88HBn8B051653@svn.freebsd.org> From: "Jayachandran C." Date: Wed, 8 Sep 2010 17:11:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r212324 - head/sys/mips/rmi/dev/nlge X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Sep 2010 17:11:49 -0000 Author: jchandra Date: Wed Sep 8 17:11:49 2010 New Revision: 212324 URL: http://svn.freebsd.org/changeset/base/212324 Log: nlge (alternate XLR GMAC driver) updates: - Updates for the message ring clean up in r212321. - Instead of dropping Tx packet on credit fail, retry send until it succeeds. - Fix freeing mbufs in case of P2P descriptors: We cannot free the mbuf when the P2P descriptor freeback is received. The mbuf may be still in use by the GMAC, since the P2P freeback indicates that it read the P2D descriptors in the P2P message. Now we free just the P2P descriptor when the P2P freeback message is received. Another freeback P2D message has been added to the end of the packet descriptors, the mbuf will be freed only when we received this. The P2P descriptor issue was reported by srgorti at netlogicmicro dot com. Modified: head/sys/mips/rmi/dev/nlge/if_nlge.c Modified: head/sys/mips/rmi/dev/nlge/if_nlge.c ============================================================================== --- head/sys/mips/rmi/dev/nlge/if_nlge.c Wed Sep 8 16:59:22 2010 (r212323) +++ head/sys/mips/rmi/dev/nlge/if_nlge.c Wed Sep 8 17:11:49 2010 (r212324) @@ -207,7 +207,7 @@ static int prepare_fmn_message(struct nl uint64_t fr_stid, struct nlge_tx_desc **tx_desc); static void release_mbuf(uint64_t phy_addr); -static void release_tx_desc(struct msgrng_msg *msg); +static void release_tx_desc(vm_paddr_t phy_addr); static int send_fmn_msg_tx(struct nlge_softc *, struct msgrng_msg *, uint32_t n_entries); @@ -637,7 +637,7 @@ nlge_msgring_handler(int bucket, int siz struct nlna_softc *na_sc; struct nlge_softc *sc; struct ifnet *ifp; - uint64_t phys_addr; + vm_paddr_t phys_addr; unsigned long addr; uint32_t length; int ctrl; @@ -655,14 +655,15 @@ nlge_msgring_handler(int bucket, int siz tx_error = 0; length = (msg->msg0 >> 40) & 0x3fff; na_sc = (struct nlna_softc *)data; - phys_addr = (uint64_t) (msg->msg0 & 0xffffffffe0ULL); if (length == 0) { ctrl = CTRL_REG_FREE; + phys_addr = msg->msg0 & 0xffffffffffULL; port = (msg->msg0 >> 54) & 0x0f; is_p2p = (msg->msg0 >> 62) & 0x1; tx_error = (msg->msg0 >> 58) & 0xf; } else { ctrl = CTRL_SNGL; + phys_addr = msg->msg0 & 0xffffffffe0ULL; length = length - BYTE_OFFSET - MAC_CRC_LEN; port = msg->msg0 & 0x0f; } @@ -676,11 +677,12 @@ nlge_msgring_handler(int bucket, int siz } if (ctrl == CTRL_REG_FREE || ctrl == CTRL_JUMBO_FREE) { - if (is_p2p) - release_tx_desc(msg); - else { - release_mbuf(msg->msg0 & 0xffffffffffULL); + if (is_p2p) { + release_tx_desc(phys_addr); + } else { + release_mbuf(phys_addr); } + ifp = sc->nlge_if; if (ifp->if_drv_flags & IFF_DRV_OACTIVE){ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; @@ -742,7 +744,7 @@ nlge_start_locked(struct ifnet *ifp, str goto fail; } sent = send_fmn_msg_tx(sc, &msg, n_entries); - if (!sent) { + if (sent != 0) { goto fail; } } while(1); @@ -1011,28 +1013,27 @@ static __inline__ int nlna_send_free_desc(struct nlna_softc *sc, vm_paddr_t addr) { struct msgrng_msg msg; - int stid; - int code; - int i; + uint32_t msgrng_flags; + int i = 0, stid, code, ret; stid = sc->rfrbucket; memset(&msg, 0, sizeof(msg)); msg.msg0 = (uint64_t) addr & 0xffffffffe0ULL; code = (sc->na_type == XLR_XGMAC) ? MSGRNG_CODE_XGMAC : MSGRNG_CODE_MAC; - for (i = 0; i < MAX_MSG_SND_ATTEMPTS; i++) { - if (message_send(1, code, stid, &msg) == 0) - return (0); - } - printf("Error: failed to send free desc to station %d\n", stid); - return (1); + do { + msgrng_flags = msgrng_access_enable(); + ret = message_send_retry(1, code, stid, &msg); + msgrng_restore(msgrng_flags); + KASSERT(i++ < 100000, ("Too many credit fails\n")); + } while (ret != 0); + return (0); } static void nlna_submit_rx_free_desc(struct nlna_softc *sc, uint32_t n_desc) { void *ptr; - unsigned long msgrng_flags; int i; int ret; @@ -1050,10 +1051,8 @@ nlna_submit_rx_free_desc(struct nlna_sof } /* Send the free Rx desc to the MAC */ - msgrng_access_enable(msgrng_flags); ret = nlna_send_free_desc(sc, vtophys(ptr)); - msgrng_access_disable(msgrng_flags); - if (ret) /* no point trying other descriptors after + if (ret != 0) /* no point trying other descriptors after a failure. */ break; } @@ -1907,9 +1906,10 @@ prepare_fmn_message(struct nlge_softc *s while (len) { if (msg_sz == (FMN_SZ - 1)) { - p2p = uma_zalloc(nl_tx_desc_zone, M_WAITOK); - if (p2p == NULL) + p2p = uma_zalloc(nl_tx_desc_zone, M_NOWAIT); + if (p2p == NULL) { return 2; + } /* * As we currently use xlr_paddr_lw on a 32-bit * OS, both the pointers are laid out in one @@ -1922,7 +1922,7 @@ prepare_fmn_message(struct nlge_softc *s ((vm_offset_t) mbuf_chain); cur_p2d = &p2p->frag[0]; is_p2p = 1; - } else if (msg_sz == (FMN_SZ - 1 + XLR_MAX_TX_FRAGS)) { + } else if (msg_sz == (FMN_SZ - 2 + XLR_MAX_TX_FRAGS)) { uma_zfree(nl_tx_desc_zone, p2p); return 1; } @@ -1940,26 +1940,24 @@ prepare_fmn_message(struct nlge_softc *s } } - if (msg_sz > 0) { - cur_p2d[-1] |= (1ULL << 63); /* set eop in most-recent p2d */ - } else { + if (msg_sz == 0) { printf("Zero-length mbuf chain ??\n"); *n_entries = msg_sz ; return 0; } + cur_p2d[-1] |= (1ULL << 63); /* set eop in most-recent p2d */ + *cur_p2d = (1ULL << 63) | ((uint64_t)fb_stn_id << 54) | + (vm_offset_t) mbuf_chain; *tx_desc = p2p; if (is_p2p) { paddr = vtophys(p2p); - fmn_msg->msg3 = (1ULL << 63) | (1ULL << 62) | - ((uint64_t)fb_stn_id << 54) | + p2p_sz++; + fmn_msg->msg3 = (1ULL << 62) | ((uint64_t)fb_stn_id << 54) | ((uint64_t)(p2p_sz * 8) << 40) | paddr; *n_entries = FMN_SZ; } else { - /* zero-len p2d */ - *cur_p2d = (1ULL << 63) | ((uint64_t)fb_stn_id << 54) | - (vm_offset_t) mbuf_chain; *n_entries = msg_sz + 1; } @@ -1970,15 +1968,17 @@ static int send_fmn_msg_tx(struct nlge_softc *sc, struct msgrng_msg *msg, uint32_t n_entries) { - unsigned long mflags; - int ret; + uint32_t msgrng_flags; + int i = 0, ret; - mflags = 0; - msgrng_access_enable(mflags); - ret = message_send_retry(n_entries, MSGRNG_CODE_MAC, sc->tx_bucket_id, - msg); - msgrng_access_disable(mflags); - return (!ret); + do { + msgrng_flags = msgrng_access_enable(); + ret = message_send_retry(n_entries, MSGRNG_CODE_MAC, + sc->tx_bucket_id, msg); + msgrng_restore(msgrng_flags); + KASSERT(i++ < 100000, ("Too many credit fails\n")); + } while (ret != 0); + return (0); } static void @@ -1991,25 +1991,20 @@ release_mbuf(uint64_t phy_addr) } static void -release_tx_desc(struct msgrng_msg *msg) +release_tx_desc(vm_paddr_t paddr) { - vm_paddr_t paddr; - uint64_t temp; struct nlge_tx_desc *tx_desc; - struct mbuf *m; uint32_t sr; + uint32_t val1, val2; - paddr = msg->msg0 & 0xffffffffffULL; paddr += (XLR_MAX_TX_FRAGS * sizeof(uint64_t)); sr = xlr_enable_kx(); - temp = xlr_paddr_lw(paddr); - tx_desc = (struct nlge_tx_desc*)((intptr_t) temp); + val1 = xlr_paddr_lw(paddr); paddr += sizeof(void *); - temp = xlr_paddr_lw(paddr); + val2 = xlr_paddr_lw(paddr); mips_wr_status(sr); - m = (struct mbuf *)((intptr_t) temp); - m_freem(m); + tx_desc = (struct nlge_tx_desc*)(intptr_t) val1; uma_zfree(nl_tx_desc_zone, tx_desc); }