iPXE
smscusb.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <string.h>
27 #include <errno.h>
28 #include <unistd.h>
29 #include <ipxe/usb.h>
30 #include <ipxe/usbnet.h>
31 #include <ipxe/ethernet.h>
32 #include <ipxe/profile.h>
33 #include <ipxe/fdt.h>
34 #include "smscusb.h"
35 
36 /** @file
37  *
38  * SMSC USB Ethernet drivers
39  *
40  */
41 
42 /** Interrupt completion profiler */
43 static struct profiler smscusb_intr_profiler __profiler =
44  { .name = "smscusb.intr" };
45 
46 /******************************************************************************
47  *
48  * Register access
49  *
50  ******************************************************************************
51  */
52 
53 /**
54  * Write register (without byte-swapping)
55  *
56  * @v smscusb Smscusb device
57  * @v address Register address
58  * @v value Register value
59  * @ret rc Return status code
60  */
61 int smscusb_raw_writel ( struct smscusb_device *smscusb, unsigned int address,
62  uint32_t value ) {
63  int rc;
64 
65  /* Write register */
66  DBGCIO ( smscusb, "SMSCUSB %p [%03x] <= %08x\n",
67  smscusb, address, le32_to_cpu ( value ) );
68  if ( ( rc = usb_control ( smscusb->usb, SMSCUSB_REGISTER_WRITE, 0,
69  address, &value, sizeof ( value ) ) ) != 0 ) {
70  DBGC ( smscusb, "SMSCUSB %p could not write %03x: %s\n",
71  smscusb, address, strerror ( rc ) );
72  return rc;
73  }
74 
75  return 0;
76 }
77 
78 /**
79  * Read register (without byte-swapping)
80  *
81  * @v smscusb SMSC USB device
82  * @v address Register address
83  * @ret value Register value
84  * @ret rc Return status code
85  */
86 int smscusb_raw_readl ( struct smscusb_device *smscusb, unsigned int address,
87  uint32_t *value ) {
88  int rc;
89 
90  /* Read register */
91  if ( ( rc = usb_control ( smscusb->usb, SMSCUSB_REGISTER_READ, 0,
92  address, value, sizeof ( *value ) ) ) != 0 ) {
93  DBGC ( smscusb, "SMSCUSB %p could not read %03x: %s\n",
94  smscusb, address, strerror ( rc ) );
95  return rc;
96  }
97  DBGCIO ( smscusb, "SMSCUSB %p [%03x] => %08x\n",
98  smscusb, address, le32_to_cpu ( *value ) );
99 
100  return 0;
101 }
102 
103 /******************************************************************************
104  *
105  * EEPROM access
106  *
107  ******************************************************************************
108  */
109 
110 /**
111  * Wait for EEPROM to become idle
112  *
113  * @v smscusb SMSC USB device
114  * @v e2p_base E2P register base
115  * @ret rc Return status code
116  */
117 static int smscusb_eeprom_wait ( struct smscusb_device *smscusb,
118  unsigned int e2p_base ) {
119  uint32_t e2p_cmd;
120  unsigned int i;
121  int rc;
122 
123  /* Wait for EPC_BSY to become clear */
124  for ( i = 0 ; i < SMSCUSB_EEPROM_MAX_WAIT_MS ; i++ ) {
125 
126  /* Read E2P_CMD and check EPC_BSY */
127  if ( ( rc = smscusb_readl ( smscusb,
128  ( e2p_base + SMSCUSB_E2P_CMD ),
129  &e2p_cmd ) ) != 0 )
130  return rc;
131  if ( ! ( e2p_cmd & SMSCUSB_E2P_CMD_EPC_BSY ) )
132  return 0;
133 
134  /* Delay */
135  mdelay ( 1 );
136  }
137 
138  DBGC ( smscusb, "SMSCUSB %p timed out waiting for EEPROM\n",
139  smscusb );
140  return -ETIMEDOUT;
141 }
142 
143 /**
144  * Read byte from EEPROM
145  *
146  * @v smscusb SMSC USB device
147  * @v e2p_base E2P register base
148  * @v address EEPROM address
149  * @ret byte Byte read, or negative error
150  */
151 static int smscusb_eeprom_read_byte ( struct smscusb_device *smscusb,
152  unsigned int e2p_base,
153  unsigned int address ) {
154  uint32_t e2p_cmd;
155  uint32_t e2p_data;
156  int rc;
157 
158  /* Wait for EEPROM to become idle */
159  if ( ( rc = smscusb_eeprom_wait ( smscusb, e2p_base ) ) != 0 )
160  return rc;
161 
162  /* Initiate read command */
165  if ( ( rc = smscusb_writel ( smscusb, ( e2p_base + SMSCUSB_E2P_CMD ),
166  e2p_cmd ) ) != 0 )
167  return rc;
168 
169  /* Wait for command to complete */
170  if ( ( rc = smscusb_eeprom_wait ( smscusb, e2p_base ) ) != 0 )
171  return rc;
172 
173  /* Read EEPROM data */
174  if ( ( rc = smscusb_readl ( smscusb, ( e2p_base + SMSCUSB_E2P_DATA ),
175  &e2p_data ) ) != 0 )
176  return rc;
177 
178  return SMSCUSB_E2P_DATA_GET ( e2p_data );
179 }
180 
181 /**
182  * Read data from EEPROM
183  *
184  * @v smscusb SMSC USB device
185  * @v e2p_base E2P register base
186  * @v address EEPROM address
187  * @v data Data buffer
188  * @v len Length of data
189  * @ret rc Return status code
190  */
191 static int smscusb_eeprom_read ( struct smscusb_device *smscusb,
192  unsigned int e2p_base, unsigned int address,
193  void *data, size_t len ) {
194  uint8_t *bytes;
195  int byte;
196 
197  /* Read bytes */
198  for ( bytes = data ; len-- ; address++, bytes++ ) {
199  byte = smscusb_eeprom_read_byte ( smscusb, e2p_base, address );
200  if ( byte < 0 )
201  return byte;
202  *bytes = byte;
203  }
204 
205  return 0;
206 }
207 
208 /**
209  * Fetch MAC address from EEPROM
210  *
211  * @v smscusb SMSC USB device
212  * @v e2p_base E2P register base
213  * @ret rc Return status code
214  */
216  unsigned int e2p_base ) {
217  struct net_device *netdev = smscusb->netdev;
218  int rc;
219 
220  /* Read MAC address from EEPROM */
221  if ( ( rc = smscusb_eeprom_read ( smscusb, e2p_base, SMSCUSB_EEPROM_MAC,
222  netdev->hw_addr, ETH_ALEN ) ) != 0 )
223  return rc;
224 
225  /* Check that EEPROM is physically present */
226  if ( ! is_valid_ether_addr ( netdev->hw_addr ) ) {
227  DBGC ( smscusb, "SMSCUSB %p has no EEPROM MAC (%s)\n",
228  smscusb, eth_ntoa ( netdev->hw_addr ) );
229  return -ENODEV;
230  }
231 
232  DBGC ( smscusb, "SMSCUSB %p using EEPROM MAC %s\n",
233  smscusb, eth_ntoa ( netdev->hw_addr ) );
234  return 0;
235 }
236 
237 /******************************************************************************
238  *
239  * OTP access
240  *
241  ******************************************************************************
242  */
243 
244 /**
245  * Power up OTP
246  *
247  * @v smscusb SMSC USB device
248  * @v otp_base OTP register base
249  * @ret rc Return status code
250  */
251 static int smscusb_otp_power_up ( struct smscusb_device *smscusb,
252  unsigned int otp_base ) {
253  uint32_t otp_power;
254  unsigned int i;
255  int rc;
256 
257  /* Power up OTP */
258  if ( ( rc = smscusb_writel ( smscusb, ( otp_base + SMSCUSB_OTP_POWER ),
259  0 ) ) != 0 )
260  return rc;
261 
262  /* Wait for OTP_POWER_DOWN to become clear */
263  for ( i = 0 ; i < SMSCUSB_OTP_MAX_WAIT_MS ; i++ ) {
264 
265  /* Read OTP_POWER and check OTP_POWER_DOWN */
266  if ( ( rc = smscusb_readl ( smscusb,
267  ( otp_base + SMSCUSB_OTP_POWER ),
268  &otp_power ) ) != 0 )
269  return rc;
270  if ( ! ( otp_power & SMSCUSB_OTP_POWER_DOWN ) )
271  return 0;
272 
273  /* Delay */
274  mdelay ( 1 );
275  }
276 
277  DBGC ( smscusb, "SMSCUSB %p timed out waiting for OTP power up\n",
278  smscusb );
279  return -ETIMEDOUT;
280 }
281 
282 /**
283  * Wait for OTP to become idle
284  *
285  * @v smscusb SMSC USB device
286  * @v otp_base OTP register base
287  * @ret rc Return status code
288  */
289 static int smscusb_otp_wait ( struct smscusb_device *smscusb,
290  unsigned int otp_base ) {
291  uint32_t otp_status;
292  unsigned int i;
293  int rc;
294 
295  /* Wait for OTP_STATUS_BUSY to become clear */
296  for ( i = 0 ; i < SMSCUSB_OTP_MAX_WAIT_MS ; i++ ) {
297 
298  /* Read OTP_STATUS and check OTP_STATUS_BUSY */
299  if ( ( rc = smscusb_readl ( smscusb,
300  ( otp_base + SMSCUSB_OTP_STATUS ),
301  &otp_status ) ) != 0 )
302  return rc;
303  if ( ! ( otp_status & SMSCUSB_OTP_STATUS_BUSY ) )
304  return 0;
305 
306  /* Delay */
307  mdelay ( 1 );
308  }
309 
310  DBGC ( smscusb, "SMSCUSB %p timed out waiting for OTP\n",
311  smscusb );
312  return -ETIMEDOUT;
313 }
314 
315 /**
316  * Read byte from OTP
317  *
318  * @v smscusb SMSC USB device
319  * @v otp_base OTP register base
320  * @v address OTP address
321  * @ret byte Byte read, or negative error
322  */
323 static int smscusb_otp_read_byte ( struct smscusb_device *smscusb,
324  unsigned int otp_base,
325  unsigned int address ) {
326  uint8_t addrh = ( address >> 8 );
327  uint8_t addrl = ( address >> 0 );
328  uint32_t otp_data;
329  int rc;
330 
331  /* Wait for OTP to become idle */
332  if ( ( rc = smscusb_otp_wait ( smscusb, otp_base ) ) != 0 )
333  return rc;
334 
335  /* Initiate read command */
336  if ( ( rc = smscusb_writel ( smscusb, ( otp_base + SMSCUSB_OTP_ADDRH ),
337  addrh ) ) != 0 )
338  return rc;
339  if ( ( rc = smscusb_writel ( smscusb, ( otp_base + SMSCUSB_OTP_ADDRL ),
340  addrl ) ) != 0 )
341  return rc;
342  if ( ( rc = smscusb_writel ( smscusb, ( otp_base + SMSCUSB_OTP_CMD ),
343  SMSCUSB_OTP_CMD_READ ) ) != 0 )
344  return rc;
345  if ( ( rc = smscusb_writel ( smscusb, ( otp_base + SMSCUSB_OTP_GO ),
346  SMSCUSB_OTP_GO_GO ) ) != 0 )
347  return rc;
348 
349  /* Wait for command to complete */
350  if ( ( rc = smscusb_otp_wait ( smscusb, otp_base ) ) != 0 )
351  return rc;
352 
353  /* Read OTP data */
354  if ( ( rc = smscusb_readl ( smscusb, ( otp_base + SMSCUSB_OTP_DATA ),
355  &otp_data ) ) != 0 )
356  return rc;
357 
358  return SMSCUSB_OTP_DATA_GET ( otp_data );
359 }
360 
361 /**
362  * Read data from OTP
363  *
364  * @v smscusb SMSC USB device
365  * @v otp_base OTP register base
366  * @v address OTP address
367  * @v data Data buffer
368  * @v len Length of data
369  * @ret rc Return status code
370  */
371 static int smscusb_otp_read ( struct smscusb_device *smscusb,
372  unsigned int otp_base, unsigned int address,
373  void *data, size_t len ) {
374  uint8_t *bytes;
375  int byte;
376  int rc;
377 
378  /* Power up OTP */
379  if ( ( rc = smscusb_otp_power_up ( smscusb, otp_base ) ) != 0 )
380  return rc;
381 
382  /* Read bytes */
383  for ( bytes = data ; len-- ; address++, bytes++ ) {
384  byte = smscusb_otp_read_byte ( smscusb, otp_base, address );
385  if ( byte < 0 )
386  return byte;
387  *bytes = byte;
388  }
389 
390  return 0;
391 }
392 
393 /**
394  * Fetch MAC address from OTP
395  *
396  * @v smscusb SMSC USB device
397  * @v otp_base OTP register base
398  * @ret rc Return status code
399  */
400 int smscusb_otp_fetch_mac ( struct smscusb_device *smscusb,
401  unsigned int otp_base ) {
402  struct net_device *netdev = smscusb->netdev;
404  unsigned int address;
405  int rc;
406 
407  /* Read OTP signature byte */
408  if ( ( rc = smscusb_otp_read ( smscusb, otp_base, 0, &signature,
409  sizeof ( signature ) ) ) != 0 )
410  return rc;
411 
412  /* Determine location of MAC address */
413  switch ( signature ) {
414  case SMSCUSB_OTP_1_SIG:
416  break;
417  case SMSCUSB_OTP_2_SIG:
419  break;
420  default:
421  DBGC ( smscusb, "SMSCUSB %p unknown OTP signature %#02x\n",
422  smscusb, signature );
423  return -ENOTSUP;
424  }
425 
426  /* Read MAC address from OTP */
427  if ( ( rc = smscusb_otp_read ( smscusb, otp_base, address,
428  netdev->hw_addr, ETH_ALEN ) ) != 0 )
429  return rc;
430 
431  /* Check that OTP is valid */
432  if ( ! is_valid_ether_addr ( netdev->hw_addr ) ) {
433  DBGC ( smscusb, "SMSCUSB %p has no layout %#02x OTP MAC (%s)\n",
434  smscusb, signature, eth_ntoa ( netdev->hw_addr ) );
435  return -ENODEV;
436  }
437 
438  DBGC ( smscusb, "SMSCUSB %p using layout %#02x OTP MAC %s\n",
439  smscusb, signature, eth_ntoa ( netdev->hw_addr ) );
440  return 0;
441 }
442 
443 /******************************************************************************
444  *
445  * Device tree
446  *
447  ******************************************************************************
448  */
449 
450 /**
451  * Fetch MAC address from device tree
452  *
453  * @v smscusb SMSC USB device
454  * @ret rc Return status code
455  */
456 int smscusb_fdt_fetch_mac ( struct smscusb_device *smscusb ) {
457  struct net_device *netdev = smscusb->netdev;
458  unsigned int offset;
459  int rc;
460 
461  /* Look for "ethernet[0]" alias */
462  if ( ( rc = fdt_alias ( "ethernet", &offset ) != 0 ) &&
463  ( rc = fdt_alias ( "ethernet0", &offset ) != 0 ) ) {
464  return rc;
465  }
466 
467  /* Fetch MAC address */
468  if ( ( rc = fdt_mac ( offset, netdev ) ) != 0 )
469  return rc;
470 
471  DBGC ( smscusb, "SMSCUSB %p using FDT MAC %s\n",
472  smscusb, eth_ntoa ( netdev->hw_addr ) );
473  return 0;
474 }
475 
476 /******************************************************************************
477  *
478  * MII access
479  *
480  ******************************************************************************
481  */
482 
483 /**
484  * Wait for MII to become idle
485  *
486  * @v smscusb SMSC USB device
487  * @ret rc Return status code
488  */
489 static int smscusb_mii_wait ( struct smscusb_device *smscusb ) {
490  unsigned int base = smscusb->mii_base;
491  uint32_t mii_access;
492  unsigned int i;
493  int rc;
494 
495  /* Wait for MIIBZY to become clear */
496  for ( i = 0 ; i < SMSCUSB_MII_MAX_WAIT_MS ; i++ ) {
497 
498  /* Read MII_ACCESS and check MIIBZY */
499  if ( ( rc = smscusb_readl ( smscusb,
500  ( base + SMSCUSB_MII_ACCESS ),
501  &mii_access ) ) != 0 )
502  return rc;
503  if ( ! ( mii_access & SMSCUSB_MII_ACCESS_MIIBZY ) )
504  return 0;
505 
506  /* Delay */
507  mdelay ( 1 );
508  }
509 
510  DBGC ( smscusb, "SMSCUSB %p timed out waiting for MII\n",
511  smscusb );
512  return -ETIMEDOUT;
513 }
514 
515 /**
516  * Read from MII register
517  *
518  * @v mdio MII interface
519  * @v phy PHY address
520  * @v reg Register address
521  * @ret value Data read, or negative error
522  */
523 static int smscusb_mii_read ( struct mii_interface *mdio,
524  unsigned int phy __unused, unsigned int reg ) {
525  struct smscusb_device *smscusb =
526  container_of ( mdio, struct smscusb_device, mdio );
527  unsigned int base = smscusb->mii_base;
528  uint32_t mii_access;
529  uint32_t mii_data;
530  int rc;
531 
532  /* Wait for MII to become idle */
533  if ( ( rc = smscusb_mii_wait ( smscusb ) ) != 0 )
534  return rc;
535 
536  /* Initiate read command */
537  mii_access = ( SMSCUSB_MII_ACCESS_PHY_ADDRESS |
540  if ( ( rc = smscusb_writel ( smscusb, ( base + SMSCUSB_MII_ACCESS ),
541  mii_access ) ) != 0 )
542  return rc;
543 
544  /* Wait for command to complete */
545  if ( ( rc = smscusb_mii_wait ( smscusb ) ) != 0 )
546  return rc;
547 
548  /* Read MII data */
549  if ( ( rc = smscusb_readl ( smscusb, ( base + SMSCUSB_MII_DATA ),
550  &mii_data ) ) != 0 )
551  return rc;
552 
553  return SMSCUSB_MII_DATA_GET ( mii_data );
554 }
555 
556 /**
557  * Write to MII register
558  *
559  * @v mdio MII interface
560  * @v phy PHY address
561  * @v reg Register address
562  * @v data Data to write
563  * @ret rc Return status code
564  */
565 static int smscusb_mii_write ( struct mii_interface *mdio,
566  unsigned int phy __unused, unsigned int reg,
567  unsigned int data ) {
568  struct smscusb_device *smscusb =
569  container_of ( mdio, struct smscusb_device, mdio );
570  unsigned int base = smscusb->mii_base;
571  uint32_t mii_access;
572  uint32_t mii_data;
573  int rc;
574 
575  /* Wait for MII to become idle */
576  if ( ( rc = smscusb_mii_wait ( smscusb ) ) != 0 )
577  return rc;
578 
579  /* Write MII data */
580  mii_data = SMSCUSB_MII_DATA_SET ( data );
581  if ( ( rc = smscusb_writel ( smscusb, ( base + SMSCUSB_MII_DATA ),
582  mii_data ) ) != 0 )
583  return rc;
584 
585  /* Initiate write command */
586  mii_access = ( SMSCUSB_MII_ACCESS_PHY_ADDRESS |
590  if ( ( rc = smscusb_writel ( smscusb, ( base + SMSCUSB_MII_ACCESS ),
591  mii_access ) ) != 0 )
592  return rc;
593 
594  /* Wait for command to complete */
595  if ( ( rc = smscusb_mii_wait ( smscusb ) ) != 0 )
596  return rc;
597 
598  return 0;
599 }
600 
601 /** MII operations */
604  .write = smscusb_mii_write,
605 };
606 
607 /**
608  * Check link status
609  *
610  * @v smscusb SMSC USB device
611  * @ret rc Return status code
612  */
613 int smscusb_mii_check_link ( struct smscusb_device *smscusb ) {
614  struct net_device *netdev = smscusb->netdev;
615  int intr;
616  int rc;
617 
618  /* Read PHY interrupt source */
619  intr = mii_read ( &smscusb->mii, smscusb->phy_source );
620  if ( intr < 0 ) {
621  rc = intr;
622  DBGC ( smscusb, "SMSCUSB %p could not get PHY interrupt "
623  "source: %s\n", smscusb, strerror ( rc ) );
624  return rc;
625  }
626 
627  /* Acknowledge PHY interrupt */
628  if ( ( rc = mii_write ( &smscusb->mii, smscusb->phy_source,
629  intr ) ) != 0 ) {
630  DBGC ( smscusb, "SMSCUSB %p could not acknowledge PHY "
631  "interrupt: %s\n", smscusb, strerror ( rc ) );
632  return rc;
633  }
634 
635  /* Check link status */
636  if ( ( rc = mii_check_link ( &smscusb->mii, netdev ) ) != 0 ) {
637  DBGC ( smscusb, "SMSCUSB %p could not check link: %s\n",
638  smscusb, strerror ( rc ) );
639  return rc;
640  }
641 
642  DBGC ( smscusb, "SMSCUSB %p link %s (intr %#04x)\n",
643  smscusb, ( netdev_link_ok ( netdev ) ? "up" : "down" ), intr );
644  return 0;
645 }
646 
647 /**
648  * Enable PHY interrupts and update link status
649  *
650  * @v smscusb SMSC USB device
651  * @v phy_mask PHY interrupt mask register
652  * @v intrs PHY interrupts to enable
653  * @ret rc Return status code
654  */
655 int smscusb_mii_open ( struct smscusb_device *smscusb,
656  unsigned int phy_mask, unsigned int intrs ) {
657  int rc;
658 
659  /* Enable PHY interrupts */
660  if ( ( rc = mii_write ( &smscusb->mii, phy_mask, intrs ) ) != 0 ) {
661  DBGC ( smscusb, "SMSCUSB %p could not set PHY interrupt "
662  "mask: %s\n", smscusb, strerror ( rc ) );
663  return rc;
664  }
665 
666  /* Update link status */
667  smscusb_mii_check_link ( smscusb );
668 
669  return 0;
670 }
671 
672 /******************************************************************************
673  *
674  * Receive filtering
675  *
676  ******************************************************************************
677  */
678 
679 /**
680  * Set receive address
681  *
682  * @v smscusb SMSC USB device
683  * @v addr_base Receive address register base
684  * @ret rc Return status code
685  */
686 int smscusb_set_address ( struct smscusb_device *smscusb,
687  unsigned int addr_base ) {
688  struct net_device *netdev = smscusb->netdev;
689  union smscusb_mac mac;
690  int rc;
691 
692  /* Copy MAC address */
693  memset ( &mac, 0, sizeof ( mac ) );
694  memcpy ( mac.raw, netdev->ll_addr, ETH_ALEN );
695 
696  /* Write MAC address high register */
697  if ( ( rc = smscusb_raw_writel ( smscusb,
698  ( addr_base + SMSCUSB_RX_ADDRH ),
699  mac.addr.h ) ) != 0 )
700  return rc;
701 
702  /* Write MAC address low register */
703  if ( ( rc = smscusb_raw_writel ( smscusb,
704  ( addr_base + SMSCUSB_RX_ADDRL ),
705  mac.addr.l ) ) != 0 )
706  return rc;
707 
708  return 0;
709 }
710 
711 /**
712  * Set receive filter
713  *
714  * @v smscusb SMSC USB device
715  * @v filt_base Receive filter register base
716  * @ret rc Return status code
717  */
718 int smscusb_set_filter ( struct smscusb_device *smscusb,
719  unsigned int filt_base ) {
720  struct net_device *netdev = smscusb->netdev;
721  union smscusb_mac mac;
722  int rc;
723 
724  /* Copy MAC address */
725  memset ( &mac, 0, sizeof ( mac ) );
726  memcpy ( mac.raw, netdev->ll_addr, ETH_ALEN );
728 
729  /* Write MAC address perfect filter high register */
730  if ( ( rc = smscusb_raw_writel ( smscusb,
731  ( filt_base + SMSCUSB_ADDR_FILTH(0) ),
732  mac.addr.h ) ) != 0 )
733  return rc;
734 
735  /* Write MAC address perfect filter low register */
736  if ( ( rc = smscusb_raw_writel ( smscusb,
737  ( filt_base + SMSCUSB_ADDR_FILTL(0) ),
738  mac.addr.l ) ) != 0 )
739  return rc;
740 
741  return 0;
742 }
743 
744 /******************************************************************************
745  *
746  * Endpoint operations
747  *
748  ******************************************************************************
749  */
750 
751 /**
752  * Complete interrupt transfer
753  *
754  * @v ep USB endpoint
755  * @v iobuf I/O buffer
756  * @v rc Completion status code
757  */
758 static void smscusb_intr_complete ( struct usb_endpoint *ep,
759  struct io_buffer *iobuf, int rc ) {
760  struct smscusb_device *smscusb =
761  container_of ( ep, struct smscusb_device, usbnet.intr );
762  struct net_device *netdev = smscusb->netdev;
763  struct smscusb_interrupt *intr;
764 
765  /* Profile completions */
766  profile_start ( &smscusb_intr_profiler );
767 
768  /* Ignore packets cancelled when the endpoint closes */
769  if ( ! ep->open )
770  goto done;
771 
772  /* Record USB errors against the network device */
773  if ( rc != 0 ) {
774  DBGC ( smscusb, "SMSCUSB %p interrupt failed: %s\n",
775  smscusb, strerror ( rc ) );
776  DBGC_HDA ( smscusb, 0, iobuf->data, iob_len ( iobuf ) );
777  netdev_rx_err ( netdev, NULL, rc );
778  goto done;
779  }
780 
781  /* Extract interrupt data */
782  if ( iob_len ( iobuf ) != sizeof ( *intr ) ) {
783  DBGC ( smscusb, "SMSCUSB %p malformed interrupt\n",
784  smscusb );
785  DBGC_HDA ( smscusb, 0, iobuf->data, iob_len ( iobuf ) );
786  netdev_rx_err ( netdev, NULL, rc );
787  goto done;
788  }
789  intr = iobuf->data;
790 
791  /* Record interrupt status */
792  smscusb->int_sts = le32_to_cpu ( intr->int_sts );
793  profile_stop ( &smscusb_intr_profiler );
794 
795  done:
796  /* Free I/O buffer */
797  free_iob ( iobuf );
798 }
799 
800 /** Interrupt endpoint operations */
803 };
804 
805 /**
806  * Complete bulk OUT transfer
807  *
808  * @v ep USB endpoint
809  * @v iobuf I/O buffer
810  * @v rc Completion status code
811  */
812 static void smscusb_out_complete ( struct usb_endpoint *ep,
813  struct io_buffer *iobuf, int rc ) {
814  struct smscusb_device *smscusb =
815  container_of ( ep, struct smscusb_device, usbnet.out );
816  struct net_device *netdev = smscusb->netdev;
817 
818  /* Report TX completion */
819  netdev_tx_complete_err ( netdev, iobuf, rc );
820 }
821 
822 /** Bulk OUT endpoint operations */
825 };
int smscusb_set_address(struct smscusb_device *smscusb, unsigned int addr_base)
Set receive address.
Definition: smscusb.c:686
#define SMSCUSB_MII_ACCESS_MIIWNR
MII write.
Definition: smscusb.h:101
#define SMSCUSB_E2P_CMD_EPC_ADDR(addr)
EPC address.
Definition: smscusb.h:40
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static struct profiler smscusb_intr_profiler __profiler
Interrupt completion profiler.
Definition: smscusb.c:43
static int smscusb_otp_read_byte(struct smscusb_device *smscusb, unsigned int otp_base, unsigned int address)
Read byte from OTP.
Definition: smscusb.c:323
void(* complete)(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete transfer.
Definition: usb.h:481
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition: netdevice.c:501
#define SMSCUSB_OTP_STATUS
OTP status register offset.
Definition: smscusb.h:79
static void smscusb_out_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk OUT transfer.
Definition: smscusb.c:812
Interrupt packet format.
Definition: smscusb.h:141
#define le32_to_cpu(value)
Definition: byteswap.h:113
Error codes.
An SMSC USB device.
Definition: smscusb.h:147
int fdt_mac(unsigned int offset, struct net_device *netdev)
Get MAC address from property.
Definition: fdt.c:377
#define SMSCUSB_REGISTER_WRITE
Register write command.
Definition: smscusb.h:22
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
uint64_t address
Base address.
Definition: ena.h:24
int(* read)(struct mii_interface *mdio, unsigned int phy, unsigned int reg)
Read from MII register.
Definition: mii.h:27
#define SMSCUSB_OTP_1_MAC
OTP layout 1 MAC address offset.
Definition: smscusb.h:89
#define SMSCUSB_EEPROM_MAC
MAC address EEPROM address.
Definition: smscusb.h:49
#define DBGC(...)
Definition: compiler.h:505
#define SMSCUSB_ADDR_FILTH_VALID
Address valid.
Definition: smscusb.h:135
struct usb_device * usb
USB device.
Definition: smscusb.h:149
static int smscusb_mii_read(struct mii_interface *mdio, unsigned int phy __unused, unsigned int reg)
Read from MII register.
Definition: smscusb.c:523
#define SMSCUSB_OTP_2_MAC
OTP layout 2 MAC address offset.
Definition: smscusb.h:95
static int smscusb_writel(struct smscusb_device *smscusb, unsigned int address, uint32_t value)
Write register.
Definition: smscusb.h:182
#define SMSCUSB_OTP_DATA_GET(otp_data)
OTP data.
Definition: smscusb.h:66
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
A data structure for storing profiling information.
Definition: profile.h:26
static int smscusb_otp_power_up(struct smscusb_device *smscusb, unsigned int otp_base)
Power up OTP.
Definition: smscusb.c:251
int open
Endpoint is open.
Definition: usb.h:404
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition: profile.h:171
struct usb_endpoint intr
Interrupt endpoint.
Definition: usbnet.h:27
#define SMSCUSB_MII_DATA
MII data register offset.
Definition: smscusb.h:105
int smscusb_mii_open(struct smscusb_device *smscusb, unsigned int phy_mask, unsigned int intrs)
Enable PHY interrupts and update link status.
Definition: smscusb.c:655
int usb_control(struct usb_device *usb, unsigned int request, unsigned int value, unsigned int index, void *data, size_t len)
Issue USB control transaction.
Definition: usb.c:753
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
#define SMSCUSB_MII_ACCESS_MIIRINDA(addr)
MII register.
Definition: smscusb.h:100
#define SMSCUSB_MII_DATA_GET(mii_data)
Get data.
Definition: smscusb.h:107
#define SMSCUSB_RX_ADDRH
MAC receive address high register offset.
Definition: smscusb.h:128
struct usb_endpoint out
Bulk OUT endpoint.
Definition: usbnet.h:31
int smscusb_set_filter(struct smscusb_device *smscusb, unsigned int filt_base)
Set receive filter.
Definition: smscusb.c:718
u8 signature
Definition: CIB_PRM.h:35
#define SMSCUSB_OTP_2_SIG
OTP layout 2 signature.
Definition: smscusb.h:92
uint32_t int_sts
Interrupt status.
Definition: smscusb.h:165
#define SMSCUSB_MII_MAX_WAIT_MS
Maximum time to wait for MII (in milliseconds)
Definition: smscusb.h:112
uint16_t phy_source
PHY interrupt source register.
Definition: smscusb.h:163
A USB endpoint.
Definition: usb.h:389
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define SMSCUSB_OTP_CMD
OTP command selection register offset.
Definition: smscusb.h:71
const char * name
Name.
Definition: profile.h:28
#define SMSCUSB_OTP_MAX_WAIT_MS
Maximum time to wait for OTP (in milliseconds)
Definition: smscusb.h:83
struct usbnet_device usbnet
USB network device.
Definition: smscusb.h:155
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
Ethernet protocol.
#define SMSCUSB_OTP_GO_GO
Initiate command.
Definition: smscusb.h:76
#define SMSCUSB_MII_ACCESS_PHY_ADDRESS
PHY address.
Definition: smscusb.h:99
uint8_t intr
Interrupts enabled.
Definition: ena.h:14
#define SMSCUSB_OTP_CMD_READ
Read command.
Definition: smscusb.h:72
#define DBGC_HDA(...)
Definition: compiler.h:506
static int netdev_link_ok(struct net_device *netdev)
Check link state of network device.
Definition: netdevice.h:630
static int smscusb_otp_wait(struct smscusb_device *smscusb, unsigned int otp_base)
Wait for OTP to become idle.
Definition: smscusb.c:289
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static struct net_device * netdev
Definition: gdbudp.c:52
int smscusb_raw_writel(struct smscusb_device *smscusb, unsigned int address, uint32_t value)
Write register (without byte-swapping)
Definition: smscusb.c:61
static int smscusb_readl(struct smscusb_device *smscusb, unsigned int address, uint32_t *value)
Read register.
Definition: smscusb.h:203
#define SMSCUSB_E2P_CMD_EPC_BSY
EPC busy.
Definition: smscusb.h:38
#define SMSCUSB_ADDR_FILTL(n)
MAC address perfect filter N low register offset.
Definition: smscusb.h:138
static void profile_start(struct profiler *profiler)
Start profiling.
Definition: profile.h:158
Profiling.
#define SMSCUSB_MII_ACCESS_MIIBZY
MII busy.
Definition: smscusb.h:102
#define SMSCUSB_MII_DATA_SET(data)
Set data.
Definition: smscusb.h:106
#define SMSCUSB_E2P_DATA_GET(e2p_data)
EEPROM data.
Definition: smscusb.h:44
MAC address.
Definition: smscusb.h:115
static int smscusb_mii_write(struct mii_interface *mdio, unsigned int phy __unused, unsigned int reg, unsigned int data)
Write to MII register.
Definition: smscusb.c:565
static int smscusb_mii_wait(struct smscusb_device *smscusb)
Wait for MII to become idle.
Definition: smscusb.c:489
#define SMSCUSB_OTP_ADDRH
OTP address high byte register offset.
Definition: smscusb.h:59
#define cpu_to_le32(value)
Definition: byteswap.h:107
struct mii_interface mdio
MII interface.
Definition: smscusb.h:157
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
int smscusb_eeprom_fetch_mac(struct smscusb_device *smscusb, unsigned int e2p_base)
Fetch MAC address from EEPROM.
Definition: smscusb.c:215
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static int smscusb_eeprom_wait(struct smscusb_device *smscusb, unsigned int e2p_base)
Wait for EEPROM to become idle.
Definition: smscusb.c:117
static unsigned int unsigned int reg
Definition: intel.h:245
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition: ethernet.c:175
A network device.
Definition: netdevice.h:348
#define ENODEV
No such device.
Definition: errno.h:509
SMSC USB Ethernet drivers.
unsigned char uint8_t
Definition: stdint.h:10
#define SMSCUSB_ADDR_FILTH(n)
MAC address perfect filter N high register offset.
Definition: smscusb.h:134
#define DBGCIO(...)
Definition: compiler.h:556
#define ETH_ALEN
Definition: if_ether.h:8
int smscusb_raw_readl(struct smscusb_device *smscusb, unsigned int address, uint32_t *value)
Read register (without byte-swapping)
Definition: smscusb.c:86
struct mii_device mii
MII device.
Definition: smscusb.h:159
unsigned int uint32_t
Definition: stdint.h:12
int mii_check_link(struct mii_device *mii, struct net_device *netdev)
Update link status via MII.
Definition: mii.c:126
static int is_valid_ether_addr(const void *addr)
Check if Ethernet address is valid.
Definition: ethernet.h:77
unsigned char byte
Definition: smc9000.h:38
uint16_t base
Base address.
Definition: edd.h:14
#define SMSCUSB_OTP_POWER_DOWN
OTP power down.
Definition: smscusb.h:56
static int smscusb_eeprom_read(struct smscusb_device *smscusb, unsigned int e2p_base, unsigned int address, void *data, size_t len)
Read data from EEPROM.
Definition: smscusb.c:191
#define SMSCUSB_OTP_DATA
OTP data register offset.
Definition: smscusb.h:65
#define SMSCUSB_EEPROM_MAX_WAIT_MS
Maximum time to wait for EEPROM (in milliseconds)
Definition: smscusb.h:52
MII interface operations.
Definition: mii.h:18
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
USB network devices.
#define SMSCUSB_E2P_CMD
EEPROM command register offset.
Definition: smscusb.h:37
int smscusb_otp_fetch_mac(struct smscusb_device *smscusb, unsigned int otp_base)
Fetch MAC address from OTP.
Definition: smscusb.c:400
void netdev_tx_complete_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Complete network transmission.
Definition: netdevice.c:395
struct usb_endpoint_driver_operations smscusb_intr_operations
Interrupt endpoint operations.
Definition: smscusb.c:801
uint32_t len
Length.
Definition: ena.h:14
#define SMSCUSB_MII_ACCESS
MII access register offset.
Definition: smscusb.h:98
#define SMSCUSB_OTP_GO
OTP command initiation register offset.
Definition: smscusb.h:75
Universal Serial Bus (USB)
struct usb_endpoint_driver_operations smscusb_out_operations
Bulk OUT endpoint operations.
Definition: smscusb.c:823
#define SMSCUSB_OTP_ADDRL
OTP address low byte register offset.
Definition: smscusb.h:62
void * data
Start of data.
Definition: iobuf.h:44
int smscusb_mii_check_link(struct smscusb_device *smscusb)
Check link status.
Definition: smscusb.c:613
Flattened Device Tree.
uint16_t mii_base
MII register base.
Definition: smscusb.h:161
An MII interface.
Definition: mii.h:43
#define SMSCUSB_E2P_CMD_EPC_CMD_READ
READ command.
Definition: smscusb.h:39
#define SMSCUSB_REGISTER_READ
Register read command.
Definition: smscusb.h:27
static int mii_read(int phy_id, int location)
Definition: epic100.c:499
#define SMSCUSB_RX_ADDRL
MAC receive address low register offset.
Definition: smscusb.h:131
#define SMSCUSB_OTP_STATUS_BUSY
OTP busy.
Definition: smscusb.h:80
struct net_device * netdev
Network device.
Definition: smscusb.h:153
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:381
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
USB endpoint driver operations.
Definition: usb.h:474
static int smscusb_otp_read(struct smscusb_device *smscusb, unsigned int otp_base, unsigned int address, void *data, size_t len)
Read data from OTP.
Definition: smscusb.c:371
static int smscusb_eeprom_read_byte(struct smscusb_device *smscusb, unsigned int e2p_base, unsigned int address)
Read byte from EEPROM.
Definition: smscusb.c:151
uint8_t bytes[64]
Definition: ib_mad.h:16
#define SMSCUSB_OTP_POWER
OTP power register offset.
Definition: smscusb.h:55
#define SMSCUSB_OTP_1_SIG
OTP layout 1 signature.
Definition: smscusb.h:86
static int mii_write(struct mii_device *mii, unsigned int reg, unsigned int data)
Write to MII register.
Definition: mii.h:104
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:375
static void smscusb_intr_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete interrupt transfer.
Definition: smscusb.c:758
int smscusb_fdt_fetch_mac(struct smscusb_device *smscusb)
Fetch MAC address from device tree.
Definition: smscusb.c:456
#define SMSCUSB_E2P_DATA
EEPROM data register offset.
Definition: smscusb.h:43
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
String functions.
struct bofm_section_header done
Definition: bofm_test.c:46
struct mii_operations smscusb_mii_operations
MII operations.
Definition: smscusb.c:602
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:32
int fdt_alias(const char *name, unsigned int *offset)
Find node by alias.
Definition: fdt.c:284