source: rtems-libbsd/rtemsbsd/sys/powerpc/drivers/net/ethernet/freescale/sdk_dpaa/if_ml.c @ d62a3df

55-freebsd-126-freebsd-12
Last change on this file since d62a3df was d62a3df, checked in by Sebastian Huber <sebastian.huber@…>, on 01/17/18 at 12:28:45

sdk_dpaa: Port to RTEMS

Update #3277.

  • Property mode set to 100644
File size: 4.8 KB
Line 
1#include <machine/rtems-bsd-kernel-space.h>
2
3#include <rtems/bsd/local/opt_dpaa.h>
4
5/*
6 * Copyright (c) 2018 embedded brains GmbH
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <machine/rtems-bsd-kernel-space.h>
32
33#include <linux/kernel.h>
34
35#include "../../../../../../../../linux/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h"
36
37#include <soc/fsl/bman.h>
38
39#include <sys/bus.h>
40#include <sys/callout.h>
41#include <sys/kernel.h>
42#include <sys/malloc.h>
43#include <sys/mbuf.h>
44#include <sys/module.h>
45#include <sys/queue.h>
46#include <sys/socket.h>
47#include <sys/sockio.h>
48
49#include <net/if.h>
50#include <net/ethernet.h>
51#include <net/if_arp.h>
52#include <net/if_dl.h>
53#include <net/if_media.h>
54#include <net/if_types.h>
55#include <net/if_var.h>
56
57#define IF_ML_LOCK(sc) mtx_lock(&(sc)->mtx)
58#define IF_ML_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
59
60static void
61if_ml_start(struct ifnet *ifp)
62{
63        struct if_ml_softc *sc;
64        struct dpaa_priv *priv;
65        int queue;
66        struct dpaa_bp *bp;
67        struct qman_fq *egress_fq;
68
69        sc = ifp->if_softc;
70        priv = netdev_priv(&sc->net_dev);
71        queue = 0;
72        bp = priv->dpaa_bps[queue];
73        egress_fq = priv->egress_fqs[queue];
74
75        for (;;) {
76                struct mbuf *m;
77                struct bm_buffer bmb;
78                struct qm_fd fd;
79                uintptr_t buf_addr;
80                char *dst;
81                int len;
82                int err;
83                int i;
84
85                IF_DEQUEUE(&ifp->if_snd, m);
86                if (m == NULL)
87                        break;
88
89                err = bman_acquire(bp->pool, &bmb, 1);
90                if (unlikely(err <= 0)) {
91                        if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1);
92                        m_freem(m);
93                        continue;
94                }
95
96                qm_fd_clear_fd(&fd);
97                len = m->m_pkthdr.len;
98                qm_fd_set_contig(&fd, priv->tx_headroom, len);
99                fd.bpid = bp->bpid;
100                buf_addr = bm_buf_addr(&bmb);
101                qm_fd_addr_set64(&fd, buf_addr);
102                dst = (char *)(buf_addr + priv->tx_headroom);
103
104                do {
105                        len = m->m_len;
106                        dst = memcpy(dst, mtod(m, const void *), len);
107                        dst += len;
108                        m = m_free(m);
109                } while (m != NULL);
110
111                for (i = 0; i < DPAA_ENQUEUE_RETRIES; ++i) {
112                        err = qman_enqueue(egress_fq, &fd);
113                        if (err != -EBUSY) {
114                                break;
115                        }
116                }
117
118                if (unlikely(err < 0)) {
119                        if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1);
120                        continue;
121                }
122        }
123}
124
125static void
126if_ml_init_locked(struct if_ml_softc* sc_p)
127{
128        struct ifnet *ifp;
129
130        ifp = sc_p->ifp;
131        if (ifp->if_drv_flags & IFF_DRV_RUNNING)
132                return;
133
134        ifp->if_drv_flags |= IFF_DRV_RUNNING;
135}
136
137static void
138if_ml_stop_locked(struct if_ml_softc* sc_p)
139{
140}
141
142static int
143if_ml_ioctl(struct ifnet* ifp, ioctl_command_t cmd, caddr_t data)
144{
145        struct if_ml_softc *sc;
146        int error;
147
148        sc = ifp->if_softc;
149
150        switch (cmd) {
151        case SIOCSIFFLAGS:
152                IF_ML_LOCK(sc);
153                if (ifp->if_flags & IFF_UP) {
154                        if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
155                                if_ml_init_locked(sc);
156                } else {
157                        if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
158                                if_ml_stop_locked(sc);
159                }
160                IF_ML_UNLOCK(sc);
161                error = 0;
162                break;
163
164        default:
165                error = ether_ioctl(ifp, cmd, data);
166                break;
167        }
168
169        return error;
170}
171
172static void
173if_ml_init(void* arg)
174{
175        struct if_ml_softc *sc;
176
177        sc = arg;
178        IF_ML_LOCK(sc);
179        if_ml_init_locked(sc);
180        IF_ML_UNLOCK(sc);
181}
182
183void
184if_ml_attach(struct if_ml_softc *sc, int unit, const uint8_t *mac_address)
185{
186        struct ifnet *ifp;
187
188        BSD_ASSERT(mac_address != NULL);
189
190        sc->ifp = ifp = if_alloc(IFT_ETHER);
191        BSD_ASSERT(ifp != NULL);
192
193        sc->net_dev.ifp = ifp;
194
195        mtx_init(&sc->mtx, "if_ml", MTX_NETWORK_LOCK, MTX_DEF);
196
197        ifp->if_softc = sc;
198        if_initname(ifp, "ml", unit);
199        ifp->if_flags = IFF_SIMPLEX | IFF_MULTICAST | IFF_BROADCAST;
200        ifp->if_start = if_ml_start;
201        ifp->if_ioctl = if_ml_ioctl;
202        ifp->if_init = if_ml_init;
203        IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
204        ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
205        IFQ_SET_READY(&ifp->if_snd);
206
207        ether_ifattach(ifp, mac_address);
208}
Note: See TracBrowser for help on using the repository browser.