bgmac.c (f004eaf4d17d205842424a7e95dcff9a46fe3c5f) bgmac.c (49a467b4f607245d44d21627999ab75abe2c7f8b)
1/*
2 * Driver for (BCM4706)? GBit MAC core on BCMA bus.
3 *
4 * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com>
5 *
6 * Licensed under the GNU/GPL. See COPYING for details.
7 */
8

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

144
145 dma_desc = ring->cpu_base;
146 dma_desc += ring->end;
147 dma_desc->addr_low = cpu_to_le32(lower_32_bits(slot->dma_addr));
148 dma_desc->addr_high = cpu_to_le32(upper_32_bits(slot->dma_addr));
149 dma_desc->ctl0 = cpu_to_le32(ctl0);
150 dma_desc->ctl1 = cpu_to_le32(ctl1);
151
1/*
2 * Driver for (BCM4706)? GBit MAC core on BCMA bus.
3 *
4 * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com>
5 *
6 * Licensed under the GNU/GPL. See COPYING for details.
7 */
8

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

144
145 dma_desc = ring->cpu_base;
146 dma_desc += ring->end;
147 dma_desc->addr_low = cpu_to_le32(lower_32_bits(slot->dma_addr));
148 dma_desc->addr_high = cpu_to_le32(upper_32_bits(slot->dma_addr));
149 dma_desc->ctl0 = cpu_to_le32(ctl0);
150 dma_desc->ctl1 = cpu_to_le32(ctl1);
151
152 netdev_sent_queue(net_dev, skb->len);
153
152 wmb();
153
154 /* Increase ring->end to point empty slot. We tell hardware the first
155 * slot it should *not* read.
156 */
157 if (++ring->end >= BGMAC_TX_RING_SLOTS)
158 ring->end = 0;
159 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX,

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

173}
174
175/* Free transmitted packets */
176static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
177{
178 struct device *dma_dev = bgmac->core->dma_dev;
179 int empty_slot;
180 bool freed = false;
154 wmb();
155
156 /* Increase ring->end to point empty slot. We tell hardware the first
157 * slot it should *not* read.
158 */
159 if (++ring->end >= BGMAC_TX_RING_SLOTS)
160 ring->end = 0;
161 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX,

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

175}
176
177/* Free transmitted packets */
178static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
179{
180 struct device *dma_dev = bgmac->core->dma_dev;
181 int empty_slot;
182 bool freed = false;
183 unsigned bytes_compl = 0, pkts_compl = 0;
181
182 /* The last slot that hardware didn't consume yet */
183 empty_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
184 empty_slot &= BGMAC_DMA_TX_STATDPTR;
185 empty_slot -= ring->index_base;
186 empty_slot &= BGMAC_DMA_TX_STATDPTR;
187 empty_slot /= sizeof(struct bgmac_dma_desc);
188
189 while (ring->start != empty_slot) {
190 struct bgmac_slot_info *slot = &ring->slots[ring->start];
191
192 if (slot->skb) {
193 /* Unmap no longer used buffer */
194 dma_unmap_single(dma_dev, slot->dma_addr,
195 slot->skb->len, DMA_TO_DEVICE);
196 slot->dma_addr = 0;
197
184
185 /* The last slot that hardware didn't consume yet */
186 empty_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
187 empty_slot &= BGMAC_DMA_TX_STATDPTR;
188 empty_slot -= ring->index_base;
189 empty_slot &= BGMAC_DMA_TX_STATDPTR;
190 empty_slot /= sizeof(struct bgmac_dma_desc);
191
192 while (ring->start != empty_slot) {
193 struct bgmac_slot_info *slot = &ring->slots[ring->start];
194
195 if (slot->skb) {
196 /* Unmap no longer used buffer */
197 dma_unmap_single(dma_dev, slot->dma_addr,
198 slot->skb->len, DMA_TO_DEVICE);
199 slot->dma_addr = 0;
200
201 bytes_compl += slot->skb->len;
202 pkts_compl++;
203
198 /* Free memory! :) */
199 dev_kfree_skb(slot->skb);
200 slot->skb = NULL;
201 } else {
202 bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n",
203 ring->start, ring->end);
204 }
205
206 if (++ring->start >= BGMAC_TX_RING_SLOTS)
207 ring->start = 0;
208 freed = true;
209 }
210
204 /* Free memory! :) */
205 dev_kfree_skb(slot->skb);
206 slot->skb = NULL;
207 } else {
208 bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n",
209 ring->start, ring->end);
210 }
211
212 if (++ring->start >= BGMAC_TX_RING_SLOTS)
213 ring->start = 0;
214 freed = true;
215 }
216
217 netdev_completed_queue(bgmac->net_dev, pkts_compl, bytes_compl);
218
211 if (freed && netif_queue_stopped(bgmac->net_dev))
212 netif_wake_queue(bgmac->net_dev);
213}
214
215static void bgmac_dma_rx_reset(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
216{
217 if (!ring->mmio_base)
218 return;

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

983 if (core->id.id == BCMA_CORE_4706_MAC_GBIT)
984 bcma_maskset32(bgmac->cmn, BCMA_GMAC_CMN_PHY_CTL, ~0,
985 BCMA_GMAC_CMN_PC_MTE);
986 else
987 bgmac_set(bgmac, BGMAC_PHY_CNTL, BGMAC_PC_MTE);
988 bgmac_miiconfig(bgmac);
989 bgmac_phy_init(bgmac);
990
219 if (freed && netif_queue_stopped(bgmac->net_dev))
220 netif_wake_queue(bgmac->net_dev);
221}
222
223static void bgmac_dma_rx_reset(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
224{
225 if (!ring->mmio_base)
226 return;

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

991 if (core->id.id == BCMA_CORE_4706_MAC_GBIT)
992 bcma_maskset32(bgmac->cmn, BCMA_GMAC_CMN_PHY_CTL, ~0,
993 BCMA_GMAC_CMN_PC_MTE);
994 else
995 bgmac_set(bgmac, BGMAC_PHY_CNTL, BGMAC_PC_MTE);
996 bgmac_miiconfig(bgmac);
997 bgmac_phy_init(bgmac);
998
999 netdev_reset_queue(bgmac->net_dev);
1000
991 bgmac->int_status = 0;
992}
993
994static void bgmac_chip_intrs_on(struct bgmac *bgmac)
995{
996 bgmac_write(bgmac, BGMAC_INT_MASK, bgmac->int_mask);
997}
998

--- 565 unchanged lines hidden ---
1001 bgmac->int_status = 0;
1002}
1003
1004static void bgmac_chip_intrs_on(struct bgmac *bgmac)
1005{
1006 bgmac_write(bgmac, BGMAC_INT_MASK, bgmac->int_mask);
1007}
1008

--- 565 unchanged lines hidden ---