iPXE
smscusb.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2017 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017  * 02110-1301, USA.
00018  *
00019  * You can also choose to distribute this program under the terms of
00020  * the Unmodified Binary Distribution Licence (as given in the file
00021  * COPYING.UBDL), provided that you have satisfied its requirements.
00022  */
00023 
00024 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00025 
00026 #include <string.h>
00027 #include <errno.h>
00028 #include <unistd.h>
00029 #include <ipxe/usb.h>
00030 #include <ipxe/usbnet.h>
00031 #include <ipxe/ethernet.h>
00032 #include <ipxe/profile.h>
00033 #include "smscusb.h"
00034 
00035 /** @file
00036  *
00037  * SMSC USB Ethernet drivers
00038  *
00039  */
00040 
00041 /** Interrupt completion profiler */
00042 static struct profiler smscusb_intr_profiler __profiler =
00043         { .name = "smscusb.intr" };
00044 
00045 /******************************************************************************
00046  *
00047  * Register access
00048  *
00049  ******************************************************************************
00050  */
00051 
00052 /**
00053  * Write register (without byte-swapping)
00054  *
00055  * @v smscusb           Smscusb device
00056  * @v address           Register address
00057  * @v value             Register value
00058  * @ret rc              Return status code
00059  */
00060 int smscusb_raw_writel ( struct smscusb_device *smscusb, unsigned int address,
00061                          uint32_t value ) {
00062         int rc;
00063 
00064         /* Write register */
00065         DBGCIO ( smscusb, "SMSCUSB %p [%03x] <= %08x\n",
00066                  smscusb, address, le32_to_cpu ( value ) );
00067         if ( ( rc = usb_control ( smscusb->usb, SMSCUSB_REGISTER_WRITE, 0,
00068                                   address, &value, sizeof ( value ) ) ) != 0 ) {
00069                 DBGC ( smscusb, "SMSCUSB %p could not write %03x: %s\n",
00070                        smscusb, address, strerror ( rc ) );
00071                 return rc;
00072         }
00073 
00074         return 0;
00075 }
00076 
00077 /**
00078  * Read register (without byte-swapping)
00079  *
00080  * @v smscusb           SMSC USB device
00081  * @v address           Register address
00082  * @ret value           Register value
00083  * @ret rc              Return status code
00084  */
00085 int smscusb_raw_readl ( struct smscusb_device *smscusb, unsigned int address,
00086                         uint32_t *value ) {
00087         int rc;
00088 
00089         /* Read register */
00090         if ( ( rc = usb_control ( smscusb->usb, SMSCUSB_REGISTER_READ, 0,
00091                                   address, value, sizeof ( *value ) ) ) != 0 ) {
00092                 DBGC ( smscusb, "SMSCUSB %p could not read %03x: %s\n",
00093                        smscusb, address, strerror ( rc ) );
00094                 return rc;
00095         }
00096         DBGCIO ( smscusb, "SMSCUSB %p [%03x] => %08x\n",
00097                  smscusb, address, le32_to_cpu ( *value ) );
00098 
00099         return 0;
00100 }
00101 
00102 /******************************************************************************
00103  *
00104  * EEPROM access
00105  *
00106  ******************************************************************************
00107  */
00108 
00109 /**
00110  * Wait for EEPROM to become idle
00111  *
00112  * @v smscusb           SMSC USB device
00113  * @v e2p_base          E2P register base
00114  * @ret rc              Return status code
00115  */
00116 static int smscusb_eeprom_wait ( struct smscusb_device *smscusb,
00117                                  unsigned int e2p_base ) {
00118         uint32_t e2p_cmd;
00119         unsigned int i;
00120         int rc;
00121 
00122         /* Wait for EPC_BSY to become clear */
00123         for ( i = 0 ; i < SMSCUSB_EEPROM_MAX_WAIT_MS ; i++ ) {
00124 
00125                 /* Read E2P_CMD and check EPC_BSY */
00126                 if ( ( rc = smscusb_readl ( smscusb,
00127                                             ( e2p_base + SMSCUSB_E2P_CMD ),
00128                                             &e2p_cmd ) ) != 0 )
00129                         return rc;
00130                 if ( ! ( e2p_cmd & SMSCUSB_E2P_CMD_EPC_BSY ) )
00131                         return 0;
00132 
00133                 /* Delay */
00134                 mdelay ( 1 );
00135         }
00136 
00137         DBGC ( smscusb, "SMSCUSB %p timed out waiting for EEPROM\n",
00138                smscusb );
00139         return -ETIMEDOUT;
00140 }
00141 
00142 /**
00143  * Read byte from EEPROM
00144  *
00145  * @v smscusb           SMSC USB device
00146  * @v e2p_base          E2P register base
00147  * @v address           EEPROM address
00148  * @ret byte            Byte read, or negative error
00149  */
00150 static int smscusb_eeprom_read_byte ( struct smscusb_device *smscusb,
00151                                       unsigned int e2p_base,
00152                                       unsigned int address ) {
00153         uint32_t e2p_cmd;
00154         uint32_t e2p_data;
00155         int rc;
00156 
00157         /* Wait for EEPROM to become idle */
00158         if ( ( rc = smscusb_eeprom_wait ( smscusb, e2p_base ) ) != 0 )
00159                 return rc;
00160 
00161         /* Initiate read command */
00162         e2p_cmd = ( SMSCUSB_E2P_CMD_EPC_BSY | SMSCUSB_E2P_CMD_EPC_CMD_READ |
00163                     SMSCUSB_E2P_CMD_EPC_ADDR ( address ) );
00164         if ( ( rc = smscusb_writel ( smscusb, ( e2p_base + SMSCUSB_E2P_CMD ),
00165                                      e2p_cmd ) ) != 0 )
00166                 return rc;
00167 
00168         /* Wait for command to complete */
00169         if ( ( rc = smscusb_eeprom_wait ( smscusb, e2p_base ) ) != 0 )
00170                 return rc;
00171 
00172         /* Read EEPROM data */
00173         if ( ( rc = smscusb_readl ( smscusb, ( e2p_base + SMSCUSB_E2P_DATA ),
00174                                     &e2p_data ) ) != 0 )
00175                 return rc;
00176 
00177         return SMSCUSB_E2P_DATA_GET ( e2p_data );
00178 }
00179 
00180 /**
00181  * Read data from EEPROM
00182  *
00183  * @v smscusb           SMSC USB device
00184  * @v e2p_base          E2P register base
00185  * @v address           EEPROM address
00186  * @v data              Data buffer
00187  * @v len               Length of data
00188  * @ret rc              Return status code
00189  */
00190 static int smscusb_eeprom_read ( struct smscusb_device *smscusb,
00191                                  unsigned int e2p_base, unsigned int address,
00192                                  void *data, size_t len ) {
00193         uint8_t *bytes;
00194         int byte;
00195 
00196         /* Read bytes */
00197         for ( bytes = data ; len-- ; address++, bytes++ ) {
00198                 byte = smscusb_eeprom_read_byte ( smscusb, e2p_base, address );
00199                 if ( byte < 0 )
00200                         return byte;
00201                 *bytes = byte;
00202         }
00203 
00204         return 0;
00205 }
00206 
00207 /**
00208  * Fetch MAC address from EEPROM
00209  *
00210  * @v smscusb           SMSC USB device
00211  * @v e2p_base          E2P register base
00212  * @ret rc              Return status code
00213  */
00214 int smscusb_eeprom_fetch_mac ( struct smscusb_device *smscusb,
00215                                unsigned int e2p_base ) {
00216         struct net_device *netdev = smscusb->netdev;
00217         int rc;
00218 
00219         /* Read MAC address from EEPROM */
00220         if ( ( rc = smscusb_eeprom_read ( smscusb, e2p_base, SMSCUSB_EEPROM_MAC,
00221                                           netdev->hw_addr, ETH_ALEN ) ) != 0 )
00222                 return rc;
00223 
00224         /* Check that EEPROM is physically present */
00225         if ( ! is_valid_ether_addr ( netdev->hw_addr ) ) {
00226                 DBGC ( smscusb, "SMSCUSB %p has no EEPROM MAC (%s)\n",
00227                        smscusb, eth_ntoa ( netdev->hw_addr ) );
00228                 return -ENODEV;
00229         }
00230 
00231         DBGC ( smscusb, "SMSCUSB %p using EEPROM MAC %s\n",
00232                smscusb, eth_ntoa ( netdev->hw_addr ) );
00233         return 0;
00234 }
00235 
00236 /******************************************************************************
00237  *
00238  * OTP access
00239  *
00240  ******************************************************************************
00241  */
00242 
00243 /**
00244  * Power up OTP
00245  *
00246  * @v smscusb           SMSC USB device
00247  * @v otp_base          OTP register base
00248  * @ret rc              Return status code
00249  */
00250 static int smscusb_otp_power_up ( struct smscusb_device *smscusb,
00251                                   unsigned int otp_base ) {
00252         uint32_t otp_power;
00253         unsigned int i;
00254         int rc;
00255 
00256         /* Power up OTP */
00257         if ( ( rc = smscusb_writel ( smscusb, ( otp_base + SMSCUSB_OTP_POWER ),
00258                                      0 ) ) != 0 )
00259                 return rc;
00260 
00261         /* Wait for OTP_POWER_DOWN to become clear */
00262         for ( i = 0 ; i < SMSCUSB_OTP_MAX_WAIT_MS ; i++ ) {
00263 
00264                 /* Read OTP_POWER and check OTP_POWER_DOWN */
00265                 if ( ( rc = smscusb_readl ( smscusb,
00266                                             ( otp_base + SMSCUSB_OTP_POWER ),
00267                                             &otp_power ) ) != 0 )
00268                         return rc;
00269                 if ( ! ( otp_power & SMSCUSB_OTP_POWER_DOWN ) )
00270                         return 0;
00271 
00272                 /* Delay */
00273                 mdelay ( 1 );
00274         }
00275 
00276         DBGC ( smscusb, "SMSCUSB %p timed out waiting for OTP power up\n",
00277                smscusb );
00278         return -ETIMEDOUT;
00279 }
00280 
00281 /**
00282  * Wait for OTP to become idle
00283  *
00284  * @v smscusb           SMSC USB device
00285  * @v otp_base          OTP register base
00286  * @ret rc              Return status code
00287  */
00288 static int smscusb_otp_wait ( struct smscusb_device *smscusb,
00289                               unsigned int otp_base ) {
00290         uint32_t otp_status;
00291         unsigned int i;
00292         int rc;
00293 
00294         /* Wait for OTP_STATUS_BUSY to become clear */
00295         for ( i = 0 ; i < SMSCUSB_OTP_MAX_WAIT_MS ; i++ ) {
00296 
00297                 /* Read OTP_STATUS and check OTP_STATUS_BUSY */
00298                 if ( ( rc = smscusb_readl ( smscusb,
00299                                             ( otp_base + SMSCUSB_OTP_STATUS ),
00300                                             &otp_status ) ) != 0 )
00301                         return rc;
00302                 if ( ! ( otp_status & SMSCUSB_OTP_STATUS_BUSY ) )
00303                         return 0;
00304 
00305                 /* Delay */
00306                 mdelay ( 1 );
00307         }
00308 
00309         DBGC ( smscusb, "SMSCUSB %p timed out waiting for OTP\n",
00310                smscusb );
00311         return -ETIMEDOUT;
00312 }
00313 
00314 /**
00315  * Read byte from OTP
00316  *
00317  * @v smscusb           SMSC USB device
00318  * @v otp_base          OTP register base
00319  * @v address           OTP address
00320  * @ret byte            Byte read, or negative error
00321  */
00322 static int smscusb_otp_read_byte ( struct smscusb_device *smscusb,
00323                                    unsigned int otp_base,
00324                                    unsigned int address ) {
00325         uint8_t addrh = ( address >> 8 );
00326         uint8_t addrl = ( address >> 0 );
00327         uint32_t otp_data;
00328         int rc;
00329 
00330         /* Wait for OTP to become idle */
00331         if ( ( rc = smscusb_otp_wait ( smscusb, otp_base ) ) != 0 )
00332                 return rc;
00333 
00334         /* Initiate read command */
00335         if ( ( rc = smscusb_writel ( smscusb, ( otp_base + SMSCUSB_OTP_ADDRH ),
00336                                      addrh ) ) != 0 )
00337                 return rc;
00338         if ( ( rc = smscusb_writel ( smscusb, ( otp_base + SMSCUSB_OTP_ADDRL ),
00339                                      addrl ) ) != 0 )
00340                 return rc;
00341         if ( ( rc = smscusb_writel ( smscusb, ( otp_base + SMSCUSB_OTP_CMD ),
00342                                      SMSCUSB_OTP_CMD_READ ) ) != 0 )
00343                 return rc;
00344         if ( ( rc = smscusb_writel ( smscusb, ( otp_base + SMSCUSB_OTP_GO ),
00345                                      SMSCUSB_OTP_GO_GO ) ) != 0 )
00346                 return rc;
00347 
00348         /* Wait for command to complete */
00349         if ( ( rc = smscusb_otp_wait ( smscusb, otp_base ) ) != 0 )
00350                 return rc;
00351 
00352         /* Read OTP data */
00353         if ( ( rc = smscusb_readl ( smscusb, ( otp_base + SMSCUSB_OTP_DATA ),
00354                                     &otp_data ) ) != 0 )
00355                 return rc;
00356 
00357         return SMSCUSB_OTP_DATA_GET ( otp_data );
00358 }
00359 
00360 /**
00361  * Read data from OTP
00362  *
00363  * @v smscusb           SMSC USB device
00364  * @v otp_base          OTP register base
00365  * @v address           OTP address
00366  * @v data              Data buffer
00367  * @v len               Length of data
00368  * @ret rc              Return status code
00369  */
00370 static int smscusb_otp_read ( struct smscusb_device *smscusb,
00371                               unsigned int otp_base, unsigned int address,
00372                               void *data, size_t len ) {
00373         uint8_t *bytes;
00374         int byte;
00375         int rc;
00376 
00377         /* Power up OTP */
00378         if ( ( rc = smscusb_otp_power_up ( smscusb, otp_base ) ) != 0 )
00379                 return rc;
00380 
00381         /* Read bytes */
00382         for ( bytes = data ; len-- ; address++, bytes++ ) {
00383                 byte = smscusb_otp_read_byte ( smscusb, otp_base, address );
00384                 if ( byte < 0 )
00385                         return byte;
00386                 *bytes = byte;
00387         }
00388 
00389         return 0;
00390 }
00391 
00392 /**
00393  * Fetch MAC address from OTP
00394  *
00395  * @v smscusb           SMSC USB device
00396  * @v otp_base          OTP register base
00397  * @ret rc              Return status code
00398  */
00399 int smscusb_otp_fetch_mac ( struct smscusb_device *smscusb,
00400                             unsigned int otp_base ) {
00401         struct net_device *netdev = smscusb->netdev;
00402         uint8_t signature;
00403         unsigned int address;
00404         int rc;
00405 
00406         /* Read OTP signature byte */
00407         if ( ( rc = smscusb_otp_read ( smscusb, otp_base, 0, &signature,
00408                                        sizeof ( signature ) ) ) != 0 )
00409                 return rc;
00410 
00411         /* Determine location of MAC address */
00412         switch ( signature ) {
00413         case SMSCUSB_OTP_1_SIG:
00414                 address = SMSCUSB_OTP_1_MAC;
00415                 break;
00416         case SMSCUSB_OTP_2_SIG:
00417                 address = SMSCUSB_OTP_2_MAC;
00418                 break;
00419         default:
00420                 DBGC ( smscusb, "SMSCUSB %p unknown OTP signature %#02x\n",
00421                        smscusb, signature );
00422                 return -ENOTSUP;
00423         }
00424 
00425         /* Read MAC address from OTP */
00426         if ( ( rc = smscusb_otp_read ( smscusb, otp_base, address,
00427                                        netdev->hw_addr, ETH_ALEN ) ) != 0 )
00428                 return rc;
00429 
00430         /* Check that OTP is valid */
00431         if ( ! is_valid_ether_addr ( netdev->hw_addr ) ) {
00432                 DBGC ( smscusb, "SMSCUSB %p has no layout %#02x OTP MAC (%s)\n",
00433                        smscusb, signature, eth_ntoa ( netdev->hw_addr ) );
00434                 return -ENODEV;
00435         }
00436 
00437         DBGC ( smscusb, "SMSCUSB %p using layout %#02x OTP MAC %s\n",
00438                smscusb, signature, eth_ntoa ( netdev->hw_addr ) );
00439         return 0;
00440 }
00441 
00442 /******************************************************************************
00443  *
00444  * MII access
00445  *
00446  ******************************************************************************
00447  */
00448 
00449 /**
00450  * Wait for MII to become idle
00451  *
00452  * @v smscusb           SMSC USB device
00453  * @ret rc              Return status code
00454  */
00455 static int smscusb_mii_wait ( struct smscusb_device *smscusb ) {
00456         unsigned int base = smscusb->mii_base;
00457         uint32_t mii_access;
00458         unsigned int i;
00459         int rc;
00460 
00461         /* Wait for MIIBZY to become clear */
00462         for ( i = 0 ; i < SMSCUSB_MII_MAX_WAIT_MS ; i++ ) {
00463 
00464                 /* Read MII_ACCESS and check MIIBZY */
00465                 if ( ( rc = smscusb_readl ( smscusb,
00466                                             ( base + SMSCUSB_MII_ACCESS ),
00467                                             &mii_access ) ) != 0 )
00468                         return rc;
00469                 if ( ! ( mii_access & SMSCUSB_MII_ACCESS_MIIBZY ) )
00470                         return 0;
00471 
00472                 /* Delay */
00473                 mdelay ( 1 );
00474         }
00475 
00476         DBGC ( smscusb, "SMSCUSB %p timed out waiting for MII\n",
00477                smscusb );
00478         return -ETIMEDOUT;
00479 }
00480 
00481 /**
00482  * Read from MII register
00483  *
00484  * @v mdio              MII interface
00485  * @v phy               PHY address
00486  * @v reg               Register address
00487  * @ret value           Data read, or negative error
00488  */
00489 static int smscusb_mii_read ( struct mii_interface *mdio,
00490                               unsigned int phy __unused, unsigned int reg ) {
00491         struct smscusb_device *smscusb =
00492                 container_of ( mdio, struct smscusb_device, mdio );
00493         unsigned int base = smscusb->mii_base;
00494         uint32_t mii_access;
00495         uint32_t mii_data;
00496         int rc;
00497 
00498         /* Wait for MII to become idle */
00499         if ( ( rc = smscusb_mii_wait ( smscusb ) ) != 0 )
00500                 return rc;
00501 
00502         /* Initiate read command */
00503         mii_access = ( SMSCUSB_MII_ACCESS_PHY_ADDRESS |
00504                        SMSCUSB_MII_ACCESS_MIIRINDA ( reg ) |
00505                        SMSCUSB_MII_ACCESS_MIIBZY );
00506         if ( ( rc = smscusb_writel ( smscusb, ( base + SMSCUSB_MII_ACCESS ),
00507                                      mii_access ) ) != 0 )
00508                 return rc;
00509 
00510         /* Wait for command to complete */
00511         if ( ( rc = smscusb_mii_wait ( smscusb ) ) != 0 )
00512                 return rc;
00513 
00514         /* Read MII data */
00515         if ( ( rc = smscusb_readl ( smscusb, ( base + SMSCUSB_MII_DATA ),
00516                                     &mii_data ) ) != 0 )
00517                 return rc;
00518 
00519         return SMSCUSB_MII_DATA_GET ( mii_data );
00520 }
00521 
00522 /**
00523  * Write to MII register
00524  *
00525  * @v mdio              MII interface
00526  * @v phy               PHY address
00527  * @v reg               Register address
00528  * @v data              Data to write
00529  * @ret rc              Return status code
00530  */
00531 static int smscusb_mii_write ( struct mii_interface *mdio,
00532                                unsigned int phy __unused, unsigned int reg,
00533                                unsigned int data ) {
00534         struct smscusb_device *smscusb =
00535                 container_of ( mdio, struct smscusb_device, mdio );
00536         unsigned int base = smscusb->mii_base;
00537         uint32_t mii_access;
00538         uint32_t mii_data;
00539         int rc;
00540 
00541         /* Wait for MII to become idle */
00542         if ( ( rc = smscusb_mii_wait ( smscusb ) ) != 0 )
00543                 return rc;
00544 
00545         /* Write MII data */
00546         mii_data = SMSCUSB_MII_DATA_SET ( data );
00547         if ( ( rc = smscusb_writel ( smscusb, ( base + SMSCUSB_MII_DATA ),
00548                                      mii_data ) ) != 0 )
00549                 return rc;
00550 
00551         /* Initiate write command */
00552         mii_access = ( SMSCUSB_MII_ACCESS_PHY_ADDRESS |
00553                        SMSCUSB_MII_ACCESS_MIIRINDA ( reg ) |
00554                        SMSCUSB_MII_ACCESS_MIIWNR |
00555                        SMSCUSB_MII_ACCESS_MIIBZY );
00556         if ( ( rc = smscusb_writel ( smscusb, ( base + SMSCUSB_MII_ACCESS ),
00557                                      mii_access ) ) != 0 )
00558                 return rc;
00559 
00560         /* Wait for command to complete */
00561         if ( ( rc = smscusb_mii_wait ( smscusb ) ) != 0 )
00562                 return rc;
00563 
00564         return 0;
00565 }
00566 
00567 /** MII operations */
00568 struct mii_operations smscusb_mii_operations = {
00569         .read = smscusb_mii_read,
00570         .write = smscusb_mii_write,
00571 };
00572 
00573 /**
00574  * Check link status
00575  *
00576  * @v smscusb           SMSC USB device
00577  * @ret rc              Return status code
00578  */
00579 int smscusb_mii_check_link ( struct smscusb_device *smscusb ) {
00580         struct net_device *netdev = smscusb->netdev;
00581         int intr;
00582         int rc;
00583 
00584         /* Read PHY interrupt source */
00585         intr = mii_read ( &smscusb->mii, smscusb->phy_source );
00586         if ( intr < 0 ) {
00587                 rc = intr;
00588                 DBGC ( smscusb, "SMSCUSB %p could not get PHY interrupt "
00589                        "source: %s\n", smscusb, strerror ( rc ) );
00590                 return rc;
00591         }
00592 
00593         /* Acknowledge PHY interrupt */
00594         if ( ( rc = mii_write ( &smscusb->mii, smscusb->phy_source,
00595                                 intr ) ) != 0 ) {
00596                 DBGC ( smscusb, "SMSCUSB %p could not acknowledge PHY "
00597                        "interrupt: %s\n", smscusb, strerror ( rc ) );
00598                 return rc;
00599         }
00600 
00601         /* Check link status */
00602         if ( ( rc = mii_check_link ( &smscusb->mii, netdev ) ) != 0 ) {
00603                 DBGC ( smscusb, "SMSCUSB %p could not check link: %s\n",
00604                        smscusb, strerror ( rc ) );
00605                 return rc;
00606         }
00607 
00608         DBGC ( smscusb, "SMSCUSB %p link %s (intr %#04x)\n",
00609                smscusb, ( netdev_link_ok ( netdev ) ? "up" : "down" ), intr );
00610         return 0;
00611 }
00612 
00613 /**
00614  * Enable PHY interrupts and update link status
00615  *
00616  * @v smscusb           SMSC USB device
00617  * @v phy_mask          PHY interrupt mask register
00618  * @v intrs             PHY interrupts to enable
00619  * @ret rc              Return status code
00620  */
00621 int smscusb_mii_open ( struct smscusb_device *smscusb,
00622                        unsigned int phy_mask, unsigned int intrs ) {
00623         int rc;
00624 
00625         /* Enable PHY interrupts */
00626         if ( ( rc = mii_write ( &smscusb->mii, phy_mask, intrs ) ) != 0 ) {
00627                 DBGC ( smscusb, "SMSCUSB %p could not set PHY interrupt "
00628                        "mask: %s\n", smscusb, strerror ( rc ) );
00629                 return rc;
00630         }
00631 
00632         /* Update link status */
00633         smscusb_mii_check_link ( smscusb );
00634 
00635         return 0;
00636 }
00637 
00638 /******************************************************************************
00639  *
00640  * Receive filtering
00641  *
00642  ******************************************************************************
00643  */
00644 
00645 /**
00646  * Set receive address
00647  *
00648  * @v smscusb           SMSC USB device
00649  * @v addr_base         Receive address register base
00650  * @ret rc              Return status code
00651  */
00652 int smscusb_set_address ( struct smscusb_device *smscusb,
00653                           unsigned int addr_base ) {
00654         struct net_device *netdev = smscusb->netdev;
00655         union smscusb_mac mac;
00656         int rc;
00657 
00658         /* Copy MAC address */
00659         memset ( &mac, 0, sizeof ( mac ) );
00660         memcpy ( mac.raw, netdev->ll_addr, ETH_ALEN );
00661 
00662         /* Write MAC address high register */
00663         if ( ( rc = smscusb_raw_writel ( smscusb,
00664                                          ( addr_base + SMSCUSB_RX_ADDRH ),
00665                                          mac.addr.h ) ) != 0 )
00666                 return rc;
00667 
00668         /* Write MAC address low register */
00669         if ( ( rc = smscusb_raw_writel ( smscusb,
00670                                          ( addr_base + SMSCUSB_RX_ADDRL ),
00671                                          mac.addr.l ) ) != 0 )
00672                 return rc;
00673 
00674         return 0;
00675 }
00676 
00677 /**
00678  * Set receive filter
00679  *
00680  * @v smscusb           SMSC USB device
00681  * @v filt_base         Receive filter register base
00682  * @ret rc              Return status code
00683  */
00684 int smscusb_set_filter ( struct smscusb_device *smscusb,
00685                          unsigned int filt_base ) {
00686         struct net_device *netdev = smscusb->netdev;
00687         union smscusb_mac mac;
00688         int rc;
00689 
00690         /* Copy MAC address */
00691         memset ( &mac, 0, sizeof ( mac ) );
00692         memcpy ( mac.raw, netdev->ll_addr, ETH_ALEN );
00693         mac.addr.h |= cpu_to_le32 ( SMSCUSB_ADDR_FILTH_VALID );
00694 
00695         /* Write MAC address perfect filter high register */
00696         if ( ( rc = smscusb_raw_writel ( smscusb,
00697                                          ( filt_base + SMSCUSB_ADDR_FILTH(0) ),
00698                                          mac.addr.h ) ) != 0 )
00699                 return rc;
00700 
00701         /* Write MAC address perfect filter low register */
00702         if ( ( rc = smscusb_raw_writel ( smscusb,
00703                                          ( filt_base + SMSCUSB_ADDR_FILTL(0) ),
00704                                          mac.addr.l ) ) != 0 )
00705                 return rc;
00706 
00707         return 0;
00708 }
00709 
00710 /******************************************************************************
00711  *
00712  * Endpoint operations
00713  *
00714  ******************************************************************************
00715  */
00716 
00717 /**
00718  * Complete interrupt transfer
00719  *
00720  * @v ep                USB endpoint
00721  * @v iobuf             I/O buffer
00722  * @v rc                Completion status code
00723  */
00724 static void smscusb_intr_complete ( struct usb_endpoint *ep,
00725                                     struct io_buffer *iobuf, int rc ) {
00726         struct smscusb_device *smscusb =
00727                 container_of ( ep, struct smscusb_device, usbnet.intr );
00728         struct net_device *netdev = smscusb->netdev;
00729         struct smscusb_interrupt *intr;
00730 
00731         /* Profile completions */
00732         profile_start ( &smscusb_intr_profiler );
00733 
00734         /* Ignore packets cancelled when the endpoint closes */
00735         if ( ! ep->open )
00736                 goto done;
00737 
00738         /* Record USB errors against the network device */
00739         if ( rc != 0 ) {
00740                 DBGC ( smscusb, "SMSCUSB %p interrupt failed: %s\n",
00741                        smscusb, strerror ( rc ) );
00742                 DBGC_HDA ( smscusb, 0, iobuf->data, iob_len ( iobuf ) );
00743                 netdev_rx_err ( netdev, NULL, rc );
00744                 goto done;
00745         }
00746 
00747         /* Extract interrupt data */
00748         if ( iob_len ( iobuf ) != sizeof ( *intr ) ) {
00749                 DBGC ( smscusb, "SMSCUSB %p malformed interrupt\n",
00750                        smscusb );
00751                 DBGC_HDA ( smscusb, 0, iobuf->data, iob_len ( iobuf ) );
00752                 netdev_rx_err ( netdev, NULL, rc );
00753                 goto done;
00754         }
00755         intr = iobuf->data;
00756 
00757         /* Record interrupt status */
00758         smscusb->int_sts = le32_to_cpu ( intr->int_sts );
00759         profile_stop ( &smscusb_intr_profiler );
00760 
00761  done:
00762         /* Free I/O buffer */
00763         free_iob ( iobuf );
00764 }
00765 
00766 /** Interrupt endpoint operations */
00767 struct usb_endpoint_driver_operations smscusb_intr_operations = {
00768         .complete = smscusb_intr_complete,
00769 };
00770 
00771 /**
00772  * Complete bulk OUT transfer
00773  *
00774  * @v ep                USB endpoint
00775  * @v iobuf             I/O buffer
00776  * @v rc                Completion status code
00777  */
00778 static void smscusb_out_complete ( struct usb_endpoint *ep,
00779                                    struct io_buffer *iobuf, int rc ) {
00780         struct smscusb_device *smscusb =
00781                 container_of ( ep, struct smscusb_device, usbnet.out );
00782         struct net_device *netdev = smscusb->netdev;
00783 
00784         /* Report TX completion */
00785         netdev_tx_complete_err ( netdev, iobuf, rc );
00786 }
00787 
00788 /** Bulk OUT endpoint operations */
00789 struct usb_endpoint_driver_operations smscusb_out_operations = {
00790         .complete = smscusb_out_complete,
00791 };