The history of PF_PACKET sockets starts differing from that of common (i.e., PF_INET) ones as early as the socket() system call is invoked. The socket() system call, handled internally by the sys_socket() function in net/socket.c, uses the sock_create() function to determine the protocol family operations related to the specified family. This piece of information comes from the net_families array, where it has been put at kernel startup time by a call to sock_register(). At this point, the kernel is able to call the create() function specific for the given family, which will produce an appropriate sock structure and complete the creation phase.
In the case of PF_PACKET sockets, the create() function corresponds to packet_create() in net/packet/af_packet.c. Among other things, this function takes care of writing a reference into the sock structure to the protocol-specific operations. Note that this is different from the family-specific operations: the latter contain just a pointer to the create function, while the protocol-specific operations entail the whole set of functions that can be executed for a given socket (e.g., accept, connect, bind, ioctl, listen, sendmsg and so on—have a look at include/linux/net.h for the complete list).