cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dwc-xlgmac-desc.c (16150B)


      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	skb_frag_t *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_channels_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}