Lines Matching +full:save +full:- +full:mac +full:- +full:address

1 // SPDX-License-Identifier: GPL-2.0-or-later
6 * This driver is designed for the Broadcom SiByte SOC built-in
48 /* A few user-configurable values which may be modified when a driver
84 #error invalid SiByte MAC configuration
95 #error invalid SiByte MAC configuration
116 sbmac_duplex_none = -1,
142 #define SBDMA_NEXTBUF(d,f) ((((d)->f+1) == (d)->sbdma_dscrtable_end) ? \
143 (d)->sbdma_dscrtable : (d)->f+1)
174 MAC */
189 /* descriptor base address */
192 address */
222 * Linux-specific things
232 * Controller-specific things
234 void __iomem *sbm_base; /* MAC's base address */
237 void __iomem *sbm_macenable; /* MAC Enable Register */
238 void __iomem *sbm_maccfg; /* MAC Config Register */
318 static char sbmac_string[] = "sb1250-mac";
320 static char sbmac_mdio_string[] = "sb1250-mac-mdio";
340 * Synchronize with the MII - send a pattern of bits to the MII
344 * sbm_mdio - address of the MAC's MDIO register
371 * Send some bits to the MII. The bits to be sent are right-
375 * sbm_mdio - address of the MAC's MDIO register
376 * data - data to send
377 * bitcnt - number of bits to send
393 curmask = 1 << (bitcnt - 1); in sbmac_mii_senddata()
413 * bus - MDIO bus handle
414 * phyaddr - PHY's address
415 * regnum - index of register to read
423 struct sbmac_softc *sc = (struct sbmac_softc *)bus->priv; in sbmac_mii_read()
424 void __iomem *sbm_mdio = sc->sbm_mdio; in sbmac_mii_read()
505 * bus - MDIO bus handle
506 * phyaddr - PHY to use
507 * regidx - register within the PHY
508 * regval - data to write to register
517 struct sbmac_softc *sc = (struct sbmac_softc *)bus->priv; in sbmac_mii_write()
518 void __iomem *sbm_mdio = sc->sbm_mdio; in sbmac_mii_write()
543 * eight DMA channels per MAC, it's nice to do this in a standard
547 * d - struct sbmacdma (DMA channel context)
548 * s - struct sbmac_softc (pointer to a MAC)
549 * chan - channel number (0..1 right now)
550 * txrx - Identifies DMA_TX or DMA_RX for channel direction
551 * maxdescr - number of descriptors
565 * Save away interesting stuff in the structure in sbdma_initctx()
568 d->sbdma_eth = s; in sbdma_initctx()
569 d->sbdma_channel = chan; in sbdma_initctx()
570 d->sbdma_txdir = txrx; in sbdma_initctx()
574 s->sbe_idx =(s->sbm_base - A_MAC_BASE_0)/MAC_SPACING; in sbdma_initctx()
577 __raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_BYTES); in sbdma_initctx()
578 __raw_writeq(0, s->sbm_base + R_MAC_RMON_COLLISIONS); in sbdma_initctx()
579 __raw_writeq(0, s->sbm_base + R_MAC_RMON_LATE_COL); in sbdma_initctx()
580 __raw_writeq(0, s->sbm_base + R_MAC_RMON_EX_COL); in sbdma_initctx()
581 __raw_writeq(0, s->sbm_base + R_MAC_RMON_FCS_ERROR); in sbdma_initctx()
582 __raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_ABORT); in sbdma_initctx()
583 __raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_BAD); in sbdma_initctx()
584 __raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_GOOD); in sbdma_initctx()
585 __raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_RUNT); in sbdma_initctx()
586 __raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_OVERSIZE); in sbdma_initctx()
587 __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_BYTES); in sbdma_initctx()
588 __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_MCAST); in sbdma_initctx()
589 __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_BCAST); in sbdma_initctx()
590 __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_BAD); in sbdma_initctx()
591 __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_GOOD); in sbdma_initctx()
592 __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_RUNT); in sbdma_initctx()
593 __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_OVERSIZE); in sbdma_initctx()
594 __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_FCS_ERROR); in sbdma_initctx()
595 __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_LENGTH_ERROR); in sbdma_initctx()
596 __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_CODE_ERROR); in sbdma_initctx()
597 __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_ALIGN_ERROR); in sbdma_initctx()
603 d->sbdma_config0 = in sbdma_initctx()
604 s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG0); in sbdma_initctx()
605 d->sbdma_config1 = in sbdma_initctx()
606 s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG1); in sbdma_initctx()
607 d->sbdma_dscrbase = in sbdma_initctx()
608 s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_BASE); in sbdma_initctx()
609 d->sbdma_dscrcnt = in sbdma_initctx()
610 s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_CNT); in sbdma_initctx()
611 d->sbdma_curdscr = in sbdma_initctx()
612 s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CUR_DSCRADDR); in sbdma_initctx()
613 if (d->sbdma_txdir) in sbdma_initctx()
614 d->sbdma_oodpktlost = NULL; in sbdma_initctx()
616 d->sbdma_oodpktlost = in sbdma_initctx()
617 s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_OODPKTLOST_RX); in sbdma_initctx()
623 d->sbdma_maxdescr = maxdescr; in sbdma_initctx()
625 d->sbdma_dscrtable_unaligned = kcalloc(d->sbdma_maxdescr + 1, in sbdma_initctx()
626 sizeof(*d->sbdma_dscrtable), in sbdma_initctx()
631 * MAC will corrupt it. in sbdma_initctx()
633 d->sbdma_dscrtable = (struct sbdmadscr *) in sbdma_initctx()
634 ALIGN((unsigned long)d->sbdma_dscrtable_unaligned, in sbdma_initctx()
635 sizeof(*d->sbdma_dscrtable)); in sbdma_initctx()
637 d->sbdma_dscrtable_end = d->sbdma_dscrtable + d->sbdma_maxdescr; in sbdma_initctx()
639 d->sbdma_dscrtable_phys = virt_to_phys(d->sbdma_dscrtable); in sbdma_initctx()
645 d->sbdma_ctxtable = kcalloc(d->sbdma_maxdescr, in sbdma_initctx()
646 sizeof(*d->sbdma_ctxtable), GFP_KERNEL); in sbdma_initctx()
655 d->sbdma_int_pktcnt = int_pktcnt; in sbdma_initctx()
657 d->sbdma_int_pktcnt = 1; in sbdma_initctx()
662 d->sbdma_int_timeout = int_timeout; in sbdma_initctx()
664 d->sbdma_int_timeout = 0; in sbdma_initctx()
676 * d - DMA channel to init (context must be previously init'd
677 * rxtx - DMA_RX or DMA_TX depending on what type of channel
690 __raw_writeq(V_DMA_INT_TIMEOUT(d->sbdma_int_timeout) | in sbdma_channel_start()
691 0, d->sbdma_config1); in sbdma_channel_start()
693 V_DMA_RINGSZ(d->sbdma_maxdescr) | in sbdma_channel_start()
694 V_DMA_INT_PKTCNT(d->sbdma_int_pktcnt) | in sbdma_channel_start()
695 0, d->sbdma_config0); in sbdma_channel_start()
697 __raw_writeq(0, d->sbdma_config1); in sbdma_channel_start()
698 __raw_writeq(V_DMA_RINGSZ(d->sbdma_maxdescr) | in sbdma_channel_start()
699 0, d->sbdma_config0); in sbdma_channel_start()
702 __raw_writeq(d->sbdma_dscrtable_phys, d->sbdma_dscrbase); in sbdma_channel_start()
708 d->sbdma_addptr = d->sbdma_dscrtable; in sbdma_channel_start()
709 d->sbdma_remptr = d->sbdma_dscrtable; in sbdma_channel_start()
718 * d - DMA channel to init (context must be previously init'd
730 __raw_writeq(0, d->sbdma_config1); in sbdma_channel_stop()
732 __raw_writeq(0, d->sbdma_dscrbase); in sbdma_channel_stop()
734 __raw_writeq(0, d->sbdma_config0); in sbdma_channel_stop()
740 d->sbdma_addptr = NULL; in sbdma_channel_stop()
741 d->sbdma_remptr = NULL; in sbdma_channel_stop()
747 unsigned char *addr = skb->data; in sbdma_align_skb()
750 skb_reserve(skb, newaddr - addr + offset); in sbdma_align_skb()
761 * sc - softc structure
762 * d - DMA channel descriptor
763 * sb - sk_buff to add, or NULL if we should allocate one
774 struct net_device *dev = sc->sbm_dev; in sbdma_add_rcvbuffer()
782 dsc = d->sbdma_addptr; in sbdma_add_rcvbuffer()
786 * figure out if the ring is full - if the next descriptor in sbdma_add_rcvbuffer()
791 if (nextdsc == d->sbdma_remptr) { in sbdma_add_rcvbuffer()
792 return -ENOSPC; in sbdma_add_rcvbuffer()
808 * Remember, the SOCs MAC writes whole cache lines at a time, in sbdma_add_rcvbuffer()
819 return -ENOBUFS; in sbdma_add_rcvbuffer()
827 * and sb->data already points to a good place. in sbdma_add_rcvbuffer()
839 dsc->dscr_a = virt_to_phys(sb_new->data) | in sbdma_add_rcvbuffer()
842 dsc->dscr_a = virt_to_phys(sb_new->data) | in sbdma_add_rcvbuffer()
848 dsc->dscr_b = 0; in sbdma_add_rcvbuffer()
854 d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = sb_new; in sbdma_add_rcvbuffer()
860 d->sbdma_addptr = nextdsc; in sbdma_add_rcvbuffer()
866 __raw_writeq(1, d->sbdma_dscrcnt); in sbdma_add_rcvbuffer()
878 * d - DMA channel descriptor
879 * sb - sk_buff to add
897 dsc = d->sbdma_addptr; in sbdma_add_txbuffer()
901 * figure out if the ring is full - if the next descriptor in sbdma_add_txbuffer()
906 if (nextdsc == d->sbdma_remptr) { in sbdma_add_txbuffer()
907 return -ENOSPC; in sbdma_add_txbuffer()
916 length = sb->len; in sbdma_add_txbuffer()
925 phys = virt_to_phys(sb->data); in sbdma_add_txbuffer()
926 ncb = NUMCACHEBLKS(length+(phys & (SMP_CACHE_BYTES - 1))); in sbdma_add_txbuffer()
928 dsc->dscr_a = phys | in sbdma_add_txbuffer()
937 dsc->dscr_b = V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_APPENDCRC_APPENDPAD) | in sbdma_add_txbuffer()
944 d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = sb; in sbdma_add_txbuffer()
950 d->sbdma_addptr = nextdsc; in sbdma_add_txbuffer()
956 __raw_writeq(1, d->sbdma_dscrcnt); in sbdma_add_txbuffer()
970 * d - DMA channel
981 for (idx = 0; idx < d->sbdma_maxdescr; idx++) { in sbdma_emptyring()
982 sb = d->sbdma_ctxtable[idx]; in sbdma_emptyring()
985 d->sbdma_ctxtable[idx] = NULL; in sbdma_emptyring()
998 * sc - softc structure
999 * d - DMA channel
1009 for (idx = 0; idx < SBMAC_MAX_RXDESCR - 1; idx++) { in sbdma_fillring()
1019 int irq = sc->sbm_dev->irq; in sbmac_netpoll()
1021 __raw_writeq(0, sc->sbm_imr); in sbmac_netpoll()
1028 sc->sbm_imr); in sbmac_netpoll()
1031 (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), sc->sbm_imr); in sbmac_netpoll()
1042 * sc - softc structure
1043 * d - DMA channel context
1044 * work_to_do - no. of packets to process before enabling interrupt
1046 * poll - 1: using polling (for NAPI)
1055 struct net_device *dev = sc->sbm_dev; in sbdma_rx_process()
1068 dev->stats.rx_fifo_errors in sbdma_rx_process()
1069 += __raw_readq(sc->sbm_rxdma.sbdma_oodpktlost) & 0xffff; in sbdma_rx_process()
1070 __raw_writeq(0, sc->sbm_rxdma.sbdma_oodpktlost); in sbdma_rx_process()
1072 while (work_to_do-- > 0) { in sbdma_rx_process()
1078 * descriptor table was page-aligned and contiguous in in sbdma_rx_process()
1079 * both virtual and physical memory -- you could then in sbdma_rx_process()
1080 * just compare the low-order bits of the virtual address in sbdma_rx_process()
1081 * (sbdma_remptr) and the physical address (sbdma_curdscr CSR) in sbdma_rx_process()
1084 dsc = d->sbdma_remptr; in sbdma_rx_process()
1085 curidx = dsc - d->sbdma_dscrtable; in sbdma_rx_process()
1088 prefetch(&d->sbdma_ctxtable[curidx]); in sbdma_rx_process()
1090 hwidx = ((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) - in sbdma_rx_process()
1091 d->sbdma_dscrtable_phys) / in sbdma_rx_process()
1092 sizeof(*d->sbdma_dscrtable); in sbdma_rx_process()
1107 sb = d->sbdma_ctxtable[curidx]; in sbdma_rx_process()
1108 d->sbdma_ctxtable[curidx] = NULL; in sbdma_rx_process()
1110 len = (int)G_DMA_DSCRB_PKT_SIZE(dsc->dscr_b) - 4; in sbdma_rx_process()
1118 if (likely (!(dsc->dscr_a & M_DMA_ETHRX_BAD))) { in sbdma_rx_process()
1127 -ENOBUFS)) { in sbdma_rx_process()
1128 dev->stats.rx_dropped++; in sbdma_rx_process()
1129 /* Re-add old buffer */ in sbdma_rx_process()
1133 d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); in sbdma_rx_process()
1146 sb->protocol = eth_type_trans(sb,d->sbdma_eth->sbm_dev); in sbdma_rx_process()
1148 if (sc->rx_hw_checksum == ENABLE) { in sbdma_rx_process()
1149 if (!((dsc->dscr_a) & M_DMA_ETHRX_BADIP4CS) && in sbdma_rx_process()
1150 !((dsc->dscr_a) & M_DMA_ETHRX_BADTCPCS)) { in sbdma_rx_process()
1151 sb->ip_summed = CHECKSUM_UNNECESSARY; in sbdma_rx_process()
1152 /* don't need to set sb->csum */ in sbdma_rx_process()
1157 prefetch(sb->data); in sbdma_rx_process()
1158 prefetch((const void *)(((char *)sb->data)+32)); in sbdma_rx_process()
1165 dev->stats.rx_dropped++; in sbdma_rx_process()
1166 d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); in sbdma_rx_process()
1170 dev->stats.rx_bytes += len; in sbdma_rx_process()
1171 dev->stats.rx_packets++; in sbdma_rx_process()
1179 dev->stats.rx_errors++; in sbdma_rx_process()
1188 d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); in sbdma_rx_process()
1209 * sc - softc structure
1210 * d - DMA channel context
1211 * poll - 1: using polling (for NAPI)
1220 struct net_device *dev = sc->sbm_dev; in sbdma_tx_process()
1228 spin_lock_irqsave(&(sc->sbm_lock), flags); in sbdma_tx_process()
1230 if (d->sbdma_remptr == d->sbdma_addptr) in sbdma_tx_process()
1233 hwidx = ((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) - in sbdma_tx_process()
1234 d->sbdma_dscrtable_phys) / sizeof(*d->sbdma_dscrtable); in sbdma_tx_process()
1242 * descriptor table was page-aligned and contiguous in in sbdma_tx_process()
1243 * both virtual and physical memory -- you could then in sbdma_tx_process()
1244 * just compare the low-order bits of the virtual address in sbdma_tx_process()
1245 * (sbdma_remptr) and the physical address (sbdma_curdscr CSR) in sbdma_tx_process()
1248 curidx = d->sbdma_remptr - d->sbdma_dscrtable; in sbdma_tx_process()
1263 dsc = &(d->sbdma_dscrtable[curidx]); in sbdma_tx_process()
1264 sb = d->sbdma_ctxtable[curidx]; in sbdma_tx_process()
1265 d->sbdma_ctxtable[curidx] = NULL; in sbdma_tx_process()
1271 dev->stats.tx_bytes += sb->len; in sbdma_tx_process()
1272 dev->stats.tx_packets++; in sbdma_tx_process()
1284 d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); in sbdma_tx_process()
1297 netif_wake_queue(d->sbdma_eth->sbm_dev); in sbdma_tx_process()
1300 spin_unlock_irqrestore(&(sc->sbm_lock), flags); in sbdma_tx_process()
1309 * Initialize an Ethernet context structure - this is called
1310 * once per MAC on the 1250. Memory is allocated here, so don't
1315 * s - sbmac context structure
1328 s->sbm_macenable = s->sbm_base + R_MAC_ENABLE; in sbmac_initctx()
1329 s->sbm_maccfg = s->sbm_base + R_MAC_CFG; in sbmac_initctx()
1330 s->sbm_fifocfg = s->sbm_base + R_MAC_THRSH_CFG; in sbmac_initctx()
1331 s->sbm_framecfg = s->sbm_base + R_MAC_FRAMECFG; in sbmac_initctx()
1332 s->sbm_rxfilter = s->sbm_base + R_MAC_ADFILTER_CFG; in sbmac_initctx()
1333 s->sbm_isr = s->sbm_base + R_MAC_STATUS; in sbmac_initctx()
1334 s->sbm_imr = s->sbm_base + R_MAC_INT_MASK; in sbmac_initctx()
1335 s->sbm_mdio = s->sbm_base + R_MAC_MDIO; in sbmac_initctx()
1338 * Initialize the DMA channels. Right now, only one per MAC is used in sbmac_initctx()
1342 sbdma_initctx(&(s->sbm_txdma),s,0,DMA_TX,SBMAC_MAX_TXDESCR); in sbmac_initctx()
1343 sbdma_initctx(&(s->sbm_rxdma),s,0,DMA_RX,SBMAC_MAX_RXDESCR); in sbmac_initctx()
1349 s->sbm_state = sbmac_state_off; in sbmac_initctx()
1357 kfree(d->sbdma_dscrtable_unaligned); in sbdma_uninitctx()
1358 d->sbdma_dscrtable_unaligned = d->sbdma_dscrtable = NULL; in sbdma_uninitctx()
1360 kfree(d->sbdma_ctxtable); in sbdma_uninitctx()
1361 d->sbdma_ctxtable = NULL; in sbdma_uninitctx()
1367 sbdma_uninitctx(&(sc->sbm_txdma)); in sbmac_uninitctx()
1368 sbdma_uninitctx(&(sc->sbm_rxdma)); in sbmac_uninitctx()
1375 * Start packet processing on this MAC.
1378 * s - sbmac structure
1395 if (s->sbm_state == sbmac_state_on) in sbmac_channel_start()
1402 __raw_writeq(0, s->sbm_macenable); in sbmac_channel_start()
1408 __raw_writeq(0, s->sbm_rxfilter); in sbmac_channel_start()
1433 ((s->sbm_speed == sbmac_speed_1000) in sbmac_channel_start()
1446 * Clear out the hash address map in sbmac_channel_start()
1449 port = s->sbm_base + R_MAC_HASH_BASE; in sbmac_channel_start()
1456 * Clear out the exact-match table in sbmac_channel_start()
1459 port = s->sbm_base + R_MAC_ADDR_BASE; in sbmac_channel_start()
1469 port = s->sbm_base + R_MAC_CHUP0_BASE; in sbmac_channel_start()
1476 port = s->sbm_base + R_MAC_CHLO0_BASE; in sbmac_channel_start()
1483 * Program the hardware address. It goes into the hardware-address in sbmac_channel_start()
1487 reg = sbmac_addr2reg(s->sbm_hwaddr); in sbmac_channel_start()
1489 port = s->sbm_base + R_MAC_ADDR_BASE; in sbmac_channel_start()
1491 port = s->sbm_base + R_MAC_ETHERNET_ADDR; in sbmac_channel_start()
1500 __raw_writeq(0, s->sbm_rxfilter); in sbmac_channel_start()
1501 __raw_writeq(0, s->sbm_imr); in sbmac_channel_start()
1502 __raw_writeq(framecfg, s->sbm_framecfg); in sbmac_channel_start()
1503 __raw_writeq(fifo, s->sbm_fifocfg); in sbmac_channel_start()
1504 __raw_writeq(cfg, s->sbm_maccfg); in sbmac_channel_start()
1510 sbdma_channel_start(&(s->sbm_rxdma), DMA_RX); in sbmac_channel_start()
1511 sbdma_channel_start(&(s->sbm_txdma), DMA_TX); in sbmac_channel_start()
1517 sbmac_set_speed(s,s->sbm_speed); in sbmac_channel_start()
1518 sbmac_set_duplex(s,s->sbm_duplex,s->sbm_fc); in sbmac_channel_start()
1524 sbdma_fillring(s, &(s->sbm_rxdma)); in sbmac_channel_start()
1532 M_MAC_TXDMA_EN0, s->sbm_macenable); in sbmac_channel_start()
1537 M_MAC_TX_ENABLE, s->sbm_macenable); in sbmac_channel_start()
1539 #error invalid SiByte MAC configuration in sbmac_channel_start()
1544 ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), s->sbm_imr); in sbmac_channel_start()
1547 (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), s->sbm_imr); in sbmac_channel_start()
1554 __raw_writeq(M_MAC_UCAST_EN | M_MAC_BCAST_EN, s->sbm_rxfilter); in sbmac_channel_start()
1560 s->sbm_state = sbmac_state_on; in sbmac_channel_start()
1572 if (s->sbm_devflags & IFF_PROMISC) { in sbmac_channel_start()
1582 * Stop packet processing on this MAC.
1585 * s - sbmac structure
1595 if (s->sbm_state == sbmac_state_off) in sbmac_channel_stop()
1600 __raw_writeq(0, s->sbm_rxfilter); in sbmac_channel_stop()
1601 __raw_writeq(0, s->sbm_imr); in sbmac_channel_stop()
1609 __raw_writeq(0, s->sbm_macenable); in sbmac_channel_stop()
1613 s->sbm_state = sbmac_state_off; in sbmac_channel_stop()
1619 sbdma_channel_stop(&(s->sbm_rxdma)); in sbmac_channel_stop()
1620 sbdma_channel_stop(&(s->sbm_txdma)); in sbmac_channel_stop()
1624 sbdma_emptyring(&(s->sbm_rxdma)); in sbmac_channel_stop()
1625 sbdma_emptyring(&(s->sbm_txdma)); in sbmac_channel_stop()
1635 * state - new state
1643 enum sbmac_state oldstate = sc->sbm_state; in sbmac_set_channel_state()
1678 * sc - softc
1679 * onoff - 1 to turn on, 0 to turn off
1689 if (sc->sbm_state != sbmac_state_on) in sbmac_promiscuous_mode()
1693 reg = __raw_readq(sc->sbm_rxfilter); in sbmac_promiscuous_mode()
1695 __raw_writeq(reg, sc->sbm_rxfilter); in sbmac_promiscuous_mode()
1698 reg = __raw_readq(sc->sbm_rxfilter); in sbmac_promiscuous_mode()
1700 __raw_writeq(reg, sc->sbm_rxfilter); in sbmac_promiscuous_mode()
1710 * sc - softc
1721 reg = __raw_readq(sc->sbm_rxfilter); in sbmac_set_iphdr_offset()
1723 __raw_writeq(reg, sc->sbm_rxfilter); in sbmac_set_iphdr_offset()
1728 sc->rx_hw_checksum = DISABLE; in sbmac_set_iphdr_offset()
1730 sc->rx_hw_checksum = ENABLE; in sbmac_set_iphdr_offset()
1738 * Convert six bytes into the 64-bit register value that
1739 * we typically write into the SBMAC's address/mcast registers
1742 * ptr - pointer to 6 bytes
1754 reg |= (uint64_t) *(--ptr); in sbmac_addr2reg()
1756 reg |= (uint64_t) *(--ptr); in sbmac_addr2reg()
1758 reg |= (uint64_t) *(--ptr); in sbmac_addr2reg()
1760 reg |= (uint64_t) *(--ptr); in sbmac_addr2reg()
1762 reg |= (uint64_t) *(--ptr); in sbmac_addr2reg()
1764 reg |= (uint64_t) *(--ptr); in sbmac_addr2reg()
1773 * Configure LAN speed for the specified MAC.
1774 * Warning: must be called when MAC is off!
1777 * s - sbmac structure
1778 * speed - speed to set MAC to (see enum sbmac_speed)
1791 * Save new current values in sbmac_set_speed()
1794 s->sbm_speed = speed; in sbmac_set_speed()
1796 if (s->sbm_state == sbmac_state_on) in sbmac_set_speed()
1797 return 0; /* save for next restart */ in sbmac_set_speed()
1803 cfg = __raw_readq(s->sbm_maccfg); in sbmac_set_speed()
1804 framecfg = __raw_readq(s->sbm_framecfg); in sbmac_set_speed()
1851 __raw_writeq(framecfg, s->sbm_framecfg); in sbmac_set_speed()
1852 __raw_writeq(cfg, s->sbm_maccfg); in sbmac_set_speed()
1860 * Set Ethernet duplex and flow control options for this MAC
1861 * Warning: must be called when MAC is off!
1864 * s - sbmac structure
1865 * duplex - duplex setting (see enum sbmac_duplex)
1866 * fc - flow control setting (see enum sbmac_fc)
1879 * Save new current values in sbmac_set_duplex()
1882 s->sbm_duplex = duplex; in sbmac_set_duplex()
1883 s->sbm_fc = fc; in sbmac_set_duplex()
1885 if (s->sbm_state == sbmac_state_on) in sbmac_set_duplex()
1886 return 0; /* save for next restart */ in sbmac_set_duplex()
1892 cfg = __raw_readq(s->sbm_maccfg); in sbmac_set_duplex()
1946 __raw_writeq(cfg, s->sbm_maccfg); in sbmac_set_duplex()
1957 * Interrupt handler for MAC interrupts
1960 * MAC structure
1977 isr = __raw_readq(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR; in sbmac_intr()
1988 sbdma_tx_process(sc,&(sc->sbm_txdma), 0); in sbmac_intr()
1991 if (napi_schedule_prep(&sc->napi)) { in sbmac_intr()
1992 __raw_writeq(0, sc->sbm_imr); in sbmac_intr()
1993 __napi_schedule(&sc->napi); in sbmac_intr()
1998 sbdma_rx_process(sc,&(sc->sbm_rxdma), in sbmac_intr()
2024 spin_lock_irqsave(&sc->sbm_lock, flags); in sbmac_start_tx()
2031 if (sbdma_add_txbuffer(&(sc->sbm_txdma),skb)) { in sbmac_start_tx()
2032 /* XXX save skb that we could not send */ in sbmac_start_tx()
2034 spin_unlock_irqrestore(&sc->sbm_lock, flags); in sbmac_start_tx()
2039 spin_unlock_irqrestore(&sc->sbm_lock, flags); in sbmac_start_tx()
2052 * sc - softc
2064 struct net_device *dev = sc->sbm_dev; in sbmac_setmulti()
2069 * the first one, which is used for our station address in sbmac_setmulti()
2073 port = sc->sbm_base + R_MAC_ADDR_BASE+(idx*sizeof(uint64_t)); in sbmac_setmulti()
2078 port = sc->sbm_base + R_MAC_HASH_BASE+(idx*sizeof(uint64_t)); in sbmac_setmulti()
2086 reg = __raw_readq(sc->sbm_rxfilter); in sbmac_setmulti()
2088 __raw_writeq(reg, sc->sbm_rxfilter); in sbmac_setmulti()
2090 if (dev->flags & IFF_ALLMULTI) { in sbmac_setmulti()
2095 reg = __raw_readq(sc->sbm_rxfilter); in sbmac_setmulti()
2097 __raw_writeq(reg, sc->sbm_rxfilter); in sbmac_setmulti()
2111 idx = 1; /* skip station address */ in sbmac_setmulti()
2115 reg = sbmac_addr2reg(ha->addr); in sbmac_setmulti()
2116 port = sc->sbm_base + R_MAC_ADDR_BASE+(idx * sizeof(uint64_t)); in sbmac_setmulti()
2127 reg = __raw_readq(sc->sbm_rxfilter); in sbmac_setmulti()
2129 __raw_writeq(reg, sc->sbm_rxfilter); in sbmac_setmulti()
2150 * Attach routine - init hardware and hook ourselves into linux
2153 * dev - net_device structure
2162 int idx = pldev->id; in sbmac_init()
2169 sc->sbm_dev = dev; in sbmac_init()
2170 sc->sbe_idx = idx; in sbmac_init()
2172 eaddr = sc->sbm_hwaddr; in sbmac_init()
2175 * Read the ethernet address. The firmware left this programmed in sbmac_init()
2176 * for us in the ethernet address register for each mac. in sbmac_init()
2179 ea_reg = __raw_readq(sc->sbm_base + R_MAC_ETHERNET_ADDR); in sbmac_init()
2180 __raw_writeq(0, sc->sbm_base + R_MAC_ETHERNET_ADDR); in sbmac_init()
2199 spin_lock_init(&(sc->sbm_lock)); in sbmac_init()
2201 dev->netdev_ops = &sbmac_netdev_ops; in sbmac_init()
2202 dev->watchdog_timeo = TX_TIMEOUT; in sbmac_init()
2203 dev->min_mtu = 0; in sbmac_init()
2204 dev->max_mtu = ENET_PACKET_SIZE; in sbmac_init()
2206 netif_napi_add_weight(dev, &sc->napi, sbmac_poll, 16); in sbmac_init()
2208 dev->irq = UNIT_INT(idx); in sbmac_init()
2213 sc->mii_bus = mdiobus_alloc(); in sbmac_init()
2214 if (sc->mii_bus == NULL) { in sbmac_init()
2215 err = -ENOMEM; in sbmac_init()
2219 sc->mii_bus->name = sbmac_mdio_string; in sbmac_init()
2220 snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", in sbmac_init()
2221 pldev->name, idx); in sbmac_init()
2222 sc->mii_bus->priv = sc; in sbmac_init()
2223 sc->mii_bus->read = sbmac_mii_read; in sbmac_init()
2224 sc->mii_bus->write = sbmac_mii_write; in sbmac_init()
2226 sc->mii_bus->parent = &pldev->dev; in sbmac_init()
2228 * Probe PHY address in sbmac_init()
2230 err = mdiobus_register(sc->mii_bus); in sbmac_init()
2233 dev->name); in sbmac_init()
2236 platform_set_drvdata(pldev, sc->mii_bus); in sbmac_init()
2245 pr_info("%s.%d: registered as %s\n", sbmac_string, idx, dev->name); in sbmac_init()
2247 if (sc->rx_hw_checksum == ENABLE) in sbmac_init()
2248 pr_info("%s: enabling TCP rcv checksum\n", dev->name); in sbmac_init()
2251 * Display Ethernet address (this is called during the config in sbmac_init()
2255 pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %pM\n", in sbmac_init()
2256 dev->name, base, eaddr); in sbmac_init()
2260 mdiobus_unregister(sc->mii_bus); in sbmac_init()
2262 mdiobus_free(sc->mii_bus); in sbmac_init()
2275 pr_debug("%s: sbmac_open() irq %d.\n", dev->name, dev->irq); in sbmac_open()
2279 * weird is pending; we haven't initialized the mac registers in sbmac_open()
2283 __raw_readq(sc->sbm_isr); in sbmac_open()
2284 err = request_irq(dev->irq, sbmac_intr, IRQF_SHARED, dev->name, dev); in sbmac_open()
2286 printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name, in sbmac_open()
2287 dev->irq); in sbmac_open()
2291 sc->sbm_speed = sbmac_speed_none; in sbmac_open()
2292 sc->sbm_duplex = sbmac_duplex_none; in sbmac_open()
2293 sc->sbm_fc = sbmac_fc_none; in sbmac_open()
2294 sc->sbm_pause = -1; in sbmac_open()
2295 sc->sbm_link = 0; in sbmac_open()
2314 phy_start(sc->phy_dev); in sbmac_open()
2316 napi_enable(&sc->napi); in sbmac_open()
2321 free_irq(dev->irq, dev); in sbmac_open()
2331 phy_dev = phy_find_first(sc->mii_bus); in sbmac_mii_probe()
2333 printk(KERN_ERR "%s: no PHY found\n", dev->name); in sbmac_mii_probe()
2334 return -ENXIO; in sbmac_mii_probe()
2337 phy_dev = phy_connect(dev, dev_name(&phy_dev->mdio.dev), in sbmac_mii_probe()
2340 printk(KERN_ERR "%s: could not attach to PHY\n", dev->name); in sbmac_mii_probe()
2350 sc->phy_dev = phy_dev; in sbmac_mii_probe()
2359 struct phy_device *phy_dev = sc->phy_dev; in sbmac_mii_poll()
2364 link_chg = (sc->sbm_link != phy_dev->link); in sbmac_mii_poll()
2365 speed_chg = (sc->sbm_speed != phy_dev->speed); in sbmac_mii_poll()
2366 duplex_chg = (sc->sbm_duplex != phy_dev->duplex); in sbmac_mii_poll()
2367 pause_chg = (sc->sbm_pause != phy_dev->pause); in sbmac_mii_poll()
2372 if (!phy_dev->link) { in sbmac_mii_poll()
2374 sc->sbm_link = phy_dev->link; in sbmac_mii_poll()
2375 sc->sbm_speed = sbmac_speed_none; in sbmac_mii_poll()
2376 sc->sbm_duplex = sbmac_duplex_none; in sbmac_mii_poll()
2377 sc->sbm_fc = sbmac_fc_disabled; in sbmac_mii_poll()
2378 sc->sbm_pause = -1; in sbmac_mii_poll()
2379 pr_info("%s: link unavailable\n", dev->name); in sbmac_mii_poll()
2384 if (phy_dev->duplex == DUPLEX_FULL) { in sbmac_mii_poll()
2385 if (phy_dev->pause) in sbmac_mii_poll()
2391 fc_chg = (sc->sbm_fc != fc); in sbmac_mii_poll()
2393 pr_info("%s: link available: %dbase-%cD\n", dev->name, phy_dev->speed, in sbmac_mii_poll()
2394 phy_dev->duplex == DUPLEX_FULL ? 'F' : 'H'); in sbmac_mii_poll()
2396 spin_lock_irqsave(&sc->sbm_lock, flags); in sbmac_mii_poll()
2398 sc->sbm_speed = phy_dev->speed; in sbmac_mii_poll()
2399 sc->sbm_duplex = phy_dev->duplex; in sbmac_mii_poll()
2400 sc->sbm_fc = fc; in sbmac_mii_poll()
2401 sc->sbm_pause = phy_dev->pause; in sbmac_mii_poll()
2402 sc->sbm_link = phy_dev->link; in sbmac_mii_poll()
2405 sc->sbm_state != sbmac_state_off) { in sbmac_mii_poll()
2411 "because PHY state changed\n", dev->name); in sbmac_mii_poll()
2416 spin_unlock_irqrestore(&sc->sbm_lock, flags); in sbmac_mii_poll()
2425 spin_lock_irqsave(&sc->sbm_lock, flags); in sbmac_tx_timeout()
2429 dev->stats.tx_errors++; in sbmac_tx_timeout()
2431 spin_unlock_irqrestore(&sc->sbm_lock, flags); in sbmac_tx_timeout()
2433 printk (KERN_WARNING "%s: Transmit timed out\n",dev->name); in sbmac_tx_timeout()
2444 spin_lock_irqsave(&sc->sbm_lock, flags); in sbmac_set_rx_mode()
2445 if ((dev->flags ^ sc->sbm_devflags) & IFF_PROMISC) { in sbmac_set_rx_mode()
2450 if (dev->flags & IFF_PROMISC) { in sbmac_set_rx_mode()
2457 spin_unlock_irqrestore(&sc->sbm_lock, flags); in sbmac_set_rx_mode()
2471 if (!netif_running(dev) || !sc->phy_dev) in sbmac_mii_ioctl()
2472 return -EINVAL; in sbmac_mii_ioctl()
2474 return phy_mii_ioctl(sc->phy_dev, rq, cmd); in sbmac_mii_ioctl()
2481 napi_disable(&sc->napi); in sbmac_close()
2483 phy_stop(sc->phy_dev); in sbmac_close()
2490 pr_debug("%s: Shutting down ethercard\n", dev->name); in sbmac_close()
2492 phy_disconnect(sc->phy_dev); in sbmac_close()
2493 sc->phy_dev = NULL; in sbmac_close()
2494 free_irq(dev->irq, dev); in sbmac_close()
2496 sbdma_emptyring(&(sc->sbm_txdma)); in sbmac_close()
2497 sbdma_emptyring(&(sc->sbm_rxdma)); in sbmac_close()
2507 work_done = sbdma_rx_process(sc, &(sc->sbm_rxdma), budget, 1); in sbmac_poll()
2508 sbdma_tx_process(sc, &(sc->sbm_txdma), 1); in sbmac_poll()
2516 sc->sbm_imr); in sbmac_poll()
2519 (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), sc->sbm_imr); in sbmac_poll()
2539 dev_name(&pldev->dev)); in sbmac_probe()
2540 err = -EINVAL; in sbmac_probe()
2543 sbm_base = ioremap(res->start, resource_size(res)); in sbmac_probe()
2546 dev_name(&pldev->dev)); in sbmac_probe()
2547 err = -ENOMEM; in sbmac_probe()
2553 * value for us by the firmware if we're going to use this MAC. in sbmac_probe()
2554 * If we find a zero, skip this MAC. in sbmac_probe()
2557 pr_debug("%s: %sconfiguring MAC at 0x%08Lx\n", dev_name(&pldev->dev), in sbmac_probe()
2558 sbmac_orig_hwaddr ? "" : "not ", (long long)res->start); in sbmac_probe()
2565 * Okay, cool. Initialize this MAC. in sbmac_probe()
2569 err = -ENOMEM; in sbmac_probe()
2574 SET_NETDEV_DEV(dev, &pldev->dev); in sbmac_probe()
2577 sc->sbm_base = sbm_base; in sbmac_probe()
2579 err = sbmac_init(pldev, res->start); in sbmac_probe()
2603 mdiobus_unregister(sc->mii_bus); in sbmac_remove()
2604 mdiobus_free(sc->mii_bus); in sbmac_remove()
2605 iounmap(sc->sbm_base); in sbmac_remove()