Deleted Added
full compact
if_bce.c (163338) if_bce.c (163339)
1/*-
2 * Copyright (c) 2006 Broadcom Corporation
3 * David Christensen <davidch@broadcom.com>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *

--- 15 unchanged lines hidden (view full) ---

24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2006 Broadcom Corporation
3 * David Christensen <davidch@broadcom.com>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *

--- 15 unchanged lines hidden (view full) ---

24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/sys/dev/bce/if_bce.c 163338 2006-10-14 04:28:23Z scottl $");
32__FBSDID("$FreeBSD: head/sys/dev/bce/if_bce.c 163339 2006-10-14 05:30:12Z scottl $");
33
34/*
35 * The following controllers are supported by this driver:
36 * BCM5706C A2, A3
37 * BCM5708C B1
38 *
39 * The following controllers are not supported by this driver:
40 * (These are not "Production" versions of the controller.)

--- 254 unchanged lines hidden (view full) ---

295static int bce_blockinit (struct bce_softc *);
296static int bce_get_buf (struct bce_softc *, struct mbuf *, u16 *, u16 *, u32 *);
297
298static int bce_init_tx_chain (struct bce_softc *);
299static int bce_init_rx_chain (struct bce_softc *);
300static void bce_free_rx_chain (struct bce_softc *);
301static void bce_free_tx_chain (struct bce_softc *);
302
33
34/*
35 * The following controllers are supported by this driver:
36 * BCM5706C A2, A3
37 * BCM5708C B1
38 *
39 * The following controllers are not supported by this driver:
40 * (These are not "Production" versions of the controller.)

--- 254 unchanged lines hidden (view full) ---

295static int bce_blockinit (struct bce_softc *);
296static int bce_get_buf (struct bce_softc *, struct mbuf *, u16 *, u16 *, u32 *);
297
298static int bce_init_tx_chain (struct bce_softc *);
299static int bce_init_rx_chain (struct bce_softc *);
300static void bce_free_rx_chain (struct bce_softc *);
301static void bce_free_tx_chain (struct bce_softc *);
302
303static int bce_tx_encap (struct bce_softc *, struct mbuf *, u16 *, u16 *, u32 *);
303static int bce_tx_encap (struct bce_softc *, struct mbuf *, u16 *);
304static void bce_start_locked (struct ifnet *);
305static void bce_start (struct ifnet *);
306static int bce_ioctl (struct ifnet *, u_long, caddr_t);
307static void bce_watchdog (struct ifnet *);
308static int bce_ifmedia_upd (struct ifnet *);
309static void bce_ifmedia_sts (struct ifnet *, struct ifmediareq *);
310static void bce_init_locked (struct bce_softc *);
311static void bce_init (void *);

--- 4322 unchanged lines hidden (view full) ---

4634/****************************************************************************/
4635/* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
4636/* memory visible to the controller. */
4637/* */
4638/* Returns: */
4639/* 0 for success, positive value for failure. */
4640/****************************************************************************/
4641static int
304static void bce_start_locked (struct ifnet *);
305static void bce_start (struct ifnet *);
306static int bce_ioctl (struct ifnet *, u_long, caddr_t);
307static void bce_watchdog (struct ifnet *);
308static int bce_ifmedia_upd (struct ifnet *);
309static void bce_ifmedia_sts (struct ifnet *, struct ifmediareq *);
310static void bce_init_locked (struct bce_softc *);
311static void bce_init (void *);

--- 4322 unchanged lines hidden (view full) ---

4634/****************************************************************************/
4635/* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
4636/* memory visible to the controller. */
4637/* */
4638/* Returns: */
4639/* 0 for success, positive value for failure. */
4640/****************************************************************************/
4641static int
4642bce_tx_encap(struct bce_softc *sc, struct mbuf *m_head, u16 *prod,
4643 u16 *chain_prod, u32 *prod_bseq)
4642bce_tx_encap(struct bce_softc *sc, struct mbuf *m_head, u16 *prod)
4644{
4645 u32 vlan_tag_flags = 0;
4643{
4644 u32 vlan_tag_flags = 0;
4645 u16 chain_prod;
4646 struct bce_dmamap_arg map_arg;
4647 bus_dmamap_t map;
4648 int error, rc = 0;
4649
4650 /* Transfer any checksum offload flags to the bd. */
4651 if (m_head->m_pkthdr.csum_flags) {
4652 if (m_head->m_pkthdr.csum_flags & CSUM_IP)
4653 vlan_tag_flags |= TX_BD_FLAGS_IP_CKSUM;
4654 if (m_head->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
4655 vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
4656 }
4657
4658 /* Transfer any VLAN tags to the bd. */
4659 if (m_head->m_flags & M_VLANTAG)
4660 vlan_tag_flags |= (TX_BD_FLAGS_VLAN_TAG |
4661 (m_head->m_pkthdr.ether_vtag << 16));
4662
4663 /* Map the mbuf into DMAable memory. */
4646 struct bce_dmamap_arg map_arg;
4647 bus_dmamap_t map;
4648 int error, rc = 0;
4649
4650 /* Transfer any checksum offload flags to the bd. */
4651 if (m_head->m_pkthdr.csum_flags) {
4652 if (m_head->m_pkthdr.csum_flags & CSUM_IP)
4653 vlan_tag_flags |= TX_BD_FLAGS_IP_CKSUM;
4654 if (m_head->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
4655 vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
4656 }
4657
4658 /* Transfer any VLAN tags to the bd. */
4659 if (m_head->m_flags & M_VLANTAG)
4660 vlan_tag_flags |= (TX_BD_FLAGS_VLAN_TAG |
4661 (m_head->m_pkthdr.ether_vtag << 16));
4662
4663 /* Map the mbuf into DMAable memory. */
4664 map = sc->tx_mbuf_map[*chain_prod];
4664 chain_prod = TX_CHAIN_IDX(*prod);
4665 map = sc->tx_mbuf_map[chain_prod];
4665 map_arg.sc = sc;
4666 map_arg.prod = *prod;
4666 map_arg.sc = sc;
4667 map_arg.prod = *prod;
4667 map_arg.chain_prod = *chain_prod;
4668 map_arg.prod_bseq = *prod_bseq;
4668 map_arg.chain_prod = chain_prod;
4669 map_arg.prod_bseq = sc->tx_prod_bseq;
4669 map_arg.tx_flags = vlan_tag_flags;
4670 map_arg.maxsegs = USABLE_TX_BD - sc->used_tx_bd -
4671 BCE_TX_SLACK_SPACE;
4672
4673 KASSERT(map_arg.maxsegs > 0, ("Invalid TX maxsegs value!"));
4674
4675 /* Map the mbuf into our DMA address space. */
4676 error = bus_dmamap_load_mbuf(sc->tx_mbuf_tag, map, m_head,

--- 32 unchanged lines hidden (view full) ---

4709 * Ensure that the map for this transmission
4710 * is placed at the array index of the last
4711 * descriptor in this chain. This is done
4712 * because a single map is used for all
4713 * segments of the mbuf and we don't want to
4714 * delete the map before all of the segments
4715 * have been freed.
4716 */
4670 map_arg.tx_flags = vlan_tag_flags;
4671 map_arg.maxsegs = USABLE_TX_BD - sc->used_tx_bd -
4672 BCE_TX_SLACK_SPACE;
4673
4674 KASSERT(map_arg.maxsegs > 0, ("Invalid TX maxsegs value!"));
4675
4676 /* Map the mbuf into our DMA address space. */
4677 error = bus_dmamap_load_mbuf(sc->tx_mbuf_tag, map, m_head,

--- 32 unchanged lines hidden (view full) ---

4710 * Ensure that the map for this transmission
4711 * is placed at the array index of the last
4712 * descriptor in this chain. This is done
4713 * because a single map is used for all
4714 * segments of the mbuf and we don't want to
4715 * delete the map before all of the segments
4716 * have been freed.
4717 */
4717 sc->tx_mbuf_map[*chain_prod] =
4718 sc->tx_mbuf_map[chain_prod] =
4718 sc->tx_mbuf_map[map_arg.chain_prod];
4719 sc->tx_mbuf_map[map_arg.chain_prod] = map;
4720 sc->tx_mbuf_ptr[map_arg.chain_prod] = m_head;
4721 sc->used_tx_bd += map_arg.maxsegs;
4722
4723 DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
4724 sc->tx_hi_watermark = sc->used_tx_bd);
4725
4726 DBRUNIF(1, sc->tx_mbuf_alloc++);
4727
4719 sc->tx_mbuf_map[map_arg.chain_prod];
4720 sc->tx_mbuf_map[map_arg.chain_prod] = map;
4721 sc->tx_mbuf_ptr[map_arg.chain_prod] = m_head;
4722 sc->used_tx_bd += map_arg.maxsegs;
4723
4724 DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
4725 sc->tx_hi_watermark = sc->used_tx_bd);
4726
4727 DBRUNIF(1, sc->tx_mbuf_alloc++);
4728
4728 DBRUN(BCE_VERBOSE_SEND, bce_dump_tx_mbuf_chain(sc, *chain_prod,
4729 DBRUN(BCE_VERBOSE_SEND, bce_dump_tx_mbuf_chain(sc, chain_prod,
4729 map_arg.maxsegs));
4730
4731 /* prod still points the last used tx_bd at this point. */
4732 *prod = map_arg.prod;
4730 map_arg.maxsegs));
4731
4732 /* prod still points the last used tx_bd at this point. */
4733 *prod = map_arg.prod;
4733 *chain_prod = map_arg.chain_prod;
4734 *prod_bseq = map_arg.prod_bseq;
4734 sc->tx_prod_bseq = map_arg.prod_bseq;
4735
4736bce_tx_encap_exit:
4737
4738 return(rc);
4739}
4740
4741
4742/****************************************************************************/

--- 4 unchanged lines hidden (view full) ---

4747/****************************************************************************/
4748static void
4749bce_start_locked(struct ifnet *ifp)
4750{
4751 struct bce_softc *sc = ifp->if_softc;
4752 struct mbuf *m_head = NULL;
4753 int count = 0;
4754 u16 tx_prod, tx_chain_prod;
4735
4736bce_tx_encap_exit:
4737
4738 return(rc);
4739}
4740
4741
4742/****************************************************************************/

--- 4 unchanged lines hidden (view full) ---

4747/****************************************************************************/
4748static void
4749bce_start_locked(struct ifnet *ifp)
4750{
4751 struct bce_softc *sc = ifp->if_softc;
4752 struct mbuf *m_head = NULL;
4753 int count = 0;
4754 u16 tx_prod, tx_chain_prod;
4755 u32 tx_prod_bseq;
4756
4757 /* If there's no link or the transmit queue is empty then just exit. */
4758 if (!sc->bce_link || IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
4759 DBPRINT(sc, BCE_INFO_SEND, "%s(): No link or transmit queue empty.\n",
4760 __FUNCTION__);
4761 goto bce_start_locked_exit;
4762 }
4763
4764 /* prod points to the next free tx_bd. */
4765 tx_prod = sc->tx_prod;
4766 tx_chain_prod = TX_CHAIN_IDX(tx_prod);
4755
4756 /* If there's no link or the transmit queue is empty then just exit. */
4757 if (!sc->bce_link || IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
4758 DBPRINT(sc, BCE_INFO_SEND, "%s(): No link or transmit queue empty.\n",
4759 __FUNCTION__);
4760 goto bce_start_locked_exit;
4761 }
4762
4763 /* prod points to the next free tx_bd. */
4764 tx_prod = sc->tx_prod;
4765 tx_chain_prod = TX_CHAIN_IDX(tx_prod);
4767 tx_prod_bseq = sc->tx_prod_bseq;
4768
4769 DBPRINT(sc, BCE_INFO_SEND,
4770 "%s(): Start: tx_prod = 0x%04X, tx_chain_prod = %04X, "
4771 "tx_prod_bseq = 0x%08X\n",
4766
4767 DBPRINT(sc, BCE_INFO_SEND,
4768 "%s(): Start: tx_prod = 0x%04X, tx_chain_prod = %04X, "
4769 "tx_prod_bseq = 0x%08X\n",
4772 __FUNCTION__, tx_prod, tx_chain_prod, tx_prod_bseq);
4770 __FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
4773
4774 /* Keep adding entries while there is space in the ring. */
4775 while(sc->tx_mbuf_ptr[tx_chain_prod] == NULL) {
4776
4777 /* Check for any frames to send. */
4778 IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
4779 if (m_head == NULL)
4780 break;
4781
4782 /*
4783 * Pack the data into the transmit ring. If we
4784 * don't have room, place the mbuf back at the
4785 * head of the queue and set the OACTIVE flag
4786 * to wait for the NIC to drain the chain.
4787 */
4771
4772 /* Keep adding entries while there is space in the ring. */
4773 while(sc->tx_mbuf_ptr[tx_chain_prod] == NULL) {
4774
4775 /* Check for any frames to send. */
4776 IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
4777 if (m_head == NULL)
4778 break;
4779
4780 /*
4781 * Pack the data into the transmit ring. If we
4782 * don't have room, place the mbuf back at the
4783 * head of the queue and set the OACTIVE flag
4784 * to wait for the NIC to drain the chain.
4785 */
4788 if (bce_tx_encap(sc, m_head, &tx_prod, &tx_chain_prod, &tx_prod_bseq)) {
4786 if (bce_tx_encap(sc, m_head, &tx_prod)) {
4789 IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
4790 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
4791 DBPRINT(sc, BCE_INFO_SEND,
4792 "TX chain is closed for business! Total tx_bd used = %d\n",
4793 sc->used_tx_bd);
4794 break;
4795 }
4796
4797 count++;
4798
4799 /* Send a copy of the frame to any BPF listeners. */
4800 BPF_MTAP(ifp, m_head);
4801
4802 tx_prod = NEXT_TX_BD(tx_prod);
4787 IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
4788 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
4789 DBPRINT(sc, BCE_INFO_SEND,
4790 "TX chain is closed for business! Total tx_bd used = %d\n",
4791 sc->used_tx_bd);
4792 break;
4793 }
4794
4795 count++;
4796
4797 /* Send a copy of the frame to any BPF listeners. */
4798 BPF_MTAP(ifp, m_head);
4799
4800 tx_prod = NEXT_TX_BD(tx_prod);
4803 tx_chain_prod = TX_CHAIN_IDX(tx_prod);
4804 }
4805
4806 if (count == 0) {
4807 /* no packets were dequeued */
4808 DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were dequeued\n",
4809 __FUNCTION__);
4810 goto bce_start_locked_exit;
4811 }
4812
4813 /* Update the driver's counters. */
4814 sc->tx_prod = tx_prod;
4801 }
4802
4803 if (count == 0) {
4804 /* no packets were dequeued */
4805 DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were dequeued\n",
4806 __FUNCTION__);
4807 goto bce_start_locked_exit;
4808 }
4809
4810 /* Update the driver's counters. */
4811 sc->tx_prod = tx_prod;
4815 sc->tx_prod_bseq = tx_prod_bseq;
4812 tx_chain_prod = TX_CHAIN_IDX(tx_prod);
4816
4817 DBPRINT(sc, BCE_INFO_SEND,
4818 "%s(): End: tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
4819 "tx_prod_bseq = 0x%08X\n",
4813
4814 DBPRINT(sc, BCE_INFO_SEND,
4815 "%s(): End: tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
4816 "tx_prod_bseq = 0x%08X\n",
4820 __FUNCTION__, tx_prod, tx_chain_prod, tx_prod_bseq);
4817 __FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
4821
4822 /* Start the transmit. */
4823 REG_WR16(sc, MB_TX_CID_ADDR + BCE_L2CTX_TX_HOST_BIDX, sc->tx_prod);
4824 REG_WR(sc, MB_TX_CID_ADDR + BCE_L2CTX_TX_HOST_BSEQ, sc->tx_prod_bseq);
4825
4826 /* Set the tx timeout. */
4827 ifp->if_timer = BCE_TX_TIMEOUT;
4828

--- 2035 unchanged lines hidden ---
4818
4819 /* Start the transmit. */
4820 REG_WR16(sc, MB_TX_CID_ADDR + BCE_L2CTX_TX_HOST_BIDX, sc->tx_prod);
4821 REG_WR(sc, MB_TX_CID_ADDR + BCE_L2CTX_TX_HOST_BSEQ, sc->tx_prod_bseq);
4822
4823 /* Set the tx timeout. */
4824 ifp->if_timer = BCE_TX_TIMEOUT;
4825

--- 2035 unchanged lines hidden ---