Lines Matching refs:cp

161 #define CAS_MAX_MTU                     min(((cp->page_size << 1) - 0x50), 9000)
230 static void cas_set_link_modes(struct cas *cp);
232 static inline void cas_lock_tx(struct cas *cp) in cas_lock_tx() argument
237 spin_lock_nested(&cp->tx_lock[i], i); in cas_lock_tx()
240 static inline void cas_lock_all(struct cas *cp) in cas_lock_all() argument
242 spin_lock_irq(&cp->lock); in cas_lock_all()
243 cas_lock_tx(cp); in cas_lock_all()
254 #define cas_lock_all_save(cp, flags) \ argument
256 struct cas *xxxcp = (cp); \
261 static inline void cas_unlock_tx(struct cas *cp) in cas_unlock_tx() argument
266 spin_unlock(&cp->tx_lock[i - 1]); in cas_unlock_tx()
269 static inline void cas_unlock_all(struct cas *cp) in cas_unlock_all() argument
271 cas_unlock_tx(cp); in cas_unlock_all()
272 spin_unlock_irq(&cp->lock); in cas_unlock_all()
275 #define cas_unlock_all_restore(cp, flags) \ argument
277 struct cas *xxxcp = (cp); \
282 static void cas_disable_irq(struct cas *cp, const int ring) in cas_disable_irq() argument
286 writel(0xFFFFFFFF, cp->regs + REG_INTR_MASK); in cas_disable_irq()
291 if (cp->cas_flags & CAS_FLAG_REG_PLUS) { in cas_disable_irq()
304 cp->regs + REG_PLUS_INTRN_MASK(ring)); in cas_disable_irq()
308 writel(INTRN_MASK_CLEAR_ALL, cp->regs + in cas_disable_irq()
315 static inline void cas_mask_intr(struct cas *cp) in cas_mask_intr() argument
320 cas_disable_irq(cp, i); in cas_mask_intr()
323 static void cas_enable_irq(struct cas *cp, const int ring) in cas_enable_irq() argument
326 writel(INTR_TX_DONE, cp->regs + REG_INTR_MASK); in cas_enable_irq()
330 if (cp->cas_flags & CAS_FLAG_REG_PLUS) { in cas_enable_irq()
342 writel(INTRN_MASK_RX_EN, cp->regs + in cas_enable_irq()
352 static inline void cas_unmask_intr(struct cas *cp) in cas_unmask_intr() argument
357 cas_enable_irq(cp, i); in cas_unmask_intr()
360 static inline void cas_entropy_gather(struct cas *cp) in cas_entropy_gather() argument
363 if ((cp->cas_flags & CAS_FLAG_ENTROPY_DEV) == 0) in cas_entropy_gather()
366 batch_entropy_store(readl(cp->regs + REG_ENTROPY_IV), in cas_entropy_gather()
367 readl(cp->regs + REG_ENTROPY_IV), in cas_entropy_gather()
372 static inline void cas_entropy_reset(struct cas *cp) in cas_entropy_reset() argument
375 if ((cp->cas_flags & CAS_FLAG_ENTROPY_DEV) == 0) in cas_entropy_reset()
379 cp->regs + REG_BIM_LOCAL_DEV_EN); in cas_entropy_reset()
380 writeb(ENTROPY_RESET_STC_MODE, cp->regs + REG_ENTROPY_RESET); in cas_entropy_reset()
381 writeb(0x55, cp->regs + REG_ENTROPY_RAND_REG); in cas_entropy_reset()
384 if (readb(cp->regs + REG_ENTROPY_RAND_REG) == 0) in cas_entropy_reset()
385 cp->cas_flags &= ~CAS_FLAG_ENTROPY_DEV; in cas_entropy_reset()
392 static u16 cas_phy_read(struct cas *cp, int reg) in cas_phy_read() argument
398 cmd |= CAS_BASE(MIF_FRAME_PHY_ADDR, cp->phy_addr); in cas_phy_read()
401 writel(cmd, cp->regs + REG_MIF_FRAME); in cas_phy_read()
406 cmd = readl(cp->regs + REG_MIF_FRAME); in cas_phy_read()
413 static int cas_phy_write(struct cas *cp, int reg, u16 val) in cas_phy_write() argument
419 cmd |= CAS_BASE(MIF_FRAME_PHY_ADDR, cp->phy_addr); in cas_phy_write()
423 writel(cmd, cp->regs + REG_MIF_FRAME); in cas_phy_write()
428 cmd = readl(cp->regs + REG_MIF_FRAME); in cas_phy_write()
435 static void cas_phy_powerup(struct cas *cp) in cas_phy_powerup() argument
437 u16 ctl = cas_phy_read(cp, MII_BMCR); in cas_phy_powerup()
442 cas_phy_write(cp, MII_BMCR, ctl); in cas_phy_powerup()
445 static void cas_phy_powerdown(struct cas *cp) in cas_phy_powerdown() argument
447 u16 ctl = cas_phy_read(cp, MII_BMCR); in cas_phy_powerdown()
452 cas_phy_write(cp, MII_BMCR, ctl); in cas_phy_powerdown()
456 static int cas_page_free(struct cas *cp, cas_page_t *page) in cas_page_free() argument
458 pci_unmap_page(cp->pdev, page->dma_addr, cp->page_size, in cas_page_free()
460 __free_pages(page->buffer, cp->page_order); in cas_page_free()
476 static cas_page_t *cas_page_alloc(struct cas *cp, const gfp_t flags) in cas_page_alloc() argument
486 page->buffer = alloc_pages(flags, cp->page_order); in cas_page_alloc()
489 page->dma_addr = pci_map_page(cp->pdev, page->buffer, 0, in cas_page_alloc()
490 cp->page_size, PCI_DMA_FROMDEVICE); in cas_page_alloc()
499 static void cas_spare_init(struct cas *cp) in cas_spare_init() argument
501 spin_lock(&cp->rx_inuse_lock); in cas_spare_init()
502 INIT_LIST_HEAD(&cp->rx_inuse_list); in cas_spare_init()
503 spin_unlock(&cp->rx_inuse_lock); in cas_spare_init()
505 spin_lock(&cp->rx_spare_lock); in cas_spare_init()
506 INIT_LIST_HEAD(&cp->rx_spare_list); in cas_spare_init()
507 cp->rx_spares_needed = RX_SPARE_COUNT; in cas_spare_init()
508 spin_unlock(&cp->rx_spare_lock); in cas_spare_init()
512 static void cas_spare_free(struct cas *cp) in cas_spare_free() argument
518 spin_lock(&cp->rx_spare_lock); in cas_spare_free()
519 list_splice_init(&cp->rx_spare_list, &list); in cas_spare_free()
520 spin_unlock(&cp->rx_spare_lock); in cas_spare_free()
522 cas_page_free(cp, list_entry(elem, cas_page_t, list)); in cas_spare_free()
531 spin_lock(&cp->rx_inuse_lock); in cas_spare_free()
532 list_splice_init(&cp->rx_inuse_list, &list); in cas_spare_free()
533 spin_unlock(&cp->rx_inuse_lock); in cas_spare_free()
535 spin_lock(&cp->rx_spare_lock); in cas_spare_free()
536 list_splice_init(&cp->rx_inuse_list, &list); in cas_spare_free()
537 spin_unlock(&cp->rx_spare_lock); in cas_spare_free()
540 cas_page_free(cp, list_entry(elem, cas_page_t, list)); in cas_spare_free()
545 static void cas_spare_recover(struct cas *cp, const gfp_t flags) in cas_spare_recover() argument
556 spin_lock(&cp->rx_inuse_lock); in cas_spare_recover()
557 list_splice_init(&cp->rx_inuse_list, &list); in cas_spare_recover()
558 spin_unlock(&cp->rx_inuse_lock); in cas_spare_recover()
579 spin_lock(&cp->rx_spare_lock); in cas_spare_recover()
580 if (cp->rx_spares_needed > 0) { in cas_spare_recover()
581 list_add(elem, &cp->rx_spare_list); in cas_spare_recover()
582 cp->rx_spares_needed--; in cas_spare_recover()
583 spin_unlock(&cp->rx_spare_lock); in cas_spare_recover()
585 spin_unlock(&cp->rx_spare_lock); in cas_spare_recover()
586 cas_page_free(cp, page); in cas_spare_recover()
592 spin_lock(&cp->rx_inuse_lock); in cas_spare_recover()
593 list_splice(&list, &cp->rx_inuse_list); in cas_spare_recover()
594 spin_unlock(&cp->rx_inuse_lock); in cas_spare_recover()
597 spin_lock(&cp->rx_spare_lock); in cas_spare_recover()
598 needed = cp->rx_spares_needed; in cas_spare_recover()
599 spin_unlock(&cp->rx_spare_lock); in cas_spare_recover()
607 cas_page_t *spare = cas_page_alloc(cp, flags); in cas_spare_recover()
614 spin_lock(&cp->rx_spare_lock); in cas_spare_recover()
615 list_splice(&list, &cp->rx_spare_list); in cas_spare_recover()
616 cp->rx_spares_needed -= i; in cas_spare_recover()
617 spin_unlock(&cp->rx_spare_lock); in cas_spare_recover()
621 static cas_page_t *cas_page_dequeue(struct cas *cp) in cas_page_dequeue() argument
626 spin_lock(&cp->rx_spare_lock); in cas_page_dequeue()
627 if (list_empty(&cp->rx_spare_list)) { in cas_page_dequeue()
629 spin_unlock(&cp->rx_spare_lock); in cas_page_dequeue()
630 cas_spare_recover(cp, GFP_ATOMIC); in cas_page_dequeue()
631 spin_lock(&cp->rx_spare_lock); in cas_page_dequeue()
632 if (list_empty(&cp->rx_spare_list)) { in cas_page_dequeue()
633 netif_err(cp, rx_err, cp->dev, in cas_page_dequeue()
635 spin_unlock(&cp->rx_spare_lock); in cas_page_dequeue()
640 entry = cp->rx_spare_list.next; in cas_page_dequeue()
642 recover = ++cp->rx_spares_needed; in cas_page_dequeue()
643 spin_unlock(&cp->rx_spare_lock); in cas_page_dequeue()
648 atomic_inc(&cp->reset_task_pending); in cas_page_dequeue()
649 atomic_inc(&cp->reset_task_pending_spare); in cas_page_dequeue()
650 schedule_work(&cp->reset_task); in cas_page_dequeue()
652 atomic_set(&cp->reset_task_pending, CAS_RESET_SPARE); in cas_page_dequeue()
653 schedule_work(&cp->reset_task); in cas_page_dequeue()
660 static void cas_mif_poll(struct cas *cp, const int enable) in cas_mif_poll() argument
664 cfg = readl(cp->regs + REG_MIF_CFG); in cas_mif_poll()
667 if (cp->phy_type & CAS_PHY_MII_MDIO1) in cas_mif_poll()
674 cfg |= CAS_BASE(MIF_CFG_POLL_PHY, cp->phy_addr); in cas_mif_poll()
677 cp->regs + REG_MIF_MASK); in cas_mif_poll()
678 writel(cfg, cp->regs + REG_MIF_CFG); in cas_mif_poll()
682 static void cas_begin_auto_negotiation(struct cas *cp, in cas_begin_auto_negotiation() argument
689 int oldstate = cp->lstate; in cas_begin_auto_negotiation()
695 lcntl = cp->link_cntl; in cas_begin_auto_negotiation()
697 cp->link_cntl = BMCR_ANENABLE; in cas_begin_auto_negotiation()
700 cp->link_cntl = 0; in cas_begin_auto_negotiation()
702 cp->link_cntl |= BMCR_SPEED100; in cas_begin_auto_negotiation()
704 cp->link_cntl |= CAS_BMCR_SPEED1000; in cas_begin_auto_negotiation()
706 cp->link_cntl |= BMCR_FULLDPLX; in cas_begin_auto_negotiation()
709 changed = (lcntl != cp->link_cntl); in cas_begin_auto_negotiation()
712 if (cp->lstate == link_up) { in cas_begin_auto_negotiation()
713 netdev_info(cp->dev, "PCS link down\n"); in cas_begin_auto_negotiation()
716 netdev_info(cp->dev, "link configuration changed\n"); in cas_begin_auto_negotiation()
719 cp->lstate = link_down; in cas_begin_auto_negotiation()
720 cp->link_transition = LINK_TRANSITION_LINK_DOWN; in cas_begin_auto_negotiation()
721 if (!cp->hw_running) in cas_begin_auto_negotiation()
730 netif_carrier_off(cp->dev); in cas_begin_auto_negotiation()
737 atomic_inc(&cp->reset_task_pending); in cas_begin_auto_negotiation()
738 atomic_inc(&cp->reset_task_pending_all); in cas_begin_auto_negotiation()
739 schedule_work(&cp->reset_task); in cas_begin_auto_negotiation()
740 cp->timer_ticks = 0; in cas_begin_auto_negotiation()
741 mod_timer(&cp->link_timer, jiffies + CAS_LINK_TIMEOUT); in cas_begin_auto_negotiation()
745 if (cp->phy_type & CAS_PHY_SERDES) { in cas_begin_auto_negotiation()
746 u32 val = readl(cp->regs + REG_PCS_MII_CTRL); in cas_begin_auto_negotiation()
748 if (cp->link_cntl & BMCR_ANENABLE) { in cas_begin_auto_negotiation()
750 cp->lstate = link_aneg; in cas_begin_auto_negotiation()
752 if (cp->link_cntl & BMCR_FULLDPLX) in cas_begin_auto_negotiation()
755 cp->lstate = link_force_ok; in cas_begin_auto_negotiation()
757 cp->link_transition = LINK_TRANSITION_LINK_CONFIG; in cas_begin_auto_negotiation()
758 writel(val, cp->regs + REG_PCS_MII_CTRL); in cas_begin_auto_negotiation()
761 cas_mif_poll(cp, 0); in cas_begin_auto_negotiation()
762 ctl = cas_phy_read(cp, MII_BMCR); in cas_begin_auto_negotiation()
765 ctl |= cp->link_cntl; in cas_begin_auto_negotiation()
768 cp->lstate = link_aneg; in cas_begin_auto_negotiation()
770 cp->lstate = link_force_ok; in cas_begin_auto_negotiation()
772 cp->link_transition = LINK_TRANSITION_LINK_CONFIG; in cas_begin_auto_negotiation()
773 cas_phy_write(cp, MII_BMCR, ctl); in cas_begin_auto_negotiation()
774 cas_mif_poll(cp, 1); in cas_begin_auto_negotiation()
777 cp->timer_ticks = 0; in cas_begin_auto_negotiation()
778 mod_timer(&cp->link_timer, jiffies + CAS_LINK_TIMEOUT); in cas_begin_auto_negotiation()
782 static int cas_reset_mii_phy(struct cas *cp) in cas_reset_mii_phy() argument
787 cas_phy_write(cp, MII_BMCR, BMCR_RESET); in cas_reset_mii_phy()
790 val = cas_phy_read(cp, MII_BMCR); in cas_reset_mii_phy()
798 static void cas_saturn_firmware_init(struct cas *cp) in cas_saturn_firmware_init() argument
804 if (PHY_NS_DP83065 != cp->phy_id) in cas_saturn_firmware_init()
807 err = request_firmware(&fw, fw_name, &cp->pdev->dev); in cas_saturn_firmware_init()
818 cp->fw_load_addr= fw->data[1] << 8 | fw->data[0]; in cas_saturn_firmware_init()
819 cp->fw_size = fw->size - 2; in cas_saturn_firmware_init()
820 cp->fw_data = vmalloc(cp->fw_size); in cas_saturn_firmware_init()
821 if (!cp->fw_data) in cas_saturn_firmware_init()
823 memcpy(cp->fw_data, &fw->data[2], cp->fw_size); in cas_saturn_firmware_init()
828 static void cas_saturn_firmware_load(struct cas *cp) in cas_saturn_firmware_load() argument
832 if (!cp->fw_data) in cas_saturn_firmware_load()
835 cas_phy_powerdown(cp); in cas_saturn_firmware_load()
838 cas_phy_write(cp, DP83065_MII_MEM, 0x0); in cas_saturn_firmware_load()
841 cas_phy_write(cp, DP83065_MII_REGE, 0x8ff9); in cas_saturn_firmware_load()
842 cas_phy_write(cp, DP83065_MII_REGD, 0xbd); in cas_saturn_firmware_load()
843 cas_phy_write(cp, DP83065_MII_REGE, 0x8ffa); in cas_saturn_firmware_load()
844 cas_phy_write(cp, DP83065_MII_REGD, 0x82); in cas_saturn_firmware_load()
845 cas_phy_write(cp, DP83065_MII_REGE, 0x8ffb); in cas_saturn_firmware_load()
846 cas_phy_write(cp, DP83065_MII_REGD, 0x0); in cas_saturn_firmware_load()
847 cas_phy_write(cp, DP83065_MII_REGE, 0x8ffc); in cas_saturn_firmware_load()
848 cas_phy_write(cp, DP83065_MII_REGD, 0x39); in cas_saturn_firmware_load()
851 cas_phy_write(cp, DP83065_MII_MEM, 0x1); in cas_saturn_firmware_load()
852 cas_phy_write(cp, DP83065_MII_REGE, cp->fw_load_addr); in cas_saturn_firmware_load()
853 for (i = 0; i < cp->fw_size; i++) in cas_saturn_firmware_load()
854 cas_phy_write(cp, DP83065_MII_REGD, cp->fw_data[i]); in cas_saturn_firmware_load()
857 cas_phy_write(cp, DP83065_MII_REGE, 0x8ff8); in cas_saturn_firmware_load()
858 cas_phy_write(cp, DP83065_MII_REGD, 0x1); in cas_saturn_firmware_load()
863 static void cas_phy_init(struct cas *cp) in cas_phy_init() argument
868 if (CAS_PHY_MII(cp->phy_type)) { in cas_phy_init()
870 cp->regs + REG_PCS_DATAPATH_MODE); in cas_phy_init()
872 cas_mif_poll(cp, 0); in cas_phy_init()
873 cas_reset_mii_phy(cp); /* take out of isolate mode */ in cas_phy_init()
875 if (PHY_LUCENT_B0 == cp->phy_id) { in cas_phy_init()
877 cas_phy_write(cp, LUCENT_MII_REG, 0x8000); in cas_phy_init()
878 cas_phy_write(cp, MII_BMCR, 0x00f1); in cas_phy_init()
879 cas_phy_write(cp, LUCENT_MII_REG, 0x0); in cas_phy_init()
881 } else if (PHY_BROADCOM_B0 == (cp->phy_id & 0xFFFFFFFC)) { in cas_phy_init()
883 cas_phy_write(cp, BROADCOM_MII_REG8, 0x0C20); in cas_phy_init()
884 cas_phy_write(cp, BROADCOM_MII_REG7, 0x0012); in cas_phy_init()
885 cas_phy_write(cp, BROADCOM_MII_REG5, 0x1804); in cas_phy_init()
886 cas_phy_write(cp, BROADCOM_MII_REG7, 0x0013); in cas_phy_init()
887 cas_phy_write(cp, BROADCOM_MII_REG5, 0x1204); in cas_phy_init()
888 cas_phy_write(cp, BROADCOM_MII_REG7, 0x8006); in cas_phy_init()
889 cas_phy_write(cp, BROADCOM_MII_REG5, 0x0132); in cas_phy_init()
890 cas_phy_write(cp, BROADCOM_MII_REG7, 0x8006); in cas_phy_init()
891 cas_phy_write(cp, BROADCOM_MII_REG5, 0x0232); in cas_phy_init()
892 cas_phy_write(cp, BROADCOM_MII_REG7, 0x201F); in cas_phy_init()
893 cas_phy_write(cp, BROADCOM_MII_REG5, 0x0A20); in cas_phy_init()
895 } else if (PHY_BROADCOM_5411 == cp->phy_id) { in cas_phy_init()
896 val = cas_phy_read(cp, BROADCOM_MII_REG4); in cas_phy_init()
897 val = cas_phy_read(cp, BROADCOM_MII_REG4); in cas_phy_init()
900 cas_phy_write(cp, BROADCOM_MII_REG4, in cas_phy_init()
904 } else if (cp->cas_flags & CAS_FLAG_SATURN) { in cas_phy_init()
905 writel((cp->phy_type & CAS_PHY_MII_MDIO0) ? in cas_phy_init()
907 cp->regs + REG_SATURN_PCFG); in cas_phy_init()
913 if (PHY_NS_DP83065 == cp->phy_id) { in cas_phy_init()
914 cas_saturn_firmware_load(cp); in cas_phy_init()
916 cas_phy_powerup(cp); in cas_phy_init()
920 val = cas_phy_read(cp, MII_BMCR); in cas_phy_init()
922 cas_phy_write(cp, MII_BMCR, val); in cas_phy_init()
925 cas_phy_write(cp, MII_ADVERTISE, in cas_phy_init()
926 cas_phy_read(cp, MII_ADVERTISE) | in cas_phy_init()
932 if (cp->cas_flags & CAS_FLAG_1000MB_CAP) { in cas_phy_init()
936 val = cas_phy_read(cp, CAS_MII_1000_CTRL); in cas_phy_init()
939 cas_phy_write(cp, CAS_MII_1000_CTRL, val); in cas_phy_init()
948 cp->regs + REG_PCS_DATAPATH_MODE); in cas_phy_init()
951 if (cp->cas_flags & CAS_FLAG_SATURN) in cas_phy_init()
952 writel(0, cp->regs + REG_SATURN_PCFG); in cas_phy_init()
955 val = readl(cp->regs + REG_PCS_MII_CTRL); in cas_phy_init()
957 writel(val, cp->regs + REG_PCS_MII_CTRL); in cas_phy_init()
962 if ((readl(cp->regs + REG_PCS_MII_CTRL) & in cas_phy_init()
967 netdev_warn(cp->dev, "PCS reset bit would not clear [%08x]\n", in cas_phy_init()
968 readl(cp->regs + REG_PCS_STATE_MACHINE)); in cas_phy_init()
973 writel(0x0, cp->regs + REG_PCS_CFG); in cas_phy_init()
976 val = readl(cp->regs + REG_PCS_MII_ADVERT); in cas_phy_init()
980 writel(val, cp->regs + REG_PCS_MII_ADVERT); in cas_phy_init()
983 writel(PCS_CFG_EN, cp->regs + REG_PCS_CFG); in cas_phy_init()
987 cp->regs + REG_PCS_SERDES_CTRL); in cas_phy_init()
992 static int cas_pcs_link_check(struct cas *cp) in cas_pcs_link_check() argument
1001 stat = readl(cp->regs + REG_PCS_MII_STATUS); in cas_pcs_link_check()
1003 stat = readl(cp->regs + REG_PCS_MII_STATUS); in cas_pcs_link_check()
1011 netif_info(cp, link, cp->dev, "PCS RemoteFault\n"); in cas_pcs_link_check()
1016 state_machine = readl(cp->regs + REG_PCS_STATE_MACHINE); in cas_pcs_link_check()
1024 if (cp->lstate != link_up) { in cas_pcs_link_check()
1025 if (cp->opened) { in cas_pcs_link_check()
1026 cp->lstate = link_up; in cas_pcs_link_check()
1027 cp->link_transition = LINK_TRANSITION_LINK_UP; in cas_pcs_link_check()
1029 cas_set_link_modes(cp); in cas_pcs_link_check()
1030 netif_carrier_on(cp->dev); in cas_pcs_link_check()
1033 } else if (cp->lstate == link_up) { in cas_pcs_link_check()
1034 cp->lstate = link_down; in cas_pcs_link_check()
1036 cp->link_transition != LINK_TRANSITION_REQUESTED_RESET && in cas_pcs_link_check()
1037 !cp->link_transition_jiffies_valid) { in cas_pcs_link_check()
1051 cp->link_transition = LINK_TRANSITION_REQUESTED_RESET; in cas_pcs_link_check()
1052 cp->link_transition_jiffies = jiffies; in cas_pcs_link_check()
1053 cp->link_transition_jiffies_valid = 1; in cas_pcs_link_check()
1055 cp->link_transition = LINK_TRANSITION_ON_FAILURE; in cas_pcs_link_check()
1057 netif_carrier_off(cp->dev); in cas_pcs_link_check()
1058 if (cp->opened) in cas_pcs_link_check()
1059 netif_info(cp, link, cp->dev, "PCS link down\n"); in cas_pcs_link_check()
1069 if ((cp->cas_flags & CAS_FLAG_REG_PLUS) == 0) { in cas_pcs_link_check()
1071 stat = readl(cp->regs + REG_PCS_SERDES_STATE); in cas_pcs_link_check()
1075 } else if (cp->lstate == link_down) { in cas_pcs_link_check()
1077 cp->link_transition != LINK_TRANSITION_REQUESTED_RESET && in cas_pcs_link_check()
1078 !cp->link_transition_jiffies_valid) { in cas_pcs_link_check()
1085 cp->link_transition = LINK_TRANSITION_REQUESTED_RESET; in cas_pcs_link_check()
1086 cp->link_transition_jiffies = jiffies; in cas_pcs_link_check()
1087 cp->link_transition_jiffies_valid = 1; in cas_pcs_link_check()
1089 cp->link_transition = LINK_TRANSITION_STILL_FAILED; in cas_pcs_link_check()
1097 struct cas *cp, u32 status) in cas_pcs_interrupt() argument
1099 u32 stat = readl(cp->regs + REG_PCS_INTR_STATUS); in cas_pcs_interrupt()
1103 return cas_pcs_link_check(cp); in cas_pcs_interrupt()
1107 struct cas *cp, u32 status) in cas_txmac_interrupt() argument
1109 u32 txmac_stat = readl(cp->regs + REG_MAC_TX_STATUS); in cas_txmac_interrupt()
1114 netif_printk(cp, intr, KERN_DEBUG, cp->dev, in cas_txmac_interrupt()
1124 spin_lock(&cp->stat_lock[0]); in cas_txmac_interrupt()
1127 cp->net_stats[0].tx_fifo_errors++; in cas_txmac_interrupt()
1132 cp->net_stats[0].tx_errors++; in cas_txmac_interrupt()
1139 cp->net_stats[0].collisions += 0x10000; in cas_txmac_interrupt()
1142 cp->net_stats[0].tx_aborted_errors += 0x10000; in cas_txmac_interrupt()
1143 cp->net_stats[0].collisions += 0x10000; in cas_txmac_interrupt()
1147 cp->net_stats[0].tx_aborted_errors += 0x10000; in cas_txmac_interrupt()
1148 cp->net_stats[0].collisions += 0x10000; in cas_txmac_interrupt()
1150 spin_unlock(&cp->stat_lock[0]); in cas_txmac_interrupt()
1158 static void cas_load_firmware(struct cas *cp, cas_hp_inst_t *firmware) in cas_load_firmware() argument
1166 writel(i, cp->regs + REG_HP_INSTR_RAM_ADDR); in cas_load_firmware()
1170 writel(val, cp->regs + REG_HP_INSTR_RAM_DATA_HI); in cas_load_firmware()
1179 writel(val, cp->regs + REG_HP_INSTR_RAM_DATA_MID); in cas_load_firmware()
1185 writel(val, cp->regs + REG_HP_INSTR_RAM_DATA_LOW); in cas_load_firmware()
1191 static void cas_init_rx_dma(struct cas *cp) in cas_init_rx_dma() argument
1193 u64 desc_dma = cp->block_dvma; in cas_init_rx_dma()
1202 (cp->cas_flags & CAS_FLAG_REG_PLUS)) /* do desc 2 */ in cas_init_rx_dma()
1204 writel(val, cp->regs + REG_RX_CFG); in cas_init_rx_dma()
1206 val = (unsigned long) cp->init_rxds[0] - in cas_init_rx_dma()
1207 (unsigned long) cp->init_block; in cas_init_rx_dma()
1208 writel((desc_dma + val) >> 32, cp->regs + REG_RX_DB_HI); in cas_init_rx_dma()
1209 writel((desc_dma + val) & 0xffffffff, cp->regs + REG_RX_DB_LOW); in cas_init_rx_dma()
1210 writel(RX_DESC_RINGN_SIZE(0) - 4, cp->regs + REG_RX_KICK); in cas_init_rx_dma()
1212 if (cp->cas_flags & CAS_FLAG_REG_PLUS) { in cas_init_rx_dma()
1216 val = (unsigned long) cp->init_rxds[1] - in cas_init_rx_dma()
1217 (unsigned long) cp->init_block; in cas_init_rx_dma()
1218 writel((desc_dma + val) >> 32, cp->regs + REG_PLUS_RX_DB1_HI); in cas_init_rx_dma()
1219 writel((desc_dma + val) & 0xffffffff, cp->regs + in cas_init_rx_dma()
1221 writel(RX_DESC_RINGN_SIZE(1) - 4, cp->regs + in cas_init_rx_dma()
1226 val = (unsigned long) cp->init_rxcs[0] - in cas_init_rx_dma()
1227 (unsigned long) cp->init_block; in cas_init_rx_dma()
1228 writel((desc_dma + val) >> 32, cp->regs + REG_RX_CB_HI); in cas_init_rx_dma()
1229 writel((desc_dma + val) & 0xffffffff, cp->regs + REG_RX_CB_LOW); in cas_init_rx_dma()
1231 if (cp->cas_flags & CAS_FLAG_REG_PLUS) { in cas_init_rx_dma()
1234 val = (unsigned long) cp->init_rxcs[i] - in cas_init_rx_dma()
1235 (unsigned long) cp->init_block; in cas_init_rx_dma()
1236 writel((desc_dma + val) >> 32, cp->regs + in cas_init_rx_dma()
1238 writel((desc_dma + val) & 0xffffffff, cp->regs + in cas_init_rx_dma()
1247 readl(cp->regs + REG_INTR_STATUS_ALIAS); in cas_init_rx_dma()
1248 writel(INTR_RX_DONE | INTR_RX_BUF_UNAVAIL, cp->regs + REG_ALIAS_CLEAR); in cas_init_rx_dma()
1249 if (cp->cas_flags & CAS_FLAG_REG_PLUS) { in cas_init_rx_dma()
1251 readl(cp->regs + REG_PLUS_INTRN_STATUS_ALIAS(i)); in cas_init_rx_dma()
1256 cp->regs + REG_PLUS_ALIASN_CLEAR(1)); in cas_init_rx_dma()
1260 cp->regs + REG_PLUS_ALIASN_CLEAR(i)); in cas_init_rx_dma()
1265 cp->rx_pause_off / RX_PAUSE_THRESH_QUANTUM); in cas_init_rx_dma()
1267 cp->rx_pause_on / RX_PAUSE_THRESH_QUANTUM); in cas_init_rx_dma()
1268 writel(val, cp->regs + REG_RX_PAUSE_THRESH); in cas_init_rx_dma()
1272 writel(i, cp->regs + REG_RX_TABLE_ADDR); in cas_init_rx_dma()
1273 writel(0x0, cp->regs + REG_RX_TABLE_DATA_LOW); in cas_init_rx_dma()
1274 writel(0x0, cp->regs + REG_RX_TABLE_DATA_MID); in cas_init_rx_dma()
1275 writel(0x0, cp->regs + REG_RX_TABLE_DATA_HI); in cas_init_rx_dma()
1279 writel(0x0, cp->regs + REG_RX_CTRL_FIFO_ADDR); in cas_init_rx_dma()
1280 writel(0x0, cp->regs + REG_RX_IPP_FIFO_ADDR); in cas_init_rx_dma()
1286 writel(val, cp->regs + REG_RX_BLANK); in cas_init_rx_dma()
1288 writel(0x0, cp->regs + REG_RX_BLANK); in cas_init_rx_dma()
1298 writel(val, cp->regs + REG_RX_AE_THRESH); in cas_init_rx_dma()
1299 if (cp->cas_flags & CAS_FLAG_REG_PLUS) { in cas_init_rx_dma()
1301 writel(val, cp->regs + REG_PLUS_RX_AE1_THRESH); in cas_init_rx_dma()
1307 writel(0x0, cp->regs + REG_RX_RED); in cas_init_rx_dma()
1311 if (cp->page_size == 0x1000) in cas_init_rx_dma()
1313 else if (cp->page_size == 0x2000) in cas_init_rx_dma()
1315 else if (cp->page_size == 0x4000) in cas_init_rx_dma()
1319 size = cp->dev->mtu + 64; in cas_init_rx_dma()
1320 if (size > cp->page_size) in cas_init_rx_dma()
1321 size = cp->page_size; in cas_init_rx_dma()
1332 cp->mtu_stride = 1 << (i + 10); in cas_init_rx_dma()
1335 val |= CAS_BASE(RX_PAGE_SIZE_MTU_COUNT, cp->page_size >> (i + 10)); in cas_init_rx_dma()
1337 writel(val, cp->regs + REG_RX_PAGE_SIZE); in cas_init_rx_dma()
1346 writel(val, cp->regs + REG_HP_CFG); in cas_init_rx_dma()
1359 static inline cas_page_t *cas_page_spare(struct cas *cp, const int index) in cas_page_spare() argument
1361 cas_page_t *page = cp->rx_pages[1][index]; in cas_page_spare()
1367 new = cas_page_dequeue(cp); in cas_page_spare()
1369 spin_lock(&cp->rx_inuse_lock); in cas_page_spare()
1370 list_add(&page->list, &cp->rx_inuse_list); in cas_page_spare()
1371 spin_unlock(&cp->rx_inuse_lock); in cas_page_spare()
1377 static cas_page_t *cas_page_swap(struct cas *cp, const int ring, in cas_page_swap() argument
1380 cas_page_t **page0 = cp->rx_pages[0]; in cas_page_swap()
1381 cas_page_t **page1 = cp->rx_pages[1]; in cas_page_swap()
1385 cas_page_t *new = cas_page_spare(cp, index); in cas_page_swap()
1395 static void cas_clean_rxds(struct cas *cp) in cas_clean_rxds() argument
1398 struct cas_rx_desc *rxd = cp->init_rxds[0]; in cas_clean_rxds()
1404 while ((skb = __skb_dequeue(&cp->rx_flows[i]))) { in cas_clean_rxds()
1412 cas_page_t *page = cas_page_swap(cp, 0, i); in cas_clean_rxds()
1418 cp->rx_old[0] = RX_DESC_RINGN_SIZE(0) - 4; in cas_clean_rxds()
1419 cp->rx_last[0] = 0; in cas_clean_rxds()
1420 cp->cas_flags &= ~CAS_FLAG_RXD_POST(0); in cas_clean_rxds()
1423 static void cas_clean_rxcs(struct cas *cp) in cas_clean_rxcs() argument
1428 memset(cp->rx_cur, 0, sizeof(*cp->rx_cur)*N_RX_COMP_RINGS); in cas_clean_rxcs()
1429 memset(cp->rx_new, 0, sizeof(*cp->rx_new)*N_RX_COMP_RINGS); in cas_clean_rxcs()
1431 struct cas_rx_comp *rxc = cp->init_rxcs[i]; in cas_clean_rxcs()
1445 static int cas_rxmac_reset(struct cas *cp)
1447 struct net_device *dev = cp->dev;
1452 writel(cp->mac_rx_cfg & ~MAC_RX_CFG_EN, cp->regs + REG_MAC_RX_CFG);
1454 if (!(readl(cp->regs + REG_MAC_RX_CFG) & MAC_RX_CFG_EN))
1464 writel(0, cp->regs + REG_RX_CFG);
1466 if (!(readl(cp->regs + REG_RX_CFG) & RX_CFG_DMA_EN))
1478 writel(SW_RESET_RX, cp->regs + REG_SW_RESET);
1480 if (!(readl(cp->regs + REG_SW_RESET) & SW_RESET_RX))
1490 cas_clean_rxds(cp);
1491 cas_clean_rxcs(cp);
1494 cas_init_rx_dma(cp);
1497 val = readl(cp->regs + REG_RX_CFG);
1498 writel(val | RX_CFG_DMA_EN, cp->regs + REG_RX_CFG);
1499 writel(MAC_RX_FRAME_RECV, cp->regs + REG_MAC_RX_MASK);
1500 val = readl(cp->regs + REG_MAC_RX_CFG);
1501 writel(val | MAC_RX_CFG_EN, cp->regs + REG_MAC_RX_CFG);
1506 static int cas_rxmac_interrupt(struct net_device *dev, struct cas *cp, in cas_rxmac_interrupt() argument
1509 u32 stat = readl(cp->regs + REG_MAC_RX_STATUS); in cas_rxmac_interrupt()
1514 netif_dbg(cp, intr, cp->dev, "rxmac interrupt, stat: 0x%x\n", stat); in cas_rxmac_interrupt()
1517 spin_lock(&cp->stat_lock[0]); in cas_rxmac_interrupt()
1519 cp->net_stats[0].rx_frame_errors += 0x10000; in cas_rxmac_interrupt()
1522 cp->net_stats[0].rx_crc_errors += 0x10000; in cas_rxmac_interrupt()
1525 cp->net_stats[0].rx_length_errors += 0x10000; in cas_rxmac_interrupt()
1528 cp->net_stats[0].rx_over_errors++; in cas_rxmac_interrupt()
1529 cp->net_stats[0].rx_fifo_errors++; in cas_rxmac_interrupt()
1535 spin_unlock(&cp->stat_lock[0]); in cas_rxmac_interrupt()
1539 static int cas_mac_interrupt(struct net_device *dev, struct cas *cp, in cas_mac_interrupt() argument
1542 u32 stat = readl(cp->regs + REG_MAC_CTRL_STATUS); in cas_mac_interrupt()
1547 netif_printk(cp, intr, KERN_DEBUG, cp->dev, in cas_mac_interrupt()
1555 cp->pause_entered++; in cas_mac_interrupt()
1558 cp->pause_last_time_recvd = (stat >> 16); in cas_mac_interrupt()
1565 static inline int cas_mdio_link_not_up(struct cas *cp) in cas_mdio_link_not_up() argument
1569 switch (cp->lstate) { in cas_mdio_link_not_up()
1571 netif_info(cp, link, cp->dev, "Autoneg failed again, keeping forced mode\n"); in cas_mdio_link_not_up()
1572 cas_phy_write(cp, MII_BMCR, cp->link_fcntl); in cas_mdio_link_not_up()
1573 cp->timer_ticks = 5; in cas_mdio_link_not_up()
1574 cp->lstate = link_force_ok; in cas_mdio_link_not_up()
1575 cp->link_transition = LINK_TRANSITION_LINK_CONFIG; in cas_mdio_link_not_up()
1579 val = cas_phy_read(cp, MII_BMCR); in cas_mdio_link_not_up()
1586 val |= (cp->cas_flags & CAS_FLAG_1000MB_CAP) ? in cas_mdio_link_not_up()
1588 cas_phy_write(cp, MII_BMCR, val); in cas_mdio_link_not_up()
1589 cp->timer_ticks = 5; in cas_mdio_link_not_up()
1590 cp->lstate = link_force_try; in cas_mdio_link_not_up()
1591 cp->link_transition = LINK_TRANSITION_LINK_CONFIG; in cas_mdio_link_not_up()
1596 val = cas_phy_read(cp, MII_BMCR); in cas_mdio_link_not_up()
1597 cp->timer_ticks = 5; in cas_mdio_link_not_up()
1601 cas_phy_write(cp, MII_BMCR, val); in cas_mdio_link_not_up()
1611 cas_phy_write(cp, MII_BMCR, val); in cas_mdio_link_not_up()
1622 static int cas_mii_link_check(struct cas *cp, const u16 bmsr) in cas_mii_link_check() argument
1632 if ((cp->lstate == link_force_try) && in cas_mii_link_check()
1633 (cp->link_cntl & BMCR_ANENABLE)) { in cas_mii_link_check()
1634 cp->lstate = link_force_ret; in cas_mii_link_check()
1635 cp->link_transition = LINK_TRANSITION_LINK_CONFIG; in cas_mii_link_check()
1636 cas_mif_poll(cp, 0); in cas_mii_link_check()
1637 cp->link_fcntl = cas_phy_read(cp, MII_BMCR); in cas_mii_link_check()
1638 cp->timer_ticks = 5; in cas_mii_link_check()
1639 if (cp->opened) in cas_mii_link_check()
1640 netif_info(cp, link, cp->dev, in cas_mii_link_check()
1642 cas_phy_write(cp, MII_BMCR, in cas_mii_link_check()
1643 cp->link_fcntl | BMCR_ANENABLE | in cas_mii_link_check()
1645 cas_mif_poll(cp, 1); in cas_mii_link_check()
1647 } else if (cp->lstate != link_up) { in cas_mii_link_check()
1648 cp->lstate = link_up; in cas_mii_link_check()
1649 cp->link_transition = LINK_TRANSITION_LINK_UP; in cas_mii_link_check()
1651 if (cp->opened) { in cas_mii_link_check()
1652 cas_set_link_modes(cp); in cas_mii_link_check()
1653 netif_carrier_on(cp->dev); in cas_mii_link_check()
1663 if (cp->lstate == link_up) { in cas_mii_link_check()
1664 cp->lstate = link_down; in cas_mii_link_check()
1665 cp->link_transition = LINK_TRANSITION_LINK_DOWN; in cas_mii_link_check()
1667 netif_carrier_off(cp->dev); in cas_mii_link_check()
1668 if (cp->opened) in cas_mii_link_check()
1669 netif_info(cp, link, cp->dev, "Link down\n"); in cas_mii_link_check()
1672 } else if (++cp->timer_ticks > 10) in cas_mii_link_check()
1673 cas_mdio_link_not_up(cp); in cas_mii_link_check()
1678 static int cas_mif_interrupt(struct net_device *dev, struct cas *cp, in cas_mif_interrupt() argument
1681 u32 stat = readl(cp->regs + REG_MIF_STATUS); in cas_mif_interrupt()
1689 return cas_mii_link_check(cp, bmsr); in cas_mif_interrupt()
1692 static int cas_pci_interrupt(struct net_device *dev, struct cas *cp, in cas_pci_interrupt() argument
1695 u32 stat = readl(cp->regs + REG_PCI_ERR_STATUS); in cas_pci_interrupt()
1701 stat, readl(cp->regs + REG_BIM_DIAG)); in cas_pci_interrupt()
1705 ((cp->cas_flags & CAS_FLAG_REG_PLUS) == 0)) in cas_pci_interrupt()
1724 pci_read_config_word(cp->pdev, PCI_STATUS, &cfg); in cas_pci_interrupt()
1746 pci_write_config_word(cp->pdev, PCI_STATUS, cfg); in cas_pci_interrupt()
1758 static int cas_abnormal_irq(struct net_device *dev, struct cas *cp, in cas_abnormal_irq() argument
1763 netif_printk(cp, rx_err, KERN_DEBUG, cp->dev, in cas_abnormal_irq()
1765 spin_lock(&cp->stat_lock[0]); in cas_abnormal_irq()
1766 cp->net_stats[0].rx_errors++; in cas_abnormal_irq()
1767 spin_unlock(&cp->stat_lock[0]); in cas_abnormal_irq()
1773 netif_printk(cp, rx_err, KERN_DEBUG, cp->dev, in cas_abnormal_irq()
1775 spin_lock(&cp->stat_lock[0]); in cas_abnormal_irq()
1776 cp->net_stats[0].rx_errors++; in cas_abnormal_irq()
1777 spin_unlock(&cp->stat_lock[0]); in cas_abnormal_irq()
1782 if (cas_pcs_interrupt(dev, cp, status)) in cas_abnormal_irq()
1787 if (cas_txmac_interrupt(dev, cp, status)) in cas_abnormal_irq()
1792 if (cas_rxmac_interrupt(dev, cp, status)) in cas_abnormal_irq()
1797 if (cas_mac_interrupt(dev, cp, status)) in cas_abnormal_irq()
1802 if (cas_mif_interrupt(dev, cp, status)) in cas_abnormal_irq()
1807 if (cas_pci_interrupt(dev, cp, status)) in cas_abnormal_irq()
1814 atomic_inc(&cp->reset_task_pending); in cas_abnormal_irq()
1815 atomic_inc(&cp->reset_task_pending_all); in cas_abnormal_irq()
1817 schedule_work(&cp->reset_task); in cas_abnormal_irq()
1819 atomic_set(&cp->reset_task_pending, CAS_RESET_ALL); in cas_abnormal_irq()
1821 schedule_work(&cp->reset_task); in cas_abnormal_irq()
1831 static inline int cas_calc_tabort(struct cas *cp, const unsigned long addr, in cas_calc_tabort() argument
1836 if (CAS_TABORT(cp) == 1) in cas_calc_tabort()
1843 static inline void cas_tx_ringN(struct cas *cp, int ring, int limit) in cas_tx_ringN() argument
1847 struct net_device *dev = cp->dev; in cas_tx_ringN()
1850 spin_lock(&cp->tx_lock[ring]); in cas_tx_ringN()
1851 txds = cp->init_txds[ring]; in cas_tx_ringN()
1852 skbs = cp->tx_skbs[ring]; in cas_tx_ringN()
1853 entry = cp->tx_old[ring]; in cas_tx_ringN()
1870 + cp->tx_tiny_use[ring][entry].nbufs + 1; in cas_tx_ringN()
1874 netif_printk(cp, tx_done, KERN_DEBUG, cp->dev, in cas_tx_ringN()
1878 cp->tx_tiny_use[ring][entry].nbufs = 0; in cas_tx_ringN()
1886 pci_unmap_page(cp->pdev, daddr, dlen, in cas_tx_ringN()
1891 if (cp->tx_tiny_use[ring][entry].used) { in cas_tx_ringN()
1892 cp->tx_tiny_use[ring][entry].used = 0; in cas_tx_ringN()
1897 spin_lock(&cp->stat_lock[ring]); in cas_tx_ringN()
1898 cp->net_stats[ring].tx_packets++; in cas_tx_ringN()
1899 cp->net_stats[ring].tx_bytes += skb->len; in cas_tx_ringN()
1900 spin_unlock(&cp->stat_lock[ring]); in cas_tx_ringN()
1903 cp->tx_old[ring] = entry; in cas_tx_ringN()
1910 (TX_BUFFS_AVAIL(cp, ring) > CAS_TABORT(cp)*(MAX_SKB_FRAGS + 1))) in cas_tx_ringN()
1912 spin_unlock(&cp->tx_lock[ring]); in cas_tx_ringN()
1915 static void cas_tx(struct net_device *dev, struct cas *cp, in cas_tx() argument
1920 u64 compwb = le64_to_cpu(cp->init_block->tx_compwb); in cas_tx()
1922 netif_printk(cp, intr, KERN_DEBUG, cp->dev, in cas_tx()
1933 limit = readl(cp->regs + REG_TX_COMPN(ring)); in cas_tx()
1935 if (cp->tx_old[ring] != limit) in cas_tx()
1936 cas_tx_ringN(cp, ring, limit); in cas_tx()
1941 static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, in cas_rx_process_pkt() argument
1962 skb = netdev_alloc_skb(cp->dev, alloclen + swivel + cp->crc_size); in cas_rx_process_pkt()
1973 page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)]; in cas_rx_process_pkt()
1979 i += cp->crc_size; in cas_rx_process_pkt()
1980 pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr + off, i, in cas_rx_process_pkt()
1984 pci_dma_sync_single_for_device(cp->pdev, page->dma_addr + off, i, in cas_rx_process_pkt()
1998 page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)]; in cas_rx_process_pkt()
2001 hlen = min(cp->page_size - off, dlen); in cas_rx_process_pkt()
2003 netif_printk(cp, rx_err, KERN_DEBUG, cp->dev, in cas_rx_process_pkt()
2010 i += cp->crc_size; in cas_rx_process_pkt()
2011 pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr + off, i, in cas_rx_process_pkt()
2019 pci_dma_sync_single_for_device(cp->pdev, page->dma_addr + off, i, in cas_rx_process_pkt()
2024 RX_USED_ADD(page, cp->mtu_stride); in cas_rx_process_pkt()
2046 page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)]; in cas_rx_process_pkt()
2047 pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr, in cas_rx_process_pkt()
2048 hlen + cp->crc_size, in cas_rx_process_pkt()
2050 pci_dma_sync_single_for_device(cp->pdev, page->dma_addr, in cas_rx_process_pkt()
2051 hlen + cp->crc_size, in cas_rx_process_pkt()
2063 RX_USED_ADD(page, hlen + cp->crc_size); in cas_rx_process_pkt()
2066 if (cp->crc_size) { in cas_rx_process_pkt()
2077 page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)]; in cas_rx_process_pkt()
2079 hlen = min(cp->page_size - off, dlen); in cas_rx_process_pkt()
2081 netif_printk(cp, rx_err, KERN_DEBUG, cp->dev, in cas_rx_process_pkt()
2088 i += cp->crc_size; in cas_rx_process_pkt()
2089 pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr + off, i, in cas_rx_process_pkt()
2093 pci_dma_sync_single_for_device(cp->pdev, page->dma_addr + off, i, in cas_rx_process_pkt()
2097 RX_USED_ADD(page, cp->mtu_stride); in cas_rx_process_pkt()
2105 page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)]; in cas_rx_process_pkt()
2106 pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr, in cas_rx_process_pkt()
2107 dlen + cp->crc_size, in cas_rx_process_pkt()
2110 memcpy(p, addr, dlen + cp->crc_size); in cas_rx_process_pkt()
2111 pci_dma_sync_single_for_device(cp->pdev, page->dma_addr, in cas_rx_process_pkt()
2112 dlen + cp->crc_size, in cas_rx_process_pkt()
2115 RX_USED_ADD(page, dlen + cp->crc_size); in cas_rx_process_pkt()
2118 if (cp->crc_size) { in cas_rx_process_pkt()
2126 if (cp->crc_size) { in cas_rx_process_pkt()
2128 csum = csum_fold(csum_partial(crcaddr, cp->crc_size, in cas_rx_process_pkt()
2133 skb->protocol = eth_type_trans(skb, cp->dev); in cas_rx_process_pkt()
2157 static inline void cas_rx_flow_pkt(struct cas *cp, const u64 *words, in cas_rx_flow_pkt() argument
2161 struct sk_buff_head *flow = &cp->rx_flows[flowid]; in cas_rx_flow_pkt()
2178 static void cas_post_page(struct cas *cp, const int ring, const int index) in cas_post_page() argument
2183 entry = cp->rx_old[ring]; in cas_post_page()
2185 new = cas_page_swap(cp, ring, index); in cas_post_page()
2186 cp->init_rxds[ring][entry].buffer = cpu_to_le64(new->dma_addr); in cas_post_page()
2187 cp->init_rxds[ring][entry].index = in cas_post_page()
2192 cp->rx_old[ring] = entry; in cas_post_page()
2198 writel(entry, cp->regs + REG_RX_KICK); in cas_post_page()
2200 (cp->cas_flags & CAS_FLAG_REG_PLUS)) in cas_post_page()
2201 writel(entry, cp->regs + REG_PLUS_RX_KICK1); in cas_post_page()
2206 static int cas_post_rxds_ringN(struct cas *cp, int ring, int num) in cas_post_rxds_ringN() argument
2210 cas_page_t **page = cp->rx_pages[ring]; in cas_post_rxds_ringN()
2212 entry = cp->rx_old[ring]; in cas_post_rxds_ringN()
2214 netif_printk(cp, intr, KERN_DEBUG, cp->dev, in cas_post_rxds_ringN()
2224 cas_page_t *new = cas_page_dequeue(cp); in cas_post_rxds_ringN()
2229 cp->cas_flags |= CAS_FLAG_RXD_POST(ring); in cas_post_rxds_ringN()
2230 if (!timer_pending(&cp->link_timer)) in cas_post_rxds_ringN()
2231 mod_timer(&cp->link_timer, jiffies + in cas_post_rxds_ringN()
2233 cp->rx_old[ring] = entry; in cas_post_rxds_ringN()
2234 cp->rx_last[ring] = num ? num - released : 0; in cas_post_rxds_ringN()
2237 spin_lock(&cp->rx_inuse_lock); in cas_post_rxds_ringN()
2238 list_add(&page[entry]->list, &cp->rx_inuse_list); in cas_post_rxds_ringN()
2239 spin_unlock(&cp->rx_inuse_lock); in cas_post_rxds_ringN()
2240 cp->init_rxds[ring][entry].buffer = in cas_post_rxds_ringN()
2253 cp->rx_old[ring] = entry; in cas_post_rxds_ringN()
2259 writel(cluster, cp->regs + REG_RX_KICK); in cas_post_rxds_ringN()
2261 (cp->cas_flags & CAS_FLAG_REG_PLUS)) in cas_post_rxds_ringN()
2262 writel(cluster, cp->regs + REG_PLUS_RX_KICK1); in cas_post_rxds_ringN()
2279 static int cas_rx_ringN(struct cas *cp, int ring, int budget) in cas_rx_ringN() argument
2281 struct cas_rx_comp *rxcs = cp->init_rxcs[ring]; in cas_rx_ringN()
2285 netif_printk(cp, intr, KERN_DEBUG, cp->dev, in cas_rx_ringN()
2288 readl(cp->regs + REG_RX_COMP_HEAD), cp->rx_new[ring]); in cas_rx_ringN()
2290 entry = cp->rx_new[ring]; in cas_rx_ringN()
2316 spin_lock(&cp->stat_lock[ring]); in cas_rx_ringN()
2317 cp->net_stats[ring].rx_errors++; in cas_rx_ringN()
2319 cp->net_stats[ring].rx_length_errors++; in cas_rx_ringN()
2321 cp->net_stats[ring].rx_crc_errors++; in cas_rx_ringN()
2322 spin_unlock(&cp->stat_lock[ring]); in cas_rx_ringN()
2326 spin_lock(&cp->stat_lock[ring]); in cas_rx_ringN()
2327 ++cp->net_stats[ring].rx_dropped; in cas_rx_ringN()
2328 spin_unlock(&cp->stat_lock[ring]); in cas_rx_ringN()
2332 len = cas_rx_process_pkt(cp, rxc, entry, words, &skb); in cas_rx_ringN()
2345 cas_rx_flow_pkt(cp, words, skb); in cas_rx_ringN()
2348 spin_lock(&cp->stat_lock[ring]); in cas_rx_ringN()
2349 cp->net_stats[ring].rx_packets++; in cas_rx_ringN()
2350 cp->net_stats[ring].rx_bytes += len; in cas_rx_ringN()
2351 spin_unlock(&cp->stat_lock[ring]); in cas_rx_ringN()
2361 cas_post_page(cp, dring, i); in cas_rx_ringN()
2368 cas_post_page(cp, dring, i); in cas_rx_ringN()
2375 cas_post_page(cp, dring, i); in cas_rx_ringN()
2386 cp->rx_new[ring] = entry; in cas_rx_ringN()
2389 netdev_info(cp->dev, "Memory squeeze, deferring packet\n"); in cas_rx_ringN()
2396 struct cas *cp, int ring) in cas_post_rxcs_ringN() argument
2398 struct cas_rx_comp *rxc = cp->init_rxcs[ring]; in cas_post_rxcs_ringN()
2401 last = cp->rx_cur[ring]; in cas_post_rxcs_ringN()
2402 entry = cp->rx_new[ring]; in cas_post_rxcs_ringN()
2403 netif_printk(cp, intr, KERN_DEBUG, dev, in cas_post_rxcs_ringN()
2405 ring, readl(cp->regs + REG_RX_COMP_HEAD), entry); in cas_post_rxcs_ringN()
2412 cp->rx_cur[ring] = last; in cas_post_rxcs_ringN()
2415 writel(last, cp->regs + REG_RX_COMP_TAIL); in cas_post_rxcs_ringN()
2416 else if (cp->cas_flags & CAS_FLAG_REG_PLUS) in cas_post_rxcs_ringN()
2417 writel(last, cp->regs + REG_PLUS_RX_COMPN_TAIL(ring)); in cas_post_rxcs_ringN()
2427 struct cas *cp, const u32 status, in cas_handle_irqN() argument
2431 cas_post_rxcs_ringN(dev, cp, ring); in cas_handle_irqN()
2437 struct cas *cp = netdev_priv(dev); in cas_interruptN() local
2439 int ring = (irq == cp->pci_irq_INTC) ? 2 : 3; in cas_interruptN()
2440 u32 status = readl(cp->regs + REG_PLUS_INTRN_STATUS(ring)); in cas_interruptN()
2446 spin_lock_irqsave(&cp->lock, flags); in cas_interruptN()
2449 cas_mask_intr(cp); in cas_interruptN()
2450 napi_schedule(&cp->napi); in cas_interruptN()
2452 cas_rx_ringN(cp, ring, 0); in cas_interruptN()
2458 cas_handle_irqN(dev, cp, status, ring); in cas_interruptN()
2459 spin_unlock_irqrestore(&cp->lock, flags); in cas_interruptN()
2466 static inline void cas_handle_irq1(struct cas *cp, const u32 status) in cas_handle_irq1() argument
2471 cas_post_rxds_ringN(cp, 1, 0); in cas_handle_irq1()
2472 spin_lock(&cp->stat_lock[1]); in cas_handle_irq1()
2473 cp->net_stats[1].rx_dropped++; in cas_handle_irq1()
2474 spin_unlock(&cp->stat_lock[1]); in cas_handle_irq1()
2478 cas_post_rxds_ringN(cp, 1, RX_DESC_RINGN_SIZE(1) - in cas_handle_irq1()
2482 cas_post_rxcs_ringN(cp, 1); in cas_handle_irq1()
2489 struct cas *cp = netdev_priv(dev); in cas_interrupt1() local
2491 u32 status = readl(cp->regs + REG_PLUS_INTRN_STATUS(1)); in cas_interrupt1()
2497 spin_lock_irqsave(&cp->lock, flags); in cas_interrupt1()
2500 cas_mask_intr(cp); in cas_interrupt1()
2501 napi_schedule(&cp->napi); in cas_interrupt1()
2503 cas_rx_ringN(cp, 1, 0); in cas_interrupt1()
2508 cas_handle_irq1(cp, status); in cas_interrupt1()
2509 spin_unlock_irqrestore(&cp->lock, flags); in cas_interrupt1()
2515 struct cas *cp, const u32 status) in cas_handle_irq() argument
2519 cas_abnormal_irq(dev, cp, status); in cas_handle_irq()
2525 cas_post_rxds_ringN(cp, 0, 0); in cas_handle_irq()
2526 spin_lock(&cp->stat_lock[0]); in cas_handle_irq()
2527 cp->net_stats[0].rx_dropped++; in cas_handle_irq()
2528 spin_unlock(&cp->stat_lock[0]); in cas_handle_irq()
2530 cas_post_rxds_ringN(cp, 0, RX_DESC_RINGN_SIZE(0) - in cas_handle_irq()
2535 cas_post_rxcs_ringN(dev, cp, 0); in cas_handle_irq()
2541 struct cas *cp = netdev_priv(dev); in cas_interrupt() local
2543 u32 status = readl(cp->regs + REG_INTR_STATUS); in cas_interrupt()
2548 spin_lock_irqsave(&cp->lock, flags); in cas_interrupt()
2550 cas_tx(dev, cp, status); in cas_interrupt()
2556 cas_mask_intr(cp); in cas_interrupt()
2557 napi_schedule(&cp->napi); in cas_interrupt()
2559 cas_rx_ringN(cp, 0, 0); in cas_interrupt()
2565 cas_handle_irq(dev, cp, status); in cas_interrupt()
2566 spin_unlock_irqrestore(&cp->lock, flags); in cas_interrupt()
2574 struct cas *cp = container_of(napi, struct cas, napi); in cas_poll() local
2575 struct net_device *dev = cp->dev; in cas_poll()
2577 u32 status = readl(cp->regs + REG_INTR_STATUS); in cas_poll()
2580 spin_lock_irqsave(&cp->lock, flags); in cas_poll()
2581 cas_tx(dev, cp, status); in cas_poll()
2582 spin_unlock_irqrestore(&cp->lock, flags); in cas_poll()
2596 credits += cas_rx_ringN(cp, j, budget / N_RX_COMP_RINGS); in cas_poll()
2606 spin_lock_irqsave(&cp->lock, flags); in cas_poll()
2608 cas_handle_irq(dev, cp, status); in cas_poll()
2612 status = readl(cp->regs + REG_PLUS_INTRN_STATUS(1)); in cas_poll()
2614 cas_handle_irq1(dev, cp, status); in cas_poll()
2620 status = readl(cp->regs + REG_PLUS_INTRN_STATUS(2)); in cas_poll()
2622 cas_handle_irqN(dev, cp, status, 2); in cas_poll()
2628 status = readl(cp->regs + REG_PLUS_INTRN_STATUS(3)); in cas_poll()
2630 cas_handle_irqN(dev, cp, status, 3); in cas_poll()
2633 spin_unlock_irqrestore(&cp->lock, flags); in cas_poll()
2636 cas_unmask_intr(cp); in cas_poll()
2645 struct cas *cp = netdev_priv(dev); in cas_netpoll() local
2647 cas_disable_irq(cp, 0); in cas_netpoll()
2648 cas_interrupt(cp->pdev->irq, dev); in cas_netpoll()
2649 cas_enable_irq(cp, 0); in cas_netpoll()
2671 struct cas *cp = netdev_priv(dev); in cas_tx_timeout() local
2674 if (!cp->hw_running) { in cas_tx_timeout()
2680 readl(cp->regs + REG_MIF_STATE_MACHINE)); in cas_tx_timeout()
2683 readl(cp->regs + REG_MAC_STATE_MACHINE)); in cas_tx_timeout()
2686 readl(cp->regs + REG_TX_CFG), in cas_tx_timeout()
2687 readl(cp->regs + REG_MAC_TX_STATUS), in cas_tx_timeout()
2688 readl(cp->regs + REG_MAC_TX_CFG), in cas_tx_timeout()
2689 readl(cp->regs + REG_TX_FIFO_PKT_CNT), in cas_tx_timeout()
2690 readl(cp->regs + REG_TX_FIFO_WRITE_PTR), in cas_tx_timeout()
2691 readl(cp->regs + REG_TX_FIFO_READ_PTR), in cas_tx_timeout()
2692 readl(cp->regs + REG_TX_SM_1), in cas_tx_timeout()
2693 readl(cp->regs + REG_TX_SM_2)); in cas_tx_timeout()
2696 readl(cp->regs + REG_RX_CFG), in cas_tx_timeout()
2697 readl(cp->regs + REG_MAC_RX_STATUS), in cas_tx_timeout()
2698 readl(cp->regs + REG_MAC_RX_CFG)); in cas_tx_timeout()
2701 readl(cp->regs + REG_HP_STATE_MACHINE), in cas_tx_timeout()
2702 readl(cp->regs + REG_HP_STATUS0), in cas_tx_timeout()
2703 readl(cp->regs + REG_HP_STATUS1), in cas_tx_timeout()
2704 readl(cp->regs + REG_HP_STATUS2)); in cas_tx_timeout()
2707 atomic_inc(&cp->reset_task_pending); in cas_tx_timeout()
2708 atomic_inc(&cp->reset_task_pending_all); in cas_tx_timeout()
2709 schedule_work(&cp->reset_task); in cas_tx_timeout()
2711 atomic_set(&cp->reset_task_pending, CAS_RESET_ALL); in cas_tx_timeout()
2712 schedule_work(&cp->reset_task); in cas_tx_timeout()
2725 static void cas_write_txd(struct cas *cp, int ring, int entry, in cas_write_txd() argument
2728 struct cas_tx_desc *txd = cp->init_txds[ring] + entry; in cas_write_txd()
2739 static inline void *tx_tiny_buf(struct cas *cp, const int ring, in tx_tiny_buf() argument
2742 return cp->tx_tiny_bufs[ring] + TX_TINY_BUF_LEN*entry; in tx_tiny_buf()
2745 static inline dma_addr_t tx_tiny_map(struct cas *cp, const int ring, in tx_tiny_map() argument
2748 cp->tx_tiny_use[ring][tentry].nbufs++; in tx_tiny_map()
2749 cp->tx_tiny_use[ring][entry].used = 1; in tx_tiny_map()
2750 return cp->tx_tiny_dvma[ring] + TX_TINY_BUF_LEN*entry; in tx_tiny_map()
2753 static inline int cas_xmit_tx_ringN(struct cas *cp, int ring, in cas_xmit_tx_ringN() argument
2756 struct net_device *dev = cp->dev; in cas_xmit_tx_ringN()
2763 spin_lock_irqsave(&cp->tx_lock[ring], flags); in cas_xmit_tx_ringN()
2766 if (TX_BUFFS_AVAIL(cp, ring) <= in cas_xmit_tx_ringN()
2767 CAS_TABORT(cp)*(skb_shinfo(skb)->nr_frags + 1)) { in cas_xmit_tx_ringN()
2769 spin_unlock_irqrestore(&cp->tx_lock[ring], flags); in cas_xmit_tx_ringN()
2784 entry = cp->tx_new[ring]; in cas_xmit_tx_ringN()
2785 cp->tx_skbs[ring][entry] = skb; in cas_xmit_tx_ringN()
2789 mapping = pci_map_page(cp->pdev, virt_to_page(skb->data), in cas_xmit_tx_ringN()
2794 tabort = cas_calc_tabort(cp, (unsigned long) skb->data, len); in cas_xmit_tx_ringN()
2797 cas_write_txd(cp, ring, entry, mapping, len - tabort, in cas_xmit_tx_ringN()
2802 tx_tiny_buf(cp, ring, entry), tabort); in cas_xmit_tx_ringN()
2803 mapping = tx_tiny_map(cp, ring, entry, tentry); in cas_xmit_tx_ringN()
2804 cas_write_txd(cp, ring, entry, mapping, tabort, ctrl, in cas_xmit_tx_ringN()
2807 cas_write_txd(cp, ring, entry, mapping, len, ctrl | in cas_xmit_tx_ringN()
2816 mapping = skb_frag_dma_map(&cp->pdev->dev, fragp, 0, len, in cas_xmit_tx_ringN()
2819 tabort = cas_calc_tabort(cp, skb_frag_off(fragp), len); in cas_xmit_tx_ringN()
2824 cas_write_txd(cp, ring, entry, mapping, len - tabort, in cas_xmit_tx_ringN()
2829 memcpy(tx_tiny_buf(cp, ring, entry), in cas_xmit_tx_ringN()
2833 mapping = tx_tiny_map(cp, ring, entry, tentry); in cas_xmit_tx_ringN()
2837 cas_write_txd(cp, ring, entry, mapping, len, ctrl, in cas_xmit_tx_ringN()
2842 cp->tx_new[ring] = entry; in cas_xmit_tx_ringN()
2843 if (TX_BUFFS_AVAIL(cp, ring) <= CAS_TABORT(cp)*(MAX_SKB_FRAGS + 1)) in cas_xmit_tx_ringN()
2846 netif_printk(cp, tx_queued, KERN_DEBUG, dev, in cas_xmit_tx_ringN()
2848 ring, entry, skb->len, TX_BUFFS_AVAIL(cp, ring)); in cas_xmit_tx_ringN()
2849 writel(entry, cp->regs + REG_TX_KICKN(ring)); in cas_xmit_tx_ringN()
2850 spin_unlock_irqrestore(&cp->tx_lock[ring], flags); in cas_xmit_tx_ringN()
2856 struct cas *cp = netdev_priv(dev); in cas_start_xmit() local
2863 if (skb_padto(skb, cp->min_frame_size)) in cas_start_xmit()
2869 if (cas_xmit_tx_ringN(cp, ring++ & N_TX_RINGS_MASK, skb)) in cas_start_xmit()
2874 static void cas_init_tx_dma(struct cas *cp) in cas_init_tx_dma() argument
2876 u64 desc_dma = cp->block_dvma; in cas_init_tx_dma()
2884 writel((desc_dma + off) >> 32, cp->regs + REG_TX_COMPWB_DB_HI); in cas_init_tx_dma()
2885 writel((desc_dma + off) & 0xffffffff, cp->regs + REG_TX_COMPWB_DB_LOW); in cas_init_tx_dma()
2898 off = (unsigned long) cp->init_txds[i] - in cas_init_tx_dma()
2899 (unsigned long) cp->init_block; in cas_init_tx_dma()
2902 writel((desc_dma + off) >> 32, cp->regs + REG_TX_DBN_HI(i)); in cas_init_tx_dma()
2903 writel((desc_dma + off) & 0xffffffff, cp->regs + in cas_init_tx_dma()
2909 writel(val, cp->regs + REG_TX_CFG); in cas_init_tx_dma()
2915 writel(0x800, cp->regs + REG_TX_MAXBURST_0); in cas_init_tx_dma()
2916 writel(0x1600, cp->regs + REG_TX_MAXBURST_1); in cas_init_tx_dma()
2917 writel(0x2400, cp->regs + REG_TX_MAXBURST_2); in cas_init_tx_dma()
2918 writel(0x4800, cp->regs + REG_TX_MAXBURST_3); in cas_init_tx_dma()
2920 writel(0x800, cp->regs + REG_TX_MAXBURST_0); in cas_init_tx_dma()
2921 writel(0x800, cp->regs + REG_TX_MAXBURST_1); in cas_init_tx_dma()
2922 writel(0x800, cp->regs + REG_TX_MAXBURST_2); in cas_init_tx_dma()
2923 writel(0x800, cp->regs + REG_TX_MAXBURST_3); in cas_init_tx_dma()
2928 static inline void cas_init_dma(struct cas *cp) in cas_init_dma() argument
2930 cas_init_tx_dma(cp); in cas_init_dma()
2931 cas_init_rx_dma(cp); in cas_init_dma()
2934 static void cas_process_mc_list(struct cas *cp) in cas_process_mc_list() argument
2942 netdev_for_each_mc_addr(ha, cp->dev) { in cas_process_mc_list()
2948 cp->regs + REG_MAC_ADDRN(i*3 + 0)); in cas_process_mc_list()
2950 cp->regs + REG_MAC_ADDRN(i*3 + 1)); in cas_process_mc_list()
2952 cp->regs + REG_MAC_ADDRN(i*3 + 2)); in cas_process_mc_list()
2965 writel(hash_table[i], cp->regs + REG_MAC_HASH_TABLEN(i)); in cas_process_mc_list()
2969 static u32 cas_setup_multicast(struct cas *cp) in cas_setup_multicast() argument
2974 if (cp->dev->flags & IFF_PROMISC) { in cas_setup_multicast()
2977 } else if (cp->dev->flags & IFF_ALLMULTI) { in cas_setup_multicast()
2979 writel(0xFFFF, cp->regs + REG_MAC_HASH_TABLEN(i)); in cas_setup_multicast()
2983 cas_process_mc_list(cp); in cas_setup_multicast()
2991 static void cas_clear_mac_err(struct cas *cp) in cas_clear_mac_err() argument
2993 writel(0, cp->regs + REG_MAC_COLL_NORMAL); in cas_clear_mac_err()
2994 writel(0, cp->regs + REG_MAC_COLL_FIRST); in cas_clear_mac_err()
2995 writel(0, cp->regs + REG_MAC_COLL_EXCESS); in cas_clear_mac_err()
2996 writel(0, cp->regs + REG_MAC_COLL_LATE); in cas_clear_mac_err()
2997 writel(0, cp->regs + REG_MAC_TIMER_DEFER); in cas_clear_mac_err()
2998 writel(0, cp->regs + REG_MAC_ATTEMPTS_PEAK); in cas_clear_mac_err()
2999 writel(0, cp->regs + REG_MAC_RECV_FRAME); in cas_clear_mac_err()
3000 writel(0, cp->regs + REG_MAC_LEN_ERR); in cas_clear_mac_err()
3001 writel(0, cp->regs + REG_MAC_ALIGN_ERR); in cas_clear_mac_err()
3002 writel(0, cp->regs + REG_MAC_FCS_ERR); in cas_clear_mac_err()
3003 writel(0, cp->regs + REG_MAC_RX_CODE_ERR); in cas_clear_mac_err()
3007 static void cas_mac_reset(struct cas *cp) in cas_mac_reset() argument
3012 writel(0x1, cp->regs + REG_MAC_TX_RESET); in cas_mac_reset()
3013 writel(0x1, cp->regs + REG_MAC_RX_RESET); in cas_mac_reset()
3018 if (readl(cp->regs + REG_MAC_TX_RESET) == 0) in cas_mac_reset()
3026 if (readl(cp->regs + REG_MAC_RX_RESET) == 0) in cas_mac_reset()
3031 if (readl(cp->regs + REG_MAC_TX_RESET) | in cas_mac_reset()
3032 readl(cp->regs + REG_MAC_RX_RESET)) in cas_mac_reset()
3033 netdev_err(cp->dev, "mac tx[%d]/rx[%d] reset failed [%08x]\n", in cas_mac_reset()
3034 readl(cp->regs + REG_MAC_TX_RESET), in cas_mac_reset()
3035 readl(cp->regs + REG_MAC_RX_RESET), in cas_mac_reset()
3036 readl(cp->regs + REG_MAC_STATE_MACHINE)); in cas_mac_reset()
3041 static void cas_init_mac(struct cas *cp) in cas_init_mac() argument
3043 unsigned char *e = &cp->dev->dev_addr[0]; in cas_init_mac()
3045 cas_mac_reset(cp); in cas_init_mac()
3048 writel(CAWR_RR_DIS, cp->regs + REG_CAWR); in cas_init_mac()
3054 if ((cp->cas_flags & CAS_FLAG_TARGET_ABORT) == 0) in cas_init_mac()
3055 writel(INF_BURST_EN, cp->regs + REG_INF_BURST); in cas_init_mac()
3058 writel(0x1BF0, cp->regs + REG_MAC_SEND_PAUSE); in cas_init_mac()
3060 writel(0x00, cp->regs + REG_MAC_IPG0); in cas_init_mac()
3061 writel(0x08, cp->regs + REG_MAC_IPG1); in cas_init_mac()
3062 writel(0x04, cp->regs + REG_MAC_IPG2); in cas_init_mac()
3065 writel(0x40, cp->regs + REG_MAC_SLOT_TIME); in cas_init_mac()
3068 writel(ETH_ZLEN + 4, cp->regs + REG_MAC_FRAMESIZE_MIN); in cas_init_mac()
3077 cp->regs + REG_MAC_FRAMESIZE_MAX); in cas_init_mac()
3083 if ((cp->cas_flags & CAS_FLAG_SATURN) && cp->crc_size) in cas_init_mac()
3084 writel(0x41, cp->regs + REG_MAC_PA_SIZE); in cas_init_mac()
3086 writel(0x07, cp->regs + REG_MAC_PA_SIZE); in cas_init_mac()
3087 writel(0x04, cp->regs + REG_MAC_JAM_SIZE); in cas_init_mac()
3088 writel(0x10, cp->regs + REG_MAC_ATTEMPT_LIMIT); in cas_init_mac()
3089 writel(0x8808, cp->regs + REG_MAC_CTRL_TYPE); in cas_init_mac()
3091 writel((e[5] | (e[4] << 8)) & 0x3ff, cp->regs + REG_MAC_RANDOM_SEED); in cas_init_mac()
3093 writel(0, cp->regs + REG_MAC_ADDR_FILTER0); in cas_init_mac()
3094 writel(0, cp->regs + REG_MAC_ADDR_FILTER1); in cas_init_mac()
3095 writel(0, cp->regs + REG_MAC_ADDR_FILTER2); in cas_init_mac()
3096 writel(0, cp->regs + REG_MAC_ADDR_FILTER2_1_MASK); in cas_init_mac()
3097 writel(0, cp->regs + REG_MAC_ADDR_FILTER0_MASK); in cas_init_mac()
3101 writel(0x0, cp->regs + REG_MAC_ADDRN(i)); in cas_init_mac()
3103 writel((e[4] << 8) | e[5], cp->regs + REG_MAC_ADDRN(0)); in cas_init_mac()
3104 writel((e[2] << 8) | e[3], cp->regs + REG_MAC_ADDRN(1)); in cas_init_mac()
3105 writel((e[0] << 8) | e[1], cp->regs + REG_MAC_ADDRN(2)); in cas_init_mac()
3107 writel(0x0001, cp->regs + REG_MAC_ADDRN(42)); in cas_init_mac()
3108 writel(0xc200, cp->regs + REG_MAC_ADDRN(43)); in cas_init_mac()
3109 writel(0x0180, cp->regs + REG_MAC_ADDRN(44)); in cas_init_mac()
3111 cp->mac_rx_cfg = cas_setup_multicast(cp); in cas_init_mac()
3113 spin_lock(&cp->stat_lock[N_TX_RINGS]); in cas_init_mac()
3114 cas_clear_mac_err(cp); in cas_init_mac()
3115 spin_unlock(&cp->stat_lock[N_TX_RINGS]); in cas_init_mac()
3121 writel(MAC_TX_FRAME_XMIT, cp->regs + REG_MAC_TX_MASK); in cas_init_mac()
3122 writel(MAC_RX_FRAME_RECV, cp->regs + REG_MAC_RX_MASK); in cas_init_mac()
3127 writel(0xffffffff, cp->regs + REG_MAC_CTRL_MASK); in cas_init_mac()
3131 static void cas_init_pause_thresholds(struct cas *cp) in cas_init_pause_thresholds() argument
3136 if (cp->rx_fifo_size <= (2 * 1024)) { in cas_init_pause_thresholds()
3137 cp->rx_pause_off = cp->rx_pause_on = cp->rx_fifo_size; in cas_init_pause_thresholds()
3139 int max_frame = (cp->dev->mtu + ETH_HLEN + 4 + 4 + 64) & ~63; in cas_init_pause_thresholds()
3140 if (max_frame * 3 > cp->rx_fifo_size) { in cas_init_pause_thresholds()
3141 cp->rx_pause_off = 7104; in cas_init_pause_thresholds()
3142 cp->rx_pause_on = 960; in cas_init_pause_thresholds()
3144 int off = (cp->rx_fifo_size - (max_frame * 2)); in cas_init_pause_thresholds()
3146 cp->rx_pause_off = off; in cas_init_pause_thresholds()
3147 cp->rx_pause_on = on; in cas_init_pause_thresholds()
3176 static int cas_get_vpd_info(struct cas *cp, unsigned char *dev_addr, in cas_get_vpd_info() argument
3179 void __iomem *p = cp->regs + REG_EXPANSION_ROM_RUN_START; in cas_get_vpd_info()
3195 cp->regs + REG_BIM_LOCAL_DEV_EN); in cas_get_vpd_info()
3300 cp->cas_flags |= CAS_FLAG_ENTROPY_DEV; in cas_get_vpd_info()
3341 addr = of_get_property(cp->of_node, "local-mac-address", NULL); in cas_get_vpd_info()
3356 writel(0, cp->regs + REG_BIM_LOCAL_DEV_EN); in cas_get_vpd_info()
3361 static void cas_check_pci_invariants(struct cas *cp) in cas_check_pci_invariants() argument
3363 struct pci_dev *pdev = cp->pdev; in cas_check_pci_invariants()
3365 cp->cas_flags = 0; in cas_check_pci_invariants()
3369 cp->cas_flags |= CAS_FLAG_REG_PLUS; in cas_check_pci_invariants()
3371 cp->cas_flags |= CAS_FLAG_TARGET_ABORT; in cas_check_pci_invariants()
3377 cp->cas_flags |= CAS_FLAG_NO_HW_CSUM; in cas_check_pci_invariants()
3380 cp->cas_flags |= CAS_FLAG_REG_PLUS; in cas_check_pci_invariants()
3387 cp->cas_flags |= CAS_FLAG_SATURN; in cas_check_pci_invariants()
3392 static int cas_check_invariants(struct cas *cp) in cas_check_invariants() argument
3394 struct pci_dev *pdev = cp->pdev; in cas_check_invariants()
3399 cp->page_order = 0; in cas_check_invariants()
3408 cp->page_order = CAS_JUMBO_PAGE_SHIFT - PAGE_SHIFT; in cas_check_invariants()
3414 cp->page_size = (PAGE_SIZE << cp->page_order); in cas_check_invariants()
3417 cp->tx_fifo_size = readl(cp->regs + REG_TX_FIFO_SIZE) * 64; in cas_check_invariants()
3418 cp->rx_fifo_size = RX_FIFO_SIZE; in cas_check_invariants()
3423 cp->phy_type = cas_get_vpd_info(cp, cp->dev->dev_addr, in cas_check_invariants()
3425 if (cp->phy_type & CAS_PHY_SERDES) { in cas_check_invariants()
3426 cp->cas_flags |= CAS_FLAG_1000MB_CAP; in cas_check_invariants()
3431 cfg = readl(cp->regs + REG_MIF_CFG); in cas_check_invariants()
3433 cp->phy_type = CAS_PHY_MII_MDIO1; in cas_check_invariants()
3435 cp->phy_type = CAS_PHY_MII_MDIO0; in cas_check_invariants()
3438 cas_mif_poll(cp, 0); in cas_check_invariants()
3439 writel(PCS_DATAPATH_MODE_MII, cp->regs + REG_PCS_DATAPATH_MODE); in cas_check_invariants()
3446 cp->phy_addr = i; in cas_check_invariants()
3447 phy_id = cas_phy_read(cp, MII_PHYSID1) << 16; in cas_check_invariants()
3448 phy_id |= cas_phy_read(cp, MII_PHYSID2); in cas_check_invariants()
3450 cp->phy_id = phy_id; in cas_check_invariants()
3456 readl(cp->regs + REG_MIF_STATE_MACHINE)); in cas_check_invariants()
3461 cfg = cas_phy_read(cp, MII_BMSR); in cas_check_invariants()
3463 cas_phy_read(cp, CAS_MII_1000_EXTEND)) in cas_check_invariants()
3464 cp->cas_flags |= CAS_FLAG_1000MB_CAP; in cas_check_invariants()
3469 static inline void cas_start_dma(struct cas *cp) in cas_start_dma() argument
3476 val = readl(cp->regs + REG_TX_CFG) | TX_CFG_DMA_EN; in cas_start_dma()
3477 writel(val, cp->regs + REG_TX_CFG); in cas_start_dma()
3478 val = readl(cp->regs + REG_RX_CFG) | RX_CFG_DMA_EN; in cas_start_dma()
3479 writel(val, cp->regs + REG_RX_CFG); in cas_start_dma()
3482 val = readl(cp->regs + REG_MAC_TX_CFG) | MAC_TX_CFG_EN; in cas_start_dma()
3483 writel(val, cp->regs + REG_MAC_TX_CFG); in cas_start_dma()
3484 val = readl(cp->regs + REG_MAC_RX_CFG) | MAC_RX_CFG_EN; in cas_start_dma()
3485 writel(val, cp->regs + REG_MAC_RX_CFG); in cas_start_dma()
3489 val = readl(cp->regs + REG_MAC_TX_CFG); in cas_start_dma()
3497 val = readl(cp->regs + REG_MAC_RX_CFG); in cas_start_dma()
3500 netdev_err(cp->dev, in cas_start_dma()
3502 readl(cp->regs + REG_MIF_STATE_MACHINE), in cas_start_dma()
3503 readl(cp->regs + REG_MAC_STATE_MACHINE)); in cas_start_dma()
3509 netdev_err(cp->dev, "enabling mac failed [%s:%08x:%08x]\n", in cas_start_dma()
3511 readl(cp->regs + REG_MIF_STATE_MACHINE), in cas_start_dma()
3512 readl(cp->regs + REG_MAC_STATE_MACHINE)); in cas_start_dma()
3515 cas_unmask_intr(cp); /* enable interrupts */ in cas_start_dma()
3516 writel(RX_DESC_RINGN_SIZE(0) - 4, cp->regs + REG_RX_KICK); in cas_start_dma()
3517 writel(0, cp->regs + REG_RX_COMP_TAIL); in cas_start_dma()
3519 if (cp->cas_flags & CAS_FLAG_REG_PLUS) { in cas_start_dma()
3522 cp->regs + REG_PLUS_RX_KICK1); in cas_start_dma()
3525 writel(0, cp->regs + REG_PLUS_RX_COMPN_TAIL(i)); in cas_start_dma()
3530 static void cas_read_pcs_link_mode(struct cas *cp, int *fd, int *spd, in cas_read_pcs_link_mode() argument
3533 u32 val = readl(cp->regs + REG_PCS_MII_LPA); in cas_read_pcs_link_mode()
3542 static void cas_read_mii_link_mode(struct cas *cp, int *fd, int *spd, in cas_read_mii_link_mode() argument
3552 val = cas_phy_read(cp, MII_LPA); in cas_read_mii_link_mode()
3564 if (cp->cas_flags & CAS_FLAG_1000MB_CAP) { in cas_read_mii_link_mode()
3565 val = cas_phy_read(cp, CAS_MII_1000_STATUS); in cas_read_mii_link_mode()
3578 static void cas_set_link_modes(struct cas *cp) in cas_set_link_modes() argument
3587 if (CAS_PHY_MII(cp->phy_type)) { in cas_set_link_modes()
3588 cas_mif_poll(cp, 0); in cas_set_link_modes()
3589 val = cas_phy_read(cp, MII_BMCR); in cas_set_link_modes()
3591 cas_read_mii_link_mode(cp, &full_duplex, &speed, in cas_set_link_modes()
3600 speed = (cp->cas_flags & CAS_FLAG_1000MB_CAP) ? in cas_set_link_modes()
3603 cas_mif_poll(cp, 1); in cas_set_link_modes()
3606 val = readl(cp->regs + REG_PCS_MII_CTRL); in cas_set_link_modes()
3607 cas_read_pcs_link_mode(cp, &full_duplex, &speed, &pause); in cas_set_link_modes()
3614 netif_info(cp, link, cp->dev, "Link up at %d Mbps, %s-duplex\n", in cas_set_link_modes()
3618 if (CAS_PHY_MII(cp->phy_type)) { in cas_set_link_modes()
3627 writel(val, cp->regs + REG_MAC_XIF_CFG); in cas_set_link_modes()
3649 cp->regs + REG_MAC_TX_CFG); in cas_set_link_modes()
3651 val = readl(cp->regs + REG_MAC_RX_CFG); in cas_set_link_modes()
3654 cp->regs + REG_MAC_RX_CFG); in cas_set_link_modes()
3656 writel(0x200, cp->regs + REG_MAC_SLOT_TIME); in cas_set_link_modes()
3658 cp->crc_size = 4; in cas_set_link_modes()
3660 cp->min_frame_size = CAS_1000MB_MIN_FRAME; in cas_set_link_modes()
3663 writel(val, cp->regs + REG_MAC_TX_CFG); in cas_set_link_modes()
3668 val = readl(cp->regs + REG_MAC_RX_CFG); in cas_set_link_modes()
3671 cp->crc_size = 0; in cas_set_link_modes()
3672 cp->min_frame_size = CAS_MIN_MTU; in cas_set_link_modes()
3675 cp->crc_size = 4; in cas_set_link_modes()
3676 cp->min_frame_size = CAS_MIN_FRAME; in cas_set_link_modes()
3679 cp->regs + REG_MAC_RX_CFG); in cas_set_link_modes()
3680 writel(0x40, cp->regs + REG_MAC_SLOT_TIME); in cas_set_link_modes()
3683 if (netif_msg_link(cp)) { in cas_set_link_modes()
3685 netdev_info(cp->dev, "Pause is enabled (rxfifo: %d off: %d on: %d)\n", in cas_set_link_modes()
3686 cp->rx_fifo_size, in cas_set_link_modes()
3687 cp->rx_pause_off, in cas_set_link_modes()
3688 cp->rx_pause_on); in cas_set_link_modes()
3690 netdev_info(cp->dev, "TX pause enabled\n"); in cas_set_link_modes()
3692 netdev_info(cp->dev, "Pause is disabled\n"); in cas_set_link_modes()
3696 val = readl(cp->regs + REG_MAC_CTRL_CFG); in cas_set_link_modes()
3704 writel(val, cp->regs + REG_MAC_CTRL_CFG); in cas_set_link_modes()
3705 cas_start_dma(cp); in cas_set_link_modes()
3709 static void cas_init_hw(struct cas *cp, int restart_link) in cas_init_hw() argument
3712 cas_phy_init(cp); in cas_init_hw()
3714 cas_init_pause_thresholds(cp); in cas_init_hw()
3715 cas_init_mac(cp); in cas_init_hw()
3716 cas_init_dma(cp); in cas_init_hw()
3720 cp->timer_ticks = 0; in cas_init_hw()
3721 cas_begin_auto_negotiation(cp, NULL); in cas_init_hw()
3722 } else if (cp->lstate == link_up) { in cas_init_hw()
3723 cas_set_link_modes(cp); in cas_init_hw()
3724 netif_carrier_on(cp->dev); in cas_init_hw()
3732 static void cas_hard_reset(struct cas *cp) in cas_hard_reset() argument
3734 writel(BIM_LOCAL_DEV_SOFT_0, cp->regs + REG_BIM_LOCAL_DEV_EN); in cas_hard_reset()
3736 pci_restore_state(cp->pdev); in cas_hard_reset()
3740 static void cas_global_reset(struct cas *cp, int blkflag) in cas_global_reset() argument
3745 if (blkflag && !CAS_PHY_MII(cp->phy_type)) { in cas_global_reset()
3753 cp->regs + REG_SW_RESET); in cas_global_reset()
3755 writel(SW_RESET_TX | SW_RESET_RX, cp->regs + REG_SW_RESET); in cas_global_reset()
3763 u32 val = readl(cp->regs + REG_SW_RESET); in cas_global_reset()
3768 netdev_err(cp->dev, "sw reset failed\n"); in cas_global_reset()
3773 BIM_CFG_RTA_INTR_ENABLE, cp->regs + REG_BIM_CFG); in cas_global_reset()
3781 PCI_ERR_BIM_DMA_READ), cp->regs + in cas_global_reset()
3787 writel(PCS_DATAPATH_MODE_MII, cp->regs + REG_PCS_DATAPATH_MODE); in cas_global_reset()
3790 static void cas_reset(struct cas *cp, int blkflag) in cas_reset() argument
3794 cas_mask_intr(cp); in cas_reset()
3795 cas_global_reset(cp, blkflag); in cas_reset()
3796 cas_mac_reset(cp); in cas_reset()
3797 cas_entropy_reset(cp); in cas_reset()
3800 val = readl(cp->regs + REG_TX_CFG); in cas_reset()
3802 writel(val, cp->regs + REG_TX_CFG); in cas_reset()
3804 val = readl(cp->regs + REG_RX_CFG); in cas_reset()
3806 writel(val, cp->regs + REG_RX_CFG); in cas_reset()
3809 if ((cp->cas_flags & CAS_FLAG_TARGET_ABORT) || in cas_reset()
3811 cas_load_firmware(cp, CAS_HP_FIRMWARE); in cas_reset()
3813 cas_load_firmware(cp, CAS_HP_ALT_FIRMWARE); in cas_reset()
3817 spin_lock(&cp->stat_lock[N_TX_RINGS]); in cas_reset()
3818 cas_clear_mac_err(cp); in cas_reset()
3819 spin_unlock(&cp->stat_lock[N_TX_RINGS]); in cas_reset()
3823 static void cas_shutdown(struct cas *cp) in cas_shutdown() argument
3828 cp->hw_running = 0; in cas_shutdown()
3830 del_timer_sync(&cp->link_timer); in cas_shutdown()
3834 while (atomic_read(&cp->reset_task_pending_mtu) || in cas_shutdown()
3835 atomic_read(&cp->reset_task_pending_spare) || in cas_shutdown()
3836 atomic_read(&cp->reset_task_pending_all)) in cas_shutdown()
3840 while (atomic_read(&cp->reset_task_pending)) in cas_shutdown()
3844 cas_lock_all_save(cp, flags); in cas_shutdown()
3845 cas_reset(cp, 0); in cas_shutdown()
3846 if (cp->cas_flags & CAS_FLAG_SATURN) in cas_shutdown()
3847 cas_phy_powerdown(cp); in cas_shutdown()
3848 cas_unlock_all_restore(cp, flags); in cas_shutdown()
3853 struct cas *cp = netdev_priv(dev); in cas_change_mtu() local
3861 atomic_inc(&cp->reset_task_pending); in cas_change_mtu()
3862 if ((cp->phy_type & CAS_PHY_SERDES)) { in cas_change_mtu()
3863 atomic_inc(&cp->reset_task_pending_all); in cas_change_mtu()
3865 atomic_inc(&cp->reset_task_pending_mtu); in cas_change_mtu()
3867 schedule_work(&cp->reset_task); in cas_change_mtu()
3869 atomic_set(&cp->reset_task_pending, (cp->phy_type & CAS_PHY_SERDES) ? in cas_change_mtu()
3872 schedule_work(&cp->reset_task); in cas_change_mtu()
3875 flush_work(&cp->reset_task); in cas_change_mtu()
3879 static void cas_clean_txd(struct cas *cp, int ring) in cas_clean_txd() argument
3881 struct cas_tx_desc *txd = cp->init_txds[ring]; in cas_clean_txd()
3882 struct sk_buff *skb, **skbs = cp->tx_skbs[ring]; in cas_clean_txd()
3905 pci_unmap_page(cp->pdev, daddr, dlen, in cas_clean_txd()
3915 if (cp->tx_tiny_use[ring][ent].used) in cas_clean_txd()
3923 memset(cp->tx_tiny_use[ring], 0, size*sizeof(*cp->tx_tiny_use[ring])); in cas_clean_txd()
3927 static inline void cas_free_rx_desc(struct cas *cp, int ring) in cas_free_rx_desc() argument
3929 cas_page_t **page = cp->rx_pages[ring]; in cas_free_rx_desc()
3935 cas_page_free(cp, page[i]); in cas_free_rx_desc()
3941 static void cas_free_rxds(struct cas *cp) in cas_free_rxds() argument
3946 cas_free_rx_desc(cp, i); in cas_free_rxds()
3950 static void cas_clean_rings(struct cas *cp) in cas_clean_rings() argument
3955 memset(cp->tx_old, 0, sizeof(*cp->tx_old)*N_TX_RINGS); in cas_clean_rings()
3956 memset(cp->tx_new, 0, sizeof(*cp->tx_new)*N_TX_RINGS); in cas_clean_rings()
3958 cas_clean_txd(cp, i); in cas_clean_rings()
3961 memset(cp->init_block, 0, sizeof(struct cas_init_block)); in cas_clean_rings()
3962 cas_clean_rxds(cp); in cas_clean_rings()
3963 cas_clean_rxcs(cp); in cas_clean_rings()
3967 static inline int cas_alloc_rx_desc(struct cas *cp, int ring) in cas_alloc_rx_desc() argument
3969 cas_page_t **page = cp->rx_pages[ring]; in cas_alloc_rx_desc()
3974 if ((page[i] = cas_page_alloc(cp, GFP_KERNEL)) == NULL) in cas_alloc_rx_desc()
3980 static int cas_alloc_rxds(struct cas *cp) in cas_alloc_rxds() argument
3985 if (cas_alloc_rx_desc(cp, i) < 0) { in cas_alloc_rxds()
3986 cas_free_rxds(cp); in cas_alloc_rxds()
3995 struct cas *cp = container_of(work, struct cas, reset_task); in cas_reset_task() local
3997 int pending = atomic_read(&cp->reset_task_pending); in cas_reset_task()
3999 int pending_all = atomic_read(&cp->reset_task_pending_all); in cas_reset_task()
4000 int pending_spare = atomic_read(&cp->reset_task_pending_spare); in cas_reset_task()
4001 int pending_mtu = atomic_read(&cp->reset_task_pending_mtu); in cas_reset_task()
4007 atomic_dec(&cp->reset_task_pending); in cas_reset_task()
4015 if (cp->hw_running) { in cas_reset_task()
4019 netif_device_detach(cp->dev); in cas_reset_task()
4020 cas_lock_all_save(cp, flags); in cas_reset_task()
4022 if (cp->opened) { in cas_reset_task()
4027 cas_spare_recover(cp, GFP_ATOMIC); in cas_reset_task()
4045 cas_reset(cp, !(pending_all > 0)); in cas_reset_task()
4046 if (cp->opened) in cas_reset_task()
4047 cas_clean_rings(cp); in cas_reset_task()
4048 cas_init_hw(cp, (pending_all > 0)); in cas_reset_task()
4050 cas_reset(cp, !(pending == CAS_RESET_ALL)); in cas_reset_task()
4051 if (cp->opened) in cas_reset_task()
4052 cas_clean_rings(cp); in cas_reset_task()
4053 cas_init_hw(cp, pending == CAS_RESET_ALL); in cas_reset_task()
4057 cas_unlock_all_restore(cp, flags); in cas_reset_task()
4058 netif_device_attach(cp->dev); in cas_reset_task()
4061 atomic_sub(pending_all, &cp->reset_task_pending_all); in cas_reset_task()
4062 atomic_sub(pending_spare, &cp->reset_task_pending_spare); in cas_reset_task()
4063 atomic_sub(pending_mtu, &cp->reset_task_pending_mtu); in cas_reset_task()
4064 atomic_dec(&cp->reset_task_pending); in cas_reset_task()
4066 atomic_set(&cp->reset_task_pending, 0); in cas_reset_task()
4072 struct cas *cp = from_timer(cp, t, link_timer); in cas_link_timer() local
4077 cp->link_transition_jiffies_valid && in cas_link_timer()
4078 ((jiffies - cp->link_transition_jiffies) > in cas_link_timer()
4084 cp->link_transition_jiffies_valid = 0; in cas_link_timer()
4087 if (!cp->hw_running) in cas_link_timer()
4090 spin_lock_irqsave(&cp->lock, flags); in cas_link_timer()
4091 cas_lock_tx(cp); in cas_link_timer()
4092 cas_entropy_gather(cp); in cas_link_timer()
4098 if (atomic_read(&cp->reset_task_pending_all) || in cas_link_timer()
4099 atomic_read(&cp->reset_task_pending_spare) || in cas_link_timer()
4100 atomic_read(&cp->reset_task_pending_mtu)) in cas_link_timer()
4103 if (atomic_read(&cp->reset_task_pending)) in cas_link_timer()
4108 if ((mask = (cp->cas_flags & CAS_FLAG_RXD_POST_MASK))) { in cas_link_timer()
4117 if (cas_post_rxds_ringN(cp, i, cp->rx_last[i]) < 0) { in cas_link_timer()
4121 cp->cas_flags &= ~rmask; in cas_link_timer()
4125 if (CAS_PHY_MII(cp->phy_type)) { in cas_link_timer()
4127 cas_mif_poll(cp, 0); in cas_link_timer()
4128 bmsr = cas_phy_read(cp, MII_BMSR); in cas_link_timer()
4134 bmsr = cas_phy_read(cp, MII_BMSR); in cas_link_timer()
4135 cas_mif_poll(cp, 1); in cas_link_timer()
4136 readl(cp->regs + REG_MIF_STATUS); /* avoid dups */ in cas_link_timer()
4137 reset = cas_mii_link_check(cp, bmsr); in cas_link_timer()
4139 reset = cas_pcs_link_check(cp); in cas_link_timer()
4146 if ((readl(cp->regs + REG_MAC_TX_STATUS) & MAC_TX_FRAME_XMIT) == 0) { in cas_link_timer()
4147 u32 val = readl(cp->regs + REG_MAC_STATE_MACHINE); in cas_link_timer()
4153 netif_printk(cp, tx_err, KERN_DEBUG, cp->dev, in cas_link_timer()
4159 val = readl(cp->regs + REG_TX_FIFO_PKT_CNT); in cas_link_timer()
4160 wptr = readl(cp->regs + REG_TX_FIFO_WRITE_PTR); in cas_link_timer()
4161 rptr = readl(cp->regs + REG_TX_FIFO_READ_PTR); in cas_link_timer()
4163 netif_printk(cp, tx_err, KERN_DEBUG, cp->dev, in cas_link_timer()
4170 cas_hard_reset(cp); in cas_link_timer()
4176 atomic_inc(&cp->reset_task_pending); in cas_link_timer()
4177 atomic_inc(&cp->reset_task_pending_all); in cas_link_timer()
4178 schedule_work(&cp->reset_task); in cas_link_timer()
4180 atomic_set(&cp->reset_task_pending, CAS_RESET_ALL); in cas_link_timer()
4182 schedule_work(&cp->reset_task); in cas_link_timer()
4187 mod_timer(&cp->link_timer, jiffies + CAS_LINK_TIMEOUT); in cas_link_timer()
4188 cas_unlock_tx(cp); in cas_link_timer()
4189 spin_unlock_irqrestore(&cp->lock, flags); in cas_link_timer()
4195 static void cas_tx_tiny_free(struct cas *cp) in cas_tx_tiny_free() argument
4197 struct pci_dev *pdev = cp->pdev; in cas_tx_tiny_free()
4201 if (!cp->tx_tiny_bufs[i]) in cas_tx_tiny_free()
4205 cp->tx_tiny_bufs[i], in cas_tx_tiny_free()
4206 cp->tx_tiny_dvma[i]); in cas_tx_tiny_free()
4207 cp->tx_tiny_bufs[i] = NULL; in cas_tx_tiny_free()
4211 static int cas_tx_tiny_alloc(struct cas *cp) in cas_tx_tiny_alloc() argument
4213 struct pci_dev *pdev = cp->pdev; in cas_tx_tiny_alloc()
4217 cp->tx_tiny_bufs[i] = in cas_tx_tiny_alloc()
4219 &cp->tx_tiny_dvma[i]); in cas_tx_tiny_alloc()
4220 if (!cp->tx_tiny_bufs[i]) { in cas_tx_tiny_alloc()
4221 cas_tx_tiny_free(cp); in cas_tx_tiny_alloc()
4231 struct cas *cp = netdev_priv(dev); in cas_open() local
4235 mutex_lock(&cp->pm_mutex); in cas_open()
4237 hw_was_up = cp->hw_running; in cas_open()
4242 if (!cp->hw_running) { in cas_open()
4244 cas_lock_all_save(cp, flags); in cas_open()
4250 cas_reset(cp, 0); in cas_open()
4251 cp->hw_running = 1; in cas_open()
4252 cas_unlock_all_restore(cp, flags); in cas_open()
4256 if (cas_tx_tiny_alloc(cp) < 0) in cas_open()
4260 if (cas_alloc_rxds(cp) < 0) in cas_open()
4264 cas_spare_init(cp); in cas_open()
4265 cas_spare_recover(cp, GFP_KERNEL); in cas_open()
4272 if (request_irq(cp->pdev->irq, cas_interrupt, in cas_open()
4274 netdev_err(cp->dev, "failed to request irq !\n"); in cas_open()
4280 napi_enable(&cp->napi); in cas_open()
4283 cas_lock_all_save(cp, flags); in cas_open()
4284 cas_clean_rings(cp); in cas_open()
4285 cas_init_hw(cp, !hw_was_up); in cas_open()
4286 cp->opened = 1; in cas_open()
4287 cas_unlock_all_restore(cp, flags); in cas_open()
4290 mutex_unlock(&cp->pm_mutex); in cas_open()
4294 cas_spare_free(cp); in cas_open()
4295 cas_free_rxds(cp); in cas_open()
4297 cas_tx_tiny_free(cp); in cas_open()
4299 mutex_unlock(&cp->pm_mutex); in cas_open()
4306 struct cas *cp = netdev_priv(dev); in cas_close() local
4309 napi_disable(&cp->napi); in cas_close()
4312 mutex_lock(&cp->pm_mutex); in cas_close()
4317 cas_lock_all_save(cp, flags); in cas_close()
4318 cp->opened = 0; in cas_close()
4319 cas_reset(cp, 0); in cas_close()
4320 cas_phy_init(cp); in cas_close()
4321 cas_begin_auto_negotiation(cp, NULL); in cas_close()
4322 cas_clean_rings(cp); in cas_close()
4323 cas_unlock_all_restore(cp, flags); in cas_close()
4325 free_irq(cp->pdev->irq, (void *) dev); in cas_close()
4326 cas_spare_free(cp); in cas_close()
4327 cas_free_rxds(cp); in cas_close()
4328 cas_tx_tiny_free(cp); in cas_close()
4329 mutex_unlock(&cp->pm_mutex); in cas_close()
4380 static void cas_read_regs(struct cas *cp, u8 *ptr, int len) in cas_read_regs() argument
4386 spin_lock_irqsave(&cp->lock, flags); in cas_read_regs()
4391 hval = cas_phy_read(cp, in cas_read_regs()
4395 val= readl(cp->regs+ethtool_register_table[i].offsets); in cas_read_regs()
4399 spin_unlock_irqrestore(&cp->lock, flags); in cas_read_regs()
4404 struct cas *cp = netdev_priv(dev); in cas_get_stats() local
4405 struct net_device_stats *stats = cp->net_stats; in cas_get_stats()
4411 if (!cp->hw_running) in cas_get_stats()
4422 spin_lock_irqsave(&cp->stat_lock[N_TX_RINGS], flags); in cas_get_stats()
4424 readl(cp->regs + REG_MAC_FCS_ERR) & 0xffff; in cas_get_stats()
4426 readl(cp->regs + REG_MAC_ALIGN_ERR) &0xffff; in cas_get_stats()
4428 readl(cp->regs + REG_MAC_LEN_ERR) & 0xffff; in cas_get_stats()
4430 tmp = (readl(cp->regs + REG_MAC_COLL_EXCESS) & 0xffff) + in cas_get_stats()
4431 (readl(cp->regs + REG_MAC_COLL_LATE) & 0xffff); in cas_get_stats()
4434 tmp + (readl(cp->regs + REG_MAC_COLL_NORMAL) & 0xffff); in cas_get_stats()
4437 readl(cp->regs + REG_MAC_COLL_EXCESS); in cas_get_stats()
4438 stats[N_TX_RINGS].collisions += readl(cp->regs + REG_MAC_COLL_EXCESS) + in cas_get_stats()
4439 readl(cp->regs + REG_MAC_COLL_LATE); in cas_get_stats()
4441 cas_clear_mac_err(cp); in cas_get_stats()
4444 spin_lock(&cp->stat_lock[0]); in cas_get_stats()
4451 spin_unlock(&cp->stat_lock[0]); in cas_get_stats()
4454 spin_lock(&cp->stat_lock[i]); in cas_get_stats()
4467 spin_unlock(&cp->stat_lock[i]); in cas_get_stats()
4469 spin_unlock_irqrestore(&cp->stat_lock[N_TX_RINGS], flags); in cas_get_stats()
4476 struct cas *cp = netdev_priv(dev); in cas_set_multicast() local
4481 if (!cp->hw_running) in cas_set_multicast()
4484 spin_lock_irqsave(&cp->lock, flags); in cas_set_multicast()
4485 rxcfg = readl(cp->regs + REG_MAC_RX_CFG); in cas_set_multicast()
4488 writel(rxcfg & ~MAC_RX_CFG_EN, cp->regs + REG_MAC_RX_CFG); in cas_set_multicast()
4489 while (readl(cp->regs + REG_MAC_RX_CFG) & MAC_RX_CFG_EN) { in cas_set_multicast()
4498 writel(rxcfg & ~MAC_RX_CFG_EN, cp->regs + REG_MAC_RX_CFG); in cas_set_multicast()
4499 while (readl(cp->regs + REG_MAC_RX_CFG) & MAC_RX_CFG_HASH_FILTER_EN) { in cas_set_multicast()
4506 cp->mac_rx_cfg = rxcfg_new = cas_setup_multicast(cp); in cas_set_multicast()
4508 writel(rxcfg, cp->regs + REG_MAC_RX_CFG); in cas_set_multicast()
4509 spin_unlock_irqrestore(&cp->lock, flags); in cas_set_multicast()
4514 struct cas *cp = netdev_priv(dev); in cas_get_drvinfo() local
4517 strlcpy(info->bus_info, pci_name(cp->pdev), sizeof(info->bus_info)); in cas_get_drvinfo()
4523 struct cas *cp = netdev_priv(dev); in cas_get_link_ksettings() local
4532 if (cp->cas_flags & CAS_FLAG_1000MB_CAP) { in cas_get_link_ksettings()
4538 spin_lock_irqsave(&cp->lock, flags); in cas_get_link_ksettings()
4540 linkstate = cp->lstate; in cas_get_link_ksettings()
4541 if (CAS_PHY_MII(cp->phy_type)) { in cas_get_link_ksettings()
4543 cmd->base.phy_address = cp->phy_addr; in cas_get_link_ksettings()
4557 if (cp->hw_running) { in cas_get_link_ksettings()
4558 cas_mif_poll(cp, 0); in cas_get_link_ksettings()
4559 bmcr = cas_phy_read(cp, MII_BMCR); in cas_get_link_ksettings()
4560 cas_read_mii_link_mode(cp, &full_duplex, in cas_get_link_ksettings()
4562 cas_mif_poll(cp, 1); in cas_get_link_ksettings()
4571 if (cp->hw_running) { in cas_get_link_ksettings()
4573 bmcr = readl(cp->regs + REG_PCS_MII_CTRL); in cas_get_link_ksettings()
4574 cas_read_pcs_link_mode(cp, &full_duplex, in cas_get_link_ksettings()
4578 spin_unlock_irqrestore(&cp->lock, flags); in cas_get_link_ksettings()
4608 if (cp->link_cntl & BMCR_ANENABLE) { in cas_get_link_ksettings()
4613 if (cp->link_cntl & BMCR_SPEED100) { in cas_get_link_ksettings()
4615 } else if (cp->link_cntl & CAS_BMCR_SPEED1000) { in cas_get_link_ksettings()
4618 cmd->base.duplex = (cp->link_cntl & BMCR_FULLDPLX) ? in cas_get_link_ksettings()
4634 struct cas *cp = netdev_priv(dev); in cas_set_link_ksettings() local
4652 spin_lock_irqsave(&cp->lock, flags); in cas_set_link_ksettings()
4653 cas_begin_auto_negotiation(cp, cmd); in cas_set_link_ksettings()
4654 spin_unlock_irqrestore(&cp->lock, flags); in cas_set_link_ksettings()
4660 struct cas *cp = netdev_priv(dev); in cas_nway_reset() local
4663 if ((cp->link_cntl & BMCR_ANENABLE) == 0) in cas_nway_reset()
4667 spin_lock_irqsave(&cp->lock, flags); in cas_nway_reset()
4668 cas_begin_auto_negotiation(cp, NULL); in cas_nway_reset()
4669 spin_unlock_irqrestore(&cp->lock, flags); in cas_nway_reset()
4676 struct cas *cp = netdev_priv(dev); in cas_get_link() local
4677 return cp->lstate == link_up; in cas_get_link()
4682 struct cas *cp = netdev_priv(dev); in cas_get_msglevel() local
4683 return cp->msg_enable; in cas_get_msglevel()
4688 struct cas *cp = netdev_priv(dev); in cas_set_msglevel() local
4689 cp->msg_enable = value; in cas_set_msglevel()
4694 struct cas *cp = netdev_priv(dev); in cas_get_regs_len() local
4695 return cp->casreg_len < CAS_MAX_REGS ? cp->casreg_len: CAS_MAX_REGS; in cas_get_regs_len()
4701 struct cas *cp = netdev_priv(dev); in cas_get_regs() local
4704 cas_read_regs(cp, p, regs->len / sizeof(u32)); in cas_get_regs()
4726 struct cas *cp = netdev_priv(dev); in cas_get_ethtool_stats() local
4727 struct net_device_stats *stats = cas_get_stats(cp->dev); in cas_get_ethtool_stats()
4765 struct cas *cp = netdev_priv(dev); in cas_ioctl() local
4773 mutex_lock(&cp->pm_mutex); in cas_ioctl()
4776 data->phy_id = cp->phy_addr; in cas_ioctl()
4780 spin_lock_irqsave(&cp->lock, flags); in cas_ioctl()
4781 cas_mif_poll(cp, 0); in cas_ioctl()
4782 data->val_out = cas_phy_read(cp, data->reg_num & 0x1f); in cas_ioctl()
4783 cas_mif_poll(cp, 1); in cas_ioctl()
4784 spin_unlock_irqrestore(&cp->lock, flags); in cas_ioctl()
4789 spin_lock_irqsave(&cp->lock, flags); in cas_ioctl()
4790 cas_mif_poll(cp, 0); in cas_ioctl()
4791 rc = cas_phy_write(cp, data->reg_num & 0x1f, data->val_in); in cas_ioctl()
4792 cas_mif_poll(cp, 1); in cas_ioctl()
4793 spin_unlock_irqrestore(&cp->lock, flags); in cas_ioctl()
4799 mutex_unlock(&cp->pm_mutex); in cas_ioctl()
4908 struct cas *cp; in cas_init_one() local
4929 dev = alloc_etherdev(sizeof(*cp)); in cas_init_one()
5003 cp = netdev_priv(dev); in cas_init_one()
5004 cp->pdev = pdev; in cas_init_one()
5007 cp->orig_cacheline_size = cas_cacheline_size ? orig_cacheline_size: 0; in cas_init_one()
5009 cp->dev = dev; in cas_init_one()
5010 cp->msg_enable = (cassini_debug < 0) ? CAS_DEF_MSG_ENABLE : in cas_init_one()
5014 cp->of_node = pci_device_to_OF_node(pdev); in cas_init_one()
5017 cp->link_transition = LINK_TRANSITION_UNKNOWN; in cas_init_one()
5018 cp->link_transition_jiffies_valid = 0; in cas_init_one()
5020 spin_lock_init(&cp->lock); in cas_init_one()
5021 spin_lock_init(&cp->rx_inuse_lock); in cas_init_one()
5022 spin_lock_init(&cp->rx_spare_lock); in cas_init_one()
5024 spin_lock_init(&cp->stat_lock[i]); in cas_init_one()
5025 spin_lock_init(&cp->tx_lock[i]); in cas_init_one()
5027 spin_lock_init(&cp->stat_lock[N_TX_RINGS]); in cas_init_one()
5028 mutex_init(&cp->pm_mutex); in cas_init_one()
5030 timer_setup(&cp->link_timer, cas_link_timer, 0); in cas_init_one()
5036 atomic_set(&cp->reset_task_pending, 0); in cas_init_one()
5037 atomic_set(&cp->reset_task_pending_all, 0); in cas_init_one()
5038 atomic_set(&cp->reset_task_pending_spare, 0); in cas_init_one()
5039 atomic_set(&cp->reset_task_pending_mtu, 0); in cas_init_one()
5041 INIT_WORK(&cp->reset_task, cas_reset_task); in cas_init_one()
5045 cp->link_cntl = link_modes[link_mode]; in cas_init_one()
5047 cp->link_cntl = BMCR_ANENABLE; in cas_init_one()
5048 cp->lstate = link_down; in cas_init_one()
5049 cp->link_transition = LINK_TRANSITION_LINK_DOWN; in cas_init_one()
5050 netif_carrier_off(cp->dev); in cas_init_one()
5051 cp->timer_ticks = 0; in cas_init_one()
5054 cp->regs = pci_iomap(pdev, 0, casreg_len); in cas_init_one()
5055 if (!cp->regs) { in cas_init_one()
5059 cp->casreg_len = casreg_len; in cas_init_one()
5062 cas_check_pci_invariants(cp); in cas_init_one()
5063 cas_hard_reset(cp); in cas_init_one()
5064 cas_reset(cp, 0); in cas_init_one()
5065 if (cas_check_invariants(cp)) in cas_init_one()
5067 if (cp->cas_flags & CAS_FLAG_SATURN) in cas_init_one()
5068 cas_saturn_firmware_init(cp); in cas_init_one()
5070 cp->init_block = (struct cas_init_block *) in cas_init_one()
5072 &cp->block_dvma); in cas_init_one()
5073 if (!cp->init_block) { in cas_init_one()
5079 cp->init_txds[i] = cp->init_block->txds[i]; in cas_init_one()
5082 cp->init_rxds[i] = cp->init_block->rxds[i]; in cas_init_one()
5085 cp->init_rxcs[i] = cp->init_block->rxcs[i]; in cas_init_one()
5088 skb_queue_head_init(&cp->rx_flows[i]); in cas_init_one()
5095 netif_napi_add(dev, &cp->napi, cas_poll, 64); in cas_init_one()
5101 if ((cp->cas_flags & CAS_FLAG_NO_HW_CSUM) == 0) in cas_init_one()
5116 i = readl(cp->regs + REG_BIM_CFG); in cas_init_one()
5118 (cp->cas_flags & CAS_FLAG_REG_PLUS) ? "+" : "", in cas_init_one()
5121 (cp->phy_type == CAS_PHY_SERDES) ? "Fi" : "Cu", pdev->irq, in cas_init_one()
5125 cp->hw_running = 1; in cas_init_one()
5126 cas_entropy_reset(cp); in cas_init_one()
5127 cas_phy_init(cp); in cas_init_one()
5128 cas_begin_auto_negotiation(cp, NULL); in cas_init_one()
5133 cp->init_block, cp->block_dvma); in cas_init_one()
5136 mutex_lock(&cp->pm_mutex); in cas_init_one()
5137 if (cp->hw_running) in cas_init_one()
5138 cas_shutdown(cp); in cas_init_one()
5139 mutex_unlock(&cp->pm_mutex); in cas_init_one()
5141 pci_iounmap(pdev, cp->regs); in cas_init_one()
5164 struct cas *cp; in cas_remove_one() local
5168 cp = netdev_priv(dev); in cas_remove_one()
5171 vfree(cp->fw_data); in cas_remove_one()
5173 mutex_lock(&cp->pm_mutex); in cas_remove_one()
5174 cancel_work_sync(&cp->reset_task); in cas_remove_one()
5175 if (cp->hw_running) in cas_remove_one()
5176 cas_shutdown(cp); in cas_remove_one()
5177 mutex_unlock(&cp->pm_mutex); in cas_remove_one()
5180 if (cp->orig_cacheline_size) { in cas_remove_one()
5185 cp->orig_cacheline_size); in cas_remove_one()
5189 cp->init_block, cp->block_dvma); in cas_remove_one()
5190 pci_iounmap(pdev, cp->regs); in cas_remove_one()
5200 struct cas *cp = netdev_priv(dev); in cas_suspend() local
5203 mutex_lock(&cp->pm_mutex); in cas_suspend()
5206 if (cp->opened) { in cas_suspend()
5209 cas_lock_all_save(cp, flags); in cas_suspend()
5216 cas_reset(cp, 0); in cas_suspend()
5217 cas_clean_rings(cp); in cas_suspend()
5218 cas_unlock_all_restore(cp, flags); in cas_suspend()
5221 if (cp->hw_running) in cas_suspend()
5222 cas_shutdown(cp); in cas_suspend()
5223 mutex_unlock(&cp->pm_mutex); in cas_suspend()
5231 struct cas *cp = netdev_priv(dev); in cas_resume() local
5235 mutex_lock(&cp->pm_mutex); in cas_resume()
5236 cas_hard_reset(cp); in cas_resume()
5237 if (cp->opened) { in cas_resume()
5239 cas_lock_all_save(cp, flags); in cas_resume()
5240 cas_reset(cp, 0); in cas_resume()
5241 cp->hw_running = 1; in cas_resume()
5242 cas_clean_rings(cp); in cas_resume()
5243 cas_init_hw(cp, 1); in cas_resume()
5244 cas_unlock_all_restore(cp, flags); in cas_resume()
5248 mutex_unlock(&cp->pm_mutex); in cas_resume()