···22742274config MV643XX_ETH22752275 tristate "Marvell Discovery (643XX) and Orion ethernet support"22762276 depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) || PLAT_ORION22772277- select MII22772277+ select PHYLIB22782278 help22792279 This driver supports the gigabit ethernet MACs in the22802280 Marvell Discovery PPC/MIPS chipset family (MV643XX) and
+755-721
drivers/net/mv643xx_eth.c
···4848#include <linux/kernel.h>4949#include <linux/spinlock.h>5050#include <linux/workqueue.h>5151-#include <linux/mii.h>5151+#include <linux/phy.h>5252#include <linux/mv643xx_eth.h>5353#include <asm/io.h>5454#include <asm/types.h>5555#include <asm/system.h>56565757static char mv643xx_eth_driver_name[] = "mv643xx_eth";5858-static char mv643xx_eth_driver_version[] = "1.3";5858+static char mv643xx_eth_driver_version[] = "1.4";59596060-#define MV643XX_ETH_CHECKSUM_OFFLOAD_TX6161-#define MV643XX_ETH_NAPI6262-#define MV643XX_ETH_TX_FAST_REFILL6363-6464-#ifdef MV643XX_ETH_CHECKSUM_OFFLOAD_TX6565-#define MAX_DESCS_PER_SKB (MAX_SKB_FRAGS + 1)6666-#else6767-#define MAX_DESCS_PER_SKB 16868-#endif69607061/*7162 * Registers shared between all ports.7263 */7364#define PHY_ADDR 0x00007465#define SMI_REG 0x00046666+#define SMI_BUSY 0x100000006767+#define SMI_READ_VALID 0x080000006868+#define SMI_OPCODE_READ 0x040000006969+#define SMI_OPCODE_WRITE 0x000000007070+#define ERR_INT_CAUSE 0x00807171+#define ERR_INT_SMI_DONE 0x000000107272+#define ERR_INT_MASK 0x00847573#define WINDOW_BASE(w) (0x0200 + ((w) << 3))7674#define WINDOW_SIZE(w) (0x0204 + ((w) << 3))7775#define WINDOW_REMAP_HIGH(w) (0x0280 + ((w) << 2))···102104#define TX_BW_MTU(p) (0x0458 + ((p) << 10))103105#define TX_BW_BURST(p) (0x045c + ((p) << 10))104106#define INT_CAUSE(p) (0x0460 + ((p) << 10))105105-#define INT_TX_END_0 0x00080000106107#define INT_TX_END 0x07f80000107107-#define INT_RX 0x0007fbfc108108+#define INT_RX 0x000003fc108109#define INT_EXT 0x00000002109110#define INT_CAUSE_EXT(p) (0x0464 + ((p) << 10))110110-#define INT_EXT_LINK 0x00100000111111-#define INT_EXT_PHY 0x00010000112112-#define INT_EXT_TX_ERROR_0 0x00000100113113-#define INT_EXT_TX_0 0x00000001114114-#define INT_EXT_TX 0x0000ffff111111+#define INT_EXT_LINK_PHY 0x00110000112112+#define INT_EXT_TX 0x000000ff115113#define INT_MASK(p) (0x0468 + ((p) << 10))116114#define INT_MASK_EXT(p) (0x046c + ((p) << 10))117115#define TX_FIFO_URGENT_THRESHOLD(p) (0x0474 + ((p) << 10))···165171#define FORCE_LINK_PASS (1 << 1)166172#define SERIAL_PORT_ENABLE (1 << 0)167173168168-#define DEFAULT_RX_QUEUE_SIZE 400169169-#define DEFAULT_TX_QUEUE_SIZE 800174174+#define DEFAULT_RX_QUEUE_SIZE 128175175+#define DEFAULT_TX_QUEUE_SIZE 256170176171177172178/*···243249 void __iomem *base;244250245251 /*246246- * Protects access to SMI_REG, which is shared between ports.252252+ * Points at the right SMI instance to use.247253 */248248- spinlock_t phy_lock;254254+ struct mv643xx_eth_shared_private *smi;255255+256256+ /*257257+ * Provides access to local SMI interface.258258+ */259259+ struct mii_bus smi_bus;260260+261261+ /*262262+ * If we have access to the error interrupt pin (which is263263+ * somewhat misnamed as it not only reflects internal errors264264+ * but also reflects SMI completion), use that to wait for265265+ * SMI access completion instead of polling the SMI busy bit.266266+ */267267+ int err_interrupt;268268+ wait_queue_head_t smi_busy_wait;249269250270 /*251271 * Per-port MBUS window access register value.···271263 */272264 unsigned int t_clk;273265 int extended_rx_coal_limit;274274- int tx_bw_control_moved;266266+ int tx_bw_control;275267};268268+269269+#define TX_BW_CONTROL_ABSENT 0270270+#define TX_BW_CONTROL_OLD_LAYOUT 1271271+#define TX_BW_CONTROL_NEW_LAYOUT 2276272277273278274/* per-port *****************************************************************/···326314 dma_addr_t rx_desc_dma;327315 int rx_desc_area_size;328316 struct sk_buff **rx_skb;329329-330330- struct timer_list rx_oom;331317};332318333319struct tx_queue {···340330 struct tx_desc *tx_desc_area;341331 dma_addr_t tx_desc_dma;342332 int tx_desc_area_size;343343- struct sk_buff **tx_skb;333333+334334+ struct sk_buff_head tx_skb;335335+336336+ unsigned long tx_packets;337337+ unsigned long tx_bytes;338338+ unsigned long tx_dropped;344339};345340346341struct mv643xx_eth_private {···354339355340 struct net_device *dev;356341357357- struct mv643xx_eth_shared_private *shared_smi;358358- int phy_addr;342342+ struct phy_device *phy;359343360360- spinlock_t lock;361361-344344+ struct timer_list mib_counters_timer;345345+ spinlock_t mib_counters_lock;362346 struct mib_counters mib_counters;347347+363348 struct work_struct tx_timeout_task;364364- struct mii_if_info mii;349349+350350+ struct napi_struct napi;351351+ u8 work_link;352352+ u8 work_tx;353353+ u8 work_tx_end;354354+ u8 work_rx;355355+ u8 work_rx_refill;356356+ u8 work_rx_oom;365357366358 /*367359 * RX state.···376354 int default_rx_ring_size;377355 unsigned long rx_desc_sram_addr;378356 int rx_desc_sram_size;379379- u8 rxq_mask;380380- int rxq_primary;381381- struct napi_struct napi;357357+ int rxq_count;358358+ struct timer_list rx_oom;382359 struct rx_queue rxq[8];383360384361 /*···386365 int default_tx_ring_size;387366 unsigned long tx_desc_sram_addr;388367 int tx_desc_sram_size;389389- u8 txq_mask;390390- int txq_primary;368368+ int txq_count;391369 struct tx_queue txq[8];392392-#ifdef MV643XX_ETH_TX_FAST_REFILL393393- int tx_clean_threshold;394394-#endif395370};396371397372···457440 udelay(10);458441}459442460460-static void __txq_maybe_wake(struct tx_queue *txq)443443+static void txq_maybe_wake(struct tx_queue *txq)461444{462445 struct mv643xx_eth_private *mp = txq_to_mp(txq);446446+ struct netdev_queue *nq = netdev_get_tx_queue(mp->dev, txq->index);463447464464- /*465465- * netif_{stop,wake}_queue() flow control only applies to466466- * the primary queue.467467- */468468- BUG_ON(txq->index != mp->txq_primary);469469-470470- if (txq->tx_ring_size - txq->tx_desc_count >= MAX_DESCS_PER_SKB)471471- netif_wake_queue(mp->dev);472472-}473473-474474-475475-/* rx ***********************************************************************/476476-static void txq_reclaim(struct tx_queue *txq, int force);477477-478478-static void rxq_refill(struct rx_queue *rxq)479479-{480480- struct mv643xx_eth_private *mp = rxq_to_mp(rxq);481481- unsigned long flags;482482-483483- spin_lock_irqsave(&mp->lock, flags);484484-485485- while (rxq->rx_desc_count < rxq->rx_ring_size) {486486- int skb_size;487487- struct sk_buff *skb;488488- int unaligned;489489- int rx;490490-491491- /*492492- * Reserve 2+14 bytes for an ethernet header (the493493- * hardware automatically prepends 2 bytes of dummy494494- * data to each received packet), 16 bytes for up to495495- * four VLAN tags, and 4 bytes for the trailing FCS496496- * -- 36 bytes total.497497- */498498- skb_size = mp->dev->mtu + 36;499499-500500- /*501501- * Make sure that the skb size is a multiple of 8502502- * bytes, as the lower three bits of the receive503503- * descriptor's buffer size field are ignored by504504- * the hardware.505505- */506506- skb_size = (skb_size + 7) & ~7;507507-508508- skb = dev_alloc_skb(skb_size + dma_get_cache_alignment() - 1);509509- if (skb == NULL)510510- break;511511-512512- unaligned = (u32)skb->data & (dma_get_cache_alignment() - 1);513513- if (unaligned)514514- skb_reserve(skb, dma_get_cache_alignment() - unaligned);515515-516516- rxq->rx_desc_count++;517517- rx = rxq->rx_used_desc;518518- rxq->rx_used_desc = (rx + 1) % rxq->rx_ring_size;519519-520520- rxq->rx_desc_area[rx].buf_ptr = dma_map_single(NULL, skb->data,521521- skb_size, DMA_FROM_DEVICE);522522- rxq->rx_desc_area[rx].buf_size = skb_size;523523- rxq->rx_skb[rx] = skb;524524- wmb();525525- rxq->rx_desc_area[rx].cmd_sts = BUFFER_OWNED_BY_DMA |526526- RX_ENABLE_INTERRUPT;527527- wmb();528528-529529- /*530530- * The hardware automatically prepends 2 bytes of531531- * dummy data to each received packet, so that the532532- * IP header ends up 16-byte aligned.533533- */534534- skb_reserve(skb, 2);448448+ if (netif_tx_queue_stopped(nq)) {449449+ __netif_tx_lock(nq, smp_processor_id());450450+ if (txq->tx_ring_size - txq->tx_desc_count >= MAX_SKB_FRAGS + 1)451451+ netif_tx_wake_queue(nq);452452+ __netif_tx_unlock(nq);535453 }536536-537537- if (rxq->rx_desc_count != rxq->rx_ring_size)538538- mod_timer(&rxq->rx_oom, jiffies + (HZ / 10));539539-540540- spin_unlock_irqrestore(&mp->lock, flags);541454}542455543543-static inline void rxq_refill_timer_wrapper(unsigned long data)544544-{545545- rxq_refill((struct rx_queue *)data);546546-}547456457457+/* rx napi ******************************************************************/548458static int rxq_process(struct rx_queue *rxq, int budget)549459{550460 struct mv643xx_eth_private *mp = rxq_to_mp(rxq);···483539 struct rx_desc *rx_desc;484540 unsigned int cmd_sts;485541 struct sk_buff *skb;486486- unsigned long flags;487487-488488- spin_lock_irqsave(&mp->lock, flags);542542+ u16 byte_cnt;489543490544 rx_desc = &rxq->rx_desc_area[rxq->rx_curr_desc];491545492546 cmd_sts = rx_desc->cmd_sts;493493- if (cmd_sts & BUFFER_OWNED_BY_DMA) {494494- spin_unlock_irqrestore(&mp->lock, flags);547547+ if (cmd_sts & BUFFER_OWNED_BY_DMA)495548 break;496496- }497549 rmb();498550499551 skb = rxq->rx_skb[rxq->rx_curr_desc];500552 rxq->rx_skb[rxq->rx_curr_desc] = NULL;501553502502- rxq->rx_curr_desc = (rxq->rx_curr_desc + 1) % rxq->rx_ring_size;554554+ rxq->rx_curr_desc++;555555+ if (rxq->rx_curr_desc == rxq->rx_ring_size)556556+ rxq->rx_curr_desc = 0;503557504504- spin_unlock_irqrestore(&mp->lock, flags);505505-506506- dma_unmap_single(NULL, rx_desc->buf_ptr + 2,558558+ dma_unmap_single(NULL, rx_desc->buf_ptr,507559 rx_desc->buf_size, DMA_FROM_DEVICE);508560 rxq->rx_desc_count--;509561 rx++;562562+563563+ mp->work_rx_refill |= 1 << rxq->index;564564+565565+ byte_cnt = rx_desc->byte_cnt;510566511567 /*512568 * Update statistics.···517573 * byte CRC at the end of the packet (which we do count).518574 */519575 stats->rx_packets++;520520- stats->rx_bytes += rx_desc->byte_cnt - 2;576576+ stats->rx_bytes += byte_cnt - 2;521577522578 /*523579 * In case we received a packet without first / last bits···540596 if (cmd_sts & ERROR_SUMMARY)541597 stats->rx_errors++;542598543543- dev_kfree_skb_irq(skb);599599+ dev_kfree_skb(skb);544600 } else {545601 /*546602 * The -4 is for the CRC in the trailer of the547603 * received packet548604 */549549- skb_put(skb, rx_desc->byte_cnt - 2 - 4);605605+ skb_put(skb, byte_cnt - 2 - 4);550606551551- if (cmd_sts & LAYER_4_CHECKSUM_OK) {607607+ if (cmd_sts & LAYER_4_CHECKSUM_OK)552608 skb->ip_summed = CHECKSUM_UNNECESSARY;553553- skb->csum = htons(554554- (cmd_sts & 0x0007fff8) >> 3);555555- }556609 skb->protocol = eth_type_trans(skb, mp->dev);557557-#ifdef MV643XX_ETH_NAPI558610 netif_receive_skb(skb);559559-#else560560- netif_rx(skb);561561-#endif562611 }563612564613 mp->dev->last_rx = jiffies;565614 }566615567567- rxq_refill(rxq);616616+ if (rx < budget)617617+ mp->work_rx &= ~(1 << rxq->index);568618569619 return rx;570620}571621572572-#ifdef MV643XX_ETH_NAPI573573-static int mv643xx_eth_poll(struct napi_struct *napi, int budget)622622+static int rxq_refill(struct rx_queue *rxq, int budget)574623{575575- struct mv643xx_eth_private *mp;576576- int rx;577577- int i;624624+ struct mv643xx_eth_private *mp = rxq_to_mp(rxq);625625+ int skb_size;626626+ int refilled;578627579579- mp = container_of(napi, struct mv643xx_eth_private, napi);628628+ /*629629+ * Reserve 2+14 bytes for an ethernet header (the hardware630630+ * automatically prepends 2 bytes of dummy data to each631631+ * received packet), 16 bytes for up to four VLAN tags, and632632+ * 4 bytes for the trailing FCS -- 36 bytes total.633633+ */634634+ skb_size = rxq_to_mp(rxq)->dev->mtu + 36;580635581581-#ifdef MV643XX_ETH_TX_FAST_REFILL582582- if (++mp->tx_clean_threshold > 5) {583583- mp->tx_clean_threshold = 0;584584- for (i = 0; i < 8; i++)585585- if (mp->txq_mask & (1 << i))586586- txq_reclaim(mp->txq + i, 0);636636+ /*637637+ * Make sure that the skb size is a multiple of 8 bytes, as638638+ * the lower three bits of the receive descriptor's buffer639639+ * size field are ignored by the hardware.640640+ */641641+ skb_size = (skb_size + 7) & ~7;587642588588- if (netif_carrier_ok(mp->dev)) {589589- spin_lock_irq(&mp->lock);590590- __txq_maybe_wake(mp->txq + mp->txq_primary);591591- spin_unlock_irq(&mp->lock);643643+ refilled = 0;644644+ while (refilled < budget && rxq->rx_desc_count < rxq->rx_ring_size) {645645+ struct sk_buff *skb;646646+ int unaligned;647647+ int rx;648648+649649+ skb = dev_alloc_skb(skb_size + dma_get_cache_alignment() - 1);650650+ if (skb == NULL) {651651+ mp->work_rx_oom |= 1 << rxq->index;652652+ goto oom;592653 }654654+655655+ unaligned = (u32)skb->data & (dma_get_cache_alignment() - 1);656656+ if (unaligned)657657+ skb_reserve(skb, dma_get_cache_alignment() - unaligned);658658+659659+ refilled++;660660+ rxq->rx_desc_count++;661661+662662+ rx = rxq->rx_used_desc++;663663+ if (rxq->rx_used_desc == rxq->rx_ring_size)664664+ rxq->rx_used_desc = 0;665665+666666+ rxq->rx_desc_area[rx].buf_ptr = dma_map_single(NULL, skb->data,667667+ skb_size, DMA_FROM_DEVICE);668668+ rxq->rx_desc_area[rx].buf_size = skb_size;669669+ rxq->rx_skb[rx] = skb;670670+ wmb();671671+ rxq->rx_desc_area[rx].cmd_sts = BUFFER_OWNED_BY_DMA |672672+ RX_ENABLE_INTERRUPT;673673+ wmb();674674+675675+ /*676676+ * The hardware automatically prepends 2 bytes of677677+ * dummy data to each received packet, so that the678678+ * IP header ends up 16-byte aligned.679679+ */680680+ skb_reserve(skb, 2);593681 }594594-#endif595682596596- rx = 0;597597- for (i = 7; rx < budget && i >= 0; i--)598598- if (mp->rxq_mask & (1 << i))599599- rx += rxq_process(mp->rxq + i, budget - rx);683683+ if (refilled < budget)684684+ mp->work_rx_refill &= ~(1 << rxq->index);600685601601- if (rx < budget) {602602- netif_rx_complete(mp->dev, napi);603603- wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);604604- }605605-606606- return rx;686686+oom:687687+ return refilled;607688}608608-#endif609689610690611691/* tx ***********************************************************************/···652684653685 BUG_ON(txq->tx_desc_count >= txq->tx_ring_size);654686655655- tx_desc_curr = txq->tx_curr_desc;656656- txq->tx_curr_desc = (tx_desc_curr + 1) % txq->tx_ring_size;687687+ tx_desc_curr = txq->tx_curr_desc++;688688+ if (txq->tx_curr_desc == txq->tx_ring_size)689689+ txq->tx_curr_desc = 0;657690658691 BUG_ON(txq->tx_curr_desc == txq->tx_used_desc);659692···683714 desc->cmd_sts = BUFFER_OWNED_BY_DMA |684715 ZERO_PADDING | TX_LAST_DESC |685716 TX_ENABLE_INTERRUPT;686686- txq->tx_skb[tx_index] = skb;687717 } else {688718 desc->cmd_sts = BUFFER_OWNED_BY_DMA;689689- txq->tx_skb[tx_index] = NULL;690719 }691720692721 desc->l4i_chk = 0;···701734 return (__force __be16)sum;702735}703736704704-static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)737737+static int txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)705738{706739 struct mv643xx_eth_private *mp = txq_to_mp(txq);707740 int nr_frags = skb_shinfo(skb)->nr_frags;708741 int tx_index;709742 struct tx_desc *desc;710743 u32 cmd_sts;744744+ u16 l4i_chk;711745 int length;712746713747 cmd_sts = TX_FIRST_DESC | GEN_CRC | BUFFER_OWNED_BY_DMA;748748+ l4i_chk = 0;749749+750750+ if (skb->ip_summed == CHECKSUM_PARTIAL) {751751+ int tag_bytes;752752+753753+ BUG_ON(skb->protocol != htons(ETH_P_IP) &&754754+ skb->protocol != htons(ETH_P_8021Q));755755+756756+ tag_bytes = (void *)ip_hdr(skb) - (void *)skb->data - ETH_HLEN;757757+ if (unlikely(tag_bytes & ~12)) {758758+ if (skb_checksum_help(skb) == 0)759759+ goto no_csum;760760+ kfree_skb(skb);761761+ return 1;762762+ }763763+764764+ if (tag_bytes & 4)765765+ cmd_sts |= MAC_HDR_EXTRA_4_BYTES;766766+ if (tag_bytes & 8)767767+ cmd_sts |= MAC_HDR_EXTRA_8_BYTES;768768+769769+ cmd_sts |= GEN_TCP_UDP_CHECKSUM |770770+ GEN_IP_V4_CHECKSUM |771771+ ip_hdr(skb)->ihl << TX_IHL_SHIFT;772772+773773+ switch (ip_hdr(skb)->protocol) {774774+ case IPPROTO_UDP:775775+ cmd_sts |= UDP_FRAME;776776+ l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check));777777+ break;778778+ case IPPROTO_TCP:779779+ l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check));780780+ break;781781+ default:782782+ BUG();783783+ }784784+ } else {785785+no_csum:786786+ /* Errata BTS #50, IHL must be 5 if no HW checksum */787787+ cmd_sts |= 5 << TX_IHL_SHIFT;788788+ }714789715790 tx_index = txq_alloc_desc_index(txq);716791 desc = &txq->tx_desc_area[tx_index];717792718793 if (nr_frags) {719794 txq_submit_frag_skb(txq, skb);720720-721795 length = skb_headlen(skb);722722- txq->tx_skb[tx_index] = NULL;723796 } else {724797 cmd_sts |= ZERO_PADDING | TX_LAST_DESC | TX_ENABLE_INTERRUPT;725798 length = skb->len;726726- txq->tx_skb[tx_index] = skb;727799 }728800801801+ desc->l4i_chk = l4i_chk;729802 desc->byte_cnt = length;730803 desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);731804732732- if (skb->ip_summed == CHECKSUM_PARTIAL) {733733- int mac_hdr_len;734734-735735- BUG_ON(skb->protocol != htons(ETH_P_IP) &&736736- skb->protocol != htons(ETH_P_8021Q));737737-738738- cmd_sts |= GEN_TCP_UDP_CHECKSUM |739739- GEN_IP_V4_CHECKSUM |740740- ip_hdr(skb)->ihl << TX_IHL_SHIFT;741741-742742- mac_hdr_len = (void *)ip_hdr(skb) - (void *)skb->data;743743- switch (mac_hdr_len - ETH_HLEN) {744744- case 0:745745- break;746746- case 4:747747- cmd_sts |= MAC_HDR_EXTRA_4_BYTES;748748- break;749749- case 8:750750- cmd_sts |= MAC_HDR_EXTRA_8_BYTES;751751- break;752752- case 12:753753- cmd_sts |= MAC_HDR_EXTRA_4_BYTES;754754- cmd_sts |= MAC_HDR_EXTRA_8_BYTES;755755- break;756756- default:757757- if (net_ratelimit())758758- dev_printk(KERN_ERR, &txq_to_mp(txq)->dev->dev,759759- "mac header length is %d?!\n", mac_hdr_len);760760- break;761761- }762762-763763- switch (ip_hdr(skb)->protocol) {764764- case IPPROTO_UDP:765765- cmd_sts |= UDP_FRAME;766766- desc->l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check));767767- break;768768- case IPPROTO_TCP:769769- desc->l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check));770770- break;771771- default:772772- BUG();773773- }774774- } else {775775- /* Errata BTS #50, IHL must be 5 if no HW checksum */776776- cmd_sts |= 5 << TX_IHL_SHIFT;777777- desc->l4i_chk = 0;778778- }805805+ __skb_queue_tail(&txq->tx_skb, skb);779806780807 /* ensure all other descriptors are written before first cmd_sts */781808 wmb();782809 desc->cmd_sts = cmd_sts;783810784784- /* clear TX_END interrupt status */785785- wrl(mp, INT_CAUSE(mp->port_num), ~(INT_TX_END_0 << txq->index));786786- rdl(mp, INT_CAUSE(mp->port_num));811811+ /* clear TX_END status */812812+ mp->work_tx_end &= ~(1 << txq->index);787813788814 /* ensure all descriptors are written before poking hardware */789815 wmb();790816 txq_enable(txq);791817792818 txq->tx_desc_count += nr_frags + 1;819819+820820+ return 0;793821}794822795823static int mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev)796824{797825 struct mv643xx_eth_private *mp = netdev_priv(dev);798798- struct net_device_stats *stats = &dev->stats;826826+ int queue;799827 struct tx_queue *txq;800800- unsigned long flags;828828+ struct netdev_queue *nq;829829+830830+ queue = skb_get_queue_mapping(skb);831831+ txq = mp->txq + queue;832832+ nq = netdev_get_tx_queue(dev, queue);801833802834 if (has_tiny_unaligned_frags(skb) && __skb_linearize(skb)) {803803- stats->tx_dropped++;835835+ txq->tx_dropped++;804836 dev_printk(KERN_DEBUG, &dev->dev,805837 "failed to linearize skb with tiny "806838 "unaligned fragment\n");807839 return NETDEV_TX_BUSY;808840 }809841810810- spin_lock_irqsave(&mp->lock, flags);811811-812812- txq = mp->txq + mp->txq_primary;813813-814814- if (txq->tx_ring_size - txq->tx_desc_count < MAX_DESCS_PER_SKB) {815815- spin_unlock_irqrestore(&mp->lock, flags);816816- if (txq->index == mp->txq_primary && net_ratelimit())817817- dev_printk(KERN_ERR, &dev->dev,818818- "primary tx queue full?!\n");842842+ if (txq->tx_ring_size - txq->tx_desc_count < MAX_SKB_FRAGS + 1) {843843+ if (net_ratelimit())844844+ dev_printk(KERN_ERR, &dev->dev, "tx queue full?!\n");819845 kfree_skb(skb);820846 return NETDEV_TX_OK;821847 }822848823823- txq_submit_skb(txq, skb);824824- stats->tx_bytes += skb->len;825825- stats->tx_packets++;826826- dev->trans_start = jiffies;827827-828828- if (txq->index == mp->txq_primary) {849849+ if (!txq_submit_skb(txq, skb)) {829850 int entries_left;830851852852+ txq->tx_bytes += skb->len;853853+ txq->tx_packets++;854854+ dev->trans_start = jiffies;855855+831856 entries_left = txq->tx_ring_size - txq->tx_desc_count;832832- if (entries_left < MAX_DESCS_PER_SKB)833833- netif_stop_queue(dev);857857+ if (entries_left < MAX_SKB_FRAGS + 1)858858+ netif_tx_stop_queue(nq);834859 }835860836836- spin_unlock_irqrestore(&mp->lock, flags);837837-838861 return NETDEV_TX_OK;862862+}863863+864864+865865+/* tx napi ******************************************************************/866866+static void txq_kick(struct tx_queue *txq)867867+{868868+ struct mv643xx_eth_private *mp = txq_to_mp(txq);869869+ struct netdev_queue *nq = netdev_get_tx_queue(mp->dev, txq->index);870870+ u32 hw_desc_ptr;871871+ u32 expected_ptr;872872+873873+ __netif_tx_lock(nq, smp_processor_id());874874+875875+ if (rdl(mp, TXQ_COMMAND(mp->port_num)) & (1 << txq->index))876876+ goto out;877877+878878+ hw_desc_ptr = rdl(mp, TXQ_CURRENT_DESC_PTR(mp->port_num, txq->index));879879+ expected_ptr = (u32)txq->tx_desc_dma +880880+ txq->tx_curr_desc * sizeof(struct tx_desc);881881+882882+ if (hw_desc_ptr != expected_ptr)883883+ txq_enable(txq);884884+885885+out:886886+ __netif_tx_unlock(nq);887887+888888+ mp->work_tx_end &= ~(1 << txq->index);889889+}890890+891891+static int txq_reclaim(struct tx_queue *txq, int budget, int force)892892+{893893+ struct mv643xx_eth_private *mp = txq_to_mp(txq);894894+ struct netdev_queue *nq = netdev_get_tx_queue(mp->dev, txq->index);895895+ int reclaimed;896896+897897+ __netif_tx_lock(nq, smp_processor_id());898898+899899+ reclaimed = 0;900900+ while (reclaimed < budget && txq->tx_desc_count > 0) {901901+ int tx_index;902902+ struct tx_desc *desc;903903+ u32 cmd_sts;904904+ struct sk_buff *skb;905905+906906+ tx_index = txq->tx_used_desc;907907+ desc = &txq->tx_desc_area[tx_index];908908+ cmd_sts = desc->cmd_sts;909909+910910+ if (cmd_sts & BUFFER_OWNED_BY_DMA) {911911+ if (!force)912912+ break;913913+ desc->cmd_sts = cmd_sts & ~BUFFER_OWNED_BY_DMA;914914+ }915915+916916+ txq->tx_used_desc = tx_index + 1;917917+ if (txq->tx_used_desc == txq->tx_ring_size)918918+ txq->tx_used_desc = 0;919919+920920+ reclaimed++;921921+ txq->tx_desc_count--;922922+923923+ skb = NULL;924924+ if (cmd_sts & TX_LAST_DESC)925925+ skb = __skb_dequeue(&txq->tx_skb);926926+927927+ if (cmd_sts & ERROR_SUMMARY) {928928+ dev_printk(KERN_INFO, &mp->dev->dev, "tx error\n");929929+ mp->dev->stats.tx_errors++;930930+ }931931+932932+ if (cmd_sts & TX_FIRST_DESC) {933933+ dma_unmap_single(NULL, desc->buf_ptr,934934+ desc->byte_cnt, DMA_TO_DEVICE);935935+ } else {936936+ dma_unmap_page(NULL, desc->buf_ptr,937937+ desc->byte_cnt, DMA_TO_DEVICE);938938+ }939939+940940+ if (skb)941941+ dev_kfree_skb(skb);942942+ }943943+944944+ __netif_tx_unlock(nq);945945+946946+ if (reclaimed < budget)947947+ mp->work_tx &= ~(1 << txq->index);948948+949949+ return reclaimed;839950}840951841952···940895 if (bucket_size > 65535)941896 bucket_size = 65535;942897943943- if (mp->shared->tx_bw_control_moved) {944944- wrl(mp, TX_BW_RATE_MOVED(mp->port_num), token_rate);945945- wrl(mp, TX_BW_MTU_MOVED(mp->port_num), mtu);946946- wrl(mp, TX_BW_BURST_MOVED(mp->port_num), bucket_size);947947- } else {898898+ switch (mp->shared->tx_bw_control) {899899+ case TX_BW_CONTROL_OLD_LAYOUT:948900 wrl(mp, TX_BW_RATE(mp->port_num), token_rate);949901 wrl(mp, TX_BW_MTU(mp->port_num), mtu);950902 wrl(mp, TX_BW_BURST(mp->port_num), bucket_size);903903+ break;904904+ case TX_BW_CONTROL_NEW_LAYOUT:905905+ wrl(mp, TX_BW_RATE_MOVED(mp->port_num), token_rate);906906+ wrl(mp, TX_BW_MTU_MOVED(mp->port_num), mtu);907907+ wrl(mp, TX_BW_BURST_MOVED(mp->port_num), bucket_size);908908+ break;951909 }952910}953911···982934 /*983935 * Turn on fixed priority mode.984936 */985985- if (mp->shared->tx_bw_control_moved)986986- off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num);987987- else937937+ off = 0;938938+ switch (mp->shared->tx_bw_control) {939939+ case TX_BW_CONTROL_OLD_LAYOUT:988940 off = TXQ_FIX_PRIO_CONF(mp->port_num);941941+ break;942942+ case TX_BW_CONTROL_NEW_LAYOUT:943943+ off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num);944944+ break;945945+ }989946990990- val = rdl(mp, off);991991- val |= 1 << txq->index;992992- wrl(mp, off, val);947947+ if (off) {948948+ val = rdl(mp, off);949949+ val |= 1 << txq->index;950950+ wrl(mp, off, val);951951+ }993952}994953995954static void txq_set_wrr(struct tx_queue *txq, int weight)···1008953 /*1009954 * Turn off fixed priority mode.1010955 */10111011- if (mp->shared->tx_bw_control_moved)10121012- off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num);10131013- else956956+ off = 0;957957+ switch (mp->shared->tx_bw_control) {958958+ case TX_BW_CONTROL_OLD_LAYOUT:1014959 off = TXQ_FIX_PRIO_CONF(mp->port_num);960960+ break;961961+ case TX_BW_CONTROL_NEW_LAYOUT:962962+ off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num);963963+ break;964964+ }101596510161016- val = rdl(mp, off);10171017- val &= ~(1 << txq->index);10181018- wrl(mp, off, val);966966+ if (off) {967967+ val = rdl(mp, off);968968+ val &= ~(1 << txq->index);969969+ wrl(mp, off, val);101997010201020- /*10211021- * Configure WRR weight for this queue.10221022- */10231023- off = TXQ_BW_WRR_CONF(mp->port_num, txq->index);971971+ /*972972+ * Configure WRR weight for this queue.973973+ */974974+ off = TXQ_BW_WRR_CONF(mp->port_num, txq->index);102497510251025- val = rdl(mp, off);10261026- val = (val & ~0xff) | (weight & 0xff);10271027- wrl(mp, off, val);976976+ val = rdl(mp, off);977977+ val = (val & ~0xff) | (weight & 0xff);978978+ wrl(mp, off, val);979979+ }1028980}102998110309821031983/* mii management interface *************************************************/10321032-#define SMI_BUSY 0x1000000010331033-#define SMI_READ_VALID 0x0800000010341034-#define SMI_OPCODE_READ 0x0400000010351035-#define SMI_OPCODE_WRITE 0x0000000010361036-10371037-static void smi_reg_read(struct mv643xx_eth_private *mp, unsigned int addr,10381038- unsigned int reg, unsigned int *value)984984+static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id)1039985{10401040- void __iomem *smi_reg = mp->shared_smi->base + SMI_REG;10411041- unsigned long flags;10421042- int i;986986+ struct mv643xx_eth_shared_private *msp = dev_id;104398710441044- /* the SMI register is a shared resource */10451045- spin_lock_irqsave(&mp->shared_smi->phy_lock, flags);988988+ if (readl(msp->base + ERR_INT_CAUSE) & ERR_INT_SMI_DONE) {989989+ writel(~ERR_INT_SMI_DONE, msp->base + ERR_INT_CAUSE);990990+ wake_up(&msp->smi_busy_wait);991991+ return IRQ_HANDLED;992992+ }104699310471047- /* wait for the SMI register to become available */10481048- for (i = 0; readl(smi_reg) & SMI_BUSY; i++) {10491049- if (i == 1000) {10501050- printk("%s: PHY busy timeout\n", mp->dev->name);10511051- goto out;994994+ return IRQ_NONE;995995+}996996+997997+static int smi_is_done(struct mv643xx_eth_shared_private *msp)998998+{999999+ return !(readl(msp->base + SMI_REG) & SMI_BUSY);10001000+}10011001+10021002+static int smi_wait_ready(struct mv643xx_eth_shared_private *msp)10031003+{10041004+ if (msp->err_interrupt == NO_IRQ) {10051005+ int i;10061006+10071007+ for (i = 0; !smi_is_done(msp); i++) {10081008+ if (i == 10)10091009+ return -ETIMEDOUT;10101010+ msleep(10);10521011 }10531053- udelay(10);10121012+10131013+ return 0;10141014+ }10151015+10161016+ if (!wait_event_timeout(msp->smi_busy_wait, smi_is_done(msp),10171017+ msecs_to_jiffies(100)))10181018+ return -ETIMEDOUT;10191019+10201020+ return 0;10211021+}10221022+10231023+static int smi_bus_read(struct mii_bus *bus, int addr, int reg)10241024+{10251025+ struct mv643xx_eth_shared_private *msp = bus->priv;10261026+ void __iomem *smi_reg = msp->base + SMI_REG;10271027+ int ret;10281028+10291029+ if (smi_wait_ready(msp)) {10301030+ printk("mv643xx_eth: SMI bus busy timeout\n");10311031+ return -ETIMEDOUT;10541032 }1055103310561034 writel(SMI_OPCODE_READ | (reg << 21) | (addr << 16), smi_reg);1057103510581058- /* now wait for the data to be valid */10591059- for (i = 0; !(readl(smi_reg) & SMI_READ_VALID); i++) {10601060- if (i == 1000) {10611061- printk("%s: PHY read timeout\n", mp->dev->name);10621062- goto out;10631063- }10641064- udelay(10);10361036+ if (smi_wait_ready(msp)) {10371037+ printk("mv643xx_eth: SMI bus busy timeout\n");10381038+ return -ETIMEDOUT;10651039 }1066104010671067- *value = readl(smi_reg) & 0xffff;10681068-out:10691069- spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags);10411041+ ret = readl(smi_reg);10421042+ if (!(ret & SMI_READ_VALID)) {10431043+ printk("mv643xx_eth: SMI bus read not valid\n");10441044+ return -ENODEV;10451045+ }10461046+10471047+ return ret & 0xffff;10701048}1071104910721072-static void smi_reg_write(struct mv643xx_eth_private *mp,10731073- unsigned int addr,10741074- unsigned int reg, unsigned int value)10501050+static int smi_bus_write(struct mii_bus *bus, int addr, int reg, u16 val)10751051{10761076- void __iomem *smi_reg = mp->shared_smi->base + SMI_REG;10771077- unsigned long flags;10781078- int i;10521052+ struct mv643xx_eth_shared_private *msp = bus->priv;10531053+ void __iomem *smi_reg = msp->base + SMI_REG;1079105410801080- /* the SMI register is a shared resource */10811081- spin_lock_irqsave(&mp->shared_smi->phy_lock, flags);10821082-10831083- /* wait for the SMI register to become available */10841084- for (i = 0; readl(smi_reg) & SMI_BUSY; i++) {10851085- if (i == 1000) {10861086- printk("%s: PHY busy timeout\n", mp->dev->name);10871087- goto out;10881088- }10891089- udelay(10);10551055+ if (smi_wait_ready(msp)) {10561056+ printk("mv643xx_eth: SMI bus busy timeout\n");10571057+ return -ETIMEDOUT;10901058 }1091105910921060 writel(SMI_OPCODE_WRITE | (reg << 21) |10931093- (addr << 16) | (value & 0xffff), smi_reg);10941094-out:10951095- spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags);10611061+ (addr << 16) | (val & 0xffff), smi_reg);10621062+10631063+ if (smi_wait_ready(msp)) {10641064+ printk("mv643xx_eth: SMI bus busy timeout\n");10651065+ return -ETIMEDOUT;10661066+ }10671067+10681068+ return 0;10961069}109710701098107110991099-/* mib counters *************************************************************/10721072+/* statistics ***************************************************************/10731073+static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev)10741074+{10751075+ struct mv643xx_eth_private *mp = netdev_priv(dev);10761076+ struct net_device_stats *stats = &dev->stats;10771077+ unsigned long tx_packets = 0;10781078+ unsigned long tx_bytes = 0;10791079+ unsigned long tx_dropped = 0;10801080+ int i;10811081+10821082+ for (i = 0; i < mp->txq_count; i++) {10831083+ struct tx_queue *txq = mp->txq + i;10841084+10851085+ tx_packets += txq->tx_packets;10861086+ tx_bytes += txq->tx_bytes;10871087+ tx_dropped += txq->tx_dropped;10881088+ }10891089+10901090+ stats->tx_packets = tx_packets;10911091+ stats->tx_bytes = tx_bytes;10921092+ stats->tx_dropped = tx_dropped;10931093+10941094+ return stats;10951095+}10961096+11001097static inline u32 mib_read(struct mv643xx_eth_private *mp, int offset)11011098{11021099 return rdl(mp, MIB_COUNTERS(mp->port_num) + offset);···11661059{11671060 struct mib_counters *p = &mp->mib_counters;1168106110621062+ spin_lock(&mp->mib_counters_lock);11691063 p->good_octets_received += mib_read(mp, 0x00);11701064 p->good_octets_received += (u64)mib_read(mp, 0x04) << 32;11711065 p->bad_octets_received += mib_read(mp, 0x08);···11991091 p->bad_crc_event += mib_read(mp, 0x74);12001092 p->collision += mib_read(mp, 0x78);12011093 p->late_collision += mib_read(mp, 0x7c);10941094+ spin_unlock(&mp->mib_counters_lock);10951095+10961096+ mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ);10971097+}10981098+10991099+static void mib_counters_timer_wrapper(unsigned long _mp)11001100+{11011101+ struct mv643xx_eth_private *mp = (void *)_mp;11021102+11031103+ mib_counters_update(mp);12021104}1203110512041106···12741156 struct mv643xx_eth_private *mp = netdev_priv(dev);12751157 int err;1276115812771277- spin_lock_irq(&mp->lock);12781278- err = mii_ethtool_gset(&mp->mii, cmd);12791279- spin_unlock_irq(&mp->lock);11591159+ err = phy_read_status(mp->phy);11601160+ if (err == 0)11611161+ err = phy_ethtool_gset(mp->phy, cmd);1280116212811163 /*12821164 * The MAC does not support 1000baseT_Half.···13241206static int mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)13251207{13261208 struct mv643xx_eth_private *mp = netdev_priv(dev);13271327- int err;1328120913291210 /*13301211 * The MAC does not support 1000baseT_Half.13311212 */13321213 cmd->advertising &= ~ADVERTISED_1000baseT_Half;1333121413341334- spin_lock_irq(&mp->lock);13351335- err = mii_ethtool_sset(&mp->mii, cmd);13361336- spin_unlock_irq(&mp->lock);13371337-13381338- return err;12151215+ return phy_ethtool_sset(mp->phy, cmd);13391216}1340121713411218static int mv643xx_eth_set_settings_phyless(struct net_device *dev, struct ethtool_cmd *cmd)···13521239{13531240 struct mv643xx_eth_private *mp = netdev_priv(dev);1354124113551355- return mii_nway_restart(&mp->mii);12421242+ return genphy_restart_aneg(mp->phy);13561243}1357124413581245static int mv643xx_eth_nway_reset_phyless(struct net_device *dev)···1362124913631250static u32 mv643xx_eth_get_link(struct net_device *dev)13641251{13651365- struct mv643xx_eth_private *mp = netdev_priv(dev);13661366-13671367- return mii_link_ok(&mp->mii);13681368-}13691369-13701370-static u32 mv643xx_eth_get_link_phyless(struct net_device *dev)13711371-{13721372- return 1;12521252+ return !!netif_carrier_ok(dev);13731253}1374125413751255static void mv643xx_eth_get_strings(struct net_device *dev,···13831277 struct ethtool_stats *stats,13841278 uint64_t *data)13851279{13861386- struct mv643xx_eth_private *mp = dev->priv;12801280+ struct mv643xx_eth_private *mp = netdev_priv(dev);13871281 int i;1388128212831283+ mv643xx_eth_get_stats(dev);13891284 mib_counters_update(mp);1390128513911286 for (i = 0; i < ARRAY_SIZE(mv643xx_eth_stats); i++) {···14301323 .set_settings = mv643xx_eth_set_settings_phyless,14311324 .get_drvinfo = mv643xx_eth_get_drvinfo,14321325 .nway_reset = mv643xx_eth_nway_reset_phyless,14331433- .get_link = mv643xx_eth_get_link_phyless,13261326+ .get_link = mv643xx_eth_get_link,14341327 .set_sg = ethtool_op_set_sg,14351328 .get_strings = mv643xx_eth_get_strings,14361329 .get_ethtool_stats = mv643xx_eth_get_ethtool_stats,···1594148715951488 size = rxq->rx_ring_size * sizeof(struct rx_desc);1596148915971597- if (index == mp->rxq_primary && size <= mp->rx_desc_sram_size) {14901490+ if (index == 0 && size <= mp->rx_desc_sram_size) {15981491 rxq->rx_desc_area = ioremap(mp->rx_desc_sram_addr,15991492 mp->rx_desc_sram_size);16001493 rxq->rx_desc_dma = mp->rx_desc_sram_addr;···1622151516231516 rx_desc = (struct rx_desc *)rxq->rx_desc_area;16241517 for (i = 0; i < rxq->rx_ring_size; i++) {16251625- int nexti = (i + 1) % rxq->rx_ring_size;15181518+ int nexti;15191519+15201520+ nexti = i + 1;15211521+ if (nexti == rxq->rx_ring_size)15221522+ nexti = 0;15231523+16261524 rx_desc[i].next_desc_ptr = rxq->rx_desc_dma +16271525 nexti * sizeof(struct rx_desc);16281526 }16291629-16301630- init_timer(&rxq->rx_oom);16311631- rxq->rx_oom.data = (unsigned long)rxq;16321632- rxq->rx_oom.function = rxq_refill_timer_wrapper;1633152716341528 return 0;163515291636153016371531out_free:16381638- if (index == mp->rxq_primary && size <= mp->rx_desc_sram_size)15321532+ if (index == 0 && size <= mp->rx_desc_sram_size)16391533 iounmap(rxq->rx_desc_area);16401534 else16411535 dma_free_coherent(NULL, size,···1654154616551547 rxq_disable(rxq);1656154816571657- del_timer_sync(&rxq->rx_oom);16581658-16591549 for (i = 0; i < rxq->rx_ring_size; i++) {16601550 if (rxq->rx_skb[i]) {16611551 dev_kfree_skb(rxq->rx_skb[i]);···16671561 rxq->rx_desc_count);16681562 }1669156316701670- if (rxq->index == mp->rxq_primary &&15641564+ if (rxq->index == 0 &&16711565 rxq->rx_desc_area_size <= mp->rx_desc_sram_size)16721566 iounmap(rxq->rx_desc_area);16731567 else···1694158816951589 size = txq->tx_ring_size * sizeof(struct tx_desc);1696159016971697- if (index == mp->txq_primary && size <= mp->tx_desc_sram_size) {15911591+ if (index == 0 && size <= mp->tx_desc_sram_size) {16981592 txq->tx_desc_area = ioremap(mp->tx_desc_sram_addr,16991593 mp->tx_desc_sram_size);17001594 txq->tx_desc_dma = mp->tx_desc_sram_addr;···17071601 if (txq->tx_desc_area == NULL) {17081602 dev_printk(KERN_ERR, &mp->dev->dev,17091603 "can't allocate tx ring (%d bytes)\n", size);17101710- goto out;16041604+ return -ENOMEM;17111605 }17121606 memset(txq->tx_desc_area, 0, size);1713160717141608 txq->tx_desc_area_size = size;17151715- txq->tx_skb = kmalloc(txq->tx_ring_size * sizeof(*txq->tx_skb),17161716- GFP_KERNEL);17171717- if (txq->tx_skb == NULL) {17181718- dev_printk(KERN_ERR, &mp->dev->dev,17191719- "can't allocate tx skb ring\n");17201720- goto out_free;17211721- }1722160917231610 tx_desc = (struct tx_desc *)txq->tx_desc_area;17241611 for (i = 0; i < txq->tx_ring_size; i++) {17251612 struct tx_desc *txd = tx_desc + i;17261726- int nexti = (i + 1) % txq->tx_ring_size;16131613+ int nexti;16141614+16151615+ nexti = i + 1;16161616+ if (nexti == txq->tx_ring_size)16171617+ nexti = 0;1727161817281619 txd->cmd_sts = 0;17291620 txd->next_desc_ptr = txq->tx_desc_dma +17301621 nexti * sizeof(struct tx_desc);17311622 }1732162316241624+ skb_queue_head_init(&txq->tx_skb);16251625+17331626 return 0;17341734-17351735-17361736-out_free:17371737- if (index == mp->txq_primary && size <= mp->tx_desc_sram_size)17381738- iounmap(txq->tx_desc_area);17391739- else17401740- dma_free_coherent(NULL, size,17411741- txq->tx_desc_area,17421742- txq->tx_desc_dma);17431743-17441744-out:17451745- return -ENOMEM;17461746-}17471747-17481748-static void txq_reclaim(struct tx_queue *txq, int force)17491749-{17501750- struct mv643xx_eth_private *mp = txq_to_mp(txq);17511751- unsigned long flags;17521752-17531753- spin_lock_irqsave(&mp->lock, flags);17541754- while (txq->tx_desc_count > 0) {17551755- int tx_index;17561756- struct tx_desc *desc;17571757- u32 cmd_sts;17581758- struct sk_buff *skb;17591759- dma_addr_t addr;17601760- int count;17611761-17621762- tx_index = txq->tx_used_desc;17631763- desc = &txq->tx_desc_area[tx_index];17641764- cmd_sts = desc->cmd_sts;17651765-17661766- if (cmd_sts & BUFFER_OWNED_BY_DMA) {17671767- if (!force)17681768- break;17691769- desc->cmd_sts = cmd_sts & ~BUFFER_OWNED_BY_DMA;17701770- }17711771-17721772- txq->tx_used_desc = (tx_index + 1) % txq->tx_ring_size;17731773- txq->tx_desc_count--;17741774-17751775- addr = desc->buf_ptr;17761776- count = desc->byte_cnt;17771777- skb = txq->tx_skb[tx_index];17781778- txq->tx_skb[tx_index] = NULL;17791779-17801780- if (cmd_sts & ERROR_SUMMARY) {17811781- dev_printk(KERN_INFO, &mp->dev->dev, "tx error\n");17821782- mp->dev->stats.tx_errors++;17831783- }17841784-17851785- /*17861786- * Drop mp->lock while we free the skb.17871787- */17881788- spin_unlock_irqrestore(&mp->lock, flags);17891789-17901790- if (cmd_sts & TX_FIRST_DESC)17911791- dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE);17921792- else17931793- dma_unmap_page(NULL, addr, count, DMA_TO_DEVICE);17941794-17951795- if (skb)17961796- dev_kfree_skb_irq(skb);17971797-17981798- spin_lock_irqsave(&mp->lock, flags);17991799- }18001800- spin_unlock_irqrestore(&mp->lock, flags);18011627}1802162818031629static void txq_deinit(struct tx_queue *txq)···17371699 struct mv643xx_eth_private *mp = txq_to_mp(txq);1738170017391701 txq_disable(txq);17401740- txq_reclaim(txq, 1);17021702+ txq_reclaim(txq, txq->tx_ring_size, 1);1741170317421704 BUG_ON(txq->tx_used_desc != txq->tx_curr_desc);1743170517441744- if (txq->index == mp->txq_primary &&17061706+ if (txq->index == 0 &&17451707 txq->tx_desc_area_size <= mp->tx_desc_sram_size)17461708 iounmap(txq->tx_desc_area);17471709 else17481710 dma_free_coherent(NULL, txq->tx_desc_area_size,17491711 txq->tx_desc_area, txq->tx_desc_dma);17501750-17511751- kfree(txq->tx_skb);17521712}175317131754171417551715/* netdev ops and related ***************************************************/17161716+static int mv643xx_eth_collect_events(struct mv643xx_eth_private *mp)17171717+{17181718+ u32 int_cause;17191719+ u32 int_cause_ext;17201720+17211721+ int_cause = rdl(mp, INT_CAUSE(mp->port_num)) &17221722+ (INT_TX_END | INT_RX | INT_EXT);17231723+ if (int_cause == 0)17241724+ return 0;17251725+17261726+ int_cause_ext = 0;17271727+ if (int_cause & INT_EXT)17281728+ int_cause_ext = rdl(mp, INT_CAUSE_EXT(mp->port_num));17291729+17301730+ int_cause &= INT_TX_END | INT_RX;17311731+ if (int_cause) {17321732+ wrl(mp, INT_CAUSE(mp->port_num), ~int_cause);17331733+ mp->work_tx_end |= ((int_cause & INT_TX_END) >> 19) &17341734+ ~(rdl(mp, TXQ_COMMAND(mp->port_num)) & 0xff);17351735+ mp->work_rx |= (int_cause & INT_RX) >> 2;17361736+ }17371737+17381738+ int_cause_ext &= INT_EXT_LINK_PHY | INT_EXT_TX;17391739+ if (int_cause_ext) {17401740+ wrl(mp, INT_CAUSE_EXT(mp->port_num), ~int_cause_ext);17411741+ if (int_cause_ext & INT_EXT_LINK_PHY)17421742+ mp->work_link = 1;17431743+ mp->work_tx |= int_cause_ext & INT_EXT_TX;17441744+ }17451745+17461746+ return 1;17471747+}17481748+17491749+static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)17501750+{17511751+ struct net_device *dev = (struct net_device *)dev_id;17521752+ struct mv643xx_eth_private *mp = netdev_priv(dev);17531753+17541754+ if (unlikely(!mv643xx_eth_collect_events(mp)))17551755+ return IRQ_NONE;17561756+17571757+ wrl(mp, INT_MASK(mp->port_num), 0);17581758+ napi_schedule(&mp->napi);17591759+17601760+ return IRQ_HANDLED;17611761+}17621762+17561763static void handle_link_event(struct mv643xx_eth_private *mp)17571764{17581765 struct net_device *dev = mp->dev;···18141731 printk(KERN_INFO "%s: link down\n", dev->name);1815173218161733 netif_carrier_off(dev);18171817- netif_stop_queue(dev);1818173418191819- for (i = 0; i < 8; i++) {17351735+ for (i = 0; i < mp->txq_count; i++) {18201736 struct tx_queue *txq = mp->txq + i;1821173718221822- if (mp->txq_mask & (1 << i)) {18231823- txq_reclaim(txq, 1);18241824- txq_reset_hw_ptr(txq);18251825- }17381738+ txq_reclaim(txq, txq->tx_ring_size, 1);17391739+ txq_reset_hw_ptr(txq);18261740 }18271741 }18281742 return;···18471767 speed, duplex ? "full" : "half",18481768 fc ? "en" : "dis");1849176918501850- if (!netif_carrier_ok(dev)) {17701770+ if (!netif_carrier_ok(dev))18511771 netif_carrier_on(dev);18521852- netif_wake_queue(dev);18531853- }18541772}1855177318561856-static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)17741774+static int mv643xx_eth_poll(struct napi_struct *napi, int budget)18571775{18581858- struct net_device *dev = (struct net_device *)dev_id;18591859- struct mv643xx_eth_private *mp = netdev_priv(dev);18601860- u32 int_cause;18611861- u32 int_cause_ext;17761776+ struct mv643xx_eth_private *mp;17771777+ int work_done;1862177818631863- int_cause = rdl(mp, INT_CAUSE(mp->port_num)) &18641864- (INT_TX_END | INT_RX | INT_EXT);18651865- if (int_cause == 0)18661866- return IRQ_NONE;17791779+ mp = container_of(napi, struct mv643xx_eth_private, napi);1867178018681868- int_cause_ext = 0;18691869- if (int_cause & INT_EXT) {18701870- int_cause_ext = rdl(mp, INT_CAUSE_EXT(mp->port_num))18711871- & (INT_EXT_LINK | INT_EXT_PHY | INT_EXT_TX);18721872- wrl(mp, INT_CAUSE_EXT(mp->port_num), ~int_cause_ext);18731873- }17811781+ mp->work_rx_refill |= mp->work_rx_oom;17821782+ mp->work_rx_oom = 0;1874178318751875- if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK))18761876- handle_link_event(mp);17841784+ work_done = 0;17851785+ while (work_done < budget) {17861786+ u8 queue_mask;17871787+ int queue;17881788+ int work_tbd;1877178918781878- /*18791879- * RxBuffer or RxError set for any of the 8 queues?18801880- */18811881-#ifdef MV643XX_ETH_NAPI18821882- if (int_cause & INT_RX) {18831883- wrl(mp, INT_CAUSE(mp->port_num), ~(int_cause & INT_RX));18841884- wrl(mp, INT_MASK(mp->port_num), 0x00000000);18851885- rdl(mp, INT_MASK(mp->port_num));18861886-18871887- netif_rx_schedule(dev, &mp->napi);18881888- }18891889-#else18901890- if (int_cause & INT_RX) {18911891- int i;18921892-18931893- for (i = 7; i >= 0; i--)18941894- if (mp->rxq_mask & (1 << i))18951895- rxq_process(mp->rxq + i, INT_MAX);18961896- }18971897-#endif18981898-18991899- /*19001900- * TxBuffer or TxError set for any of the 8 queues?19011901- */19021902- if (int_cause_ext & INT_EXT_TX) {19031903- int i;19041904-19051905- for (i = 0; i < 8; i++)19061906- if (mp->txq_mask & (1 << i))19071907- txq_reclaim(mp->txq + i, 0);19081908-19091909- /*19101910- * Enough space again in the primary TX queue for a19111911- * full packet?19121912- */19131913- if (netif_carrier_ok(dev)) {19141914- spin_lock(&mp->lock);19151915- __txq_maybe_wake(mp->txq + mp->txq_primary);19161916- spin_unlock(&mp->lock);17901790+ if (mp->work_link) {17911791+ mp->work_link = 0;17921792+ handle_link_event(mp);17931793+ continue;19171794 }19181918- }1919179519201920- /*19211921- * Any TxEnd interrupts?19221922- */19231923- if (int_cause & INT_TX_END) {19241924- int i;19251925-19261926- wrl(mp, INT_CAUSE(mp->port_num), ~(int_cause & INT_TX_END));19271927-19281928- spin_lock(&mp->lock);19291929- for (i = 0; i < 8; i++) {19301930- struct tx_queue *txq = mp->txq + i;19311931- u32 hw_desc_ptr;19321932- u32 expected_ptr;19331933-19341934- if ((int_cause & (INT_TX_END_0 << i)) == 0)17961796+ queue_mask = mp->work_tx | mp->work_tx_end |17971797+ mp->work_rx | mp->work_rx_refill;17981798+ if (!queue_mask) {17991799+ if (mv643xx_eth_collect_events(mp))19351800 continue;19361936-19371937- hw_desc_ptr =19381938- rdl(mp, TXQ_CURRENT_DESC_PTR(mp->port_num, i));19391939- expected_ptr = (u32)txq->tx_desc_dma +19401940- txq->tx_curr_desc * sizeof(struct tx_desc);19411941-19421942- if (hw_desc_ptr != expected_ptr)19431943- txq_enable(txq);18011801+ break;19441802 }19451945- spin_unlock(&mp->lock);18031803+18041804+ queue = fls(queue_mask) - 1;18051805+ queue_mask = 1 << queue;18061806+18071807+ work_tbd = budget - work_done;18081808+ if (work_tbd > 16)18091809+ work_tbd = 16;18101810+18111811+ if (mp->work_tx_end & queue_mask) {18121812+ txq_kick(mp->txq + queue);18131813+ } else if (mp->work_tx & queue_mask) {18141814+ work_done += txq_reclaim(mp->txq + queue, work_tbd, 0);18151815+ txq_maybe_wake(mp->txq + queue);18161816+ } else if (mp->work_rx & queue_mask) {18171817+ work_done += rxq_process(mp->rxq + queue, work_tbd);18181818+ } else if (mp->work_rx_refill & queue_mask) {18191819+ work_done += rxq_refill(mp->rxq + queue, work_tbd);18201820+ } else {18211821+ BUG();18221822+ }19461823 }1947182419481948- return IRQ_HANDLED;18251825+ if (work_done < budget) {18261826+ if (mp->work_rx_oom)18271827+ mod_timer(&mp->rx_oom, jiffies + (HZ / 10));18281828+ napi_complete(napi);18291829+ wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);18301830+ }18311831+18321832+ return work_done;18331833+}18341834+18351835+static inline void oom_timer_wrapper(unsigned long data)18361836+{18371837+ struct mv643xx_eth_private *mp = (void *)data;18381838+18391839+ napi_schedule(&mp->napi);19491840}1950184119511842static void phy_reset(struct mv643xx_eth_private *mp)19521843{19531953- unsigned int data;18441844+ int data;1954184519551955- smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data);18461846+ data = phy_read(mp->phy, MII_BMCR);18471847+ if (data < 0)18481848+ return;18491849+19561850 data |= BMCR_RESET;19571957- smi_reg_write(mp, mp->phy_addr, MII_BMCR, data);18511851+ if (phy_write(mp->phy, MII_BMCR, data) < 0)18521852+ return;1958185319591854 do {19601960- udelay(1);19611961- smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data);19621962- } while (data & BMCR_RESET);18551855+ data = phy_read(mp->phy, MII_BMCR);18561856+ } while (data >= 0 && data & BMCR_RESET);19631857}1964185819651859static void port_start(struct mv643xx_eth_private *mp)···19441890 /*19451891 * Perform PHY reset, if there is a PHY.19461892 */19471947- if (mp->phy_addr != -1) {18931893+ if (mp->phy != NULL) {19481894 struct ethtool_cmd cmd;1949189519501896 mv643xx_eth_get_settings(mp->dev, &cmd);···19611907 wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);1962190819631909 pscr |= DO_NOT_FORCE_LINK_FAIL;19641964- if (mp->phy_addr == -1)19101910+ if (mp->phy == NULL)19651911 pscr |= FORCE_LINK_PASS;19661912 wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);19671913···19711917 * Configure TX path and queues.19721918 */19731919 tx_set_rate(mp, 1000000000, 16777216);19741974- for (i = 0; i < 8; i++) {19201920+ for (i = 0; i < mp->txq_count; i++) {19751921 struct tx_queue *txq = mp->txq + i;19761976-19771977- if ((mp->txq_mask & (1 << i)) == 0)19781978- continue;1979192219801923 txq_reset_hw_ptr(txq);19811924 txq_set_rate(txq, 1000000000, 16777216);···1986193519871936 /*19881937 * Receive all unmatched unicast, TCP, UDP, BPDU and broadcast19891989- * frames to RX queue #0.19381938+ * frames to RX queue #0, and include the pseudo-header when19391939+ * calculating receive checksums.19901940 */19911991- wrl(mp, PORT_CONFIG(mp->port_num), 0x00000000);19411941+ wrl(mp, PORT_CONFIG(mp->port_num), 0x02000000);1992194219931943 /*19941944 * Treat BPDUs as normal multicasts, and disable partition mode.···19991947 /*20001948 * Enable the receive queues.20011949 */20022002- for (i = 0; i < 8; i++) {19501950+ for (i = 0; i < mp->rxq_count; i++) {20031951 struct rx_queue *rxq = mp->rxq + i;20041952 int off = RXQ_CURRENT_DESC_PTR(mp->port_num, i);20051953 u32 addr;20062006-20072007- if ((mp->rxq_mask & (1 << i)) == 0)20082008- continue;2009195420101955 addr = (u32)rxq->rx_desc_dma;20111956 addr += rxq->rx_curr_desc * sizeof(struct rx_desc);···20532004 rdl(mp, INT_CAUSE_EXT(mp->port_num));2054200520552006 err = request_irq(dev->irq, mv643xx_eth_irq,20562056- IRQF_SHARED | IRQF_SAMPLE_RANDOM,20572057- dev->name, dev);20072007+ IRQF_SHARED, dev->name, dev);20582008 if (err) {20592009 dev_printk(KERN_ERR, &dev->dev, "can't assign irq\n");20602010 return -EAGAIN;···2061201320622014 init_mac_tables(mp);2063201520642064- for (i = 0; i < 8; i++) {20652065- if ((mp->rxq_mask & (1 << i)) == 0)20662066- continue;20162016+ napi_enable(&mp->napi);2067201720182018+ for (i = 0; i < mp->rxq_count; i++) {20682019 err = rxq_init(mp, i);20692020 if (err) {20702021 while (--i >= 0)20712071- if (mp->rxq_mask & (1 << i))20722072- rxq_deinit(mp->rxq + i);20222022+ rxq_deinit(mp->rxq + i);20732023 goto out;20742024 }2075202520762076- rxq_refill(mp->rxq + i);20262026+ rxq_refill(mp->rxq + i, INT_MAX);20772027 }2078202820792079- for (i = 0; i < 8; i++) {20802080- if ((mp->txq_mask & (1 << i)) == 0)20812081- continue;20292029+ if (mp->work_rx_oom) {20302030+ mp->rx_oom.expires = jiffies + (HZ / 10);20312031+ add_timer(&mp->rx_oom);20322032+ }2082203320342034+ for (i = 0; i < mp->txq_count; i++) {20832035 err = txq_init(mp, i);20842036 if (err) {20852037 while (--i >= 0)20862086- if (mp->txq_mask & (1 << i))20872087- txq_deinit(mp->txq + i);20382038+ txq_deinit(mp->txq + i);20882039 goto out_free;20892040 }20902041 }2091204220922092-#ifdef MV643XX_ETH_NAPI20932093- napi_enable(&mp->napi);20942094-#endif20952095-20962043 netif_carrier_off(dev);20972097- netif_stop_queue(dev);2098204420992045 port_start(mp);2100204621012047 set_rx_coal(mp, 0);21022048 set_tx_coal(mp, 0);2103204921042104- wrl(mp, INT_MASK_EXT(mp->port_num),21052105- INT_EXT_LINK | INT_EXT_PHY | INT_EXT_TX);21062106-20502050+ wrl(mp, INT_MASK_EXT(mp->port_num), INT_EXT_LINK_PHY | INT_EXT_TX);21072051 wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);2108205221092053 return 0;211020542111205521122056out_free:21132113- for (i = 0; i < 8; i++)21142114- if (mp->rxq_mask & (1 << i))21152115- rxq_deinit(mp->rxq + i);20572057+ for (i = 0; i < mp->rxq_count; i++)20582058+ rxq_deinit(mp->rxq + i);21162059out:21172060 free_irq(dev->irq, dev);21182061···21152076 unsigned int data;21162077 int i;2117207821182118- for (i = 0; i < 8; i++) {21192119- if (mp->rxq_mask & (1 << i))21202120- rxq_disable(mp->rxq + i);21212121- if (mp->txq_mask & (1 << i))21222122- txq_disable(mp->txq + i);21232123- }20792079+ for (i = 0; i < mp->rxq_count; i++)20802080+ rxq_disable(mp->rxq + i);20812081+ for (i = 0; i < mp->txq_count; i++)20822082+ txq_disable(mp->txq + i);2124208321252084 while (1) {21262085 u32 ps = rdl(mp, PORT_STATUS(mp->port_num));···21442107 wrl(mp, INT_MASK(mp->port_num), 0x00000000);21452108 rdl(mp, INT_MASK(mp->port_num));2146210921472147-#ifdef MV643XX_ETH_NAPI21102110+ del_timer_sync(&mp->mib_counters_timer);21112111+21482112 napi_disable(&mp->napi);21492149-#endif21132113+21142114+ del_timer_sync(&mp->rx_oom);21152115+21502116 netif_carrier_off(dev);21512151- netif_stop_queue(dev);2152211721532118 free_irq(dev->irq, dev);2154211921552120 port_reset(mp);21212121+ mv643xx_eth_get_stats(dev);21562122 mib_counters_update(mp);2157212321582158- for (i = 0; i < 8; i++) {21592159- if (mp->rxq_mask & (1 << i))21602160- rxq_deinit(mp->rxq + i);21612161- if (mp->txq_mask & (1 << i))21622162- txq_deinit(mp->txq + i);21632163- }21242124+ for (i = 0; i < mp->rxq_count; i++)21252125+ rxq_deinit(mp->rxq + i);21262126+ for (i = 0; i < mp->txq_count; i++)21272127+ txq_deinit(mp->txq + i);2164212821652129 return 0;21662130}···21702132{21712133 struct mv643xx_eth_private *mp = netdev_priv(dev);2172213421732173- if (mp->phy_addr != -1)21742174- return generic_mii_ioctl(&mp->mii, if_mii(ifr), cmd, NULL);21352135+ if (mp->phy != NULL)21362136+ return phy_mii_ioctl(mp->phy, if_mii(ifr), cmd);2175213721762138 return -EOPNOTSUPP;21772139}···2211217322122174 mp = container_of(ugly, struct mv643xx_eth_private, tx_timeout_task);22132175 if (netif_running(mp->dev)) {22142214- netif_stop_queue(mp->dev);22152215-21762176+ netif_tx_stop_all_queues(mp->dev);22162177 port_reset(mp);22172178 port_start(mp);22182218-22192219- __txq_maybe_wake(mp->txq + mp->txq_primary);21792179+ netif_tx_wake_all_queues(mp->dev);22202180 }22212181}22222182···22402204 wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);22412205}22422206#endif22432243-22442244-static int mv643xx_eth_mdio_read(struct net_device *dev, int addr, int reg)22452245-{22462246- struct mv643xx_eth_private *mp = netdev_priv(dev);22472247- int val;22482248-22492249- smi_reg_read(mp, addr, reg, &val);22502250-22512251- return val;22522252-}22532253-22542254-static void mv643xx_eth_mdio_write(struct net_device *dev, int addr, int reg, int val)22552255-{22562256- struct mv643xx_eth_private *mp = netdev_priv(dev);22572257- smi_reg_write(mp, addr, reg, val);22582258-}225922072260220822612209/* platform glue ************************************************************/···22922272 msp->extended_rx_coal_limit = 0;2293227322942274 /*22952295- * Check whether the TX rate control registers are in the22962296- * old or the new place.22752275+ * Check whether the MAC supports TX rate control, and if22762276+ * yes, whether its associated registers are in the old or22772277+ * the new place.22972278 */22982279 writel(1, msp->base + TX_BW_MTU_MOVED(0));22992299- if (readl(msp->base + TX_BW_MTU_MOVED(0)) & 1)23002300- msp->tx_bw_control_moved = 1;23012301- else23022302- msp->tx_bw_control_moved = 0;22802280+ if (readl(msp->base + TX_BW_MTU_MOVED(0)) & 1) {22812281+ msp->tx_bw_control = TX_BW_CONTROL_NEW_LAYOUT;22822282+ } else {22832283+ writel(7, msp->base + TX_BW_RATE(0));22842284+ if (readl(msp->base + TX_BW_RATE(0)) & 7)22852285+ msp->tx_bw_control = TX_BW_CONTROL_OLD_LAYOUT;22862286+ else22872287+ msp->tx_bw_control = TX_BW_CONTROL_ABSENT;22882288+ }23032289}2304229023052291static int mv643xx_eth_shared_probe(struct platform_device *pdev)···23352309 if (msp->base == NULL)23362310 goto out_free;2337231123382338- spin_lock_init(&msp->phy_lock);23122312+ /*23132313+ * Set up and register SMI bus.23142314+ */23152315+ if (pd == NULL || pd->shared_smi == NULL) {23162316+ msp->smi_bus.priv = msp;23172317+ msp->smi_bus.name = "mv643xx_eth smi";23182318+ msp->smi_bus.read = smi_bus_read;23192319+ msp->smi_bus.write = smi_bus_write,23202320+ snprintf(msp->smi_bus.id, MII_BUS_ID_SIZE, "%d", pdev->id);23212321+ msp->smi_bus.dev = &pdev->dev;23222322+ msp->smi_bus.phy_mask = 0xffffffff;23232323+ if (mdiobus_register(&msp->smi_bus) < 0)23242324+ goto out_unmap;23252325+ msp->smi = msp;23262326+ } else {23272327+ msp->smi = platform_get_drvdata(pd->shared_smi);23282328+ }23292329+23302330+ msp->err_interrupt = NO_IRQ;23312331+ init_waitqueue_head(&msp->smi_busy_wait);23322332+23332333+ /*23342334+ * Check whether the error interrupt is hooked up.23352335+ */23362336+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);23372337+ if (res != NULL) {23382338+ int err;23392339+23402340+ err = request_irq(res->start, mv643xx_eth_err_irq,23412341+ IRQF_SHARED, "mv643xx_eth", msp);23422342+ if (!err) {23432343+ writel(ERR_INT_SMI_DONE, msp->base + ERR_INT_MASK);23442344+ msp->err_interrupt = res->start;23452345+ }23462346+ }2339234723402348 /*23412349 * (Re-)program MBUS remapping windows if we are asked to.···2387232723882328 return 0;2389232923302330+out_unmap:23312331+ iounmap(msp->base);23902332out_free:23912333 kfree(msp);23922334out:···23982336static int mv643xx_eth_shared_remove(struct platform_device *pdev)23992337{24002338 struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev);23392339+ struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;2401234023412341+ if (pd == NULL || pd->shared_smi == NULL)23422342+ mdiobus_unregister(&msp->smi_bus);23432343+ if (msp->err_interrupt != NO_IRQ)23442344+ free_irq(msp->err_interrupt, msp);24022345 iounmap(msp->base);24032346 kfree(msp);24042347···24492382 else24502383 uc_addr_get(mp, dev->dev_addr);2451238424522452- if (pd->phy_addr == -1) {24532453- mp->shared_smi = NULL;24542454- mp->phy_addr = -1;24552455- } else {24562456- mp->shared_smi = mp->shared;24572457- if (pd->shared_smi != NULL)24582458- mp->shared_smi = platform_get_drvdata(pd->shared_smi);24592459-24602460- if (pd->force_phy_addr || pd->phy_addr) {24612461- mp->phy_addr = pd->phy_addr & 0x3f;24622462- phy_addr_set(mp, mp->phy_addr);24632463- } else {24642464- mp->phy_addr = phy_addr_get(mp);24652465- }24662466- }24672467-24682385 mp->default_rx_ring_size = DEFAULT_RX_QUEUE_SIZE;24692386 if (pd->rx_queue_size)24702387 mp->default_rx_ring_size = pd->rx_queue_size;24712388 mp->rx_desc_sram_addr = pd->rx_sram_addr;24722389 mp->rx_desc_sram_size = pd->rx_sram_size;2473239024742474- if (pd->rx_queue_mask)24752475- mp->rxq_mask = pd->rx_queue_mask;24762476- else24772477- mp->rxq_mask = 0x01;24782478- mp->rxq_primary = fls(mp->rxq_mask) - 1;23912391+ mp->rxq_count = pd->rx_queue_count ? : 1;2479239224802393 mp->default_tx_ring_size = DEFAULT_TX_QUEUE_SIZE;24812394 if (pd->tx_queue_size)···24632416 mp->tx_desc_sram_addr = pd->tx_sram_addr;24642417 mp->tx_desc_sram_size = pd->tx_sram_size;2465241824662466- if (pd->tx_queue_mask)24672467- mp->txq_mask = pd->tx_queue_mask;24682468- else24692469- mp->txq_mask = 0x01;24702470- mp->txq_primary = fls(mp->txq_mask) - 1;24192419+ mp->txq_count = pd->tx_queue_count ? : 1;24712420}2472242124732473-static int phy_detect(struct mv643xx_eth_private *mp)24222422+static struct phy_device *phy_scan(struct mv643xx_eth_private *mp,24232423+ int phy_addr)24742424{24752475- unsigned int data;24762476- unsigned int data2;24252425+ struct mii_bus *bus = &mp->shared->smi->smi_bus;24262426+ struct phy_device *phydev;24272427+ int start;24282428+ int num;24292429+ int i;2477243024782478- smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data);24792479- smi_reg_write(mp, mp->phy_addr, MII_BMCR, data ^ BMCR_ANENABLE);24802480-24812481- smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data2);24822482- if (((data ^ data2) & BMCR_ANENABLE) == 0)24832483- return -ENODEV;24842484-24852485- smi_reg_write(mp, mp->phy_addr, MII_BMCR, data);24862486-24872487- return 0;24882488-}24892489-24902490-static int phy_init(struct mv643xx_eth_private *mp,24912491- struct mv643xx_eth_platform_data *pd)24922492-{24932493- struct ethtool_cmd cmd;24942494- int err;24952495-24962496- err = phy_detect(mp);24972497- if (err) {24982498- dev_printk(KERN_INFO, &mp->dev->dev,24992499- "no PHY detected at addr %d\n", mp->phy_addr);25002500- return err;24312431+ if (phy_addr == MV643XX_ETH_PHY_ADDR_DEFAULT) {24322432+ start = phy_addr_get(mp) & 0x1f;24332433+ num = 32;24342434+ } else {24352435+ start = phy_addr & 0x1f;24362436+ num = 1;25012437 }24382438+24392439+ phydev = NULL;24402440+ for (i = 0; i < num; i++) {24412441+ int addr = (start + i) & 0x1f;24422442+24432443+ if (bus->phy_map[addr] == NULL)24442444+ mdiobus_scan(bus, addr);24452445+24462446+ if (phydev == NULL) {24472447+ phydev = bus->phy_map[addr];24482448+ if (phydev != NULL)24492449+ phy_addr_set(mp, addr);24502450+ }24512451+ }24522452+24532453+ return phydev;24542454+}24552455+24562456+static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex)24572457+{24582458+ struct phy_device *phy = mp->phy;24592459+25022460 phy_reset(mp);2503246125042504- mp->mii.phy_id = mp->phy_addr;25052505- mp->mii.phy_id_mask = 0x3f;25062506- mp->mii.reg_num_mask = 0x1f;25072507- mp->mii.dev = mp->dev;25082508- mp->mii.mdio_read = mv643xx_eth_mdio_read;25092509- mp->mii.mdio_write = mv643xx_eth_mdio_write;24622462+ phy_attach(mp->dev, phy->dev.bus_id, 0, PHY_INTERFACE_MODE_GMII);2510246325112511- mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii);25122512-25132513- memset(&cmd, 0, sizeof(cmd));25142514-25152515- cmd.port = PORT_MII;25162516- cmd.transceiver = XCVR_INTERNAL;25172517- cmd.phy_address = mp->phy_addr;25182518- if (pd->speed == 0) {25192519- cmd.autoneg = AUTONEG_ENABLE;25202520- cmd.speed = SPEED_100;25212521- cmd.advertising = ADVERTISED_10baseT_Half |25222522- ADVERTISED_10baseT_Full |25232523- ADVERTISED_100baseT_Half |25242524- ADVERTISED_100baseT_Full;25252525- if (mp->mii.supports_gmii)25262526- cmd.advertising |= ADVERTISED_1000baseT_Full;24642464+ if (speed == 0) {24652465+ phy->autoneg = AUTONEG_ENABLE;24662466+ phy->speed = 0;24672467+ phy->duplex = 0;24682468+ phy->advertising = phy->supported | ADVERTISED_Autoneg;25272469 } else {25282528- cmd.autoneg = AUTONEG_DISABLE;25292529- cmd.speed = pd->speed;25302530- cmd.duplex = pd->duplex;24702470+ phy->autoneg = AUTONEG_DISABLE;24712471+ phy->advertising = 0;24722472+ phy->speed = speed;24732473+ phy->duplex = duplex;25312474 }25322532-25332533- mv643xx_eth_set_settings(mp->dev, &cmd);25342534-25352535- return 0;24752475+ phy_start_aneg(phy);25362476}2537247725382478static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)···25332499 }2534250025352501 pscr = MAX_RX_PACKET_9700BYTE | SERIAL_PORT_CONTROL_RESERVED;25362536- if (mp->phy_addr == -1) {25022502+ if (mp->phy == NULL) {25372503 pscr |= DISABLE_AUTO_NEG_SPEED_GMII;25382504 if (speed == SPEED_1000)25392505 pscr |= SET_GMII_SPEED_TO_1000;···25722538 return -ENODEV;25732539 }2574254025752575- dev = alloc_etherdev(sizeof(struct mv643xx_eth_private));25412541+ dev = alloc_etherdev_mq(sizeof(struct mv643xx_eth_private), 8);25762542 if (!dev)25772543 return -ENOMEM;25782544···25832549 mp->port_num = pd->port_number;2584255025852551 mp->dev = dev;25862586-#ifdef MV643XX_ETH_NAPI25872587- netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, 64);25882588-#endif2589255225902553 set_params(mp, pd);25542554+ dev->real_num_tx_queues = mp->txq_count;2591255525922592- spin_lock_init(&mp->lock);25562556+ if (pd->phy_addr != MV643XX_ETH_PHY_NONE)25572557+ mp->phy = phy_scan(mp, pd->phy_addr);2593255825942594- mib_counters_clear(mp);25952595- INIT_WORK(&mp->tx_timeout_task, tx_timeout_task);25962596-25972597- if (mp->phy_addr != -1) {25982598- err = phy_init(mp, pd);25992599- if (err)26002600- goto out;26012601-25592559+ if (mp->phy != NULL) {25602560+ phy_init(mp, pd->speed, pd->duplex);26022561 SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops);26032562 } else {26042563 SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops_phyless);26052564 }25652565+26062566 init_pscr(mp, pd->speed, pd->duplex);25672567+25682568+25692569+ mib_counters_clear(mp);25702570+25712571+ init_timer(&mp->mib_counters_timer);25722572+ mp->mib_counters_timer.data = (unsigned long)mp;25732573+ mp->mib_counters_timer.function = mib_counters_timer_wrapper;25742574+ mp->mib_counters_timer.expires = jiffies + 30 * HZ;25752575+ add_timer(&mp->mib_counters_timer);25762576+25772577+ spin_lock_init(&mp->mib_counters_lock);25782578+25792579+ INIT_WORK(&mp->tx_timeout_task, tx_timeout_task);25802580+25812581+ netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, 128);25822582+25832583+ init_timer(&mp->rx_oom);25842584+ mp->rx_oom.data = (unsigned long)mp;25852585+ mp->rx_oom.function = oom_timer_wrapper;260725862608258726092588 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);26102589 BUG_ON(!res);26112590 dev->irq = res->start;2612259125922592+ dev->get_stats = mv643xx_eth_get_stats;26132593 dev->hard_start_xmit = mv643xx_eth_xmit;26142594 dev->open = mv643xx_eth_open;26152595 dev->stop = mv643xx_eth_stop;···26382590 dev->watchdog_timeo = 2 * HZ;26392591 dev->base_addr = 0;2640259226412641-#ifdef MV643XX_ETH_CHECKSUM_OFFLOAD_TX26422642- /*26432643- * Zero copy can only work if we use Discovery II memory. Else, we will26442644- * have to map the buffers to ISA memory which is only 16 MB26452645- */26462593 dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;26472594 dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM;26482648-#endif2649259526502596 SET_NETDEV_DEV(dev, &pdev->dev);26512597···2652261026532611 dev_printk(KERN_NOTICE, &dev->dev, "port %d with MAC address %s\n",26542612 mp->port_num, print_mac(mac, dev->dev_addr));26552655-26562656- if (dev->features & NETIF_F_SG)26572657- dev_printk(KERN_NOTICE, &dev->dev, "scatter/gather enabled\n");26582658-26592659- if (dev->features & NETIF_F_IP_CSUM)26602660- dev_printk(KERN_NOTICE, &dev->dev, "tx checksum offload\n");26612661-26622662-#ifdef MV643XX_ETH_NAPI26632663- dev_printk(KERN_NOTICE, &dev->dev, "napi enabled\n");26642664-#endif2665261326662614 if (mp->tx_desc_sram_size > 0)26672615 dev_printk(KERN_NOTICE, &dev->dev, "configured with sram\n");···26692637 struct mv643xx_eth_private *mp = platform_get_drvdata(pdev);2670263826712639 unregister_netdev(mp->dev);26402640+ if (mp->phy != NULL)26412641+ phy_detach(mp->phy);26722642 flush_scheduled_work();26732643 free_netdev(mp->dev);26742644
+48-41
drivers/net/phy/mdio_bus.c
···6060 bus->reset(bus);61616262 for (i = 0; i < PHY_MAX_ADDR; i++) {6363- struct phy_device *phydev;6363+ bus->phy_map[i] = NULL;6464+ if ((bus->phy_mask & (1 << i)) == 0) {6565+ struct phy_device *phydev;64666565- if (bus->phy_mask & (1 << i)) {6666- bus->phy_map[i] = NULL;6767- continue;6767+ phydev = mdiobus_scan(bus, i);6868+ if (IS_ERR(phydev))6969+ err = PTR_ERR(phydev);6870 }6969-7070- phydev = get_phy_device(bus, i);7171-7272- if (IS_ERR(phydev))7373- return PTR_ERR(phydev);7474-7575- /* There's a PHY at this address7676- * We need to set:7777- * 1) IRQ7878- * 2) bus_id7979- * 3) parent8080- * 4) bus8181- * 5) mii_bus8282- * And, we need to register it */8383- if (phydev) {8484- phydev->irq = bus->irq[i];8585-8686- phydev->dev.parent = bus->dev;8787- phydev->dev.bus = &mdio_bus_type;8888- snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, i);8989-9090- phydev->bus = bus;9191-9292- /* Run all of the fixups for this PHY */9393- phy_scan_fixups(phydev);9494-9595- err = device_register(&phydev->dev);9696-9797- if (err) {9898- printk(KERN_ERR "phy %d failed to register\n",9999- i);100100- phy_device_free(phydev);101101- phydev = NULL;102102- }103103- }104104-105105- bus->phy_map[i] = phydev;10671 }1077210873 pr_info("%s: probed\n", bus->name);···86121 }87122}88123EXPORT_SYMBOL(mdiobus_unregister);124124+125125+struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)126126+{127127+ struct phy_device *phydev;128128+ int err;129129+130130+ phydev = get_phy_device(bus, addr);131131+ if (IS_ERR(phydev) || phydev == NULL)132132+ return phydev;133133+134134+ /* There's a PHY at this address135135+ * We need to set:136136+ * 1) IRQ137137+ * 2) bus_id138138+ * 3) parent139139+ * 4) bus140140+ * 5) mii_bus141141+ * And, we need to register it */142142+143143+ phydev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;144144+145145+ phydev->dev.parent = bus->dev;146146+ phydev->dev.bus = &mdio_bus_type;147147+ snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, addr);148148+149149+ phydev->bus = bus;150150+151151+ /* Run all of the fixups for this PHY */152152+ phy_scan_fixups(phydev);153153+154154+ err = device_register(&phydev->dev);155155+ if (err) {156156+ printk(KERN_ERR "phy %d failed to register\n", addr);157157+ phy_device_free(phydev);158158+ phydev = NULL;159159+ }160160+161161+ bus->phy_map[addr] = phydev;162162+163163+ return phydev;164164+}165165+EXPORT_SYMBOL(mdiobus_scan);8916690167/**91168 * mdio_bus_match - determine if given PHY driver supports the given PHY device
+8-5
include/linux/mv643xx_eth.h
···17171818struct mv643xx_eth_shared_platform_data {1919 struct mbus_dram_target_info *dram;2020+ struct platform_device *shared_smi;2021 unsigned int t_clk;2122};2323+2424+#define MV643XX_ETH_PHY_ADDR_DEFAULT 02525+#define MV643XX_ETH_PHY_ADDR(x) (0x80 | (x))2626+#define MV643XX_ETH_PHY_NONE 0xff22272328struct mv643xx_eth_platform_data {2429 /*···3530 /*3631 * Whether a PHY is present, and if yes, at which address.3732 */3838- struct platform_device *shared_smi;3939- int force_phy_addr;4033 int phy_addr;41344235 /*···5249 int duplex;53505451 /*5555- * Which RX/TX queues to use.5252+ * How many RX/TX queues to use.5653 */5757- int rx_queue_mask;5858- int tx_queue_mask;5454+ int rx_queue_count;5555+ int tx_queue_count;59566057 /*6158 * Override default RX/TX queue sizes if nonzero.