linux/drivers/net/ethernet/synopsys/dwc-xlgmac-desc.c
<<
>>
Prefs
   1/* Synopsys DesignWare Core Enterprise Ethernet (XLGMAC) Driver
   2 *
   3 * Copyright (c) 2017 Synopsys, Inc. (www.synopsys.com)
   4 *
   5 * This program is dual-licensed; you may select either version 2 of
   6 * the GNU General Public License ("GPL") or BSD license ("BSD").
   7 *
   8 * This Synopsys DWC XLGMAC software driver and associated documentation
   9 * (hereinafter the "Software") is an unsupported proprietary work of
  10 * Synopsys, Inc. unless otherwise expressly agreed to in writing between
  11 * Synopsys and you. The Software IS NOT an item of Licensed Software or a
  12 * Licensed Product under any End User Software License Agreement or
  13 * Agreement for Licensed Products with Synopsys or any supplement thereto.
  14 * Synopsys is a registered trademark of Synopsys, Inc. Other names included
  15 * in the SOFTWARE may be the trademarks of their respective owners.
  16 */
  17
  18#include "dwc-xlgmac.h"
  19#include "dwc-xlgmac-reg.h"
  20
  21static void xlgmac_unmap_desc_data(struct xlgmac_pdata *pdata,
  22                                   struct xlgmac_desc_data *desc_data)
  23{
  24        if (desc_data->skb_dma) {
  25                if (desc_data->mapped_as_page) {
  26                        dma_unmap_page(pdata->dev, desc_data->skb_dma,
  27                                       desc_data->skb_dma_len, DMA_TO_DEVICE);
  28                } else {
  29                        dma_unmap_single(pdata->dev, desc_data->skb_dma,
  30                                         desc_data->skb_dma_len, DMA_TO_DEVICE);
  31                }
  32                desc_data->skb_dma = 0;
  33                desc_data->skb_dma_len = 0;
  34        }
  35
  36        if (desc_data->skb) {
  37                dev_kfree_skb_any(desc_data->skb);
  38                desc_data->skb = NULL;
  39        }
  40
  41        if (desc_data->rx.hdr.pa.pages)
  42                put_page(desc_data->rx.hdr.pa.pages);
  43
  44        if (desc_data->rx.hdr.pa_unmap.pages) {
  45                dma_unmap_page(pdata->dev, desc_data->rx.hdr.pa_unmap.pages_dma,
  46                               desc_data->rx.hdr.pa_unmap.pages_len,
  47                               DMA_FROM_DEVICE);
  48                put_page(desc_data->rx.hdr.pa_unmap.pages);
  49        }
  50
  51        if (desc_data->rx.buf.pa.pages)
  52                put_page(desc_data->rx.buf.pa.pages);
  53
  54        if (desc_data->rx.buf.pa_unmap.pages) {
  55                dma_unmap_page(pdata->dev, desc_data->rx.buf.pa_unmap.pages_dma,
  56                               desc_data->rx.buf.pa_unmap.pages_len,
  57                               DMA_FROM_DEVICE);
  58                put_page(desc_data->rx.buf.pa_unmap.pages);
  59        }
  60
  61        memset(&desc_data->tx, 0, sizeof(desc_data->tx));
  62        memset(&desc_data->rx, 0, sizeof(desc_data->rx));
  63
  64        desc_data->mapped_as_page = 0;
  65
  66        if (desc_data->state_saved) {
  67                desc_data->state_saved = 0;
  68                desc_data->state.skb = NULL;
  69                desc_data->state.len = 0;
  70                desc_data->state.error = 0;
  71        }
  72}
  73
  74static void xlgmac_free_ring(struct xlgmac_pdata *pdata,
  75                             struct xlgmac_ring *ring)
  76{
  77        struct xlgmac_desc_data *desc_data;
  78        unsigned int i;
  79
  80        if (!ring)
  81                return;
  82
  83        if (ring->desc_data_head) {
  84                for (i = 0; i < ring->dma_desc_count; i++) {
  85                        desc_data = XLGMAC_GET_DESC_DATA(ring, i);
  86                        xlgmac_unmap_desc_data(pdata, desc_data);
  87                }
  88
  89                kfree(ring->desc_data_head);
  90                ring->desc_data_head = NULL;
  91        }
  92
  93        if (ring->rx_hdr_pa.pages) {
  94                dma_unmap_page(pdata->dev, ring->rx_hdr_pa.pages_dma,
  95                               ring->rx_hdr_pa.pages_len, DMA_FROM_DEVICE);
  96                put_page(ring->rx_hdr_pa.pages);
  97
  98                ring->rx_hdr_pa.pages = NULL;
  99                ring->rx_hdr_pa.pages_len = 0;
 100                ring->rx_hdr_pa.pages_offset = 0;
 101                ring->rx_hdr_pa.pages_dma = 0;
 102        }
 103
 104        if (ring->rx_buf_pa.pages) {
 105                dma_unmap_page(pdata->dev, ring->rx_buf_pa.pages_dma,
 106                               ring->rx_buf_pa.pages_len, DMA_FROM_DEVICE);
 107                put_page(ring->rx_buf_pa.pages);
 108
 109                ring->rx_buf_pa.pages = NULL;
 110                ring->rx_buf_pa.pages_len = 0;
 111                ring->rx_buf_pa.pages_offset = 0;
 112                ring->rx_buf_pa.pages_dma = 0;
 113        }
 114
 115        if (ring->dma_desc_head) {
 116                dma_free_coherent(pdata->dev,
 117                                  (sizeof(struct xlgmac_dma_desc) *
 118                                  ring->dma_desc_count),
 119                                  ring->dma_desc_head,
 120                                  ring->dma_desc_head_addr);
 121                ring->dma_desc_head = NULL;
 122        }
 123}
 124
 125static int xlgmac_init_ring(struct xlgmac_pdata *pdata,
 126                            struct xlgmac_ring *ring,
 127                            unsigned int dma_desc_count)
 128{
 129        if (!ring)
 130                return 0;
 131
 132        /* Descriptors */
 133        ring->dma_desc_count = dma_desc_count;
 134        ring->dma_desc_head = dma_alloc_coherent(pdata->dev,
 135                                        (sizeof(struct xlgmac_dma_desc) *
 136                                         dma_desc_count),
 137                                        &ring->dma_desc_head_addr,
 138                                        GFP_KERNEL);
 139        if (!ring->dma_desc_head)
 140                return -ENOMEM;
 141
 142        /* Array of descriptor data */
 143        ring->desc_data_head = kcalloc(dma_desc_count,
 144                                        sizeof(struct xlgmac_desc_data),
 145                                        GFP_KERNEL);
 146        if (!ring->desc_data_head)
 147                return -ENOMEM;
 148
 149        netif_dbg(pdata, drv, pdata->netdev,
 150                  "dma_desc_head=%p, dma_desc_head_addr=%pad, desc_data_head=%p\n",
 151                ring->dma_desc_head,
 152                &ring->dma_desc_head_addr,
 153                ring->desc_data_head);
 154
 155        return 0;
 156}
 157
 158static void xlgmac_free_rings(struct xlgmac_pdata *pdata)
 159{
 160        struct xlgmac_channel *channel;
 161        unsigned int i;
 162
 163        if (!pdata->channel_head)
 164                return;
 165
 166        channel = pdata->channel_head;
 167        for (i = 0; i < pdata->channel_count; i++, channel++) {
 168                xlgmac_free_ring(pdata, channel->tx_ring);
 169                xlgmac_free_ring(pdata, channel->rx_ring);
 170        }
 171}
 172
 173static int xlgmac_alloc_rings(struct xlgmac_pdata *pdata)
 174{
 175        struct xlgmac_channel *channel;
 176        unsigned int i;
 177        int ret;
 178
 179        channel = pdata->channel_head;
 180        for (i = 0; i < pdata->channel_count; i++, channel++) {
 181                netif_dbg(pdata, drv, pdata->netdev, "%s - Tx ring:\n",
 182                          channel->name);
 183
 184                ret = xlgmac_init_ring(pdata, channel->tx_ring,
 185                                       pdata->tx_desc_count);
 186
 187                if (ret) {
 188                        netdev_alert(pdata->netdev,
 189                                     "error initializing Tx ring");
 190                        goto err_init_ring;
 191                }
 192
 193                netif_dbg(pdata, drv, pdata->netdev, "%s - Rx ring:\n",
 194                          channel->name);
 195
 196                ret = xlgmac_init_ring(pdata, channel->rx_ring,
 197                                       pdata->rx_desc_count);
 198                if (ret) {
 199                        netdev_alert(pdata->netdev,
 200                                     "error initializing Rx ring\n");
 201                        goto err_init_ring;
 202                }
 203        }
 204
 205        return 0;
 206
 207err_init_ring:
 208        xlgmac_free_rings(pdata);
 209
 210        return ret;
 211}
 212
 213static void xlgmac_free_channels(struct xlgmac_pdata *pdata)
 214{
 215        if (!pdata->channel_head)
 216                return;
 217
 218        kfree(pdata->channel_head->tx_ring);
 219        pdata->channel_head->tx_ring = NULL;
 220
 221        kfree(pdata->channel_head->rx_ring);
 222        pdata->channel_head->rx_ring = NULL;
 223
 224        kfree(pdata->channel_head);
 225
 226        pdata->channel_head = NULL;
 227        pdata->channel_count = 0;
 228}
 229
 230static int xlgmac_alloc_channels(struct xlgmac_pdata *pdata)
 231{
 232        struct xlgmac_channel *channel_head, *channel;
 233        struct xlgmac_ring *tx_ring, *rx_ring;
 234        int ret = -ENOMEM;
 235        unsigned int i;
 236
 237        channel_head = kcalloc(pdata->channel_count,
 238                               sizeof(struct xlgmac_channel), GFP_KERNEL);
 239        if (!channel_head)
 240                return ret;
 241
 242        netif_dbg(pdata, drv, pdata->netdev,
 243                  "channel_head=%p\n", channel_head);
 244
 245        tx_ring = kcalloc(pdata->tx_ring_count, sizeof(struct xlgmac_ring),
 246                          GFP_KERNEL);
 247        if (!tx_ring)
 248                goto err_tx_ring;
 249
 250        rx_ring = kcalloc(pdata->rx_ring_count, sizeof(struct xlgmac_ring),
 251                          GFP_KERNEL);
 252        if (!rx_ring)
 253                goto err_rx_ring;
 254
 255        for (i = 0, channel = channel_head; i < pdata->channel_count;
 256                i++, channel++) {
 257                snprintf(channel->name, sizeof(channel->name), "channel-%u", i);
 258                channel->pdata = pdata;
 259                channel->queue_index = i;
 260                channel->dma_regs = pdata->mac_regs + DMA_CH_BASE +
 261                                    (DMA_CH_INC * i);
 262
 263                if (pdata->per_channel_irq) {
 264                        /* Get the per DMA interrupt */
 265                        ret = pdata->channel_irq[i];
 266                        if (ret < 0) {
 267                                netdev_err(pdata->netdev,
 268                                           "get_irq %u failed\n",
 269                                           i + 1);
 270                                goto err_irq;
 271                        }
 272                        channel->dma_irq = ret;
 273                }
 274
 275                if (i < pdata->tx_ring_count)
 276                        channel->tx_ring = tx_ring++;
 277
 278                if (i < pdata->rx_ring_count)
 279                        channel->rx_ring = rx_ring++;
 280
 281                netif_dbg(pdata, drv, pdata->netdev,
 282                          "%s: dma_regs=%p, tx_ring=%p, rx_ring=%p\n",
 283                          channel->name, channel->dma_regs,
 284                          channel->tx_ring, channel->rx_ring);
 285        }
 286
 287        pdata->channel_head = channel_head;
 288
 289        return 0;
 290
 291err_irq:
 292        kfree(rx_ring);
 293
 294err_rx_ring:
 295        kfree(tx_ring);
 296
 297err_tx_ring:
 298        kfree(channel_head);
 299
 300        return ret;
 301}
 302
 303static void xlgmac_free_channels_and_rings(struct xlgmac_pdata *pdata)
 304{
 305        xlgmac_free_rings(pdata);
 306
 307        xlgmac_free_channels(pdata);
 308}
 309
 310static int xlgmac_alloc_channels_and_rings(struct xlgmac_pdata *pdata)
 311{
 312        int ret;
 313
 314        ret = xlgmac_alloc_channels(pdata);
 315        if (ret)
 316                goto err_alloc;
 317
 318        ret = xlgmac_alloc_rings(pdata);
 319        if (ret)
 320                goto err_alloc;
 321
 322        return 0;
 323
 324err_alloc:
 325        xlgmac_free_channels_and_rings(pdata);
 326
 327        return ret;
 328}
 329
 330static int xlgmac_alloc_pages(struct xlgmac_pdata *pdata,
 331                              struct xlgmac_page_alloc *pa,
 332                              gfp_t gfp, int order)
 333{
 334        struct page *pages = NULL;
 335        dma_addr_t pages_dma;
 336
 337        /* Try to obtain pages, decreasing order if necessary */
 338        gfp |= __GFP_COMP | __GFP_NOWARN;
 339        while (order >= 0) {
 340                pages = alloc_pages(gfp, order);
 341                if (pages)
 342                        break;
 343
 344                order--;
 345        }
 346        if (!pages)
 347                return -ENOMEM;
 348
 349        /* Map the pages */
 350        pages_dma = dma_map_page(pdata->dev, pages, 0,
 351                                 PAGE_SIZE << order, DMA_FROM_DEVICE);
 352        if (dma_mapping_error(pdata->dev, pages_dma)) {
 353                put_page(pages);
 354                return -ENOMEM;
 355        }
 356
 357        pa->pages = pages;
 358        pa->pages_len = PAGE_SIZE << order;
 359        pa->pages_offset = 0;
 360        pa->pages_dma = pages_dma;
 361
 362        return 0;
 363}
 364
 365static void xlgmac_set_buffer_data(struct xlgmac_buffer_data *bd,
 366                                   struct xlgmac_page_alloc *pa,
 367                                   unsigned int len)
 368{
 369        get_page(pa->pages);
 370        bd->pa = *pa;
 371
 372        bd->dma_base = pa->pages_dma;
 373        bd->dma_off = pa->pages_offset;
 374        bd->dma_len = len;
 375
 376        pa->pages_offset += len;
 377        if ((pa->pages_offset + len) > pa->pages_len) {
 378                /* This data descriptor is responsible for unmapping page(s) */
 379                bd->pa_unmap = *pa;
 380
 381                /* Get a new allocation next time */
 382                pa->pages = NULL;
 383                pa->pages_len = 0;
 384                pa->pages_offset = 0;
 385                pa->pages_dma = 0;
 386        }
 387}
 388
 389static int xlgmac_map_rx_buffer(struct xlgmac_pdata *pdata,
 390                                struct xlgmac_ring *ring,
 391                                struct xlgmac_desc_data *desc_data)
 392{
 393        int order, ret;
 394
 395        if (!ring->rx_hdr_pa.pages) {
 396                ret = xlgmac_alloc_pages(pdata, &ring->rx_hdr_pa,
 397                                         GFP_ATOMIC, 0);
 398                if (ret)
 399                        return ret;
 400        }
 401
 402        if (!ring->rx_buf_pa.pages) {
 403                order = max_t(int, PAGE_ALLOC_COSTLY_ORDER - 1, 0);
 404                ret = xlgmac_alloc_pages(pdata, &ring->rx_buf_pa,
 405                                         GFP_ATOMIC, order);
 406                if (ret)
 407                        return ret;
 408        }
 409
 410        /* Set up the header page info */
 411        xlgmac_set_buffer_data(&desc_data->rx.hdr, &ring->rx_hdr_pa,
 412                               XLGMAC_SKB_ALLOC_SIZE);
 413
 414        /* Set up the buffer page info */
 415        xlgmac_set_buffer_data(&desc_data->rx.buf, &ring->rx_buf_pa,
 416                               pdata->rx_buf_size);
 417
 418        return 0;
 419}
 420
 421static void xlgmac_tx_desc_init(struct xlgmac_pdata *pdata)
 422{
 423        struct xlgmac_hw_ops *hw_ops = &pdata->hw_ops;
 424        struct xlgmac_desc_data *desc_data;
 425        struct xlgmac_dma_desc *dma_desc;
 426        struct xlgmac_channel *channel;
 427        struct xlgmac_ring *ring;
 428        dma_addr_t dma_desc_addr;
 429        unsigned int i, j;
 430
 431        channel = pdata->channel_head;
 432        for (i = 0; i < pdata->channel_count; i++, channel++) {
 433                ring = channel->tx_ring;
 434                if (!ring)
 435                        break;
 436
 437                dma_desc = ring->dma_desc_head;
 438                dma_desc_addr = ring->dma_desc_head_addr;
 439
 440                for (j = 0; j < ring->dma_desc_count; j++) {
 441                        desc_data = XLGMAC_GET_DESC_DATA(ring, j);
 442
 443                        desc_data->dma_desc = dma_desc;
 444                        desc_data->dma_desc_addr = dma_desc_addr;
 445
 446                        dma_desc++;
 447                        dma_desc_addr += sizeof(struct xlgmac_dma_desc);
 448                }
 449
 450                ring->cur = 0;
 451                ring->dirty = 0;
 452                memset(&ring->tx, 0, sizeof(ring->tx));
 453
 454                hw_ops->tx_desc_init(channel);
 455        }
 456}
 457
 458static void xlgmac_rx_desc_init(struct xlgmac_pdata *pdata)
 459{
 460        struct xlgmac_hw_ops *hw_ops = &pdata->hw_ops;
 461        struct xlgmac_desc_data *desc_data;
 462        struct xlgmac_dma_desc *dma_desc;
 463        struct xlgmac_channel *channel;
 464        struct xlgmac_ring *ring;
 465        dma_addr_t dma_desc_addr;
 466        unsigned int i, j;
 467
 468        channel = pdata->channel_head;
 469        for (i = 0; i < pdata->channel_count; i++, channel++) {
 470                ring = channel->rx_ring;
 471                if (!ring)
 472                        break;
 473
 474                dma_desc = ring->dma_desc_head;
 475                dma_desc_addr = ring->dma_desc_head_addr;
 476
 477                for (j = 0; j < ring->dma_desc_count; j++) {
 478                        desc_data = XLGMAC_GET_DESC_DATA(ring, j);
 479
 480                        desc_data->dma_desc = dma_desc;
 481                        desc_data->dma_desc_addr = dma_desc_addr;
 482
 483                        if (xlgmac_map_rx_buffer(pdata, ring, desc_data))
 484                                break;
 485
 486                        dma_desc++;
 487                        dma_desc_addr += sizeof(struct xlgmac_dma_desc);
 488                }
 489
 490                ring->cur = 0;
 491                ring->dirty = 0;
 492
 493                hw_ops->rx_desc_init(channel);
 494        }
 495}
 496
 497static int xlgmac_map_tx_skb(struct xlgmac_channel *channel,
 498                             struct sk_buff *skb)
 499{
 500        struct xlgmac_pdata *pdata = channel->pdata;
 501        struct xlgmac_ring *ring = channel->tx_ring;
 502        unsigned int start_index, cur_index;
 503        struct xlgmac_desc_data *desc_data;
 504        unsigned int offset, datalen, len;
 505        struct xlgmac_pkt_info *pkt_info;
 506        struct skb_frag_struct *frag;
 507        unsigned int tso, vlan;
 508        dma_addr_t skb_dma;
 509        unsigned int i;
 510
 511        offset = 0;
 512        start_index = ring->cur;
 513        cur_index = ring->cur;
 514
 515        pkt_info = &ring->pkt_info;
 516        pkt_info->desc_count = 0;
 517        pkt_info->length = 0;
 518
 519        tso = XLGMAC_GET_REG_BITS(pkt_info->attributes,
 520                                  TX_PACKET_ATTRIBUTES_TSO_ENABLE_POS,
 521                                  TX_PACKET_ATTRIBUTES_TSO_ENABLE_LEN);
 522        vlan = XLGMAC_GET_REG_BITS(pkt_info->attributes,
 523                                   TX_PACKET_ATTRIBUTES_VLAN_CTAG_POS,
 524                                   TX_PACKET_ATTRIBUTES_VLAN_CTAG_LEN);
 525
 526        /* Save space for a context descriptor if needed */
 527        if ((tso && (pkt_info->mss != ring->tx.cur_mss)) ||
 528            (vlan && (pkt_info->vlan_ctag != ring->tx.cur_vlan_ctag)))
 529                cur_index++;
 530        desc_data = XLGMAC_GET_DESC_DATA(ring, cur_index);
 531
 532        if (tso) {
 533                /* Map the TSO header */
 534                skb_dma = dma_map_single(pdata->dev, skb->data,
 535                                         pkt_info->header_len, DMA_TO_DEVICE);
 536                if (dma_mapping_error(pdata->dev, skb_dma)) {
 537                        netdev_alert(pdata->netdev, "dma_map_single failed\n");
 538                        goto err_out;
 539                }
 540                desc_data->skb_dma = skb_dma;
 541                desc_data->skb_dma_len = pkt_info->header_len;
 542                netif_dbg(pdata, tx_queued, pdata->netdev,
 543                          "skb header: index=%u, dma=%pad, len=%u\n",
 544                          cur_index, &skb_dma, pkt_info->header_len);
 545
 546                offset = pkt_info->header_len;
 547
 548                pkt_info->length += pkt_info->header_len;
 549
 550                cur_index++;
 551                desc_data = XLGMAC_GET_DESC_DATA(ring, cur_index);
 552        }
 553
 554        /* Map the (remainder of the) packet */
 555        for (datalen = skb_headlen(skb) - offset; datalen; ) {
 556                len = min_t(unsigned int, datalen, XLGMAC_TX_MAX_BUF_SIZE);
 557
 558                skb_dma = dma_map_single(pdata->dev, skb->data + offset, len,
 559                                         DMA_TO_DEVICE);
 560                if (dma_mapping_error(pdata->dev, skb_dma)) {
 561                        netdev_alert(pdata->netdev, "dma_map_single failed\n");
 562                        goto err_out;
 563                }
 564                desc_data->skb_dma = skb_dma;
 565                desc_data->skb_dma_len = len;
 566                netif_dbg(pdata, tx_queued, pdata->netdev,
 567                          "skb data: index=%u, dma=%pad, len=%u\n",
 568                          cur_index, &skb_dma, len);
 569
 570                datalen -= len;
 571                offset += len;
 572
 573                pkt_info->length += len;
 574
 575                cur_index++;
 576                desc_data = XLGMAC_GET_DESC_DATA(ring, cur_index);
 577        }
 578
 579        for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 580                netif_dbg(pdata, tx_queued, pdata->netdev,
 581                          "mapping frag %u\n", i);
 582
 583                frag = &skb_shinfo(skb)->frags[i];
 584                offset = 0;
 585
 586                for (datalen = skb_frag_size(frag); datalen; ) {
 587                        len = min_t(unsigned int, datalen,
 588                                    XLGMAC_TX_MAX_BUF_SIZE);
 589
 590                        skb_dma = skb_frag_dma_map(pdata->dev, frag, offset,
 591                                                   len, DMA_TO_DEVICE);
 592                        if (dma_mapping_error(pdata->dev, skb_dma)) {
 593                                netdev_alert(pdata->netdev,
 594                                             "skb_frag_dma_map failed\n");
 595                                goto err_out;
 596                        }
 597                        desc_data->skb_dma = skb_dma;
 598                        desc_data->skb_dma_len = len;
 599                        desc_data->mapped_as_page = 1;
 600                        netif_dbg(pdata, tx_queued, pdata->netdev,
 601                                  "skb frag: index=%u, dma=%pad, len=%u\n",
 602                                  cur_index, &skb_dma, len);
 603
 604                        datalen -= len;
 605                        offset += len;
 606
 607                        pkt_info->length += len;
 608
 609                        cur_index++;
 610                        desc_data = XLGMAC_GET_DESC_DATA(ring, cur_index);
 611                }
 612        }
 613
 614        /* Save the skb address in the last entry. We always have some data
 615         * that has been mapped so desc_data is always advanced past the last
 616         * piece of mapped data - use the entry pointed to by cur_index - 1.
 617         */
 618        desc_data = XLGMAC_GET_DESC_DATA(ring, cur_index - 1);
 619        desc_data->skb = skb;
 620
 621        /* Save the number of descriptor entries used */
 622        pkt_info->desc_count = cur_index - start_index;
 623
 624        return pkt_info->desc_count;
 625
 626err_out:
 627        while (start_index < cur_index) {
 628                desc_data = XLGMAC_GET_DESC_DATA(ring, start_index++);
 629                xlgmac_unmap_desc_data(pdata, desc_data);
 630        }
 631
 632        return 0;
 633}
 634
 635void xlgmac_init_desc_ops(struct xlgmac_desc_ops *desc_ops)
 636{
 637        desc_ops->alloc_channles_and_rings = xlgmac_alloc_channels_and_rings;
 638        desc_ops->free_channels_and_rings = xlgmac_free_channels_and_rings;
 639        desc_ops->map_tx_skb = xlgmac_map_tx_skb;
 640        desc_ops->map_rx_buffer = xlgmac_map_rx_buffer;
 641        desc_ops->unmap_desc_data = xlgmac_unmap_desc_data;
 642        desc_ops->tx_desc_init = xlgmac_tx_desc_init;
 643        desc_ops->rx_desc_init = xlgmac_rx_desc_init;
 644}
 645