1*dd4544f0SRafał Miłecki /* 2*dd4544f0SRafał Miłecki * Driver for (BCM4706)? GBit MAC core on BCMA bus. 3*dd4544f0SRafał Miłecki * 4*dd4544f0SRafał Miłecki * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com> 5*dd4544f0SRafał Miłecki * 6*dd4544f0SRafał Miłecki * Licensed under the GNU/GPL. See COPYING for details. 7*dd4544f0SRafał Miłecki */ 8*dd4544f0SRafał Miłecki 9*dd4544f0SRafał Miłecki #include "bgmac.h" 10*dd4544f0SRafał Miłecki 11*dd4544f0SRafał Miłecki #include <linux/kernel.h> 12*dd4544f0SRafał Miłecki #include <linux/module.h> 13*dd4544f0SRafał Miłecki #include <linux/delay.h> 14*dd4544f0SRafał Miłecki #include <linux/etherdevice.h> 15*dd4544f0SRafał Miłecki #include <linux/mii.h> 16*dd4544f0SRafał Miłecki #include <linux/interrupt.h> 17*dd4544f0SRafał Miłecki #include <linux/dma-mapping.h> 18*dd4544f0SRafał Miłecki #include <asm/mach-bcm47xx/nvram.h> 19*dd4544f0SRafał Miłecki 20*dd4544f0SRafał Miłecki static const struct bcma_device_id bgmac_bcma_tbl[] = { 21*dd4544f0SRafał Miłecki BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS), 22*dd4544f0SRafał Miłecki BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS), 23*dd4544f0SRafał Miłecki BCMA_CORETABLE_END 24*dd4544f0SRafał Miłecki }; 25*dd4544f0SRafał Miłecki MODULE_DEVICE_TABLE(bcma, bgmac_bcma_tbl); 26*dd4544f0SRafał Miłecki 27*dd4544f0SRafał Miłecki static bool bgmac_wait_value(struct bcma_device *core, u16 reg, u32 mask, 28*dd4544f0SRafał Miłecki u32 value, int timeout) 29*dd4544f0SRafał Miłecki { 30*dd4544f0SRafał Miłecki u32 val; 31*dd4544f0SRafał Miłecki int i; 32*dd4544f0SRafał Miłecki 33*dd4544f0SRafał Miłecki for (i = 0; i < timeout / 10; i++) { 34*dd4544f0SRafał Miłecki val = bcma_read32(core, reg); 35*dd4544f0SRafał Miłecki if ((val & mask) == value) 36*dd4544f0SRafał Miłecki return true; 37*dd4544f0SRafał Miłecki udelay(10); 38*dd4544f0SRafał Miłecki } 39*dd4544f0SRafał Miłecki pr_err("Timeout waiting for reg 0x%X\n", reg); 40*dd4544f0SRafał Miłecki return false; 41*dd4544f0SRafał Miłecki } 42*dd4544f0SRafał Miłecki 43*dd4544f0SRafał Miłecki /************************************************** 44*dd4544f0SRafał Miłecki * DMA 45*dd4544f0SRafał Miłecki **************************************************/ 46*dd4544f0SRafał Miłecki 47*dd4544f0SRafał Miłecki static void bgmac_dma_tx_reset(struct bgmac *bgmac, struct bgmac_dma_ring *ring) 48*dd4544f0SRafał Miłecki { 49*dd4544f0SRafał Miłecki u32 val; 50*dd4544f0SRafał Miłecki int i; 51*dd4544f0SRafał Miłecki 52*dd4544f0SRafał Miłecki if (!ring->mmio_base) 53*dd4544f0SRafał Miłecki return; 54*dd4544f0SRafał Miłecki 55*dd4544f0SRafał Miłecki /* Suspend DMA TX ring first. 56*dd4544f0SRafał Miłecki * bgmac_wait_value doesn't support waiting for any of few values, so 57*dd4544f0SRafał Miłecki * implement whole loop here. 58*dd4544f0SRafał Miłecki */ 59*dd4544f0SRafał Miłecki bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, 60*dd4544f0SRafał Miłecki BGMAC_DMA_TX_SUSPEND); 61*dd4544f0SRafał Miłecki for (i = 0; i < 10000 / 10; i++) { 62*dd4544f0SRafał Miłecki val = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS); 63*dd4544f0SRafał Miłecki val &= BGMAC_DMA_TX_STAT; 64*dd4544f0SRafał Miłecki if (val == BGMAC_DMA_TX_STAT_DISABLED || 65*dd4544f0SRafał Miłecki val == BGMAC_DMA_TX_STAT_IDLEWAIT || 66*dd4544f0SRafał Miłecki val == BGMAC_DMA_TX_STAT_STOPPED) { 67*dd4544f0SRafał Miłecki i = 0; 68*dd4544f0SRafał Miłecki break; 69*dd4544f0SRafał Miłecki } 70*dd4544f0SRafał Miłecki udelay(10); 71*dd4544f0SRafał Miłecki } 72*dd4544f0SRafał Miłecki if (i) 73*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Timeout suspending DMA TX ring 0x%X (BGMAC_DMA_TX_STAT: 0x%08X)\n", 74*dd4544f0SRafał Miłecki ring->mmio_base, val); 75*dd4544f0SRafał Miłecki 76*dd4544f0SRafał Miłecki /* Remove SUSPEND bit */ 77*dd4544f0SRafał Miłecki bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, 0); 78*dd4544f0SRafał Miłecki if (!bgmac_wait_value(bgmac->core, 79*dd4544f0SRafał Miłecki ring->mmio_base + BGMAC_DMA_TX_STATUS, 80*dd4544f0SRafał Miłecki BGMAC_DMA_TX_STAT, BGMAC_DMA_TX_STAT_DISABLED, 81*dd4544f0SRafał Miłecki 10000)) { 82*dd4544f0SRafał Miłecki bgmac_warn(bgmac, "DMA TX ring 0x%X wasn't disabled on time, waiting additional 300us\n", 83*dd4544f0SRafał Miłecki ring->mmio_base); 84*dd4544f0SRafał Miłecki udelay(300); 85*dd4544f0SRafał Miłecki val = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS); 86*dd4544f0SRafał Miłecki if ((val & BGMAC_DMA_TX_STAT) != BGMAC_DMA_TX_STAT_DISABLED) 87*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Reset of DMA TX ring 0x%X failed\n", 88*dd4544f0SRafał Miłecki ring->mmio_base); 89*dd4544f0SRafał Miłecki } 90*dd4544f0SRafał Miłecki } 91*dd4544f0SRafał Miłecki 92*dd4544f0SRafał Miłecki static void bgmac_dma_tx_enable(struct bgmac *bgmac, 93*dd4544f0SRafał Miłecki struct bgmac_dma_ring *ring) 94*dd4544f0SRafał Miłecki { 95*dd4544f0SRafał Miłecki u32 ctl; 96*dd4544f0SRafał Miłecki 97*dd4544f0SRafał Miłecki ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL); 98*dd4544f0SRafał Miłecki ctl |= BGMAC_DMA_TX_ENABLE; 99*dd4544f0SRafał Miłecki ctl |= BGMAC_DMA_TX_PARITY_DISABLE; 100*dd4544f0SRafał Miłecki bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, ctl); 101*dd4544f0SRafał Miłecki } 102*dd4544f0SRafał Miłecki 103*dd4544f0SRafał Miłecki static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, 104*dd4544f0SRafał Miłecki struct bgmac_dma_ring *ring, 105*dd4544f0SRafał Miłecki struct sk_buff *skb) 106*dd4544f0SRafał Miłecki { 107*dd4544f0SRafał Miłecki struct device *dma_dev = bgmac->core->dma_dev; 108*dd4544f0SRafał Miłecki struct net_device *net_dev = bgmac->net_dev; 109*dd4544f0SRafał Miłecki struct bgmac_dma_desc *dma_desc; 110*dd4544f0SRafał Miłecki struct bgmac_slot_info *slot; 111*dd4544f0SRafał Miłecki u32 ctl0, ctl1; 112*dd4544f0SRafał Miłecki int free_slots; 113*dd4544f0SRafał Miłecki 114*dd4544f0SRafał Miłecki if (skb->len > BGMAC_DESC_CTL1_LEN) { 115*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Too long skb (%d)\n", skb->len); 116*dd4544f0SRafał Miłecki goto err_stop_drop; 117*dd4544f0SRafał Miłecki } 118*dd4544f0SRafał Miłecki 119*dd4544f0SRafał Miłecki if (ring->start <= ring->end) 120*dd4544f0SRafał Miłecki free_slots = ring->start - ring->end + BGMAC_TX_RING_SLOTS; 121*dd4544f0SRafał Miłecki else 122*dd4544f0SRafał Miłecki free_slots = ring->start - ring->end; 123*dd4544f0SRafał Miłecki if (free_slots == 1) { 124*dd4544f0SRafał Miłecki bgmac_err(bgmac, "TX ring is full, queue should be stopped!\n"); 125*dd4544f0SRafał Miłecki netif_stop_queue(net_dev); 126*dd4544f0SRafał Miłecki return NETDEV_TX_BUSY; 127*dd4544f0SRafał Miłecki } 128*dd4544f0SRafał Miłecki 129*dd4544f0SRafał Miłecki slot = &ring->slots[ring->end]; 130*dd4544f0SRafał Miłecki slot->skb = skb; 131*dd4544f0SRafał Miłecki slot->dma_addr = dma_map_single(dma_dev, skb->data, skb->len, 132*dd4544f0SRafał Miłecki DMA_TO_DEVICE); 133*dd4544f0SRafał Miłecki if (dma_mapping_error(dma_dev, slot->dma_addr)) { 134*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Mapping error of skb on ring 0x%X\n", 135*dd4544f0SRafał Miłecki ring->mmio_base); 136*dd4544f0SRafał Miłecki goto err_stop_drop; 137*dd4544f0SRafał Miłecki } 138*dd4544f0SRafał Miłecki 139*dd4544f0SRafał Miłecki ctl0 = BGMAC_DESC_CTL0_IOC | BGMAC_DESC_CTL0_SOF | BGMAC_DESC_CTL0_EOF; 140*dd4544f0SRafał Miłecki if (ring->end == ring->num_slots - 1) 141*dd4544f0SRafał Miłecki ctl0 |= BGMAC_DESC_CTL0_EOT; 142*dd4544f0SRafał Miłecki ctl1 = skb->len & BGMAC_DESC_CTL1_LEN; 143*dd4544f0SRafał Miłecki 144*dd4544f0SRafał Miłecki dma_desc = ring->cpu_base; 145*dd4544f0SRafał Miłecki dma_desc += ring->end; 146*dd4544f0SRafał Miłecki dma_desc->addr_low = cpu_to_le32(lower_32_bits(slot->dma_addr)); 147*dd4544f0SRafał Miłecki dma_desc->addr_high = cpu_to_le32(upper_32_bits(slot->dma_addr)); 148*dd4544f0SRafał Miłecki dma_desc->ctl0 = cpu_to_le32(ctl0); 149*dd4544f0SRafał Miłecki dma_desc->ctl1 = cpu_to_le32(ctl1); 150*dd4544f0SRafał Miłecki 151*dd4544f0SRafał Miłecki wmb(); 152*dd4544f0SRafał Miłecki 153*dd4544f0SRafał Miłecki /* Increase ring->end to point empty slot. We tell hardware the first 154*dd4544f0SRafał Miłecki * slot it should *not* read. 155*dd4544f0SRafał Miłecki */ 156*dd4544f0SRafał Miłecki if (++ring->end >= BGMAC_TX_RING_SLOTS) 157*dd4544f0SRafał Miłecki ring->end = 0; 158*dd4544f0SRafał Miłecki bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX, 159*dd4544f0SRafał Miłecki ring->end * sizeof(struct bgmac_dma_desc)); 160*dd4544f0SRafał Miłecki 161*dd4544f0SRafał Miłecki /* Always keep one slot free to allow detecting bugged calls. */ 162*dd4544f0SRafał Miłecki if (--free_slots == 1) 163*dd4544f0SRafał Miłecki netif_stop_queue(net_dev); 164*dd4544f0SRafał Miłecki 165*dd4544f0SRafał Miłecki return NETDEV_TX_OK; 166*dd4544f0SRafał Miłecki 167*dd4544f0SRafał Miłecki err_stop_drop: 168*dd4544f0SRafał Miłecki netif_stop_queue(net_dev); 169*dd4544f0SRafał Miłecki dev_kfree_skb(skb); 170*dd4544f0SRafał Miłecki return NETDEV_TX_OK; 171*dd4544f0SRafał Miłecki } 172*dd4544f0SRafał Miłecki 173*dd4544f0SRafał Miłecki /* Free transmitted packets */ 174*dd4544f0SRafał Miłecki static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring) 175*dd4544f0SRafał Miłecki { 176*dd4544f0SRafał Miłecki struct device *dma_dev = bgmac->core->dma_dev; 177*dd4544f0SRafał Miłecki int empty_slot; 178*dd4544f0SRafał Miłecki bool freed = false; 179*dd4544f0SRafał Miłecki 180*dd4544f0SRafał Miłecki /* The last slot that hardware didn't consume yet */ 181*dd4544f0SRafał Miłecki empty_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS); 182*dd4544f0SRafał Miłecki empty_slot &= BGMAC_DMA_TX_STATDPTR; 183*dd4544f0SRafał Miłecki empty_slot /= sizeof(struct bgmac_dma_desc); 184*dd4544f0SRafał Miłecki 185*dd4544f0SRafał Miłecki while (ring->start != empty_slot) { 186*dd4544f0SRafał Miłecki struct bgmac_slot_info *slot = &ring->slots[ring->start]; 187*dd4544f0SRafał Miłecki 188*dd4544f0SRafał Miłecki if (slot->skb) { 189*dd4544f0SRafał Miłecki /* Unmap no longer used buffer */ 190*dd4544f0SRafał Miłecki dma_unmap_single(dma_dev, slot->dma_addr, 191*dd4544f0SRafał Miłecki slot->skb->len, DMA_TO_DEVICE); 192*dd4544f0SRafał Miłecki slot->dma_addr = 0; 193*dd4544f0SRafał Miłecki 194*dd4544f0SRafał Miłecki /* Free memory! :) */ 195*dd4544f0SRafał Miłecki dev_kfree_skb(slot->skb); 196*dd4544f0SRafał Miłecki slot->skb = NULL; 197*dd4544f0SRafał Miłecki } else { 198*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n", 199*dd4544f0SRafał Miłecki ring->start, ring->end); 200*dd4544f0SRafał Miłecki } 201*dd4544f0SRafał Miłecki 202*dd4544f0SRafał Miłecki if (++ring->start >= BGMAC_TX_RING_SLOTS) 203*dd4544f0SRafał Miłecki ring->start = 0; 204*dd4544f0SRafał Miłecki freed = true; 205*dd4544f0SRafał Miłecki } 206*dd4544f0SRafał Miłecki 207*dd4544f0SRafał Miłecki if (freed && netif_queue_stopped(bgmac->net_dev)) 208*dd4544f0SRafał Miłecki netif_wake_queue(bgmac->net_dev); 209*dd4544f0SRafał Miłecki } 210*dd4544f0SRafał Miłecki 211*dd4544f0SRafał Miłecki static void bgmac_dma_rx_reset(struct bgmac *bgmac, struct bgmac_dma_ring *ring) 212*dd4544f0SRafał Miłecki { 213*dd4544f0SRafał Miłecki if (!ring->mmio_base) 214*dd4544f0SRafał Miłecki return; 215*dd4544f0SRafał Miłecki 216*dd4544f0SRafał Miłecki bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL, 0); 217*dd4544f0SRafał Miłecki if (!bgmac_wait_value(bgmac->core, 218*dd4544f0SRafał Miłecki ring->mmio_base + BGMAC_DMA_RX_STATUS, 219*dd4544f0SRafał Miłecki BGMAC_DMA_RX_STAT, BGMAC_DMA_RX_STAT_DISABLED, 220*dd4544f0SRafał Miłecki 10000)) 221*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Reset of ring 0x%X RX failed\n", 222*dd4544f0SRafał Miłecki ring->mmio_base); 223*dd4544f0SRafał Miłecki } 224*dd4544f0SRafał Miłecki 225*dd4544f0SRafał Miłecki static void bgmac_dma_rx_enable(struct bgmac *bgmac, 226*dd4544f0SRafał Miłecki struct bgmac_dma_ring *ring) 227*dd4544f0SRafał Miłecki { 228*dd4544f0SRafał Miłecki u32 ctl; 229*dd4544f0SRafał Miłecki 230*dd4544f0SRafał Miłecki ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL); 231*dd4544f0SRafał Miłecki ctl &= BGMAC_DMA_RX_ADDREXT_MASK; 232*dd4544f0SRafał Miłecki ctl |= BGMAC_DMA_RX_ENABLE; 233*dd4544f0SRafał Miłecki ctl |= BGMAC_DMA_RX_PARITY_DISABLE; 234*dd4544f0SRafał Miłecki ctl |= BGMAC_DMA_RX_OVERFLOW_CONT; 235*dd4544f0SRafał Miłecki ctl |= BGMAC_RX_FRAME_OFFSET << BGMAC_DMA_RX_FRAME_OFFSET_SHIFT; 236*dd4544f0SRafał Miłecki bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL, ctl); 237*dd4544f0SRafał Miłecki } 238*dd4544f0SRafał Miłecki 239*dd4544f0SRafał Miłecki static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac, 240*dd4544f0SRafał Miłecki struct bgmac_slot_info *slot) 241*dd4544f0SRafał Miłecki { 242*dd4544f0SRafał Miłecki struct device *dma_dev = bgmac->core->dma_dev; 243*dd4544f0SRafał Miłecki struct bgmac_rx_header *rx; 244*dd4544f0SRafał Miłecki 245*dd4544f0SRafał Miłecki /* Alloc skb */ 246*dd4544f0SRafał Miłecki slot->skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE); 247*dd4544f0SRafał Miłecki if (!slot->skb) { 248*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Allocation of skb failed!\n"); 249*dd4544f0SRafał Miłecki return -ENOMEM; 250*dd4544f0SRafał Miłecki } 251*dd4544f0SRafał Miłecki 252*dd4544f0SRafał Miłecki /* Poison - if everything goes fine, hardware will overwrite it */ 253*dd4544f0SRafał Miłecki rx = (struct bgmac_rx_header *)slot->skb->data; 254*dd4544f0SRafał Miłecki rx->len = cpu_to_le16(0xdead); 255*dd4544f0SRafał Miłecki rx->flags = cpu_to_le16(0xbeef); 256*dd4544f0SRafał Miłecki 257*dd4544f0SRafał Miłecki /* Map skb for the DMA */ 258*dd4544f0SRafał Miłecki slot->dma_addr = dma_map_single(dma_dev, slot->skb->data, 259*dd4544f0SRafał Miłecki BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); 260*dd4544f0SRafał Miłecki if (dma_mapping_error(dma_dev, slot->dma_addr)) { 261*dd4544f0SRafał Miłecki bgmac_err(bgmac, "DMA mapping error\n"); 262*dd4544f0SRafał Miłecki return -ENOMEM; 263*dd4544f0SRafał Miłecki } 264*dd4544f0SRafał Miłecki if (slot->dma_addr & 0xC0000000) 265*dd4544f0SRafał Miłecki bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); 266*dd4544f0SRafał Miłecki 267*dd4544f0SRafał Miłecki return 0; 268*dd4544f0SRafał Miłecki } 269*dd4544f0SRafał Miłecki 270*dd4544f0SRafał Miłecki static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, 271*dd4544f0SRafał Miłecki int weight) 272*dd4544f0SRafał Miłecki { 273*dd4544f0SRafał Miłecki u32 end_slot; 274*dd4544f0SRafał Miłecki int handled = 0; 275*dd4544f0SRafał Miłecki 276*dd4544f0SRafał Miłecki end_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_STATUS); 277*dd4544f0SRafał Miłecki end_slot &= BGMAC_DMA_RX_STATDPTR; 278*dd4544f0SRafał Miłecki end_slot /= sizeof(struct bgmac_dma_desc); 279*dd4544f0SRafał Miłecki 280*dd4544f0SRafał Miłecki ring->end = end_slot; 281*dd4544f0SRafał Miłecki 282*dd4544f0SRafał Miłecki while (ring->start != ring->end) { 283*dd4544f0SRafał Miłecki struct device *dma_dev = bgmac->core->dma_dev; 284*dd4544f0SRafał Miłecki struct bgmac_slot_info *slot = &ring->slots[ring->start]; 285*dd4544f0SRafał Miłecki struct sk_buff *skb = slot->skb; 286*dd4544f0SRafał Miłecki struct sk_buff *new_skb; 287*dd4544f0SRafał Miłecki struct bgmac_rx_header *rx; 288*dd4544f0SRafał Miłecki u16 len, flags; 289*dd4544f0SRafał Miłecki 290*dd4544f0SRafał Miłecki /* Unmap buffer to make it accessible to the CPU */ 291*dd4544f0SRafał Miłecki dma_sync_single_for_cpu(dma_dev, slot->dma_addr, 292*dd4544f0SRafał Miłecki BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); 293*dd4544f0SRafał Miłecki 294*dd4544f0SRafał Miłecki /* Get info from the header */ 295*dd4544f0SRafał Miłecki rx = (struct bgmac_rx_header *)skb->data; 296*dd4544f0SRafał Miłecki len = le16_to_cpu(rx->len); 297*dd4544f0SRafał Miłecki flags = le16_to_cpu(rx->flags); 298*dd4544f0SRafał Miłecki 299*dd4544f0SRafał Miłecki /* Check for poison and drop or pass the packet */ 300*dd4544f0SRafał Miłecki if (len == 0xdead && flags == 0xbeef) { 301*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n", 302*dd4544f0SRafał Miłecki ring->start); 303*dd4544f0SRafał Miłecki } else { 304*dd4544f0SRafał Miłecki new_skb = netdev_alloc_skb(bgmac->net_dev, len); 305*dd4544f0SRafał Miłecki if (new_skb) { 306*dd4544f0SRafał Miłecki skb_put(new_skb, len); 307*dd4544f0SRafał Miłecki skb_copy_from_linear_data_offset(skb, BGMAC_RX_FRAME_OFFSET, 308*dd4544f0SRafał Miłecki new_skb->data, 309*dd4544f0SRafał Miłecki len); 310*dd4544f0SRafał Miłecki new_skb->protocol = 311*dd4544f0SRafał Miłecki eth_type_trans(new_skb, bgmac->net_dev); 312*dd4544f0SRafał Miłecki netif_receive_skb(new_skb); 313*dd4544f0SRafał Miłecki handled++; 314*dd4544f0SRafał Miłecki } else { 315*dd4544f0SRafał Miłecki bgmac->net_dev->stats.rx_dropped++; 316*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Allocation of skb for copying packet failed!\n"); 317*dd4544f0SRafał Miłecki } 318*dd4544f0SRafał Miłecki 319*dd4544f0SRafał Miłecki /* Poison the old skb */ 320*dd4544f0SRafał Miłecki rx->len = cpu_to_le16(0xdead); 321*dd4544f0SRafał Miłecki rx->flags = cpu_to_le16(0xbeef); 322*dd4544f0SRafał Miłecki } 323*dd4544f0SRafał Miłecki 324*dd4544f0SRafał Miłecki /* Make it back accessible to the hardware */ 325*dd4544f0SRafał Miłecki dma_sync_single_for_device(dma_dev, slot->dma_addr, 326*dd4544f0SRafał Miłecki BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); 327*dd4544f0SRafał Miłecki 328*dd4544f0SRafał Miłecki if (++ring->start >= BGMAC_RX_RING_SLOTS) 329*dd4544f0SRafał Miłecki ring->start = 0; 330*dd4544f0SRafał Miłecki 331*dd4544f0SRafał Miłecki if (handled >= weight) /* Should never be greater */ 332*dd4544f0SRafał Miłecki break; 333*dd4544f0SRafał Miłecki } 334*dd4544f0SRafał Miłecki 335*dd4544f0SRafał Miłecki return handled; 336*dd4544f0SRafał Miłecki } 337*dd4544f0SRafał Miłecki 338*dd4544f0SRafał Miłecki /* Does ring support unaligned addressing? */ 339*dd4544f0SRafał Miłecki static bool bgmac_dma_unaligned(struct bgmac *bgmac, 340*dd4544f0SRafał Miłecki struct bgmac_dma_ring *ring, 341*dd4544f0SRafał Miłecki enum bgmac_dma_ring_type ring_type) 342*dd4544f0SRafał Miłecki { 343*dd4544f0SRafał Miłecki switch (ring_type) { 344*dd4544f0SRafał Miłecki case BGMAC_DMA_RING_TX: 345*dd4544f0SRafał Miłecki bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO, 346*dd4544f0SRafał Miłecki 0xff0); 347*dd4544f0SRafał Miłecki if (bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO)) 348*dd4544f0SRafał Miłecki return true; 349*dd4544f0SRafał Miłecki break; 350*dd4544f0SRafał Miłecki case BGMAC_DMA_RING_RX: 351*dd4544f0SRafał Miłecki bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO, 352*dd4544f0SRafał Miłecki 0xff0); 353*dd4544f0SRafał Miłecki if (bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO)) 354*dd4544f0SRafał Miłecki return true; 355*dd4544f0SRafał Miłecki break; 356*dd4544f0SRafał Miłecki } 357*dd4544f0SRafał Miłecki return false; 358*dd4544f0SRafał Miłecki } 359*dd4544f0SRafał Miłecki 360*dd4544f0SRafał Miłecki static void bgmac_dma_ring_free(struct bgmac *bgmac, 361*dd4544f0SRafał Miłecki struct bgmac_dma_ring *ring) 362*dd4544f0SRafał Miłecki { 363*dd4544f0SRafał Miłecki struct device *dma_dev = bgmac->core->dma_dev; 364*dd4544f0SRafał Miłecki struct bgmac_slot_info *slot; 365*dd4544f0SRafał Miłecki int size; 366*dd4544f0SRafał Miłecki int i; 367*dd4544f0SRafał Miłecki 368*dd4544f0SRafał Miłecki for (i = 0; i < ring->num_slots; i++) { 369*dd4544f0SRafał Miłecki slot = &ring->slots[i]; 370*dd4544f0SRafał Miłecki if (slot->skb) { 371*dd4544f0SRafał Miłecki if (slot->dma_addr) 372*dd4544f0SRafał Miłecki dma_unmap_single(dma_dev, slot->dma_addr, 373*dd4544f0SRafał Miłecki slot->skb->len, DMA_TO_DEVICE); 374*dd4544f0SRafał Miłecki dev_kfree_skb(slot->skb); 375*dd4544f0SRafał Miłecki } 376*dd4544f0SRafał Miłecki } 377*dd4544f0SRafał Miłecki 378*dd4544f0SRafał Miłecki if (ring->cpu_base) { 379*dd4544f0SRafał Miłecki /* Free ring of descriptors */ 380*dd4544f0SRafał Miłecki size = ring->num_slots * sizeof(struct bgmac_dma_desc); 381*dd4544f0SRafał Miłecki dma_free_coherent(dma_dev, size, ring->cpu_base, 382*dd4544f0SRafał Miłecki ring->dma_base); 383*dd4544f0SRafał Miłecki } 384*dd4544f0SRafał Miłecki } 385*dd4544f0SRafał Miłecki 386*dd4544f0SRafał Miłecki static void bgmac_dma_free(struct bgmac *bgmac) 387*dd4544f0SRafał Miłecki { 388*dd4544f0SRafał Miłecki int i; 389*dd4544f0SRafał Miłecki 390*dd4544f0SRafał Miłecki for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) 391*dd4544f0SRafał Miłecki bgmac_dma_ring_free(bgmac, &bgmac->tx_ring[i]); 392*dd4544f0SRafał Miłecki for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) 393*dd4544f0SRafał Miłecki bgmac_dma_ring_free(bgmac, &bgmac->rx_ring[i]); 394*dd4544f0SRafał Miłecki } 395*dd4544f0SRafał Miłecki 396*dd4544f0SRafał Miłecki static int bgmac_dma_alloc(struct bgmac *bgmac) 397*dd4544f0SRafał Miłecki { 398*dd4544f0SRafał Miłecki struct device *dma_dev = bgmac->core->dma_dev; 399*dd4544f0SRafał Miłecki struct bgmac_dma_ring *ring; 400*dd4544f0SRafał Miłecki static const u16 ring_base[] = { BGMAC_DMA_BASE0, BGMAC_DMA_BASE1, 401*dd4544f0SRafał Miłecki BGMAC_DMA_BASE2, BGMAC_DMA_BASE3, }; 402*dd4544f0SRafał Miłecki int size; /* ring size: different for Tx and Rx */ 403*dd4544f0SRafał Miłecki int err; 404*dd4544f0SRafał Miłecki int i; 405*dd4544f0SRafał Miłecki 406*dd4544f0SRafał Miłecki BUILD_BUG_ON(BGMAC_MAX_TX_RINGS > ARRAY_SIZE(ring_base)); 407*dd4544f0SRafał Miłecki BUILD_BUG_ON(BGMAC_MAX_RX_RINGS > ARRAY_SIZE(ring_base)); 408*dd4544f0SRafał Miłecki 409*dd4544f0SRafał Miłecki if (!(bcma_aread32(bgmac->core, BCMA_IOST) & BCMA_IOST_DMA64)) { 410*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Core does not report 64-bit DMA\n"); 411*dd4544f0SRafał Miłecki return -ENOTSUPP; 412*dd4544f0SRafał Miłecki } 413*dd4544f0SRafał Miłecki 414*dd4544f0SRafał Miłecki for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) { 415*dd4544f0SRafał Miłecki ring = &bgmac->tx_ring[i]; 416*dd4544f0SRafał Miłecki ring->num_slots = BGMAC_TX_RING_SLOTS; 417*dd4544f0SRafał Miłecki ring->mmio_base = ring_base[i]; 418*dd4544f0SRafał Miłecki if (bgmac_dma_unaligned(bgmac, ring, BGMAC_DMA_RING_TX)) 419*dd4544f0SRafał Miłecki bgmac_warn(bgmac, "TX on ring 0x%X supports unaligned addressing but this feature is not implemented\n", 420*dd4544f0SRafał Miłecki ring->mmio_base); 421*dd4544f0SRafał Miłecki 422*dd4544f0SRafał Miłecki /* Alloc ring of descriptors */ 423*dd4544f0SRafał Miłecki size = ring->num_slots * sizeof(struct bgmac_dma_desc); 424*dd4544f0SRafał Miłecki ring->cpu_base = dma_zalloc_coherent(dma_dev, size, 425*dd4544f0SRafał Miłecki &ring->dma_base, 426*dd4544f0SRafał Miłecki GFP_KERNEL); 427*dd4544f0SRafał Miłecki if (!ring->cpu_base) { 428*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Allocation of TX ring 0x%X failed\n", 429*dd4544f0SRafał Miłecki ring->mmio_base); 430*dd4544f0SRafał Miłecki goto err_dma_free; 431*dd4544f0SRafał Miłecki } 432*dd4544f0SRafał Miłecki if (ring->dma_base & 0xC0000000) 433*dd4544f0SRafał Miłecki bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); 434*dd4544f0SRafał Miłecki 435*dd4544f0SRafał Miłecki /* No need to alloc TX slots yet */ 436*dd4544f0SRafał Miłecki } 437*dd4544f0SRafał Miłecki 438*dd4544f0SRafał Miłecki for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { 439*dd4544f0SRafał Miłecki ring = &bgmac->rx_ring[i]; 440*dd4544f0SRafał Miłecki ring->num_slots = BGMAC_RX_RING_SLOTS; 441*dd4544f0SRafał Miłecki ring->mmio_base = ring_base[i]; 442*dd4544f0SRafał Miłecki if (bgmac_dma_unaligned(bgmac, ring, BGMAC_DMA_RING_RX)) 443*dd4544f0SRafał Miłecki bgmac_warn(bgmac, "RX on ring 0x%X supports unaligned addressing but this feature is not implemented\n", 444*dd4544f0SRafał Miłecki ring->mmio_base); 445*dd4544f0SRafał Miłecki 446*dd4544f0SRafał Miłecki /* Alloc ring of descriptors */ 447*dd4544f0SRafał Miłecki size = ring->num_slots * sizeof(struct bgmac_dma_desc); 448*dd4544f0SRafał Miłecki ring->cpu_base = dma_zalloc_coherent(dma_dev, size, 449*dd4544f0SRafał Miłecki &ring->dma_base, 450*dd4544f0SRafał Miłecki GFP_KERNEL); 451*dd4544f0SRafał Miłecki if (!ring->cpu_base) { 452*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Allocation of RX ring 0x%X failed\n", 453*dd4544f0SRafał Miłecki ring->mmio_base); 454*dd4544f0SRafał Miłecki err = -ENOMEM; 455*dd4544f0SRafał Miłecki goto err_dma_free; 456*dd4544f0SRafał Miłecki } 457*dd4544f0SRafał Miłecki if (ring->dma_base & 0xC0000000) 458*dd4544f0SRafał Miłecki bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); 459*dd4544f0SRafał Miłecki 460*dd4544f0SRafał Miłecki /* Alloc RX slots */ 461*dd4544f0SRafał Miłecki for (i = 0; i < ring->num_slots; i++) { 462*dd4544f0SRafał Miłecki err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[i]); 463*dd4544f0SRafał Miłecki if (err) { 464*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Can't allocate skb for slot in RX ring\n"); 465*dd4544f0SRafał Miłecki goto err_dma_free; 466*dd4544f0SRafał Miłecki } 467*dd4544f0SRafał Miłecki } 468*dd4544f0SRafał Miłecki } 469*dd4544f0SRafał Miłecki 470*dd4544f0SRafał Miłecki return 0; 471*dd4544f0SRafał Miłecki 472*dd4544f0SRafał Miłecki err_dma_free: 473*dd4544f0SRafał Miłecki bgmac_dma_free(bgmac); 474*dd4544f0SRafał Miłecki return -ENOMEM; 475*dd4544f0SRafał Miłecki } 476*dd4544f0SRafał Miłecki 477*dd4544f0SRafał Miłecki static void bgmac_dma_init(struct bgmac *bgmac) 478*dd4544f0SRafał Miłecki { 479*dd4544f0SRafał Miłecki struct bgmac_dma_ring *ring; 480*dd4544f0SRafał Miłecki struct bgmac_dma_desc *dma_desc; 481*dd4544f0SRafał Miłecki u32 ctl0, ctl1; 482*dd4544f0SRafał Miłecki int i; 483*dd4544f0SRafał Miłecki 484*dd4544f0SRafał Miłecki for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) { 485*dd4544f0SRafał Miłecki ring = &bgmac->tx_ring[i]; 486*dd4544f0SRafał Miłecki 487*dd4544f0SRafał Miłecki /* We don't implement unaligned addressing, so enable first */ 488*dd4544f0SRafał Miłecki bgmac_dma_tx_enable(bgmac, ring); 489*dd4544f0SRafał Miłecki bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO, 490*dd4544f0SRafał Miłecki lower_32_bits(ring->dma_base)); 491*dd4544f0SRafał Miłecki bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGHI, 492*dd4544f0SRafał Miłecki upper_32_bits(ring->dma_base)); 493*dd4544f0SRafał Miłecki 494*dd4544f0SRafał Miłecki ring->start = 0; 495*dd4544f0SRafał Miłecki ring->end = 0; /* Points the slot that should *not* be read */ 496*dd4544f0SRafał Miłecki } 497*dd4544f0SRafał Miłecki 498*dd4544f0SRafał Miłecki for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { 499*dd4544f0SRafał Miłecki ring = &bgmac->rx_ring[i]; 500*dd4544f0SRafał Miłecki 501*dd4544f0SRafał Miłecki /* We don't implement unaligned addressing, so enable first */ 502*dd4544f0SRafał Miłecki bgmac_dma_rx_enable(bgmac, ring); 503*dd4544f0SRafał Miłecki bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO, 504*dd4544f0SRafał Miłecki lower_32_bits(ring->dma_base)); 505*dd4544f0SRafał Miłecki bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGHI, 506*dd4544f0SRafał Miłecki upper_32_bits(ring->dma_base)); 507*dd4544f0SRafał Miłecki 508*dd4544f0SRafał Miłecki for (i = 0, dma_desc = ring->cpu_base; i < ring->num_slots; 509*dd4544f0SRafał Miłecki i++, dma_desc++) { 510*dd4544f0SRafał Miłecki ctl0 = ctl1 = 0; 511*dd4544f0SRafał Miłecki 512*dd4544f0SRafał Miłecki if (i == ring->num_slots - 1) 513*dd4544f0SRafał Miłecki ctl0 |= BGMAC_DESC_CTL0_EOT; 514*dd4544f0SRafał Miłecki ctl1 |= BGMAC_RX_BUF_SIZE & BGMAC_DESC_CTL1_LEN; 515*dd4544f0SRafał Miłecki /* Is there any BGMAC device that requires extension? */ 516*dd4544f0SRafał Miłecki /* ctl1 |= (addrext << B43_DMA64_DCTL1_ADDREXT_SHIFT) & 517*dd4544f0SRafał Miłecki * B43_DMA64_DCTL1_ADDREXT_MASK; 518*dd4544f0SRafał Miłecki */ 519*dd4544f0SRafał Miłecki 520*dd4544f0SRafał Miłecki dma_desc->addr_low = cpu_to_le32(lower_32_bits(ring->slots[i].dma_addr)); 521*dd4544f0SRafał Miłecki dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[i].dma_addr)); 522*dd4544f0SRafał Miłecki dma_desc->ctl0 = cpu_to_le32(ctl0); 523*dd4544f0SRafał Miłecki dma_desc->ctl1 = cpu_to_le32(ctl1); 524*dd4544f0SRafał Miłecki } 525*dd4544f0SRafał Miłecki 526*dd4544f0SRafał Miłecki bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX, 527*dd4544f0SRafał Miłecki ring->num_slots * sizeof(struct bgmac_dma_desc)); 528*dd4544f0SRafał Miłecki 529*dd4544f0SRafał Miłecki ring->start = 0; 530*dd4544f0SRafał Miłecki ring->end = 0; 531*dd4544f0SRafał Miłecki } 532*dd4544f0SRafał Miłecki } 533*dd4544f0SRafał Miłecki 534*dd4544f0SRafał Miłecki /************************************************** 535*dd4544f0SRafał Miłecki * PHY ops 536*dd4544f0SRafał Miłecki **************************************************/ 537*dd4544f0SRafał Miłecki 538*dd4544f0SRafał Miłecki u16 bgmac_phy_read(struct bgmac *bgmac, u8 phyaddr, u8 reg) 539*dd4544f0SRafał Miłecki { 540*dd4544f0SRafał Miłecki struct bcma_device *core; 541*dd4544f0SRafał Miłecki u16 phy_access_addr; 542*dd4544f0SRafał Miłecki u16 phy_ctl_addr; 543*dd4544f0SRafał Miłecki u32 tmp; 544*dd4544f0SRafał Miłecki 545*dd4544f0SRafał Miłecki BUILD_BUG_ON(BGMAC_PA_DATA_MASK != BCMA_GMAC_CMN_PA_DATA_MASK); 546*dd4544f0SRafał Miłecki BUILD_BUG_ON(BGMAC_PA_ADDR_MASK != BCMA_GMAC_CMN_PA_ADDR_MASK); 547*dd4544f0SRafał Miłecki BUILD_BUG_ON(BGMAC_PA_ADDR_SHIFT != BCMA_GMAC_CMN_PA_ADDR_SHIFT); 548*dd4544f0SRafał Miłecki BUILD_BUG_ON(BGMAC_PA_REG_MASK != BCMA_GMAC_CMN_PA_REG_MASK); 549*dd4544f0SRafał Miłecki BUILD_BUG_ON(BGMAC_PA_REG_SHIFT != BCMA_GMAC_CMN_PA_REG_SHIFT); 550*dd4544f0SRafał Miłecki BUILD_BUG_ON(BGMAC_PA_WRITE != BCMA_GMAC_CMN_PA_WRITE); 551*dd4544f0SRafał Miłecki BUILD_BUG_ON(BGMAC_PA_START != BCMA_GMAC_CMN_PA_START); 552*dd4544f0SRafał Miłecki BUILD_BUG_ON(BGMAC_PC_EPA_MASK != BCMA_GMAC_CMN_PC_EPA_MASK); 553*dd4544f0SRafał Miłecki BUILD_BUG_ON(BGMAC_PC_MCT_MASK != BCMA_GMAC_CMN_PC_MCT_MASK); 554*dd4544f0SRafał Miłecki BUILD_BUG_ON(BGMAC_PC_MCT_SHIFT != BCMA_GMAC_CMN_PC_MCT_SHIFT); 555*dd4544f0SRafał Miłecki BUILD_BUG_ON(BGMAC_PC_MTE != BCMA_GMAC_CMN_PC_MTE); 556*dd4544f0SRafał Miłecki 557*dd4544f0SRafał Miłecki if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT) { 558*dd4544f0SRafał Miłecki core = bgmac->core->bus->drv_gmac_cmn.core; 559*dd4544f0SRafał Miłecki phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS; 560*dd4544f0SRafał Miłecki phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL; 561*dd4544f0SRafał Miłecki } else { 562*dd4544f0SRafał Miłecki core = bgmac->core; 563*dd4544f0SRafał Miłecki phy_access_addr = BGMAC_PHY_ACCESS; 564*dd4544f0SRafał Miłecki phy_ctl_addr = BGMAC_PHY_CNTL; 565*dd4544f0SRafał Miłecki } 566*dd4544f0SRafał Miłecki 567*dd4544f0SRafał Miłecki tmp = bcma_read32(core, phy_ctl_addr); 568*dd4544f0SRafał Miłecki tmp &= ~BGMAC_PC_EPA_MASK; 569*dd4544f0SRafał Miłecki tmp |= phyaddr; 570*dd4544f0SRafał Miłecki bcma_write32(core, phy_ctl_addr, tmp); 571*dd4544f0SRafał Miłecki 572*dd4544f0SRafał Miłecki tmp = BGMAC_PA_START; 573*dd4544f0SRafał Miłecki tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT; 574*dd4544f0SRafał Miłecki tmp |= reg << BGMAC_PA_REG_SHIFT; 575*dd4544f0SRafał Miłecki bcma_write32(core, phy_access_addr, tmp); 576*dd4544f0SRafał Miłecki 577*dd4544f0SRafał Miłecki if (!bgmac_wait_value(core, phy_access_addr, BGMAC_PA_START, 0, 1000)) { 578*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Reading PHY %d register 0x%X failed\n", 579*dd4544f0SRafał Miłecki phyaddr, reg); 580*dd4544f0SRafał Miłecki return 0xffff; 581*dd4544f0SRafał Miłecki } 582*dd4544f0SRafał Miłecki 583*dd4544f0SRafał Miłecki return bcma_read32(core, phy_access_addr) & BGMAC_PA_DATA_MASK; 584*dd4544f0SRafał Miłecki } 585*dd4544f0SRafał Miłecki 586*dd4544f0SRafał Miłecki /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphywr */ 587*dd4544f0SRafał Miłecki void bgmac_phy_write(struct bgmac *bgmac, u8 phyaddr, u8 reg, u16 value) 588*dd4544f0SRafał Miłecki { 589*dd4544f0SRafał Miłecki struct bcma_device *core; 590*dd4544f0SRafał Miłecki u16 phy_access_addr; 591*dd4544f0SRafał Miłecki u16 phy_ctl_addr; 592*dd4544f0SRafał Miłecki u32 tmp; 593*dd4544f0SRafał Miłecki 594*dd4544f0SRafał Miłecki if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT) { 595*dd4544f0SRafał Miłecki core = bgmac->core->bus->drv_gmac_cmn.core; 596*dd4544f0SRafał Miłecki phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS; 597*dd4544f0SRafał Miłecki phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL; 598*dd4544f0SRafał Miłecki } else { 599*dd4544f0SRafał Miłecki core = bgmac->core; 600*dd4544f0SRafał Miłecki phy_access_addr = BGMAC_PHY_ACCESS; 601*dd4544f0SRafał Miłecki phy_ctl_addr = BGMAC_PHY_CNTL; 602*dd4544f0SRafał Miłecki } 603*dd4544f0SRafał Miłecki 604*dd4544f0SRafał Miłecki tmp = bcma_read32(core, phy_ctl_addr); 605*dd4544f0SRafał Miłecki tmp &= ~BGMAC_PC_EPA_MASK; 606*dd4544f0SRafał Miłecki tmp |= phyaddr; 607*dd4544f0SRafał Miłecki bcma_write32(core, phy_ctl_addr, tmp); 608*dd4544f0SRafał Miłecki 609*dd4544f0SRafał Miłecki bgmac_write(bgmac, BGMAC_INT_STATUS, BGMAC_IS_MDIO); 610*dd4544f0SRafał Miłecki if (bgmac_read(bgmac, BGMAC_INT_STATUS) & BGMAC_IS_MDIO) 611*dd4544f0SRafał Miłecki bgmac_warn(bgmac, "Error setting MDIO int\n"); 612*dd4544f0SRafał Miłecki 613*dd4544f0SRafał Miłecki tmp = BGMAC_PA_START; 614*dd4544f0SRafał Miłecki tmp |= BGMAC_PA_WRITE; 615*dd4544f0SRafał Miłecki tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT; 616*dd4544f0SRafał Miłecki tmp |= reg << BGMAC_PA_REG_SHIFT; 617*dd4544f0SRafał Miłecki tmp |= value; 618*dd4544f0SRafał Miłecki bcma_write32(core, phy_access_addr, tmp); 619*dd4544f0SRafał Miłecki 620*dd4544f0SRafał Miłecki if (!bgmac_wait_value(core, phy_access_addr, BGMAC_PA_START, 0, 1000)) 621*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Writing to PHY %d register 0x%X failed\n", 622*dd4544f0SRafał Miłecki phyaddr, reg); 623*dd4544f0SRafał Miłecki } 624*dd4544f0SRafał Miłecki 625*dd4544f0SRafał Miłecki /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyforce */ 626*dd4544f0SRafał Miłecki static void bgmac_phy_force(struct bgmac *bgmac) 627*dd4544f0SRafał Miłecki { 628*dd4544f0SRafał Miłecki u16 ctl; 629*dd4544f0SRafał Miłecki u16 mask = ~(BGMAC_PHY_CTL_SPEED | BGMAC_PHY_CTL_SPEED_MSB | 630*dd4544f0SRafał Miłecki BGMAC_PHY_CTL_ANENAB | BGMAC_PHY_CTL_DUPLEX); 631*dd4544f0SRafał Miłecki 632*dd4544f0SRafał Miłecki if (bgmac->phyaddr == BGMAC_PHY_NOREGS) 633*dd4544f0SRafał Miłecki return; 634*dd4544f0SRafał Miłecki 635*dd4544f0SRafał Miłecki if (bgmac->autoneg) 636*dd4544f0SRafał Miłecki return; 637*dd4544f0SRafał Miłecki 638*dd4544f0SRafał Miłecki ctl = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL); 639*dd4544f0SRafał Miłecki ctl &= mask; 640*dd4544f0SRafał Miłecki if (bgmac->full_duplex) 641*dd4544f0SRafał Miłecki ctl |= BGMAC_PHY_CTL_DUPLEX; 642*dd4544f0SRafał Miłecki if (bgmac->speed == BGMAC_SPEED_100) 643*dd4544f0SRafał Miłecki ctl |= BGMAC_PHY_CTL_SPEED_100; 644*dd4544f0SRafał Miłecki else if (bgmac->speed == BGMAC_SPEED_1000) 645*dd4544f0SRafał Miłecki ctl |= BGMAC_PHY_CTL_SPEED_1000; 646*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL, ctl); 647*dd4544f0SRafał Miłecki } 648*dd4544f0SRafał Miłecki 649*dd4544f0SRafał Miłecki /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyadvertise */ 650*dd4544f0SRafał Miłecki static void bgmac_phy_advertise(struct bgmac *bgmac) 651*dd4544f0SRafał Miłecki { 652*dd4544f0SRafał Miłecki u16 adv; 653*dd4544f0SRafał Miłecki 654*dd4544f0SRafał Miłecki if (bgmac->phyaddr == BGMAC_PHY_NOREGS) 655*dd4544f0SRafał Miłecki return; 656*dd4544f0SRafał Miłecki 657*dd4544f0SRafał Miłecki if (!bgmac->autoneg) 658*dd4544f0SRafał Miłecki return; 659*dd4544f0SRafał Miłecki 660*dd4544f0SRafał Miłecki /* Adv selected 10/100 speeds */ 661*dd4544f0SRafał Miłecki adv = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV); 662*dd4544f0SRafał Miłecki adv &= ~(BGMAC_PHY_ADV_10HALF | BGMAC_PHY_ADV_10FULL | 663*dd4544f0SRafał Miłecki BGMAC_PHY_ADV_100HALF | BGMAC_PHY_ADV_100FULL); 664*dd4544f0SRafał Miłecki if (!bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_10) 665*dd4544f0SRafał Miłecki adv |= BGMAC_PHY_ADV_10HALF; 666*dd4544f0SRafał Miłecki if (!bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_100) 667*dd4544f0SRafał Miłecki adv |= BGMAC_PHY_ADV_100HALF; 668*dd4544f0SRafał Miłecki if (bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_10) 669*dd4544f0SRafał Miłecki adv |= BGMAC_PHY_ADV_10FULL; 670*dd4544f0SRafał Miłecki if (bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_100) 671*dd4544f0SRafał Miłecki adv |= BGMAC_PHY_ADV_100FULL; 672*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV, adv); 673*dd4544f0SRafał Miłecki 674*dd4544f0SRafał Miłecki /* Adv selected 1000 speeds */ 675*dd4544f0SRafał Miłecki adv = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV2); 676*dd4544f0SRafał Miłecki adv &= ~(BGMAC_PHY_ADV2_1000HALF | BGMAC_PHY_ADV2_1000FULL); 677*dd4544f0SRafał Miłecki if (!bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_1000) 678*dd4544f0SRafał Miłecki adv |= BGMAC_PHY_ADV2_1000HALF; 679*dd4544f0SRafał Miłecki if (bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_1000) 680*dd4544f0SRafał Miłecki adv |= BGMAC_PHY_ADV2_1000FULL; 681*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV2, adv); 682*dd4544f0SRafał Miłecki 683*dd4544f0SRafał Miłecki /* Restart */ 684*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL, 685*dd4544f0SRafał Miłecki bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL) | 686*dd4544f0SRafał Miłecki BGMAC_PHY_CTL_RESTART); 687*dd4544f0SRafał Miłecki } 688*dd4544f0SRafał Miłecki 689*dd4544f0SRafał Miłecki /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyinit */ 690*dd4544f0SRafał Miłecki static void bgmac_phy_init(struct bgmac *bgmac) 691*dd4544f0SRafał Miłecki { 692*dd4544f0SRafał Miłecki struct bcma_chipinfo *ci = &bgmac->core->bus->chipinfo; 693*dd4544f0SRafał Miłecki struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc; 694*dd4544f0SRafał Miłecki u8 i; 695*dd4544f0SRafał Miłecki 696*dd4544f0SRafał Miłecki if (ci->id == BCMA_CHIP_ID_BCM5356) { 697*dd4544f0SRafał Miłecki for (i = 0; i < 5; i++) { 698*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x1f, 0x008b); 699*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x15, 0x0100); 700*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x1f, 0x000f); 701*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x12, 0x2aaa); 702*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x1f, 0x000b); 703*dd4544f0SRafał Miłecki } 704*dd4544f0SRafał Miłecki } 705*dd4544f0SRafał Miłecki if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg != 10) || 706*dd4544f0SRafał Miłecki (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg != 10) || 707*dd4544f0SRafał Miłecki (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg != 9)) { 708*dd4544f0SRafał Miłecki bcma_chipco_chipctl_maskset(cc, 2, ~0xc0000000, 0); 709*dd4544f0SRafał Miłecki bcma_chipco_chipctl_maskset(cc, 4, ~0x80000000, 0); 710*dd4544f0SRafał Miłecki for (i = 0; i < 5; i++) { 711*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x1f, 0x000f); 712*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x16, 0x5284); 713*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x1f, 0x000b); 714*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x17, 0x0010); 715*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x1f, 0x000f); 716*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x16, 0x5296); 717*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x17, 0x1073); 718*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x17, 0x9073); 719*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x16, 0x52b6); 720*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x17, 0x9273); 721*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, i, 0x1f, 0x000b); 722*dd4544f0SRafał Miłecki } 723*dd4544f0SRafał Miłecki } 724*dd4544f0SRafał Miłecki } 725*dd4544f0SRafał Miłecki 726*dd4544f0SRafał Miłecki /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyreset */ 727*dd4544f0SRafał Miłecki static void bgmac_phy_reset(struct bgmac *bgmac) 728*dd4544f0SRafał Miłecki { 729*dd4544f0SRafał Miłecki if (bgmac->phyaddr == BGMAC_PHY_NOREGS) 730*dd4544f0SRafał Miłecki return; 731*dd4544f0SRafał Miłecki 732*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL, 733*dd4544f0SRafał Miłecki BGMAC_PHY_CTL_RESET); 734*dd4544f0SRafał Miłecki udelay(100); 735*dd4544f0SRafał Miłecki if (bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL) & 736*dd4544f0SRafał Miłecki BGMAC_PHY_CTL_RESET) 737*dd4544f0SRafał Miłecki bgmac_err(bgmac, "PHY reset failed\n"); 738*dd4544f0SRafał Miłecki bgmac_phy_init(bgmac); 739*dd4544f0SRafał Miłecki } 740*dd4544f0SRafał Miłecki 741*dd4544f0SRafał Miłecki /************************************************** 742*dd4544f0SRafał Miłecki * Chip ops 743*dd4544f0SRafał Miłecki **************************************************/ 744*dd4544f0SRafał Miłecki 745*dd4544f0SRafał Miłecki /* TODO: can we just drop @force? Can we don't reset MAC at all if there is 746*dd4544f0SRafał Miłecki * nothing to change? Try if after stabilizng driver. 747*dd4544f0SRafał Miłecki */ 748*dd4544f0SRafał Miłecki static void bgmac_cmdcfg_maskset(struct bgmac *bgmac, u32 mask, u32 set, 749*dd4544f0SRafał Miłecki bool force) 750*dd4544f0SRafał Miłecki { 751*dd4544f0SRafał Miłecki u32 cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG); 752*dd4544f0SRafał Miłecki u32 new_val = (cmdcfg & mask) | set; 753*dd4544f0SRafał Miłecki 754*dd4544f0SRafał Miłecki bgmac_set(bgmac, BGMAC_CMDCFG, BGMAC_CMDCFG_SR); 755*dd4544f0SRafał Miłecki udelay(2); 756*dd4544f0SRafał Miłecki 757*dd4544f0SRafał Miłecki if (new_val != cmdcfg || force) 758*dd4544f0SRafał Miłecki bgmac_write(bgmac, BGMAC_CMDCFG, new_val); 759*dd4544f0SRafał Miłecki 760*dd4544f0SRafał Miłecki bgmac_mask(bgmac, BGMAC_CMDCFG, ~BGMAC_CMDCFG_SR); 761*dd4544f0SRafał Miłecki udelay(2); 762*dd4544f0SRafał Miłecki } 763*dd4544f0SRafał Miłecki 764*dd4544f0SRafał Miłecki #if 0 /* We don't use that regs yet */ 765*dd4544f0SRafał Miłecki static void bgmac_chip_stats_update(struct bgmac *bgmac) 766*dd4544f0SRafał Miłecki { 767*dd4544f0SRafał Miłecki int i; 768*dd4544f0SRafał Miłecki 769*dd4544f0SRafał Miłecki if (bgmac->core->id.id != BCMA_CORE_4706_MAC_GBIT) { 770*dd4544f0SRafał Miłecki for (i = 0; i < BGMAC_NUM_MIB_TX_REGS; i++) 771*dd4544f0SRafał Miłecki bgmac->mib_tx_regs[i] = 772*dd4544f0SRafał Miłecki bgmac_read(bgmac, 773*dd4544f0SRafał Miłecki BGMAC_TX_GOOD_OCTETS + (i * 4)); 774*dd4544f0SRafał Miłecki for (i = 0; i < BGMAC_NUM_MIB_RX_REGS; i++) 775*dd4544f0SRafał Miłecki bgmac->mib_rx_regs[i] = 776*dd4544f0SRafał Miłecki bgmac_read(bgmac, 777*dd4544f0SRafał Miłecki BGMAC_RX_GOOD_OCTETS + (i * 4)); 778*dd4544f0SRafał Miłecki } 779*dd4544f0SRafał Miłecki 780*dd4544f0SRafał Miłecki /* TODO: what else? how to handle BCM4706? Specs are needed */ 781*dd4544f0SRafał Miłecki } 782*dd4544f0SRafał Miłecki #endif 783*dd4544f0SRafał Miłecki 784*dd4544f0SRafał Miłecki static void bgmac_clear_mib(struct bgmac *bgmac) 785*dd4544f0SRafał Miłecki { 786*dd4544f0SRafał Miłecki int i; 787*dd4544f0SRafał Miłecki 788*dd4544f0SRafał Miłecki if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT) 789*dd4544f0SRafał Miłecki return; 790*dd4544f0SRafał Miłecki 791*dd4544f0SRafał Miłecki bgmac_set(bgmac, BGMAC_DEV_CTL, BGMAC_DC_MROR); 792*dd4544f0SRafał Miłecki for (i = 0; i < BGMAC_NUM_MIB_TX_REGS; i++) 793*dd4544f0SRafał Miłecki bgmac_read(bgmac, BGMAC_TX_GOOD_OCTETS + (i * 4)); 794*dd4544f0SRafał Miłecki for (i = 0; i < BGMAC_NUM_MIB_RX_REGS; i++) 795*dd4544f0SRafał Miłecki bgmac_read(bgmac, BGMAC_RX_GOOD_OCTETS + (i * 4)); 796*dd4544f0SRafał Miłecki } 797*dd4544f0SRafał Miłecki 798*dd4544f0SRafał Miłecki /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_speed */ 799*dd4544f0SRafał Miłecki static void bgmac_speed(struct bgmac *bgmac, int speed) 800*dd4544f0SRafał Miłecki { 801*dd4544f0SRafał Miłecki u32 mask = ~(BGMAC_CMDCFG_ES_MASK | BGMAC_CMDCFG_HD); 802*dd4544f0SRafał Miłecki u32 set = 0; 803*dd4544f0SRafał Miłecki 804*dd4544f0SRafał Miłecki if (speed & BGMAC_SPEED_10) 805*dd4544f0SRafał Miłecki set |= BGMAC_CMDCFG_ES_10; 806*dd4544f0SRafał Miłecki if (speed & BGMAC_SPEED_100) 807*dd4544f0SRafał Miłecki set |= BGMAC_CMDCFG_ES_100; 808*dd4544f0SRafał Miłecki if (speed & BGMAC_SPEED_1000) 809*dd4544f0SRafał Miłecki set |= BGMAC_CMDCFG_ES_1000; 810*dd4544f0SRafał Miłecki if (!bgmac->full_duplex) 811*dd4544f0SRafał Miłecki set |= BGMAC_CMDCFG_HD; 812*dd4544f0SRafał Miłecki bgmac_cmdcfg_maskset(bgmac, mask, set, true); 813*dd4544f0SRafał Miłecki } 814*dd4544f0SRafał Miłecki 815*dd4544f0SRafał Miłecki static void bgmac_miiconfig(struct bgmac *bgmac) 816*dd4544f0SRafał Miłecki { 817*dd4544f0SRafał Miłecki u8 imode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >> 818*dd4544f0SRafał Miłecki BGMAC_DS_MM_SHIFT; 819*dd4544f0SRafał Miłecki if (imode == 0 || imode == 1) { 820*dd4544f0SRafał Miłecki if (bgmac->autoneg) 821*dd4544f0SRafał Miłecki bgmac_speed(bgmac, BGMAC_SPEED_100); 822*dd4544f0SRafał Miłecki else 823*dd4544f0SRafał Miłecki bgmac_speed(bgmac, bgmac->speed); 824*dd4544f0SRafał Miłecki } 825*dd4544f0SRafał Miłecki } 826*dd4544f0SRafał Miłecki 827*dd4544f0SRafał Miłecki /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipreset */ 828*dd4544f0SRafał Miłecki static void bgmac_chip_reset(struct bgmac *bgmac) 829*dd4544f0SRafał Miłecki { 830*dd4544f0SRafał Miłecki struct bcma_device *core = bgmac->core; 831*dd4544f0SRafał Miłecki struct bcma_bus *bus = core->bus; 832*dd4544f0SRafał Miłecki struct bcma_chipinfo *ci = &bus->chipinfo; 833*dd4544f0SRafał Miłecki u32 flags = 0; 834*dd4544f0SRafał Miłecki u32 iost; 835*dd4544f0SRafał Miłecki int i; 836*dd4544f0SRafał Miłecki 837*dd4544f0SRafał Miłecki if (bcma_core_is_enabled(core)) { 838*dd4544f0SRafał Miłecki if (!bgmac->stats_grabbed) { 839*dd4544f0SRafał Miłecki /* bgmac_chip_stats_update(bgmac); */ 840*dd4544f0SRafał Miłecki bgmac->stats_grabbed = true; 841*dd4544f0SRafał Miłecki } 842*dd4544f0SRafał Miłecki 843*dd4544f0SRafał Miłecki for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) 844*dd4544f0SRafał Miłecki bgmac_dma_tx_reset(bgmac, &bgmac->tx_ring[i]); 845*dd4544f0SRafał Miłecki 846*dd4544f0SRafał Miłecki bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, false); 847*dd4544f0SRafał Miłecki udelay(1); 848*dd4544f0SRafał Miłecki 849*dd4544f0SRafał Miłecki for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) 850*dd4544f0SRafał Miłecki bgmac_dma_rx_reset(bgmac, &bgmac->rx_ring[i]); 851*dd4544f0SRafał Miłecki 852*dd4544f0SRafał Miłecki /* TODO: Clear software multicast filter list */ 853*dd4544f0SRafał Miłecki } 854*dd4544f0SRafał Miłecki 855*dd4544f0SRafał Miłecki iost = bcma_aread32(core, BCMA_IOST); 856*dd4544f0SRafał Miłecki if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == 10) || 857*dd4544f0SRafał Miłecki (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg == 10) || 858*dd4544f0SRafał Miłecki (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg == 9)) 859*dd4544f0SRafał Miłecki iost &= ~BGMAC_BCMA_IOST_ATTACHED; 860*dd4544f0SRafał Miłecki 861*dd4544f0SRafał Miłecki if (iost & BGMAC_BCMA_IOST_ATTACHED) { 862*dd4544f0SRafał Miłecki flags = BGMAC_BCMA_IOCTL_SW_CLKEN; 863*dd4544f0SRafał Miłecki if (!bgmac->has_robosw) 864*dd4544f0SRafał Miłecki flags |= BGMAC_BCMA_IOCTL_SW_RESET; 865*dd4544f0SRafał Miłecki } 866*dd4544f0SRafał Miłecki 867*dd4544f0SRafał Miłecki bcma_core_enable(core, flags); 868*dd4544f0SRafał Miłecki 869*dd4544f0SRafał Miłecki if (core->id.rev > 2) { 870*dd4544f0SRafał Miłecki bgmac_set(bgmac, BCMA_CLKCTLST, 1 << 8); 871*dd4544f0SRafał Miłecki bgmac_wait_value(bgmac->core, BCMA_CLKCTLST, 1 << 24, 1 << 24, 872*dd4544f0SRafał Miłecki 1000); 873*dd4544f0SRafał Miłecki } 874*dd4544f0SRafał Miłecki 875*dd4544f0SRafał Miłecki if (ci->id == BCMA_CHIP_ID_BCM5357 || ci->id == BCMA_CHIP_ID_BCM4749 || 876*dd4544f0SRafał Miłecki ci->id == BCMA_CHIP_ID_BCM53572) { 877*dd4544f0SRafał Miłecki struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc; 878*dd4544f0SRafał Miłecki u8 et_swtype = 0; 879*dd4544f0SRafał Miłecki u8 sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHY | 880*dd4544f0SRafał Miłecki BGMAC_CHIPCTL_1_IF_TYPE_RMII; 881*dd4544f0SRafał Miłecki char buf[2]; 882*dd4544f0SRafał Miłecki 883*dd4544f0SRafał Miłecki if (nvram_getenv("et_swtype", buf, 1) > 0) { 884*dd4544f0SRafał Miłecki if (kstrtou8(buf, 0, &et_swtype)) 885*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Failed to parse et_swtype (%s)\n", 886*dd4544f0SRafał Miłecki buf); 887*dd4544f0SRafał Miłecki et_swtype &= 0x0f; 888*dd4544f0SRafał Miłecki et_swtype <<= 4; 889*dd4544f0SRafał Miłecki sw_type = et_swtype; 890*dd4544f0SRafał Miłecki } else if (ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == 9) { 891*dd4544f0SRafał Miłecki sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHYRMII; 892*dd4544f0SRafał Miłecki } else if (0) { 893*dd4544f0SRafał Miłecki /* TODO */ 894*dd4544f0SRafał Miłecki } 895*dd4544f0SRafał Miłecki bcma_chipco_chipctl_maskset(cc, 1, 896*dd4544f0SRafał Miłecki ~(BGMAC_CHIPCTL_1_IF_TYPE_MASK | 897*dd4544f0SRafał Miłecki BGMAC_CHIPCTL_1_SW_TYPE_MASK), 898*dd4544f0SRafał Miłecki sw_type); 899*dd4544f0SRafał Miłecki } 900*dd4544f0SRafał Miłecki 901*dd4544f0SRafał Miłecki if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw) 902*dd4544f0SRafał Miłecki bcma_awrite32(core, BCMA_IOCTL, 903*dd4544f0SRafał Miłecki bcma_aread32(core, BCMA_IOCTL) & 904*dd4544f0SRafał Miłecki ~BGMAC_BCMA_IOCTL_SW_RESET); 905*dd4544f0SRafał Miłecki 906*dd4544f0SRafał Miłecki /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_reset 907*dd4544f0SRafał Miłecki * Specs don't say about using BGMAC_CMDCFG_SR, but in this routine 908*dd4544f0SRafał Miłecki * BGMAC_CMDCFG is read _after_ putting chip in a reset. So it has to 909*dd4544f0SRafał Miłecki * be keps until taking MAC out of the reset. 910*dd4544f0SRafał Miłecki */ 911*dd4544f0SRafał Miłecki bgmac_cmdcfg_maskset(bgmac, 912*dd4544f0SRafał Miłecki ~(BGMAC_CMDCFG_TE | 913*dd4544f0SRafał Miłecki BGMAC_CMDCFG_RE | 914*dd4544f0SRafał Miłecki BGMAC_CMDCFG_RPI | 915*dd4544f0SRafał Miłecki BGMAC_CMDCFG_TAI | 916*dd4544f0SRafał Miłecki BGMAC_CMDCFG_HD | 917*dd4544f0SRafał Miłecki BGMAC_CMDCFG_ML | 918*dd4544f0SRafał Miłecki BGMAC_CMDCFG_CFE | 919*dd4544f0SRafał Miłecki BGMAC_CMDCFG_RL | 920*dd4544f0SRafał Miłecki BGMAC_CMDCFG_RED | 921*dd4544f0SRafał Miłecki BGMAC_CMDCFG_PE | 922*dd4544f0SRafał Miłecki BGMAC_CMDCFG_TPI | 923*dd4544f0SRafał Miłecki BGMAC_CMDCFG_PAD_EN | 924*dd4544f0SRafał Miłecki BGMAC_CMDCFG_PF), 925*dd4544f0SRafał Miłecki BGMAC_CMDCFG_PROM | 926*dd4544f0SRafał Miłecki BGMAC_CMDCFG_NLC | 927*dd4544f0SRafał Miłecki BGMAC_CMDCFG_CFE | 928*dd4544f0SRafał Miłecki BGMAC_CMDCFG_SR, 929*dd4544f0SRafał Miłecki false); 930*dd4544f0SRafał Miłecki 931*dd4544f0SRafał Miłecki bgmac_clear_mib(bgmac); 932*dd4544f0SRafał Miłecki if (core->id.id == BCMA_CORE_4706_MAC_GBIT) 933*dd4544f0SRafał Miłecki bcma_maskset32(bgmac->cmn, BCMA_GMAC_CMN_PHY_CTL, ~0, 934*dd4544f0SRafał Miłecki BCMA_GMAC_CMN_PC_MTE); 935*dd4544f0SRafał Miłecki else 936*dd4544f0SRafał Miłecki bgmac_set(bgmac, BGMAC_PHY_CNTL, BGMAC_PC_MTE); 937*dd4544f0SRafał Miłecki bgmac_miiconfig(bgmac); 938*dd4544f0SRafał Miłecki bgmac_phy_init(bgmac); 939*dd4544f0SRafał Miłecki 940*dd4544f0SRafał Miłecki bgmac->int_status = 0; 941*dd4544f0SRafał Miłecki } 942*dd4544f0SRafał Miłecki 943*dd4544f0SRafał Miłecki static void bgmac_chip_intrs_on(struct bgmac *bgmac) 944*dd4544f0SRafał Miłecki { 945*dd4544f0SRafał Miłecki bgmac_write(bgmac, BGMAC_INT_MASK, bgmac->int_mask); 946*dd4544f0SRafał Miłecki } 947*dd4544f0SRafał Miłecki 948*dd4544f0SRafał Miłecki static void bgmac_chip_intrs_off(struct bgmac *bgmac) 949*dd4544f0SRafał Miłecki { 950*dd4544f0SRafał Miłecki bgmac_write(bgmac, BGMAC_INT_MASK, 0); 951*dd4544f0SRafał Miłecki } 952*dd4544f0SRafał Miłecki 953*dd4544f0SRafał Miłecki /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_enable */ 954*dd4544f0SRafał Miłecki static void bgmac_enable(struct bgmac *bgmac) 955*dd4544f0SRafał Miłecki { 956*dd4544f0SRafał Miłecki struct bcma_chipinfo *ci = &bgmac->core->bus->chipinfo; 957*dd4544f0SRafał Miłecki u32 cmdcfg; 958*dd4544f0SRafał Miłecki u32 mode; 959*dd4544f0SRafał Miłecki u32 rxq_ctl; 960*dd4544f0SRafał Miłecki u32 fl_ctl; 961*dd4544f0SRafał Miłecki u16 bp_clk; 962*dd4544f0SRafał Miłecki u8 mdp; 963*dd4544f0SRafał Miłecki 964*dd4544f0SRafał Miłecki cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG); 965*dd4544f0SRafał Miłecki bgmac_cmdcfg_maskset(bgmac, ~(BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE), 966*dd4544f0SRafał Miłecki BGMAC_CMDCFG_SR, true); 967*dd4544f0SRafał Miłecki udelay(2); 968*dd4544f0SRafał Miłecki cmdcfg |= BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE; 969*dd4544f0SRafał Miłecki bgmac_write(bgmac, BGMAC_CMDCFG, cmdcfg); 970*dd4544f0SRafał Miłecki 971*dd4544f0SRafał Miłecki mode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >> 972*dd4544f0SRafał Miłecki BGMAC_DS_MM_SHIFT; 973*dd4544f0SRafał Miłecki if (ci->id != BCMA_CHIP_ID_BCM47162 || mode != 0) 974*dd4544f0SRafał Miłecki bgmac_set(bgmac, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT); 975*dd4544f0SRafał Miłecki if (ci->id == BCMA_CHIP_ID_BCM47162 && mode == 2) 976*dd4544f0SRafał Miłecki bcma_chipco_chipctl_maskset(&bgmac->core->bus->drv_cc, 1, ~0, 977*dd4544f0SRafał Miłecki BGMAC_CHIPCTL_1_RXC_DLL_BYPASS); 978*dd4544f0SRafał Miłecki 979*dd4544f0SRafał Miłecki switch (ci->id) { 980*dd4544f0SRafał Miłecki case BCMA_CHIP_ID_BCM5357: 981*dd4544f0SRafał Miłecki case BCMA_CHIP_ID_BCM4749: 982*dd4544f0SRafał Miłecki case BCMA_CHIP_ID_BCM53572: 983*dd4544f0SRafał Miłecki case BCMA_CHIP_ID_BCM4716: 984*dd4544f0SRafał Miłecki case BCMA_CHIP_ID_BCM47162: 985*dd4544f0SRafał Miłecki fl_ctl = 0x03cb04cb; 986*dd4544f0SRafał Miłecki if (ci->id == BCMA_CHIP_ID_BCM5357 || 987*dd4544f0SRafał Miłecki ci->id == BCMA_CHIP_ID_BCM4749 || 988*dd4544f0SRafał Miłecki ci->id == BCMA_CHIP_ID_BCM53572) 989*dd4544f0SRafał Miłecki fl_ctl = 0x2300e1; 990*dd4544f0SRafał Miłecki bgmac_write(bgmac, BGMAC_FLOW_CTL_THRESH, fl_ctl); 991*dd4544f0SRafał Miłecki bgmac_write(bgmac, BGMAC_PAUSE_CTL, 0x27fff); 992*dd4544f0SRafał Miłecki break; 993*dd4544f0SRafał Miłecki } 994*dd4544f0SRafał Miłecki 995*dd4544f0SRafał Miłecki rxq_ctl = bgmac_read(bgmac, BGMAC_RXQ_CTL); 996*dd4544f0SRafał Miłecki rxq_ctl &= ~BGMAC_RXQ_CTL_MDP_MASK; 997*dd4544f0SRafał Miłecki bp_clk = bcma_pmu_get_bus_clock(&bgmac->core->bus->drv_cc) / 1000000; 998*dd4544f0SRafał Miłecki mdp = (bp_clk * 128 / 1000) - 3; 999*dd4544f0SRafał Miłecki rxq_ctl |= (mdp << BGMAC_RXQ_CTL_MDP_SHIFT); 1000*dd4544f0SRafał Miłecki bgmac_write(bgmac, BGMAC_RXQ_CTL, rxq_ctl); 1001*dd4544f0SRafał Miłecki } 1002*dd4544f0SRafał Miłecki 1003*dd4544f0SRafał Miłecki /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */ 1004*dd4544f0SRafał Miłecki static void bgmac_chip_init(struct bgmac *bgmac, bool full_init) 1005*dd4544f0SRafał Miłecki { 1006*dd4544f0SRafał Miłecki struct bgmac_dma_ring *ring; 1007*dd4544f0SRafał Miłecki u8 *mac = bgmac->net_dev->dev_addr; 1008*dd4544f0SRafał Miłecki u32 tmp; 1009*dd4544f0SRafał Miłecki int i; 1010*dd4544f0SRafał Miłecki 1011*dd4544f0SRafał Miłecki /* 1 interrupt per received frame */ 1012*dd4544f0SRafał Miłecki bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT); 1013*dd4544f0SRafał Miłecki 1014*dd4544f0SRafał Miłecki /* Enable 802.3x tx flow control (honor received PAUSE frames) */ 1015*dd4544f0SRafał Miłecki bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_RPI, 0, true); 1016*dd4544f0SRafał Miłecki 1017*dd4544f0SRafał Miłecki if (bgmac->net_dev->flags & IFF_PROMISC) 1018*dd4544f0SRafał Miłecki bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_PROM, false); 1019*dd4544f0SRafał Miłecki else 1020*dd4544f0SRafał Miłecki bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_PROM, 0, false); 1021*dd4544f0SRafał Miłecki 1022*dd4544f0SRafał Miłecki /* Set MAC addr */ 1023*dd4544f0SRafał Miłecki tmp = (mac[0] << 24) | (mac[1] << 16) | (mac[2] << 8) | mac[3]; 1024*dd4544f0SRafał Miłecki bgmac_write(bgmac, BGMAC_MACADDR_HIGH, tmp); 1025*dd4544f0SRafał Miłecki tmp = (mac[4] << 8) | mac[5]; 1026*dd4544f0SRafał Miłecki bgmac_write(bgmac, BGMAC_MACADDR_LOW, tmp); 1027*dd4544f0SRafał Miłecki 1028*dd4544f0SRafał Miłecki if (bgmac->loopback) 1029*dd4544f0SRafał Miłecki bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, true); 1030*dd4544f0SRafał Miłecki else 1031*dd4544f0SRafał Miłecki bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_ML, 0, true); 1032*dd4544f0SRafał Miłecki 1033*dd4544f0SRafał Miłecki bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN); 1034*dd4544f0SRafał Miłecki 1035*dd4544f0SRafał Miłecki if (!bgmac->autoneg) { 1036*dd4544f0SRafał Miłecki bgmac_speed(bgmac, bgmac->speed); 1037*dd4544f0SRafał Miłecki bgmac_phy_force(bgmac); 1038*dd4544f0SRafał Miłecki } else if (bgmac->speed) { /* if there is anything to adv */ 1039*dd4544f0SRafał Miłecki bgmac_phy_advertise(bgmac); 1040*dd4544f0SRafał Miłecki } 1041*dd4544f0SRafał Miłecki 1042*dd4544f0SRafał Miłecki if (full_init) { 1043*dd4544f0SRafał Miłecki bgmac_dma_init(bgmac); 1044*dd4544f0SRafał Miłecki if (1) /* FIXME: is there any case we don't want IRQs? */ 1045*dd4544f0SRafał Miłecki bgmac_chip_intrs_on(bgmac); 1046*dd4544f0SRafał Miłecki } else { 1047*dd4544f0SRafał Miłecki for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { 1048*dd4544f0SRafał Miłecki ring = &bgmac->rx_ring[i]; 1049*dd4544f0SRafał Miłecki bgmac_dma_rx_enable(bgmac, ring); 1050*dd4544f0SRafał Miłecki } 1051*dd4544f0SRafał Miłecki } 1052*dd4544f0SRafał Miłecki 1053*dd4544f0SRafał Miłecki bgmac_enable(bgmac); 1054*dd4544f0SRafał Miłecki } 1055*dd4544f0SRafał Miłecki 1056*dd4544f0SRafał Miłecki static irqreturn_t bgmac_interrupt(int irq, void *dev_id) 1057*dd4544f0SRafał Miłecki { 1058*dd4544f0SRafał Miłecki struct bgmac *bgmac = netdev_priv(dev_id); 1059*dd4544f0SRafał Miłecki 1060*dd4544f0SRafał Miłecki u32 int_status = bgmac_read(bgmac, BGMAC_INT_STATUS); 1061*dd4544f0SRafał Miłecki int_status &= bgmac->int_mask; 1062*dd4544f0SRafał Miłecki 1063*dd4544f0SRafał Miłecki if (!int_status) 1064*dd4544f0SRafał Miłecki return IRQ_NONE; 1065*dd4544f0SRafał Miłecki 1066*dd4544f0SRafał Miłecki /* Ack */ 1067*dd4544f0SRafał Miłecki bgmac_write(bgmac, BGMAC_INT_STATUS, int_status); 1068*dd4544f0SRafał Miłecki 1069*dd4544f0SRafał Miłecki /* Disable new interrupts until handling existing ones */ 1070*dd4544f0SRafał Miłecki bgmac_chip_intrs_off(bgmac); 1071*dd4544f0SRafał Miłecki 1072*dd4544f0SRafał Miłecki bgmac->int_status = int_status; 1073*dd4544f0SRafał Miłecki 1074*dd4544f0SRafał Miłecki napi_schedule(&bgmac->napi); 1075*dd4544f0SRafał Miłecki 1076*dd4544f0SRafał Miłecki return IRQ_HANDLED; 1077*dd4544f0SRafał Miłecki } 1078*dd4544f0SRafał Miłecki 1079*dd4544f0SRafał Miłecki static int bgmac_poll(struct napi_struct *napi, int weight) 1080*dd4544f0SRafał Miłecki { 1081*dd4544f0SRafał Miłecki struct bgmac *bgmac = container_of(napi, struct bgmac, napi); 1082*dd4544f0SRafał Miłecki struct bgmac_dma_ring *ring; 1083*dd4544f0SRafał Miłecki int handled = 0; 1084*dd4544f0SRafał Miłecki 1085*dd4544f0SRafał Miłecki if (bgmac->int_status & BGMAC_IS_TX0) { 1086*dd4544f0SRafał Miłecki ring = &bgmac->tx_ring[0]; 1087*dd4544f0SRafał Miłecki bgmac_dma_tx_free(bgmac, ring); 1088*dd4544f0SRafał Miłecki bgmac->int_status &= ~BGMAC_IS_TX0; 1089*dd4544f0SRafał Miłecki } 1090*dd4544f0SRafał Miłecki 1091*dd4544f0SRafał Miłecki if (bgmac->int_status & BGMAC_IS_RX) { 1092*dd4544f0SRafał Miłecki ring = &bgmac->rx_ring[0]; 1093*dd4544f0SRafał Miłecki handled += bgmac_dma_rx_read(bgmac, ring, weight); 1094*dd4544f0SRafał Miłecki bgmac->int_status &= ~BGMAC_IS_RX; 1095*dd4544f0SRafał Miłecki } 1096*dd4544f0SRafał Miłecki 1097*dd4544f0SRafał Miłecki if (bgmac->int_status) { 1098*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", bgmac->int_status); 1099*dd4544f0SRafał Miłecki bgmac->int_status = 0; 1100*dd4544f0SRafał Miłecki } 1101*dd4544f0SRafał Miłecki 1102*dd4544f0SRafał Miłecki if (handled < weight) 1103*dd4544f0SRafał Miłecki napi_complete(napi); 1104*dd4544f0SRafał Miłecki 1105*dd4544f0SRafał Miłecki bgmac_chip_intrs_on(bgmac); 1106*dd4544f0SRafał Miłecki 1107*dd4544f0SRafał Miłecki return handled; 1108*dd4544f0SRafał Miłecki } 1109*dd4544f0SRafał Miłecki 1110*dd4544f0SRafał Miłecki /************************************************** 1111*dd4544f0SRafał Miłecki * net_device_ops 1112*dd4544f0SRafał Miłecki **************************************************/ 1113*dd4544f0SRafał Miłecki 1114*dd4544f0SRafał Miłecki static int bgmac_open(struct net_device *net_dev) 1115*dd4544f0SRafał Miłecki { 1116*dd4544f0SRafał Miłecki struct bgmac *bgmac = netdev_priv(net_dev); 1117*dd4544f0SRafał Miłecki int err = 0; 1118*dd4544f0SRafał Miłecki 1119*dd4544f0SRafał Miłecki bgmac_chip_reset(bgmac); 1120*dd4544f0SRafał Miłecki /* Specs say about reclaiming rings here, but we do that in DMA init */ 1121*dd4544f0SRafał Miłecki bgmac_chip_init(bgmac, true); 1122*dd4544f0SRafał Miłecki 1123*dd4544f0SRafał Miłecki err = request_irq(bgmac->core->irq, bgmac_interrupt, IRQF_SHARED, 1124*dd4544f0SRafał Miłecki KBUILD_MODNAME, net_dev); 1125*dd4544f0SRafał Miłecki if (err < 0) { 1126*dd4544f0SRafał Miłecki bgmac_err(bgmac, "IRQ request error: %d!\n", err); 1127*dd4544f0SRafał Miłecki goto err_out; 1128*dd4544f0SRafał Miłecki } 1129*dd4544f0SRafał Miłecki napi_enable(&bgmac->napi); 1130*dd4544f0SRafał Miłecki 1131*dd4544f0SRafał Miłecki netif_carrier_on(net_dev); 1132*dd4544f0SRafał Miłecki 1133*dd4544f0SRafał Miłecki err_out: 1134*dd4544f0SRafał Miłecki return err; 1135*dd4544f0SRafał Miłecki } 1136*dd4544f0SRafał Miłecki 1137*dd4544f0SRafał Miłecki static int bgmac_stop(struct net_device *net_dev) 1138*dd4544f0SRafał Miłecki { 1139*dd4544f0SRafał Miłecki struct bgmac *bgmac = netdev_priv(net_dev); 1140*dd4544f0SRafał Miłecki 1141*dd4544f0SRafał Miłecki netif_carrier_off(net_dev); 1142*dd4544f0SRafał Miłecki 1143*dd4544f0SRafał Miłecki napi_disable(&bgmac->napi); 1144*dd4544f0SRafał Miłecki bgmac_chip_intrs_off(bgmac); 1145*dd4544f0SRafał Miłecki free_irq(bgmac->core->irq, net_dev); 1146*dd4544f0SRafał Miłecki 1147*dd4544f0SRafał Miłecki bgmac_chip_reset(bgmac); 1148*dd4544f0SRafał Miłecki 1149*dd4544f0SRafał Miłecki return 0; 1150*dd4544f0SRafał Miłecki } 1151*dd4544f0SRafał Miłecki 1152*dd4544f0SRafał Miłecki static netdev_tx_t bgmac_start_xmit(struct sk_buff *skb, 1153*dd4544f0SRafał Miłecki struct net_device *net_dev) 1154*dd4544f0SRafał Miłecki { 1155*dd4544f0SRafał Miłecki struct bgmac *bgmac = netdev_priv(net_dev); 1156*dd4544f0SRafał Miłecki struct bgmac_dma_ring *ring; 1157*dd4544f0SRafał Miłecki 1158*dd4544f0SRafał Miłecki /* No QOS support yet */ 1159*dd4544f0SRafał Miłecki ring = &bgmac->tx_ring[0]; 1160*dd4544f0SRafał Miłecki return bgmac_dma_tx_add(bgmac, ring, skb); 1161*dd4544f0SRafał Miłecki } 1162*dd4544f0SRafał Miłecki 1163*dd4544f0SRafał Miłecki static int bgmac_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) 1164*dd4544f0SRafał Miłecki { 1165*dd4544f0SRafał Miłecki struct bgmac *bgmac = netdev_priv(net_dev); 1166*dd4544f0SRafał Miłecki struct mii_ioctl_data *data = if_mii(ifr); 1167*dd4544f0SRafał Miłecki 1168*dd4544f0SRafał Miłecki switch (cmd) { 1169*dd4544f0SRafał Miłecki case SIOCGMIIPHY: 1170*dd4544f0SRafał Miłecki data->phy_id = bgmac->phyaddr; 1171*dd4544f0SRafał Miłecki /* fallthru */ 1172*dd4544f0SRafał Miłecki case SIOCGMIIREG: 1173*dd4544f0SRafał Miłecki if (!netif_running(net_dev)) 1174*dd4544f0SRafał Miłecki return -EAGAIN; 1175*dd4544f0SRafał Miłecki data->val_out = bgmac_phy_read(bgmac, data->phy_id, 1176*dd4544f0SRafał Miłecki data->reg_num & 0x1f); 1177*dd4544f0SRafał Miłecki return 0; 1178*dd4544f0SRafał Miłecki case SIOCSMIIREG: 1179*dd4544f0SRafał Miłecki if (!netif_running(net_dev)) 1180*dd4544f0SRafał Miłecki return -EAGAIN; 1181*dd4544f0SRafał Miłecki bgmac_phy_write(bgmac, data->phy_id, data->reg_num & 0x1f, 1182*dd4544f0SRafał Miłecki data->val_in); 1183*dd4544f0SRafał Miłecki return 0; 1184*dd4544f0SRafał Miłecki default: 1185*dd4544f0SRafał Miłecki return -EOPNOTSUPP; 1186*dd4544f0SRafał Miłecki } 1187*dd4544f0SRafał Miłecki } 1188*dd4544f0SRafał Miłecki 1189*dd4544f0SRafał Miłecki static const struct net_device_ops bgmac_netdev_ops = { 1190*dd4544f0SRafał Miłecki .ndo_open = bgmac_open, 1191*dd4544f0SRafał Miłecki .ndo_stop = bgmac_stop, 1192*dd4544f0SRafał Miłecki .ndo_start_xmit = bgmac_start_xmit, 1193*dd4544f0SRafał Miłecki .ndo_set_mac_address = eth_mac_addr, /* generic, sets dev_addr */ 1194*dd4544f0SRafał Miłecki .ndo_do_ioctl = bgmac_ioctl, 1195*dd4544f0SRafał Miłecki }; 1196*dd4544f0SRafał Miłecki 1197*dd4544f0SRafał Miłecki /************************************************** 1198*dd4544f0SRafał Miłecki * ethtool_ops 1199*dd4544f0SRafał Miłecki **************************************************/ 1200*dd4544f0SRafał Miłecki 1201*dd4544f0SRafał Miłecki static int bgmac_get_settings(struct net_device *net_dev, 1202*dd4544f0SRafał Miłecki struct ethtool_cmd *cmd) 1203*dd4544f0SRafał Miłecki { 1204*dd4544f0SRafał Miłecki struct bgmac *bgmac = netdev_priv(net_dev); 1205*dd4544f0SRafał Miłecki 1206*dd4544f0SRafał Miłecki cmd->supported = SUPPORTED_10baseT_Half | 1207*dd4544f0SRafał Miłecki SUPPORTED_10baseT_Full | 1208*dd4544f0SRafał Miłecki SUPPORTED_100baseT_Half | 1209*dd4544f0SRafał Miłecki SUPPORTED_100baseT_Full | 1210*dd4544f0SRafał Miłecki SUPPORTED_1000baseT_Half | 1211*dd4544f0SRafał Miłecki SUPPORTED_1000baseT_Full | 1212*dd4544f0SRafał Miłecki SUPPORTED_Autoneg; 1213*dd4544f0SRafał Miłecki 1214*dd4544f0SRafał Miłecki if (bgmac->autoneg) { 1215*dd4544f0SRafał Miłecki WARN_ON(cmd->advertising); 1216*dd4544f0SRafał Miłecki if (bgmac->full_duplex) { 1217*dd4544f0SRafał Miłecki if (bgmac->speed & BGMAC_SPEED_10) 1218*dd4544f0SRafał Miłecki cmd->advertising |= ADVERTISED_10baseT_Full; 1219*dd4544f0SRafał Miłecki if (bgmac->speed & BGMAC_SPEED_100) 1220*dd4544f0SRafał Miłecki cmd->advertising |= ADVERTISED_100baseT_Full; 1221*dd4544f0SRafał Miłecki if (bgmac->speed & BGMAC_SPEED_1000) 1222*dd4544f0SRafał Miłecki cmd->advertising |= ADVERTISED_1000baseT_Full; 1223*dd4544f0SRafał Miłecki } else { 1224*dd4544f0SRafał Miłecki if (bgmac->speed & BGMAC_SPEED_10) 1225*dd4544f0SRafał Miłecki cmd->advertising |= ADVERTISED_10baseT_Half; 1226*dd4544f0SRafał Miłecki if (bgmac->speed & BGMAC_SPEED_100) 1227*dd4544f0SRafał Miłecki cmd->advertising |= ADVERTISED_100baseT_Half; 1228*dd4544f0SRafał Miłecki if (bgmac->speed & BGMAC_SPEED_1000) 1229*dd4544f0SRafał Miłecki cmd->advertising |= ADVERTISED_1000baseT_Half; 1230*dd4544f0SRafał Miłecki } 1231*dd4544f0SRafał Miłecki } else { 1232*dd4544f0SRafał Miłecki switch (bgmac->speed) { 1233*dd4544f0SRafał Miłecki case BGMAC_SPEED_10: 1234*dd4544f0SRafał Miłecki ethtool_cmd_speed_set(cmd, SPEED_10); 1235*dd4544f0SRafał Miłecki break; 1236*dd4544f0SRafał Miłecki case BGMAC_SPEED_100: 1237*dd4544f0SRafał Miłecki ethtool_cmd_speed_set(cmd, SPEED_100); 1238*dd4544f0SRafał Miłecki break; 1239*dd4544f0SRafał Miłecki case BGMAC_SPEED_1000: 1240*dd4544f0SRafał Miłecki ethtool_cmd_speed_set(cmd, SPEED_1000); 1241*dd4544f0SRafał Miłecki break; 1242*dd4544f0SRafał Miłecki } 1243*dd4544f0SRafał Miłecki } 1244*dd4544f0SRafał Miłecki 1245*dd4544f0SRafał Miłecki cmd->duplex = bgmac->full_duplex ? DUPLEX_FULL : DUPLEX_HALF; 1246*dd4544f0SRafał Miłecki 1247*dd4544f0SRafał Miłecki cmd->autoneg = bgmac->autoneg; 1248*dd4544f0SRafał Miłecki 1249*dd4544f0SRafał Miłecki return 0; 1250*dd4544f0SRafał Miłecki } 1251*dd4544f0SRafał Miłecki 1252*dd4544f0SRafał Miłecki #if 0 1253*dd4544f0SRafał Miłecki static int bgmac_set_settings(struct net_device *net_dev, 1254*dd4544f0SRafał Miłecki struct ethtool_cmd *cmd) 1255*dd4544f0SRafał Miłecki { 1256*dd4544f0SRafał Miłecki struct bgmac *bgmac = netdev_priv(net_dev); 1257*dd4544f0SRafał Miłecki 1258*dd4544f0SRafał Miłecki return -1; 1259*dd4544f0SRafał Miłecki } 1260*dd4544f0SRafał Miłecki #endif 1261*dd4544f0SRafał Miłecki 1262*dd4544f0SRafał Miłecki static void bgmac_get_drvinfo(struct net_device *net_dev, 1263*dd4544f0SRafał Miłecki struct ethtool_drvinfo *info) 1264*dd4544f0SRafał Miłecki { 1265*dd4544f0SRafał Miłecki strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); 1266*dd4544f0SRafał Miłecki strlcpy(info->bus_info, "BCMA", sizeof(info->bus_info)); 1267*dd4544f0SRafał Miłecki } 1268*dd4544f0SRafał Miłecki 1269*dd4544f0SRafał Miłecki static const struct ethtool_ops bgmac_ethtool_ops = { 1270*dd4544f0SRafał Miłecki .get_settings = bgmac_get_settings, 1271*dd4544f0SRafał Miłecki .get_drvinfo = bgmac_get_drvinfo, 1272*dd4544f0SRafał Miłecki }; 1273*dd4544f0SRafał Miłecki 1274*dd4544f0SRafał Miłecki /************************************************** 1275*dd4544f0SRafał Miłecki * BCMA bus ops 1276*dd4544f0SRafał Miłecki **************************************************/ 1277*dd4544f0SRafał Miłecki 1278*dd4544f0SRafał Miłecki /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipattach */ 1279*dd4544f0SRafał Miłecki static int bgmac_probe(struct bcma_device *core) 1280*dd4544f0SRafał Miłecki { 1281*dd4544f0SRafał Miłecki struct net_device *net_dev; 1282*dd4544f0SRafał Miłecki struct bgmac *bgmac; 1283*dd4544f0SRafał Miłecki struct ssb_sprom *sprom = &core->bus->sprom; 1284*dd4544f0SRafał Miłecki u8 *mac = core->core_unit ? sprom->et1mac : sprom->et0mac; 1285*dd4544f0SRafał Miłecki int err; 1286*dd4544f0SRafał Miłecki 1287*dd4544f0SRafał Miłecki /* We don't support 2nd, 3rd, ... units, SPROM has to be adjusted */ 1288*dd4544f0SRafał Miłecki if (core->core_unit > 1) { 1289*dd4544f0SRafał Miłecki pr_err("Unsupported core_unit %d\n", core->core_unit); 1290*dd4544f0SRafał Miłecki return -ENOTSUPP; 1291*dd4544f0SRafał Miłecki } 1292*dd4544f0SRafał Miłecki 1293*dd4544f0SRafał Miłecki /* Allocation and references */ 1294*dd4544f0SRafał Miłecki net_dev = alloc_etherdev(sizeof(*bgmac)); 1295*dd4544f0SRafał Miłecki if (!net_dev) 1296*dd4544f0SRafał Miłecki return -ENOMEM; 1297*dd4544f0SRafał Miłecki net_dev->netdev_ops = &bgmac_netdev_ops; 1298*dd4544f0SRafał Miłecki net_dev->irq = core->irq; 1299*dd4544f0SRafał Miłecki SET_ETHTOOL_OPS(net_dev, &bgmac_ethtool_ops); 1300*dd4544f0SRafał Miłecki bgmac = netdev_priv(net_dev); 1301*dd4544f0SRafał Miłecki bgmac->net_dev = net_dev; 1302*dd4544f0SRafał Miłecki bgmac->core = core; 1303*dd4544f0SRafał Miłecki bcma_set_drvdata(core, bgmac); 1304*dd4544f0SRafał Miłecki 1305*dd4544f0SRafał Miłecki /* Defaults */ 1306*dd4544f0SRafał Miłecki bgmac->autoneg = true; 1307*dd4544f0SRafał Miłecki bgmac->full_duplex = true; 1308*dd4544f0SRafał Miłecki bgmac->speed = BGMAC_SPEED_10 | BGMAC_SPEED_100 | BGMAC_SPEED_1000; 1309*dd4544f0SRafał Miłecki memcpy(bgmac->net_dev->dev_addr, mac, ETH_ALEN); 1310*dd4544f0SRafał Miłecki 1311*dd4544f0SRafał Miłecki /* On BCM4706 we need common core to access PHY */ 1312*dd4544f0SRafał Miłecki if (core->id.id == BCMA_CORE_4706_MAC_GBIT && 1313*dd4544f0SRafał Miłecki !core->bus->drv_gmac_cmn.core) { 1314*dd4544f0SRafał Miłecki bgmac_err(bgmac, "GMAC CMN core not found (required for BCM4706)\n"); 1315*dd4544f0SRafał Miłecki err = -ENODEV; 1316*dd4544f0SRafał Miłecki goto err_netdev_free; 1317*dd4544f0SRafał Miłecki } 1318*dd4544f0SRafał Miłecki bgmac->cmn = core->bus->drv_gmac_cmn.core; 1319*dd4544f0SRafał Miłecki 1320*dd4544f0SRafał Miłecki bgmac->phyaddr = core->core_unit ? sprom->et1phyaddr : 1321*dd4544f0SRafał Miłecki sprom->et0phyaddr; 1322*dd4544f0SRafał Miłecki bgmac->phyaddr &= BGMAC_PHY_MASK; 1323*dd4544f0SRafał Miłecki if (bgmac->phyaddr == BGMAC_PHY_MASK) { 1324*dd4544f0SRafał Miłecki bgmac_err(bgmac, "No PHY found\n"); 1325*dd4544f0SRafał Miłecki err = -ENODEV; 1326*dd4544f0SRafał Miłecki goto err_netdev_free; 1327*dd4544f0SRafał Miłecki } 1328*dd4544f0SRafał Miłecki bgmac_info(bgmac, "Found PHY addr: %d%s\n", bgmac->phyaddr, 1329*dd4544f0SRafał Miłecki bgmac->phyaddr == BGMAC_PHY_NOREGS ? " (NOREGS)" : ""); 1330*dd4544f0SRafał Miłecki 1331*dd4544f0SRafał Miłecki if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) { 1332*dd4544f0SRafał Miłecki bgmac_err(bgmac, "PCI setup not implemented\n"); 1333*dd4544f0SRafał Miłecki err = -ENOTSUPP; 1334*dd4544f0SRafał Miłecki goto err_netdev_free; 1335*dd4544f0SRafał Miłecki } 1336*dd4544f0SRafał Miłecki 1337*dd4544f0SRafał Miłecki bgmac_chip_reset(bgmac); 1338*dd4544f0SRafał Miłecki 1339*dd4544f0SRafał Miłecki err = bgmac_dma_alloc(bgmac); 1340*dd4544f0SRafał Miłecki if (err) { 1341*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Unable to alloc memory for DMA\n"); 1342*dd4544f0SRafał Miłecki goto err_netdev_free; 1343*dd4544f0SRafał Miłecki } 1344*dd4544f0SRafał Miłecki 1345*dd4544f0SRafał Miłecki bgmac->int_mask = BGMAC_IS_ERRMASK | BGMAC_IS_RX | BGMAC_IS_TX_MASK; 1346*dd4544f0SRafał Miłecki if (nvram_getenv("et0_no_txint", NULL, 0) == 0) 1347*dd4544f0SRafał Miłecki bgmac->int_mask &= ~BGMAC_IS_TX_MASK; 1348*dd4544f0SRafał Miłecki 1349*dd4544f0SRafał Miłecki /* TODO: reset the external phy. Specs are needed */ 1350*dd4544f0SRafał Miłecki bgmac_phy_reset(bgmac); 1351*dd4544f0SRafał Miłecki 1352*dd4544f0SRafał Miłecki bgmac->has_robosw = !!(core->bus->sprom.boardflags_lo & 1353*dd4544f0SRafał Miłecki BGMAC_BFL_ENETROBO); 1354*dd4544f0SRafał Miłecki if (bgmac->has_robosw) 1355*dd4544f0SRafał Miłecki bgmac_warn(bgmac, "Support for Roboswitch not implemented\n"); 1356*dd4544f0SRafał Miłecki 1357*dd4544f0SRafał Miłecki if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM) 1358*dd4544f0SRafał Miłecki bgmac_warn(bgmac, "Support for ADMtek ethernet switch not implemented\n"); 1359*dd4544f0SRafał Miłecki 1360*dd4544f0SRafał Miłecki err = register_netdev(bgmac->net_dev); 1361*dd4544f0SRafał Miłecki if (err) { 1362*dd4544f0SRafał Miłecki bgmac_err(bgmac, "Cannot register net device\n"); 1363*dd4544f0SRafał Miłecki err = -ENOTSUPP; 1364*dd4544f0SRafał Miłecki goto err_dma_free; 1365*dd4544f0SRafał Miłecki } 1366*dd4544f0SRafał Miłecki 1367*dd4544f0SRafał Miłecki netif_carrier_off(net_dev); 1368*dd4544f0SRafał Miłecki 1369*dd4544f0SRafał Miłecki netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT); 1370*dd4544f0SRafał Miłecki 1371*dd4544f0SRafał Miłecki return 0; 1372*dd4544f0SRafał Miłecki 1373*dd4544f0SRafał Miłecki err_dma_free: 1374*dd4544f0SRafał Miłecki bgmac_dma_free(bgmac); 1375*dd4544f0SRafał Miłecki 1376*dd4544f0SRafał Miłecki err_netdev_free: 1377*dd4544f0SRafał Miłecki bcma_set_drvdata(core, NULL); 1378*dd4544f0SRafał Miłecki free_netdev(net_dev); 1379*dd4544f0SRafał Miłecki 1380*dd4544f0SRafał Miłecki return err; 1381*dd4544f0SRafał Miłecki } 1382*dd4544f0SRafał Miłecki 1383*dd4544f0SRafał Miłecki static void bgmac_remove(struct bcma_device *core) 1384*dd4544f0SRafał Miłecki { 1385*dd4544f0SRafał Miłecki struct bgmac *bgmac = bcma_get_drvdata(core); 1386*dd4544f0SRafał Miłecki 1387*dd4544f0SRafał Miłecki netif_napi_del(&bgmac->napi); 1388*dd4544f0SRafał Miłecki unregister_netdev(bgmac->net_dev); 1389*dd4544f0SRafał Miłecki bgmac_dma_free(bgmac); 1390*dd4544f0SRafał Miłecki bcma_set_drvdata(core, NULL); 1391*dd4544f0SRafał Miłecki free_netdev(bgmac->net_dev); 1392*dd4544f0SRafał Miłecki } 1393*dd4544f0SRafał Miłecki 1394*dd4544f0SRafał Miłecki static struct bcma_driver bgmac_bcma_driver = { 1395*dd4544f0SRafał Miłecki .name = KBUILD_MODNAME, 1396*dd4544f0SRafał Miłecki .id_table = bgmac_bcma_tbl, 1397*dd4544f0SRafał Miłecki .probe = bgmac_probe, 1398*dd4544f0SRafał Miłecki .remove = bgmac_remove, 1399*dd4544f0SRafał Miłecki }; 1400*dd4544f0SRafał Miłecki 1401*dd4544f0SRafał Miłecki static int __init bgmac_init(void) 1402*dd4544f0SRafał Miłecki { 1403*dd4544f0SRafał Miłecki int err; 1404*dd4544f0SRafał Miłecki 1405*dd4544f0SRafał Miłecki err = bcma_driver_register(&bgmac_bcma_driver); 1406*dd4544f0SRafał Miłecki if (err) 1407*dd4544f0SRafał Miłecki return err; 1408*dd4544f0SRafał Miłecki pr_info("Broadcom 47xx GBit MAC driver loaded\n"); 1409*dd4544f0SRafał Miłecki 1410*dd4544f0SRafał Miłecki return 0; 1411*dd4544f0SRafał Miłecki } 1412*dd4544f0SRafał Miłecki 1413*dd4544f0SRafał Miłecki static void __exit bgmac_exit(void) 1414*dd4544f0SRafał Miłecki { 1415*dd4544f0SRafał Miłecki bcma_driver_unregister(&bgmac_bcma_driver); 1416*dd4544f0SRafał Miłecki } 1417*dd4544f0SRafał Miłecki 1418*dd4544f0SRafał Miłecki module_init(bgmac_init) 1419*dd4544f0SRafał Miłecki module_exit(bgmac_exit) 1420*dd4544f0SRafał Miłecki 1421*dd4544f0SRafał Miłecki MODULE_AUTHOR("Rafał Miłecki"); 1422*dd4544f0SRafał Miłecki MODULE_LICENSE("GPL"); 1423